RecentsActivity.java revision 147ecaf3ba5d72872e8ff324aa32c0d228ada7f5
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.systemui.recents; 18 19import android.app.Activity; 20import android.app.ActivityOptions; 21import android.app.SearchManager; 22import android.appwidget.AppWidgetManager; 23import android.appwidget.AppWidgetProviderInfo; 24import android.content.BroadcastReceiver; 25import android.content.Context; 26import android.content.Intent; 27import android.content.IntentFilter; 28import android.content.res.Configuration; 29import android.os.Bundle; 30import android.os.SystemClock; 31import android.os.UserHandle; 32import android.view.KeyEvent; 33import android.view.View; 34import android.view.ViewStub; 35import android.widget.Toast; 36 37import com.android.internal.logging.MetricsLogger; 38import com.android.systemui.Prefs; 39import com.android.systemui.R; 40import com.android.systemui.recents.misc.Console; 41import com.android.systemui.recents.misc.DebugTrigger; 42import com.android.systemui.recents.misc.ReferenceCountedTrigger; 43import com.android.systemui.recents.misc.SystemServicesProxy; 44import com.android.systemui.recents.model.RecentsTaskLoadPlan; 45import com.android.systemui.recents.model.RecentsTaskLoader; 46import com.android.systemui.recents.model.Task; 47import com.android.systemui.recents.model.TaskStack; 48import com.android.systemui.recents.views.DebugOverlayView; 49import com.android.systemui.recents.views.RecentsView; 50import com.android.systemui.recents.views.SystemBarScrimViews; 51import com.android.systemui.recents.views.ViewAnimation; 52 53import java.lang.ref.WeakReference; 54import java.util.ArrayList; 55 56/** 57 * The main Recents activity that is started from AlternateRecentsComponent. 58 */ 59public class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks, 60 RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks, 61 DebugOverlayView.DebugOverlayViewCallbacks { 62 63 RecentsConfiguration mConfig; 64 long mLastTabKeyEventTime; 65 66 // Top level views 67 RecentsView mRecentsView; 68 SystemBarScrimViews mScrimViews; 69 ViewStub mEmptyViewStub; 70 ViewStub mDebugOverlayStub; 71 View mEmptyView; 72 DebugOverlayView mDebugOverlay; 73 74 // Resize task debug 75 RecentsResizeTaskDialog mResizeTaskDebugDialog; 76 77 // Search AppWidget 78 AppWidgetProviderInfo mSearchWidgetInfo; 79 RecentsAppWidgetHost mAppWidgetHost; 80 RecentsAppWidgetHostView mSearchWidgetHostView; 81 82 // Runnables to finish the Recents activity 83 FinishRecentsRunnable mFinishLaunchHomeRunnable; 84 85 // Runnable to be executed after we paused ourselves 86 Runnable mAfterPauseRunnable; 87 88 /** 89 * A common Runnable to finish Recents either by calling finish() (with a custom animation) or 90 * launching Home with some ActivityOptions. Generally we always launch home when we exit 91 * Recents rather than just finishing the activity since we don't know what is behind Recents in 92 * the task stack. The only case where we finish() directly is when we are cancelling the full 93 * screen transition from the app. 94 */ 95 class FinishRecentsRunnable implements Runnable { 96 Intent mLaunchIntent; 97 ActivityOptions mLaunchOpts; 98 99 /** 100 * Creates a finish runnable that starts the specified intent, using the given 101 * ActivityOptions. 102 */ 103 public FinishRecentsRunnable(Intent launchIntent, ActivityOptions opts) { 104 mLaunchIntent = launchIntent; 105 mLaunchOpts = opts; 106 } 107 108 @Override 109 public void run() { 110 // Finish Recents 111 if (mLaunchIntent != null) { 112 try { 113 if (mLaunchOpts != null) { 114 startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(), UserHandle.CURRENT); 115 } else { 116 startActivityAsUser(mLaunchIntent, UserHandle.CURRENT); 117 } 118 } catch (Exception e) { 119 Console.logError(RecentsActivity.this, 120 getString(R.string.recents_launch_error_message, "Home")); 121 } 122 } else { 123 finish(); 124 overridePendingTransition(R.anim.recents_to_launcher_enter, 125 R.anim.recents_to_launcher_exit); 126 } 127 } 128 } 129 130 /** 131 * Broadcast receiver to handle messages from AlternateRecentsComponent. 132 */ 133 final BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() { 134 @Override 135 public void onReceive(Context context, Intent intent) { 136 String action = intent.getAction(); 137 if (action.equals(Recents.ACTION_HIDE_RECENTS_ACTIVITY)) { 138 if (intent.getBooleanExtra(Recents.EXTRA_TRIGGERED_FROM_ALT_TAB, false)) { 139 // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app 140 dismissRecentsToFocusedTaskOrHome(false); 141 } else if (intent.getBooleanExtra(Recents.EXTRA_TRIGGERED_FROM_HOME_KEY, false)) { 142 // Otherwise, dismiss Recents to Home 143 dismissRecentsToHomeRaw(true); 144 } else { 145 // Do nothing 146 } 147 } else if (action.equals(Recents.ACTION_TOGGLE_RECENTS_ACTIVITY)) { 148 // If we are toggling Recents, then first unfilter any filtered stacks first 149 dismissRecentsToFocusedTaskOrHome(true); 150 } else if (action.equals(Recents.ACTION_START_ENTER_ANIMATION)) { 151 // Trigger the enter animation 152 onEnterAnimationTriggered(); 153 // Notify the fallback receiver that we have successfully got the broadcast 154 // See AlternateRecentsComponent.onAnimationStarted() 155 setResultCode(Activity.RESULT_OK); 156 } 157 } 158 }; 159 160 /** 161 * Broadcast receiver to handle messages from the system 162 */ 163 final BroadcastReceiver mSystemBroadcastReceiver = new BroadcastReceiver() { 164 @Override 165 public void onReceive(Context context, Intent intent) { 166 String action = intent.getAction(); 167 if (action.equals(Intent.ACTION_SCREEN_OFF)) { 168 // When the screen turns off, dismiss Recents to Home 169 dismissRecentsToHome(false); 170 } else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) { 171 // When the search activity changes, update the search widget view 172 SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); 173 mSearchWidgetInfo = ssp.getOrBindSearchAppWidget(context, mAppWidgetHost); 174 refreshSearchWidgetView(); 175 } 176 } 177 }; 178 179 /** 180 * A custom debug trigger to listen for a debug key chord. 181 */ 182 final DebugTrigger mDebugTrigger = new DebugTrigger(new Runnable() { 183 @Override 184 public void run() { 185 onDebugModeTriggered(); 186 } 187 }); 188 189 /** Updates the set of recent tasks */ 190 void updateRecentsTasks() { 191 // If AlternateRecentsComponent has preloaded a load plan, then use that to prevent 192 // reconstructing the task stack 193 RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); 194 RecentsTaskLoadPlan plan = Recents.consumeInstanceLoadPlan(); 195 if (plan == null) { 196 plan = loader.createLoadPlan(this); 197 } 198 199 // Start loading tasks according to the load plan 200 if (!plan.hasTasks()) { 201 loader.preloadTasks(plan, mConfig.launchedFromHome); 202 } 203 RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options(); 204 loadOpts.runningTaskId = mConfig.launchedToTaskId; 205 loadOpts.numVisibleTasks = mConfig.launchedNumVisibleTasks; 206 loadOpts.numVisibleTaskThumbnails = mConfig.launchedNumVisibleThumbnails; 207 loader.loadTasks(this, plan, loadOpts); 208 209 TaskStack stack = plan.getTaskStack(); 210 mConfig.launchedWithNoRecentTasks = !plan.hasTasks(); 211 if (!mConfig.launchedWithNoRecentTasks) { 212 mRecentsView.setTaskStack(stack); 213 } 214 215 // Create the home intent runnable 216 Intent homeIntent = new Intent(Intent.ACTION_MAIN, null); 217 homeIntent.addCategory(Intent.CATEGORY_HOME); 218 homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 219 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 220 mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent, 221 ActivityOptions.makeCustomAnimation(this, 222 mConfig.launchedFromSearchHome ? R.anim.recents_to_search_launcher_enter : 223 R.anim.recents_to_launcher_enter, 224 mConfig.launchedFromSearchHome ? R.anim.recents_to_search_launcher_exit : 225 R.anim.recents_to_launcher_exit)); 226 227 // Mark the task that is the launch target 228 int launchTaskIndexInStack = 0; 229 if (mConfig.launchedToTaskId != -1) { 230 ArrayList<Task> tasks = stack.getTasks(); 231 int taskCount = tasks.size(); 232 for (int j = 0; j < taskCount; j++) { 233 Task t = tasks.get(j); 234 if (t.key.id == mConfig.launchedToTaskId) { 235 t.isLaunchTarget = true; 236 launchTaskIndexInStack = tasks.size() - j - 1; 237 break; 238 } 239 } 240 } 241 242 // Update the top level view's visibilities 243 if (mConfig.launchedWithNoRecentTasks) { 244 if (mEmptyView == null) { 245 mEmptyView = mEmptyViewStub.inflate(); 246 } 247 mEmptyView.setVisibility(View.VISIBLE); 248 mRecentsView.setSearchBarVisibility(View.GONE); 249 } else { 250 if (mEmptyView != null) { 251 mEmptyView.setVisibility(View.GONE); 252 } 253 if (mRecentsView.hasValidSearchBar()) { 254 mRecentsView.setSearchBarVisibility(View.VISIBLE); 255 } else { 256 refreshSearchWidgetView(); 257 } 258 } 259 260 // Animate the SystemUI scrims into view 261 mScrimViews.prepareEnterRecentsAnimation(); 262 263 // Keep track of whether we launched from the nav bar button or via alt-tab 264 if (mConfig.launchedWithAltTab) { 265 MetricsLogger.count(this, "overview_trigger_alttab", 1); 266 } else { 267 MetricsLogger.count(this, "overview_trigger_nav_btn", 1); 268 } 269 // Keep track of whether we launched from an app or from home 270 if (mConfig.launchedFromAppWithThumbnail) { 271 MetricsLogger.count(this, "overview_source_app", 1); 272 // If from an app, track the stack index of the app in the stack (for affiliated tasks) 273 MetricsLogger.histogram(this, "overview_source_app_index", launchTaskIndexInStack); 274 } else { 275 MetricsLogger.count(this, "overview_source_home", 1); 276 } 277 // Keep track of the total stack task count 278 int taskCount = stack.getTaskCount(); 279 MetricsLogger.histogram(this, "overview_task_count", taskCount); 280 } 281 282 /** Dismisses recents if we are already visible and the intent is to toggle the recents view */ 283 boolean dismissRecentsToFocusedTaskOrHome(boolean checkFilteredStackState) { 284 SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); 285 if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) { 286 // If we currently have filtered stacks, then unfilter those first 287 if (checkFilteredStackState && 288 mRecentsView.unfilterFilteredStacks()) return true; 289 // If we have a focused Task, launch that Task now 290 if (mRecentsView.launchFocusedTask()) return true; 291 // If we launched from Home, then return to Home 292 if (mConfig.launchedFromHome) { 293 dismissRecentsToHomeRaw(true); 294 return true; 295 } 296 // Otherwise, try and return to the Task that Recents was launched from 297 if (mRecentsView.launchPreviousTask()) return true; 298 // If none of the other cases apply, then just go Home 299 dismissRecentsToHomeRaw(true); 300 return true; 301 } 302 return false; 303 } 304 305 /** Dismisses Recents directly to Home. */ 306 void dismissRecentsToHomeRaw(boolean animated) { 307 if (animated) { 308 ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this, 309 null, mFinishLaunchHomeRunnable, null); 310 mRecentsView.startExitToHomeAnimation( 311 new ViewAnimation.TaskViewExitContext(exitTrigger)); 312 } else { 313 mFinishLaunchHomeRunnable.run(); 314 } 315 } 316 317 /** Dismisses Recents directly to Home without transition animation. */ 318 void dismissRecentsToHomeWithoutTransitionAnimation() { 319 finish(); 320 overridePendingTransition(0, 0); 321 } 322 323 /** Dismisses Recents directly to Home if we currently aren't transitioning. */ 324 boolean dismissRecentsToHome(boolean animated) { 325 SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); 326 if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) { 327 // Return to Home 328 dismissRecentsToHomeRaw(animated); 329 return true; 330 } 331 return false; 332 } 333 334 /** Called with the activity is first created. */ 335 @Override 336 public void onCreate(Bundle savedInstanceState) { 337 super.onCreate(savedInstanceState); 338 // For the non-primary user, ensure that the SystemServicesProxy and configuration is 339 // initialized 340 RecentsTaskLoader.initialize(this); 341 SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); 342 mConfig = RecentsConfiguration.reinitialize(this, ssp); 343 344 // Initialize the widget host (the host id is static and does not change) 345 mAppWidgetHost = new RecentsAppWidgetHost(this, Constants.Values.App.AppWidgetHostId); 346 347 // Set the Recents layout 348 setContentView(R.layout.recents); 349 mRecentsView = (RecentsView) findViewById(R.id.recents_view); 350 mRecentsView.setCallbacks(this); 351 mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | 352 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | 353 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); 354 mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub); 355 mDebugOverlayStub = (ViewStub) findViewById(R.id.debug_overlay_stub); 356 mScrimViews = new SystemBarScrimViews(this, mConfig); 357 inflateDebugOverlay(); 358 359 // Bind the search app widget when we first start up 360 mSearchWidgetInfo = ssp.getOrBindSearchAppWidget(this, mAppWidgetHost); 361 362 // Register the broadcast receiver to handle messages when the screen is turned off 363 IntentFilter filter = new IntentFilter(); 364 filter.addAction(Intent.ACTION_SCREEN_OFF); 365 filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); 366 registerReceiver(mSystemBroadcastReceiver, filter); 367 } 368 369 /** Inflates the debug overlay if debug mode is enabled. */ 370 void inflateDebugOverlay() { 371 if (!Constants.DebugFlags.App.EnableDebugMode) return; 372 373 if (mConfig.debugModeEnabled && mDebugOverlay == null) { 374 // Inflate the overlay and seek bars 375 mDebugOverlay = (DebugOverlayView) mDebugOverlayStub.inflate(); 376 mDebugOverlay.setCallbacks(this); 377 mRecentsView.setDebugOverlay(mDebugOverlay); 378 } 379 } 380 381 @Override 382 protected void onNewIntent(Intent intent) { 383 super.onNewIntent(intent); 384 setIntent(intent); 385 386 // Clear any debug rects 387 if (mDebugOverlay != null) { 388 mDebugOverlay.clear(); 389 } 390 } 391 392 @Override 393 protected void onStart() { 394 super.onStart(); 395 MetricsLogger.visible(this, MetricsLogger.OVERVIEW_ACTIVITY); 396 RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); 397 SystemServicesProxy ssp = loader.getSystemServicesProxy(); 398 Recents.notifyVisibilityChanged(this, ssp, true); 399 400 // Register the broadcast receiver to handle messages from our service 401 IntentFilter filter = new IntentFilter(); 402 filter.addAction(Recents.ACTION_HIDE_RECENTS_ACTIVITY); 403 filter.addAction(Recents.ACTION_TOGGLE_RECENTS_ACTIVITY); 404 filter.addAction(Recents.ACTION_START_ENTER_ANIMATION); 405 registerReceiver(mServiceBroadcastReceiver, filter); 406 407 // Register any broadcast receivers for the task loader 408 loader.registerReceivers(this, mRecentsView); 409 410 // Update the recent tasks 411 updateRecentsTasks(); 412 413 // If this is a new instance from a configuration change, then we have to manually trigger 414 // the enter animation state, or if recents was relaunched by AM, without going through 415 // the normal mechanisms 416 boolean wasLaunchedByAm = !mConfig.launchedFromHome && !mConfig.launchedFromAppWithThumbnail; 417 if (mConfig.launchedHasConfigurationChanged || wasLaunchedByAm) { 418 onEnterAnimationTriggered(); 419 } 420 421 if (!mConfig.launchedHasConfigurationChanged) { 422 mRecentsView.disableLayersForOneFrame(); 423 } 424 } 425 426 @Override 427 protected void onPause() { 428 super.onPause(); 429 if (mAfterPauseRunnable != null) { 430 mRecentsView.post(mAfterPauseRunnable); 431 mAfterPauseRunnable = null; 432 } 433 } 434 435 @Override 436 protected void onStop() { 437 super.onStop(); 438 MetricsLogger.hidden(this, MetricsLogger.OVERVIEW_ACTIVITY); 439 RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); 440 SystemServicesProxy ssp = loader.getSystemServicesProxy(); 441 Recents.notifyVisibilityChanged(this, ssp, false); 442 443 // Notify the views that we are no longer visible 444 mRecentsView.onRecentsHidden(); 445 446 // Unregister the RecentsService receiver 447 unregisterReceiver(mServiceBroadcastReceiver); 448 449 // Unregister any broadcast receivers for the task loader 450 loader.unregisterReceivers(); 451 452 // Workaround for b/22542869, if the RecentsActivity is started again, but without going 453 // through SystemUI, we need to reset the config launch flags to ensure that we do not 454 // wait on the system to send a signal that was never queued. 455 mConfig.launchedFromHome = false; 456 mConfig.launchedFromSearchHome = false; 457 mConfig.launchedFromAppWithThumbnail = false; 458 mConfig.launchedToTaskId = -1; 459 mConfig.launchedWithAltTab = false; 460 mConfig.launchedHasConfigurationChanged = false; 461 } 462 463 @Override 464 protected void onDestroy() { 465 super.onDestroy(); 466 467 // Unregister the system broadcast receivers 468 unregisterReceiver(mSystemBroadcastReceiver); 469 470 // Stop listening for widget package changes if there was one bound 471 mAppWidgetHost.stopListening(); 472 } 473 474 public void onEnterAnimationTriggered() { 475 // Try and start the enter animation (or restart it on configuration changed) 476 ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null); 477 ViewAnimation.TaskViewEnterContext ctx = new ViewAnimation.TaskViewEnterContext(t); 478 mRecentsView.startEnterRecentsAnimation(ctx); 479 480 if (mSearchWidgetInfo != null) { 481 final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> cbRef = 482 new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>( 483 RecentsActivity.this); 484 ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() { 485 @Override 486 public void run() { 487 // Start listening for widget package changes if there is one bound 488 RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = cbRef.get(); 489 if (cb != null) { 490 mAppWidgetHost.startListening(cb); 491 } 492 } 493 }); 494 } 495 496 // Animate the SystemUI scrim views 497 mScrimViews.startEnterRecentsAnimation(); 498 } 499 500 @Override 501 public void onTrimMemory(int level) { 502 RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); 503 if (loader != null) { 504 loader.onTrimMemory(level); 505 } 506 } 507 508 @Override 509 public boolean onKeyDown(int keyCode, KeyEvent event) { 510 switch (keyCode) { 511 case KeyEvent.KEYCODE_TAB: { 512 boolean hasRepKeyTimeElapsed = (SystemClock.elapsedRealtime() - 513 mLastTabKeyEventTime) > mConfig.altTabKeyDelay; 514 if (event.getRepeatCount() <= 0 || hasRepKeyTimeElapsed) { 515 // Focus the next task in the stack 516 final boolean backward = event.isShiftPressed(); 517 mRecentsView.focusNextTask(!backward); 518 mLastTabKeyEventTime = SystemClock.elapsedRealtime(); 519 } 520 return true; 521 } 522 case KeyEvent.KEYCODE_DPAD_UP: { 523 mRecentsView.focusNextTask(true); 524 return true; 525 } 526 case KeyEvent.KEYCODE_DPAD_DOWN: { 527 mRecentsView.focusNextTask(false); 528 return true; 529 } 530 case KeyEvent.KEYCODE_DEL: 531 case KeyEvent.KEYCODE_FORWARD_DEL: { 532 mRecentsView.dismissFocusedTask(); 533 // Keep track of deletions by keyboard 534 MetricsLogger.histogram(this, "overview_task_dismissed_source", 535 Constants.Metrics.DismissSourceKeyboard); 536 return true; 537 } 538 default: 539 break; 540 } 541 // Pass through the debug trigger 542 mDebugTrigger.onKeyEvent(keyCode); 543 return super.onKeyDown(keyCode, event); 544 } 545 546 @Override 547 public void onUserInteraction() { 548 mRecentsView.onUserInteraction(); 549 } 550 551 @Override 552 public void onBackPressed() { 553 // Test mode where back does not do anything 554 if (mConfig.debugModeEnabled) return; 555 556 // Dismiss Recents to the focused Task or Home 557 dismissRecentsToFocusedTaskOrHome(true); 558 } 559 560 /** Called when debug mode is triggered */ 561 public void onDebugModeTriggered() { 562 if (mConfig.developerOptionsEnabled) { 563 if (Prefs.getBoolean(this, Prefs.Key.DEBUG_MODE_ENABLED, false /* boolean */)) { 564 // Disable the debug mode 565 Prefs.remove(this, Prefs.Key.DEBUG_MODE_ENABLED); 566 mConfig.debugModeEnabled = false; 567 inflateDebugOverlay(); 568 if (mDebugOverlay != null) { 569 mDebugOverlay.disable(); 570 } 571 } else { 572 // Enable the debug mode 573 Prefs.putBoolean(this, Prefs.Key.DEBUG_MODE_ENABLED, true); 574 mConfig.debugModeEnabled = true; 575 inflateDebugOverlay(); 576 if (mDebugOverlay != null) { 577 mDebugOverlay.enable(); 578 } 579 } 580 Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion + ") " + 581 (mConfig.debugModeEnabled ? "Enabled" : "Disabled") + ", please restart Recents now", 582 Toast.LENGTH_SHORT).show(); 583 } 584 } 585 586 587 /**** RecentsResizeTaskDialog ****/ 588 589 private RecentsResizeTaskDialog getResizeTaskDebugDialog() { 590 if (mResizeTaskDebugDialog == null) { 591 mResizeTaskDebugDialog = new RecentsResizeTaskDialog(getFragmentManager(), this); 592 } 593 return mResizeTaskDebugDialog; 594 } 595 596 @Override 597 public void onTaskResize(Task t) { 598 getResizeTaskDebugDialog().showResizeTaskDialog(t, mRecentsView); 599 } 600 601 /**** RecentsView.RecentsViewCallbacks Implementation ****/ 602 603 @Override 604 public void onExitToHomeAnimationTriggered() { 605 // Animate the SystemUI scrim views out 606 mScrimViews.startExitRecentsAnimation(); 607 } 608 609 @Override 610 public void onTaskViewClicked() { 611 } 612 613 @Override 614 public void onTaskLaunchFailed() { 615 // Return to Home 616 dismissRecentsToHomeRaw(true); 617 } 618 619 @Override 620 public void onAllTaskViewsDismissed() { 621 mFinishLaunchHomeRunnable.run(); 622 } 623 624 @Override 625 public void onScreenPinningRequest() { 626 RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); 627 SystemServicesProxy ssp = loader.getSystemServicesProxy(); 628 Recents.startScreenPinning(this, ssp); 629 630 MetricsLogger.count(this, "overview_screen_pinned", 1); 631 } 632 633 @Override 634 public void runAfterPause(Runnable r) { 635 mAfterPauseRunnable = r; 636 } 637 638 /**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/ 639 640 @Override 641 public void refreshSearchWidgetView() { 642 if (mSearchWidgetInfo != null) { 643 SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); 644 int searchWidgetId = ssp.getSearchAppWidgetId(this); 645 mSearchWidgetHostView = (RecentsAppWidgetHostView) mAppWidgetHost.createView( 646 this, searchWidgetId, mSearchWidgetInfo); 647 Bundle opts = new Bundle(); 648 opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, 649 AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX); 650 mSearchWidgetHostView.updateAppWidgetOptions(opts); 651 // Set the padding to 0 for this search widget 652 mSearchWidgetHostView.setPadding(0, 0, 0, 0); 653 mRecentsView.setSearchBar(mSearchWidgetHostView); 654 } else { 655 mRecentsView.setSearchBar(null); 656 } 657 } 658 659 /**** DebugOverlayView.DebugOverlayViewCallbacks ****/ 660 661 @Override 662 public void onPrimarySeekBarChanged(float progress) { 663 // Do nothing 664 } 665 666 @Override 667 public void onSecondarySeekBarChanged(float progress) { 668 // Do nothing 669 } 670} 671