Fixing major regressions in Recents with multi-user. (Bug 18574950)
In the process of front-loading a lot of the loading work, we moved logic into AlternateRecentsComponent, which is not multi-user friendly. This CL proxies all the necessary events for non-primary users to their own SystemUI process to ensure that they handle them correctly, and proxies visibility changes back to the primary user (since that is the only process with the right callbacks). Change-Id: I9fed92214ac4d4e2309ad6ffc35d09b5726c2880
This commit is contained in:
@@ -197,6 +197,7 @@
|
||||
<!-- Alternate Recents -->
|
||||
<activity android:name=".recents.RecentsActivity"
|
||||
android:label="@string/accessibility_desc_recent_apps"
|
||||
android:exported="false"
|
||||
android:launchMode="singleInstance"
|
||||
android:excludeFromRecents="true"
|
||||
android:stateNotNeeded="true"
|
||||
@@ -207,6 +208,17 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<receiver android:name=".recents.RecentsUserEventProxyReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.systemui.recents.action.SHOW_RECENTS_FOR_USER" />
|
||||
<action android:name="com.android.systemui.recents.action.HIDE_RECENTS_FOR_USER" />
|
||||
<action android:name="com.android.systemui.recents.action.TOGGLE_RECENTS_FOR_USER" />
|
||||
<action android:name="com.android.systemui.recents.action.PRELOAD_RECENTS_FOR_USER" />
|
||||
<action android:name="com.android.systemui.recents.action.CONFIG_CHANGED_FOR_USER" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- started from UsbDeviceSettingsManager -->
|
||||
<activity android:name=".usb.UsbConfirmActivity"
|
||||
android:exported="true"
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.recent;
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
@@ -44,16 +45,29 @@ public class Recents extends SystemUI implements RecentsComponent {
|
||||
|
||||
// Which recents to use
|
||||
boolean mUseAlternateRecents = true;
|
||||
AlternateRecentsComponent mAlternateRecents;
|
||||
boolean mBootCompleted = false;
|
||||
static AlternateRecentsComponent sAlternateRecents;
|
||||
|
||||
/** Returns the Recents component, creating a new one in-process if necessary. */
|
||||
public static AlternateRecentsComponent getRecentsComponent(Context context,
|
||||
boolean forceInitialize) {
|
||||
if (sAlternateRecents == null) {
|
||||
sAlternateRecents = new AlternateRecentsComponent(context);
|
||||
if (forceInitialize) {
|
||||
sAlternateRecents.onStart();
|
||||
sAlternateRecents.onBootCompleted();
|
||||
}
|
||||
}
|
||||
return sAlternateRecents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (mUseAlternateRecents) {
|
||||
if (mAlternateRecents == null) {
|
||||
mAlternateRecents = new AlternateRecentsComponent(mContext);
|
||||
if (sAlternateRecents == null) {
|
||||
sAlternateRecents = getRecentsComponent(mContext, false);
|
||||
}
|
||||
mAlternateRecents.onStart();
|
||||
sAlternateRecents.onStart();
|
||||
}
|
||||
|
||||
putComponent(RecentsComponent.class, this);
|
||||
@@ -62,8 +76,8 @@ public class Recents extends SystemUI implements RecentsComponent {
|
||||
@Override
|
||||
protected void onBootCompleted() {
|
||||
if (mUseAlternateRecents) {
|
||||
if (mAlternateRecents != null) {
|
||||
mAlternateRecents.onBootCompleted();
|
||||
if (sAlternateRecents != null) {
|
||||
sAlternateRecents.onBootCompleted();
|
||||
}
|
||||
}
|
||||
mBootCompleted = true;
|
||||
@@ -72,14 +86,14 @@ public class Recents extends SystemUI implements RecentsComponent {
|
||||
@Override
|
||||
public void showRecents(boolean triggeredFromAltTab, View statusBarView) {
|
||||
if (mUseAlternateRecents) {
|
||||
mAlternateRecents.onShowRecents(triggeredFromAltTab, statusBarView);
|
||||
sAlternateRecents.onShowRecents(triggeredFromAltTab);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
|
||||
if (mUseAlternateRecents) {
|
||||
mAlternateRecents.onHideRecents(triggeredFromAltTab, triggeredFromHomeKey);
|
||||
sAlternateRecents.onHideRecents(triggeredFromAltTab, triggeredFromHomeKey);
|
||||
} else {
|
||||
Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
|
||||
intent.setPackage("com.android.systemui");
|
||||
@@ -93,7 +107,7 @@ public class Recents extends SystemUI implements RecentsComponent {
|
||||
public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
|
||||
if (mUseAlternateRecents) {
|
||||
// Launch the alternate recents if required
|
||||
mAlternateRecents.onToggleRecents(statusBarView);
|
||||
sAlternateRecents.onToggleRecents();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -241,14 +255,14 @@ public class Recents extends SystemUI implements RecentsComponent {
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
if (mUseAlternateRecents) {
|
||||
mAlternateRecents.onConfigurationChanged(newConfig);
|
||||
sAlternateRecents.onConfigurationChanged(newConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preloadRecents() {
|
||||
if (mUseAlternateRecents) {
|
||||
mAlternateRecents.onPreloadRecents();
|
||||
sAlternateRecents.onPreloadRecents();
|
||||
} else {
|
||||
Intent intent = new Intent(RecentsActivity.PRELOAD_INTENT);
|
||||
intent.setClassName("com.android.systemui",
|
||||
@@ -262,7 +276,7 @@ public class Recents extends SystemUI implements RecentsComponent {
|
||||
@Override
|
||||
public void cancelPreloadingRecents() {
|
||||
if (mUseAlternateRecents) {
|
||||
mAlternateRecents.onCancelPreloadingRecents();
|
||||
sAlternateRecents.onCancelPreloadingRecents();
|
||||
} else {
|
||||
Intent intent = new Intent(RecentsActivity.CANCEL_PRELOAD_INTENT);
|
||||
intent.setClassName("com.android.systemui",
|
||||
@@ -276,21 +290,21 @@ public class Recents extends SystemUI implements RecentsComponent {
|
||||
@Override
|
||||
public void showNextAffiliatedTask() {
|
||||
if (mUseAlternateRecents) {
|
||||
mAlternateRecents.onShowNextAffiliatedTask();
|
||||
sAlternateRecents.onShowNextAffiliatedTask();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showPrevAffiliatedTask() {
|
||||
if (mUseAlternateRecents) {
|
||||
mAlternateRecents.onShowPrevAffiliatedTask();
|
||||
sAlternateRecents.onShowPrevAffiliatedTask();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCallback(Callbacks cb) {
|
||||
if (mUseAlternateRecents) {
|
||||
mAlternateRecents.setRecentsComponentCallback(cb);
|
||||
sAlternateRecents.setRecentsComponentCallback(cb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -38,7 +39,6 @@ import android.os.UserHandle;
|
||||
import android.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.RecentsComponent;
|
||||
import com.android.systemui.recents.misc.Console;
|
||||
@@ -57,12 +57,27 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Annotation for a method that is only called from the primary user's SystemUI process and will be
|
||||
* proxied to the current user.
|
||||
*/
|
||||
@interface ProxyFromPrimaryToCurrentUser {}
|
||||
/**
|
||||
* Annotation for a method that may be called from any user's SystemUI process and will be proxied
|
||||
* to the primary user.
|
||||
*/
|
||||
@interface ProxyFromAnyToPrimaryUser {}
|
||||
|
||||
/** A proxy implementation for the recents component */
|
||||
public class AlternateRecentsComponent implements ActivityOptions.OnAnimationStartedListener {
|
||||
|
||||
final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "recents.triggeredFromAltTab";
|
||||
final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "recents.triggeredFromHomeKey";
|
||||
final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "triggeredFromAltTab";
|
||||
final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "triggeredFromHomeKey";
|
||||
final public static String EXTRA_RECENTS_VISIBILITY = "recentsVisibility";
|
||||
|
||||
// Owner proxy events
|
||||
final public static String ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER =
|
||||
"action_notify_recents_visibility_change";
|
||||
|
||||
final public static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
|
||||
final public static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
|
||||
@@ -78,9 +93,22 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
* An implementation of ITaskStackListener, that allows us to listen for changes to the system
|
||||
* task stacks and update recents accordingly.
|
||||
*/
|
||||
class TaskStackListenerImpl extends ITaskStackListener.Stub {
|
||||
class TaskStackListenerImpl extends ITaskStackListener.Stub implements Runnable {
|
||||
Handler mHandler;
|
||||
|
||||
public TaskStackListenerImpl(Handler handler) {
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskStackChanged() {
|
||||
// Debounce any task stack changes
|
||||
mHandler.removeCallbacks(this);
|
||||
mHandler.post(this);
|
||||
}
|
||||
|
||||
/** Preloads the next task */
|
||||
public void run() {
|
||||
RecentsConfiguration config = RecentsConfiguration.getInstance();
|
||||
if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
|
||||
// Load the next task only if we aren't svelte
|
||||
@@ -96,6 +124,20 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A proxy for Recents events which happens strictly for the owner.
|
||||
*/
|
||||
class RecentsOwnerEventProxyReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
switch (intent.getAction()) {
|
||||
case ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER:
|
||||
visibilityChanged(intent.getBooleanExtra(EXTRA_RECENTS_VISIBILITY, false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static RecentsComponent.Callbacks sRecentsComponentCallbacks;
|
||||
static RecentsTaskLoadPlan sInstanceLoadPlan;
|
||||
|
||||
@@ -104,6 +146,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
SystemServicesProxy mSystemServicesProxy;
|
||||
Handler mHandler;
|
||||
TaskStackListenerImpl mTaskStackListener;
|
||||
RecentsOwnerEventProxyReceiver mProxyBroadcastReceiver;
|
||||
boolean mBootCompleted;
|
||||
boolean mStartAnimationTriggered;
|
||||
boolean mCanReuseTaskStackViews = true;
|
||||
@@ -123,7 +166,6 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
TaskStackView mDummyStackView;
|
||||
|
||||
// Variables to keep track of if we need to start recents after binding
|
||||
View mStatusBarView;
|
||||
boolean mTriggeredFromAltTab;
|
||||
long mLastToggleTime;
|
||||
|
||||
@@ -136,30 +178,37 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
mTaskStackBounds = new Rect();
|
||||
|
||||
// Register the task stack listener
|
||||
mTaskStackListener = new TaskStackListenerImpl();
|
||||
mTaskStackListener = new TaskStackListenerImpl(mHandler);
|
||||
mSystemServicesProxy.registerTaskStackListener(mTaskStackListener);
|
||||
|
||||
// Only the owner has the callback to update the SysUI visibility flags, so all non-owner
|
||||
// instances of AlternateRecentsComponent needs to notify the owner when the visibility
|
||||
// changes.
|
||||
if (mSystemServicesProxy.isForegroundUserOwner()) {
|
||||
mProxyBroadcastReceiver = new RecentsOwnerEventProxyReceiver();
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(AlternateRecentsComponent.ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER);
|
||||
mContext.registerReceiverAsUser(mProxyBroadcastReceiver, UserHandle.CURRENT, filter,
|
||||
null, mHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates a new broadcast intent */
|
||||
static Intent createLocalBroadcastIntent(Context context, String action) {
|
||||
Intent intent = new Intent(action);
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
|
||||
Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
return intent;
|
||||
}
|
||||
|
||||
/** Initializes the Recents. */
|
||||
@ProxyFromPrimaryToCurrentUser
|
||||
public void onStart() {
|
||||
// Initialize some static datastructures
|
||||
TaskStackViewLayoutAlgorithm.initializeCurve();
|
||||
// Load the header bar layout
|
||||
reloadHeaderBarLayout();
|
||||
// Try and pre-emptively bind the search widget on startup to ensure that we
|
||||
// have the right thumbnail bounds to animate to.
|
||||
if (Constants.DebugFlags.App.EnableSearchLayout) {
|
||||
// If there is no id, then bind a new search app widget
|
||||
if (mConfig.searchBarAppWidgetId < 0) {
|
||||
AppWidgetHost host = new RecentsAppWidgetHost(mContext,
|
||||
Constants.Values.App.AppWidgetHostId);
|
||||
Pair<Integer, AppWidgetProviderInfo> widgetInfo =
|
||||
mSystemServicesProxy.bindSearchAppWidget(host);
|
||||
if (widgetInfo != null) {
|
||||
// Save the app widget id into the settings
|
||||
mConfig.updateSearchBarAppWidgetId(mContext, widgetInfo.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
reloadHeaderBarLayout(true);
|
||||
|
||||
// When we start, preload the data associated with the previous recent tasks.
|
||||
// We can use a new plan since the caches will be the same.
|
||||
@@ -177,9 +226,19 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
mBootCompleted = true;
|
||||
}
|
||||
|
||||
/** Shows the recents */
|
||||
public void onShowRecents(boolean triggeredFromAltTab, View statusBarView) {
|
||||
mStatusBarView = statusBarView;
|
||||
/** Shows the Recents. */
|
||||
@ProxyFromPrimaryToCurrentUser
|
||||
public void onShowRecents(boolean triggeredFromAltTab) {
|
||||
if (mSystemServicesProxy.isForegroundUserOwner()) {
|
||||
showRecents(triggeredFromAltTab);
|
||||
} else {
|
||||
Intent intent = createLocalBroadcastIntent(mContext,
|
||||
RecentsUserEventProxyReceiver.ACTION_PROXY_SHOW_RECENTS_TO_USER);
|
||||
intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
||||
}
|
||||
}
|
||||
void showRecents(boolean triggeredFromAltTab) {
|
||||
mTriggeredFromAltTab = triggeredFromAltTab;
|
||||
|
||||
try {
|
||||
@@ -189,16 +248,25 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
}
|
||||
}
|
||||
|
||||
/** Hides the recents */
|
||||
/** Hides the Recents. */
|
||||
@ProxyFromPrimaryToCurrentUser
|
||||
public void onHideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
|
||||
if (mSystemServicesProxy.isForegroundUserOwner()) {
|
||||
hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
|
||||
} else {
|
||||
Intent intent = createLocalBroadcastIntent(mContext,
|
||||
RecentsUserEventProxyReceiver.ACTION_PROXY_HIDE_RECENTS_TO_USER);
|
||||
intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
|
||||
intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey);
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
||||
}
|
||||
}
|
||||
void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
|
||||
if (mBootCompleted) {
|
||||
ActivityManager.RunningTaskInfo topTask = getTopMostTask();
|
||||
if (topTask != null && isRecentsTopMost(topTask, null)) {
|
||||
// Notify recents to hide itself
|
||||
Intent intent = new Intent(ACTION_HIDE_RECENTS_ACTIVITY);
|
||||
intent.setPackage(mContext.getPackageName());
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
|
||||
Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
Intent intent = createLocalBroadcastIntent(mContext, ACTION_HIDE_RECENTS_ACTIVITY);
|
||||
intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab);
|
||||
intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey);
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
||||
@@ -206,9 +274,18 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
}
|
||||
}
|
||||
|
||||
/** Toggles the alternate recents activity */
|
||||
public void onToggleRecents(View statusBarView) {
|
||||
mStatusBarView = statusBarView;
|
||||
/** Toggles the Recents activity. */
|
||||
@ProxyFromPrimaryToCurrentUser
|
||||
public void onToggleRecents() {
|
||||
if (mSystemServicesProxy.isForegroundUserOwner()) {
|
||||
toggleRecents();
|
||||
} else {
|
||||
Intent intent = createLocalBroadcastIntent(mContext,
|
||||
RecentsUserEventProxyReceiver.ACTION_PROXY_TOGGLE_RECENTS_TO_USER);
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
||||
}
|
||||
}
|
||||
void toggleRecents() {
|
||||
mTriggeredFromAltTab = false;
|
||||
|
||||
try {
|
||||
@@ -218,7 +295,18 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
}
|
||||
}
|
||||
|
||||
/** Preloads info for the Recents activity. */
|
||||
@ProxyFromPrimaryToCurrentUser
|
||||
public void onPreloadRecents() {
|
||||
if (mSystemServicesProxy.isForegroundUserOwner()) {
|
||||
preloadRecents();
|
||||
} else {
|
||||
Intent intent = createLocalBroadcastIntent(mContext,
|
||||
RecentsUserEventProxyReceiver.ACTION_PROXY_PRELOAD_RECENTS_TO_USER);
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
||||
}
|
||||
}
|
||||
void preloadRecents() {
|
||||
// Preload only the raw task list into a new load plan (which will be consumed by the
|
||||
// RecentsActivity)
|
||||
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
|
||||
@@ -309,15 +397,26 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
showRelativeAffiliatedTask(false);
|
||||
}
|
||||
|
||||
/** Updates on configuration change. */
|
||||
@ProxyFromPrimaryToCurrentUser
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
if (mSystemServicesProxy.isForegroundUserOwner()) {
|
||||
configurationChanged();
|
||||
} else {
|
||||
Intent intent = createLocalBroadcastIntent(mContext,
|
||||
RecentsUserEventProxyReceiver.ACTION_PROXY_CONFIG_CHANGE_TO_USER);
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
||||
}
|
||||
}
|
||||
void configurationChanged() {
|
||||
// Don't reuse task stack views if the configuration changes
|
||||
mCanReuseTaskStackViews = false;
|
||||
// Reload the header bar layout
|
||||
reloadHeaderBarLayout();
|
||||
reloadHeaderBarLayout(false);
|
||||
}
|
||||
|
||||
/** Prepares the header bar layout. */
|
||||
void reloadHeaderBarLayout() {
|
||||
void reloadHeaderBarLayout(boolean reloadWidget) {
|
||||
Resources res = mContext.getResources();
|
||||
mWindowRect = mSystemServicesProxy.getWindowRect();
|
||||
mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
|
||||
@@ -325,6 +424,10 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
mNavBarWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
|
||||
mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy);
|
||||
mConfig.updateOnConfigurationChange();
|
||||
if (reloadWidget) {
|
||||
// Reload the widget id before we get the task stack bounds
|
||||
reloadSearchBarAppWidget(mContext, mSystemServicesProxy);
|
||||
}
|
||||
mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight,
|
||||
(mConfig.hasTransposedNavBar ? mNavBarWidth : 0), mTaskStackBounds);
|
||||
if (mConfig.isLandscape && mConfig.hasTransposedNavBar) {
|
||||
@@ -350,6 +453,24 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
mHeaderBar.layout(0, 0, taskViewSize.width(), taskBarHeight);
|
||||
}
|
||||
|
||||
/** Prepares the search bar app widget */
|
||||
void reloadSearchBarAppWidget(Context context, SystemServicesProxy ssp) {
|
||||
// Try and pre-emptively bind the search widget on startup to ensure that we
|
||||
// have the right thumbnail bounds to animate to.
|
||||
if (Constants.DebugFlags.App.EnableSearchLayout) {
|
||||
// If there is no id, then bind a new search app widget
|
||||
if (mConfig.searchBarAppWidgetId < 0) {
|
||||
AppWidgetHost host = new RecentsAppWidgetHost(context,
|
||||
Constants.Values.App.AppWidgetHostId);
|
||||
Pair<Integer, AppWidgetProviderInfo> widgetInfo = ssp.bindSearchAppWidget(host);
|
||||
if (widgetInfo != null) {
|
||||
// Save the app widget id into the settings
|
||||
mConfig.updateSearchBarAppWidgetId(context, widgetInfo.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the top task. */
|
||||
ActivityManager.RunningTaskInfo getTopMostTask() {
|
||||
SystemServicesProxy ssp = mSystemServicesProxy;
|
||||
@@ -397,10 +518,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
AtomicBoolean isTopTaskHome = new AtomicBoolean(true);
|
||||
if (topTask != null && isRecentsTopMost(topTask, isTopTaskHome)) {
|
||||
// Notify recents to toggle itself
|
||||
Intent intent = new Intent(ACTION_TOGGLE_RECENTS_ACTIVITY);
|
||||
intent.setPackage(mContext.getPackageName());
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
|
||||
Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
Intent intent = createLocalBroadcastIntent(mContext, ACTION_TOGGLE_RECENTS_ACTIVITY);
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
||||
mLastToggleTime = SystemClock.elapsedRealtime();
|
||||
return;
|
||||
@@ -474,7 +592,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
}
|
||||
|
||||
mStartAnimationTriggered = false;
|
||||
return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mStatusBarView,
|
||||
return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
|
||||
thumbnail, toTaskRect.left, toTaskRect.top, toTaskRect.width(),
|
||||
toTaskRect.height(), this);
|
||||
}
|
||||
@@ -623,7 +741,19 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
}
|
||||
|
||||
/** Notifies the callbacks that the visibility of Recents has changed. */
|
||||
public static void notifyVisibilityChanged(boolean visible) {
|
||||
@ProxyFromAnyToPrimaryUser
|
||||
public static void notifyVisibilityChanged(Context context, SystemServicesProxy ssp,
|
||||
boolean visible) {
|
||||
if (ssp.isForegroundUserOwner()) {
|
||||
visibilityChanged(visible);
|
||||
} else {
|
||||
Intent intent = createLocalBroadcastIntent(context,
|
||||
ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER);
|
||||
intent.putExtra(EXTRA_RECENTS_VISIBILITY, visible);
|
||||
context.sendBroadcastAsUser(intent, UserHandle.OWNER);
|
||||
}
|
||||
}
|
||||
static void visibilityChanged(boolean visible) {
|
||||
if (sRecentsComponentCallbacks != null) {
|
||||
sRecentsComponentCallbacks.onVisibilityChanged(visible);
|
||||
}
|
||||
@@ -667,10 +797,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
};
|
||||
|
||||
// Send the broadcast to notify Recents that the animation has started
|
||||
Intent intent = new Intent(ACTION_START_ENTER_ANIMATION);
|
||||
intent.setPackage(mContext.getPackageName());
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
|
||||
Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
Intent intent = createLocalBroadcastIntent(mContext, ACTION_START_ENTER_ANIMATION);
|
||||
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
|
||||
fallbackReceiver, null, Activity.RESULT_CANCELED, null, null);
|
||||
}
|
||||
|
||||
@@ -434,7 +434,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mVisible = true;
|
||||
AlternateRecentsComponent.notifyVisibilityChanged(true);
|
||||
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
|
||||
SystemServicesProxy ssp = loader.getSystemServicesProxy();
|
||||
AlternateRecentsComponent.notifyVisibilityChanged(this, ssp, true);
|
||||
|
||||
// Register the broadcast receiver to handle messages from our service
|
||||
IntentFilter filter = new IntentFilter();
|
||||
@@ -444,7 +446,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
registerReceiver(mServiceBroadcastReceiver, filter);
|
||||
|
||||
// Register any broadcast receivers for the task loader
|
||||
RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView);
|
||||
loader.registerReceivers(this, mRecentsView);
|
||||
|
||||
// Update the recent tasks
|
||||
updateRecentsTasks(getIntent());
|
||||
@@ -454,7 +456,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mVisible = false;
|
||||
AlternateRecentsComponent.notifyVisibilityChanged(false);
|
||||
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
|
||||
SystemServicesProxy ssp = loader.getSystemServicesProxy();
|
||||
AlternateRecentsComponent.notifyVisibilityChanged(this, ssp, false);
|
||||
|
||||
// Notify the views that we are no longer visible
|
||||
mRecentsView.onRecentsHidden();
|
||||
@@ -463,7 +467,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
unregisterReceiver(mServiceBroadcastReceiver);
|
||||
|
||||
// Unregister any broadcast receivers for the task loader
|
||||
RecentsTaskLoader.getInstance().unregisterReceivers();
|
||||
loader.unregisterReceivers();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.recents;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import com.android.systemui.recent.Recents;
|
||||
|
||||
|
||||
/**
|
||||
* A proxy for Recents events which happens strictly for non-owner users.
|
||||
*/
|
||||
public class RecentsUserEventProxyReceiver extends BroadcastReceiver {
|
||||
final public static String ACTION_PROXY_SHOW_RECENTS_TO_USER =
|
||||
"com.android.systemui.recents.action.SHOW_RECENTS_FOR_USER";
|
||||
final public static String ACTION_PROXY_HIDE_RECENTS_TO_USER =
|
||||
"com.android.systemui.recents.action.HIDE_RECENTS_FOR_USER";
|
||||
final public static String ACTION_PROXY_TOGGLE_RECENTS_TO_USER =
|
||||
"com.android.systemui.recents.action.TOGGLE_RECENTS_FOR_USER";
|
||||
final public static String ACTION_PROXY_PRELOAD_RECENTS_TO_USER =
|
||||
"com.android.systemui.recents.action.PRELOAD_RECENTS_FOR_USER";
|
||||
final public static String ACTION_PROXY_CONFIG_CHANGE_TO_USER =
|
||||
"com.android.systemui.recents.action.CONFIG_CHANGED_FOR_USER";
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
AlternateRecentsComponent recents = Recents.getRecentsComponent(
|
||||
context.getApplicationContext(), true);
|
||||
switch (intent.getAction()) {
|
||||
case ACTION_PROXY_SHOW_RECENTS_TO_USER: {
|
||||
boolean triggeredFromAltTab = intent.getBooleanExtra(
|
||||
AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
|
||||
recents.showRecents(triggeredFromAltTab);
|
||||
break;
|
||||
}
|
||||
case ACTION_PROXY_HIDE_RECENTS_TO_USER: {
|
||||
boolean triggeredFromAltTab = intent.getBooleanExtra(
|
||||
AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
|
||||
boolean triggeredFromHome = intent.getBooleanExtra(
|
||||
AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_HOME_KEY, false);
|
||||
recents.hideRecents(triggeredFromAltTab, triggeredFromHome);
|
||||
break;
|
||||
}
|
||||
case ACTION_PROXY_TOGGLE_RECENTS_TO_USER:
|
||||
recents.toggleRecents();
|
||||
break;
|
||||
case ACTION_PROXY_PRELOAD_RECENTS_TO_USER:
|
||||
recents.preloadRecents();
|
||||
break;
|
||||
case ACTION_PROXY_CONFIG_CHANGE_TO_USER:
|
||||
recents.configurationChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,14 +49,12 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
@@ -395,6 +393,15 @@ public class SystemServicesProxy {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the foreground user is the owner.
|
||||
*/
|
||||
public boolean isForegroundUserOwner() {
|
||||
if (mAm == null) return false;
|
||||
|
||||
return mAm.getCurrentUser() == UserHandle.USER_OWNER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves and returns the first Recents widget from the same package as the global
|
||||
* assist activity.
|
||||
|
||||
Reference in New Issue
Block a user