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