diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 0e69f74b0a1fa..b606a6fb52ae2 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -197,6 +197,7 @@ + + + + + + + + + + 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 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); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 6baff9607f57c..ee631f54f865c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java new file mode 100644 index 0000000000000..236da5dbec1f7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsUserEventProxyReceiver.java @@ -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; + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index 3fbd5a6d344c6..542f21cce8165 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -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.