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