RecentsActivity.java revision 606b3da71ab64e489e8f65e0b1092138dbfaf7b7
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.AppWidgetHostView; 23import android.appwidget.AppWidgetManager; 24import android.appwidget.AppWidgetProviderInfo; 25import android.content.BroadcastReceiver; 26import android.content.Context; 27import android.content.Intent; 28import android.content.IntentFilter; 29import android.content.SharedPreferences; 30import android.os.Bundle; 31import android.os.UserHandle; 32import android.util.Pair; 33import android.view.KeyEvent; 34import android.view.View; 35import android.view.ViewStub; 36import android.widget.Toast; 37import com.android.systemui.R; 38import com.android.systemui.recents.misc.DebugTrigger; 39import com.android.systemui.recents.misc.ReferenceCountedTrigger; 40import com.android.systemui.recents.misc.SystemServicesProxy; 41import com.android.systemui.recents.misc.Utilities; 42import com.android.systemui.recents.model.RecentsTaskLoader; 43import com.android.systemui.recents.model.SpaceNode; 44import com.android.systemui.recents.model.Task; 45import com.android.systemui.recents.model.TaskStack; 46import com.android.systemui.recents.views.DebugOverlayView; 47import com.android.systemui.recents.views.RecentsView; 48import com.android.systemui.recents.views.SystemBarScrimViews; 49import com.android.systemui.recents.views.ViewAnimation; 50 51import java.lang.ref.WeakReference; 52import java.lang.reflect.InvocationTargetException; 53import java.util.ArrayList; 54 55/** 56 * The main Recents activity that is started from AlternateRecentsComponent. 57 */ 58public class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks, 59 RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks, 60 DebugOverlayView.DebugOverlayViewCallbacks { 61 62 RecentsConfiguration mConfig; 63 boolean mVisible; 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 // Search AppWidget 75 RecentsAppWidgetHost mAppWidgetHost; 76 AppWidgetProviderInfo mSearchAppWidgetInfo; 77 AppWidgetHostView mSearchAppWidgetHostView; 78 79 // Runnables to finish the Recents activity 80 FinishRecentsRunnable mFinishLaunchHomeRunnable; 81 82 /** 83 * A common Runnable to finish Recents either by calling finish() (with a custom animation) or 84 * launching Home with some ActivityOptions. Generally we always launch home when we exit 85 * Recents rather than just finishing the activity since we don't know what is behind Recents in 86 * the task stack. The only case where we finish() directly is when we are cancelling the full 87 * screen transition from the app. 88 */ 89 class FinishRecentsRunnable implements Runnable { 90 Intent mLaunchIntent; 91 ActivityOptions mLaunchOpts; 92 93 /** 94 * Creates a finish runnable that starts the specified intent, using the given 95 * ActivityOptions. 96 */ 97 public FinishRecentsRunnable(Intent launchIntent, ActivityOptions opts) { 98 mLaunchIntent = launchIntent; 99 mLaunchOpts = opts; 100 } 101 102 @Override 103 public void run() { 104 // Mark Recents as no longer visible 105 AlternateRecentsComponent.notifyVisibilityChanged(false); 106 mVisible = false; 107 // Finish Recents 108 if (mLaunchIntent != null) { 109 if (mLaunchOpts != null) { 110 startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(), UserHandle.CURRENT); 111 } else { 112 startActivityAsUser(mLaunchIntent, UserHandle.CURRENT); 113 } 114 } else { 115 finish(); 116 overridePendingTransition(R.anim.recents_to_launcher_enter, 117 R.anim.recents_to_launcher_exit); 118 } 119 } 120 } 121 122 /** 123 * Broadcast receiver to handle messages from AlternateRecentsComponent. 124 */ 125 final BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() { 126 @Override 127 public void onReceive(Context context, Intent intent) { 128 String action = intent.getAction(); 129 if (action.equals(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY)) { 130 // Mark Recents as no longer visible 131 AlternateRecentsComponent.notifyVisibilityChanged(false); 132 if (intent.getBooleanExtra(AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false)) { 133 // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app 134 dismissRecentsToFocusedTaskOrHome(false); 135 } else if (intent.getBooleanExtra(AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_HOME_KEY, false)) { 136 // Otherwise, dismiss Recents to Home 137 dismissRecentsToHome(true); 138 } else { 139 // Do nothing, another activity is being launched on top of Recents 140 } 141 } else if (action.equals(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY)) { 142 // If we are toggling Recents, then first unfilter any filtered stacks first 143 dismissRecentsToFocusedTaskOrHome(true); 144 } else if (action.equals(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION)) { 145 // Try and start the enter animation (or restart it on configuration changed) 146 ReferenceCountedTrigger t = new ReferenceCountedTrigger(context, null, null, null); 147 mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t)); 148 onEnterAnimationTriggered(); 149 // Notify the fallback receiver that we have successfully got the broadcast 150 // See AlternateRecentsComponent.onAnimationStarted() 151 setResultCode(Activity.RESULT_OK); 152 } 153 } 154 }; 155 156 /** 157 * Broadcast receiver to handle messages from the system 158 */ 159 final BroadcastReceiver mSystemBroadcastReceiver = new BroadcastReceiver() { 160 @Override 161 public void onReceive(Context context, Intent intent) { 162 String action = intent.getAction(); 163 if (action.equals(Intent.ACTION_SCREEN_OFF)) { 164 // When the screen turns off, dismiss Recents to Home 165 dismissRecentsToHome(false); 166 } else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) { 167 // When the search activity changes, update the Search widget 168 refreshSearchWidget(); 169 } 170 } 171 }; 172 173 /** 174 * A custom debug trigger to listen for a debug key chord. 175 */ 176 final DebugTrigger mDebugTrigger = new DebugTrigger(new Runnable() { 177 @Override 178 public void run() { 179 onDebugModeTriggered(); 180 } 181 }); 182 183 /** Updates the set of recent tasks */ 184 void updateRecentsTasks(Intent launchIntent) { 185 // Update the configuration based on the launch intent 186 boolean fromSearchHome = launchIntent.getBooleanExtra( 187 AlternateRecentsComponent.EXTRA_FROM_SEARCH_HOME, false); 188 mConfig.launchedFromHome = fromSearchHome || launchIntent.getBooleanExtra( 189 AlternateRecentsComponent.EXTRA_FROM_HOME, false); 190 mConfig.launchedFromAppWithThumbnail = launchIntent.getBooleanExtra( 191 AlternateRecentsComponent.EXTRA_FROM_APP_THUMBNAIL, false); 192 mConfig.launchedToTaskId = launchIntent.getIntExtra( 193 AlternateRecentsComponent.EXTRA_FROM_TASK_ID, -1); 194 mConfig.launchedWithAltTab = launchIntent.getBooleanExtra( 195 AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false); 196 197 // Load all the tasks 198 RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); 199 SpaceNode root = loader.reload(this, 200 Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount, 201 mConfig.launchedFromHome); 202 ArrayList<TaskStack> stacks = root.getStacks(); 203 if (!stacks.isEmpty()) { 204 mRecentsView.setTaskStacks(root.getStacks()); 205 } 206 mConfig.launchedWithNoRecentTasks = !root.hasTasks(); 207 208 // Create the home intent runnable 209 Intent homeIntent = new Intent(Intent.ACTION_MAIN, null); 210 homeIntent.addCategory(Intent.CATEGORY_HOME); 211 homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 212 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 213 mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent, 214 ActivityOptions.makeCustomAnimation(this, 215 fromSearchHome ? R.anim.recents_to_search_launcher_enter : 216 R.anim.recents_to_launcher_enter, 217 fromSearchHome ? R.anim.recents_to_search_launcher_exit : 218 R.anim.recents_to_launcher_exit)); 219 220 // Mark the task that is the launch target 221 int taskStackCount = stacks.size(); 222 if (mConfig.launchedToTaskId != -1) { 223 for (int i = 0; i < taskStackCount; i++) { 224 TaskStack stack = stacks.get(i); 225 ArrayList<Task> tasks = stack.getTasks(); 226 int taskCount = tasks.size(); 227 for (int j = 0; j < taskCount; j++) { 228 Task t = tasks.get(j); 229 if (t.key.id == mConfig.launchedToTaskId) { 230 t.isLaunchTarget = true; 231 break; 232 } 233 } 234 } 235 } 236 237 // Update the top level view's visibilities 238 if (mConfig.launchedWithNoRecentTasks) { 239 if (mEmptyView == null) { 240 mEmptyView = mEmptyViewStub.inflate(); 241 } 242 mEmptyView.setVisibility(View.VISIBLE); 243 mRecentsView.setSearchBarVisibility(View.GONE); 244 } else { 245 if (mEmptyView != null) { 246 mEmptyView.setVisibility(View.GONE); 247 } 248 if (mRecentsView.hasSearchBar()) { 249 mRecentsView.setSearchBarVisibility(View.VISIBLE); 250 } else { 251 addSearchBarAppWidgetView(); 252 } 253 } 254 255 // Animate the SystemUI scrims into view 256 mScrimViews.prepareEnterRecentsAnimation(); 257 } 258 259 /** Attempts to allocate and bind the search bar app widget */ 260 void bindSearchBarAppWidget() { 261 if (Constants.DebugFlags.App.EnableSearchLayout) { 262 SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); 263 264 // Reset the host view and widget info 265 mSearchAppWidgetHostView = null; 266 mSearchAppWidgetInfo = null; 267 268 // Try and load the app widget id from the settings 269 int appWidgetId = mConfig.searchBarAppWidgetId; 270 if (appWidgetId >= 0) { 271 mSearchAppWidgetInfo = ssp.getAppWidgetInfo(appWidgetId); 272 if (mSearchAppWidgetInfo == null) { 273 // If there is no actual widget associated with that id, then delete it and 274 // prepare to bind another app widget in its place 275 ssp.unbindSearchAppWidget(mAppWidgetHost, appWidgetId); 276 appWidgetId = -1; 277 } 278 } 279 280 // If there is no id, then bind a new search app widget 281 if (appWidgetId < 0) { 282 Pair<Integer, AppWidgetProviderInfo> widgetInfo = 283 ssp.bindSearchAppWidget(mAppWidgetHost); 284 if (widgetInfo != null) { 285 // Save the app widget id into the settings 286 mConfig.updateSearchBarAppWidgetId(this, widgetInfo.first); 287 mSearchAppWidgetInfo = widgetInfo.second; 288 } 289 } 290 } 291 } 292 293 /** Creates the search bar app widget view */ 294 void addSearchBarAppWidgetView() { 295 if (Constants.DebugFlags.App.EnableSearchLayout) { 296 int appWidgetId = mConfig.searchBarAppWidgetId; 297 if (appWidgetId >= 0) { 298 mSearchAppWidgetHostView = mAppWidgetHost.createView(this, appWidgetId, 299 mSearchAppWidgetInfo); 300 Bundle opts = new Bundle(); 301 opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, 302 AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX); 303 mSearchAppWidgetHostView.updateAppWidgetOptions(opts); 304 // Set the padding to 0 for this search widget 305 mSearchAppWidgetHostView.setPadding(0, 0, 0, 0); 306 mRecentsView.setSearchBar(mSearchAppWidgetHostView); 307 } else { 308 mRecentsView.setSearchBar(null); 309 } 310 } 311 } 312 313 /** Dismisses recents if we are already visible and the intent is to toggle the recents view */ 314 boolean dismissRecentsToFocusedTaskOrHome(boolean checkFilteredStackState) { 315 if (mVisible) { 316 // If we currently have filtered stacks, then unfilter those first 317 if (checkFilteredStackState && 318 mRecentsView.unfilterFilteredStacks()) return true; 319 // If we have a focused Task, launch that Task now 320 if (mRecentsView.launchFocusedTask()) return true; 321 // If we launched from Home, then return to Home 322 if (mConfig.launchedFromHome) { 323 dismissRecentsToHomeRaw(true); 324 return true; 325 } 326 // Otherwise, try and return to the Task that Recents was launched from 327 if (mRecentsView.launchPreviousTask()) return true; 328 // If none of the other cases apply, then just go Home 329 dismissRecentsToHomeRaw(true); 330 return true; 331 } 332 return false; 333 } 334 335 /** Dismisses Recents directly to Home. */ 336 void dismissRecentsToHomeRaw(boolean animated) { 337 if (animated) { 338 ReferenceCountedTrigger exitTrigger = new ReferenceCountedTrigger(this, 339 null, mFinishLaunchHomeRunnable, null); 340 mRecentsView.startExitToHomeAnimation( 341 new ViewAnimation.TaskViewExitContext(exitTrigger)); 342 } else { 343 mFinishLaunchHomeRunnable.run(); 344 } 345 } 346 347 /** Dismisses Recents directly to Home if we currently aren't transitioning. */ 348 boolean dismissRecentsToHome(boolean animated) { 349 if (mVisible) { 350 // Return to Home 351 dismissRecentsToHomeRaw(animated); 352 return true; 353 } 354 return false; 355 } 356 357 /** Called with the activity is first created. */ 358 @Override 359 public void onCreate(Bundle savedInstanceState) { 360 super.onCreate(savedInstanceState); 361 // For the non-primary user, ensure that the SystemSericesProxy is initialized 362 RecentsTaskLoader.initialize(this); 363 364 // Initialize the loader and the configuration 365 mConfig = RecentsConfiguration.reinitialize(this, 366 RecentsTaskLoader.getInstance().getSystemServicesProxy()); 367 368 // Initialize the widget host (the host id is static and does not change) 369 mAppWidgetHost = new RecentsAppWidgetHost(this, Constants.Values.App.AppWidgetHostId); 370 371 // Set the Recents layout 372 setContentView(R.layout.recents); 373 mRecentsView = (RecentsView) findViewById(R.id.recents_view); 374 mRecentsView.setCallbacks(this); 375 mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | 376 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | 377 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); 378 mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub); 379 mDebugOverlayStub = (ViewStub) findViewById(R.id.debug_overlay_stub); 380 mScrimViews = new SystemBarScrimViews(this, mConfig); 381 inflateDebugOverlay(); 382 383 // Bind the search app widget when we first start up 384 bindSearchBarAppWidget(); 385 // Update the recent tasks 386 updateRecentsTasks(getIntent()); 387 388 // Register the broadcast receiver to handle messages when the screen is turned off 389 IntentFilter filter = new IntentFilter(); 390 filter.addAction(Intent.ACTION_SCREEN_OFF); 391 filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); 392 registerReceiver(mSystemBroadcastReceiver, filter); 393 394 // Private API calls to make the shadows look better 395 try { 396 Utilities.setShadowProperty("ambientRatio", String.valueOf(1.5f)); 397 } catch (IllegalAccessException e) { 398 e.printStackTrace(); 399 } catch (InvocationTargetException e) { 400 e.printStackTrace(); 401 } 402 403 // Update if we are getting a configuration change 404 if (savedInstanceState != null) { 405 mConfig.updateOnConfigurationChange(); 406 onConfigurationChange(); 407 } 408 409 // Start listening for widget package changes if there is one bound, post it since we don't 410 // want it stalling the startup 411 if (mConfig.searchBarAppWidgetId >= 0) { 412 final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> callback = 413 new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(this); 414 mRecentsView.post(new Runnable() { 415 @Override 416 public void run() { 417 RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = callback.get(); 418 if (cb != null) { 419 mAppWidgetHost.startListening(cb); 420 } 421 } 422 }); 423 } 424 } 425 426 /** Inflates the debug overlay if debug mode is enabled. */ 427 void inflateDebugOverlay() { 428 if (mConfig.debugModeEnabled && mDebugOverlay == null) { 429 // Inflate the overlay and seek bars 430 mDebugOverlay = (DebugOverlayView) mDebugOverlayStub.inflate(); 431 mDebugOverlay.setCallbacks(this); 432 mRecentsView.setDebugOverlay(mDebugOverlay); 433 } 434 } 435 436 void onConfigurationChange() { 437 // Update RecentsConfiguration 438 mConfig = RecentsConfiguration.reinitialize(this, 439 RecentsTaskLoader.getInstance().getSystemServicesProxy()); 440 441 // Try and start the enter animation (or restart it on configuration changed) 442 ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null); 443 mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t)); 444 onEnterAnimationTriggered(); 445 } 446 447 @Override 448 protected void onNewIntent(Intent intent) { 449 super.onNewIntent(intent); 450 setIntent(intent); 451 452 // Reinitialize the configuration 453 RecentsConfiguration.reinitialize(this, RecentsTaskLoader.getInstance().getSystemServicesProxy()); 454 455 // Clear any debug rects 456 if (mDebugOverlay != null) { 457 mDebugOverlay.clear(); 458 } 459 460 // Update the recent tasks 461 updateRecentsTasks(intent); 462 } 463 464 @Override 465 protected void onStart() { 466 super.onStart(); 467 468 // Register the broadcast receiver to handle messages from our service 469 IntentFilter filter = new IntentFilter(); 470 filter.addAction(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY); 471 filter.addAction(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY); 472 filter.addAction(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION); 473 registerReceiver(mServiceBroadcastReceiver, filter); 474 475 // Register any broadcast receivers for the task loader 476 RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView); 477 } 478 479 @Override 480 protected void onResume() { 481 super.onResume(); 482 483 // Mark Recents as visible 484 mVisible = true; 485 } 486 487 @Override 488 protected void onStop() { 489 super.onStop(); 490 491 // Remove all the views 492 mRecentsView.removeAllTaskStacks(); 493 494 // Unregister the RecentsService receiver 495 unregisterReceiver(mServiceBroadcastReceiver); 496 497 // Unregister any broadcast receivers for the task loader 498 RecentsTaskLoader.getInstance().unregisterReceivers(); 499 } 500 501 @Override 502 protected void onDestroy() { 503 super.onDestroy(); 504 505 // Unregister the system broadcast receivers 506 unregisterReceiver(mSystemBroadcastReceiver); 507 508 // Stop listening for widget package changes if there was one bound 509 if (mAppWidgetHost.isListening()) { 510 mAppWidgetHost.stopListening(); 511 } 512 } 513 514 @Override 515 public void onTrimMemory(int level) { 516 RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); 517 if (loader != null) { 518 loader.onTrimMemory(level); 519 } 520 } 521 522 @Override 523 public boolean onKeyDown(int keyCode, KeyEvent event) { 524 switch (keyCode) { 525 case KeyEvent.KEYCODE_TAB: { 526 boolean hasRepKeyTimeElapsed = (System.currentTimeMillis() - 527 mLastTabKeyEventTime) > mConfig.altTabKeyDelay; 528 if (event.getRepeatCount() <= 0 || hasRepKeyTimeElapsed) { 529 // Focus the next task in the stack 530 final boolean backward = event.isShiftPressed(); 531 mRecentsView.focusNextTask(!backward); 532 mLastTabKeyEventTime = System.currentTimeMillis(); 533 } 534 return true; 535 } 536 case KeyEvent.KEYCODE_DPAD_UP: { 537 mRecentsView.focusNextTask(true); 538 return true; 539 } 540 case KeyEvent.KEYCODE_DPAD_DOWN: { 541 mRecentsView.focusNextTask(false); 542 return true; 543 } 544 case KeyEvent.KEYCODE_DEL: 545 case KeyEvent.KEYCODE_FORWARD_DEL: { 546 mRecentsView.dismissFocusedTask(); 547 return true; 548 } 549 default: 550 break; 551 } 552 // Pass through the debug trigger 553 mDebugTrigger.onKeyEvent(keyCode); 554 return super.onKeyDown(keyCode, event); 555 } 556 557 @Override 558 public void onUserInteraction() { 559 mRecentsView.onUserInteraction(); 560 } 561 562 @Override 563 public void onBackPressed() { 564 // Test mode where back does not do anything 565 if (mConfig.debugModeEnabled) return; 566 567 // Dismiss Recents to the focused Task or Home 568 dismissRecentsToFocusedTaskOrHome(true); 569 } 570 571 /** Called when debug mode is triggered */ 572 public void onDebugModeTriggered() { 573 574 if (mConfig.developerOptionsEnabled) { 575 SharedPreferences settings = getSharedPreferences(getPackageName(), 0); 576 if (settings.getBoolean(Constants.Values.App.Key_DebugModeEnabled, false)) { 577 // Disable the debug mode 578 settings.edit().remove(Constants.Values.App.Key_DebugModeEnabled).apply(); 579 mConfig.debugModeEnabled = false; 580 inflateDebugOverlay(); 581 mDebugOverlay.disable(); 582 } else { 583 // Enable the debug mode 584 settings.edit().putBoolean(Constants.Values.App.Key_DebugModeEnabled, true).apply(); 585 mConfig.debugModeEnabled = true; 586 inflateDebugOverlay(); 587 mDebugOverlay.enable(); 588 } 589 Toast.makeText(this, "Debug mode (" + Constants.Values.App.DebugModeVersion + ") " + 590 (mConfig.debugModeEnabled ? "Enabled" : "Disabled") + ", please restart Recents now", 591 Toast.LENGTH_SHORT).show(); 592 } 593 } 594 595 /** Called when the enter recents animation is triggered. */ 596 public void onEnterAnimationTriggered() { 597 // Animate the SystemUI scrim views 598 mScrimViews.startEnterRecentsAnimation(); 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 // Mark recents as no longer visible 612 AlternateRecentsComponent.notifyVisibilityChanged(false); 613 mVisible = false; 614 } 615 616 @Override 617 public void onTaskLaunchFailed() { 618 // Return to Home 619 dismissRecentsToHomeRaw(true); 620 } 621 622 @Override 623 public void onAllTaskViewsDismissed() { 624 mFinishLaunchHomeRunnable.run(); 625 } 626 627 /**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/ 628 629 @Override 630 public void refreshSearchWidget() { 631 bindSearchBarAppWidget(); 632 addSearchBarAppWidgetView(); 633 } 634 635 /**** DebugOverlayView.DebugOverlayViewCallbacks ****/ 636 637 @Override 638 public void onPrimarySeekBarChanged(float progress) { 639 // Do nothing 640 } 641 642 @Override 643 public void onSecondarySeekBarChanged(float progress) { 644 // Do nothing 645 } 646} 647