Use different asset when docked stack exists
- Add the ability to add a listener when the existence of the
docked stack changes.
- Register SystemUI as such a listener and switch the recents
button asset when docked stack exists.
Change-Id: I05350878c5adc7ad9f0399f0c42d8d1615d44d02
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 8f3d3e3..dd8774f 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -18,9 +18,10 @@
import android.content.Context;
import android.graphics.Rect;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Slog;
-import android.view.IDockDividerVisibilityListener;
+import android.view.IDockedStackListener;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.view.WindowManager.DOCKED_BOTTOM;
@@ -44,9 +45,9 @@
private WindowState mWindow;
private final Rect mTmpRect = new Rect();
private final Rect mLastRect = new Rect();
- private IDockDividerVisibilityListener mListener;
private boolean mLastVisibility = false;
- private boolean mForceVisibilityReevaluation;
+ private final RemoteCallbackList<IDockedStackListener> mDockedStackListeners
+ = new RemoteCallbackList<>();
DockedStackDividerController(Context context, DisplayContent displayContent) {
mDisplayContent = displayContent;
@@ -83,13 +84,11 @@
return;
}
mLastVisibility = visible;
- if (mListener != null) {
- try {
- mListener.onDockDividerVisibilityChanged(visible);
- } catch (RemoteException e) {
- Slog.e(TAG, "visibility call failed: " + e);
- }
- }
+ notifyDockedDividerVisibilityChanged(visible);
+ }
+
+ boolean wasVisible() {
+ return mLastVisibility;
}
void positionDockedStackedDivider(Rect frame) {
@@ -127,11 +126,36 @@
mLastRect.set(frame);
}
- public void registerDockDividerVisibilityListener(IDockDividerVisibilityListener listener) {
- if (mListener != null && listener != null) {
- throw new IllegalStateException("Dock divider visibility listener already set!");
+ void notifyDockedDividerVisibilityChanged(boolean visible) {
+ final int size = mDockedStackListeners.beginBroadcast();
+ for (int i = 0; i < size; ++i) {
+ final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
+ try {
+ listener.onDividerVisibilityChanged(visible);
+ } catch (RemoteException e) {
+ Slog.e(TAG_WM, "Error delivering divider visibility changed event.", e);
+ }
}
- mListener = listener;
- reevaluateVisibility(true);
+ mDockedStackListeners.finishBroadcast();
+ }
+
+ void notifyDockedStackExistsChanged(boolean exists) {
+ final int size = mDockedStackListeners.beginBroadcast();
+ for (int i = 0; i < size; ++i) {
+ final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
+ try {
+ listener.onDockedStackExistsChanged(exists);
+ } catch (RemoteException e) {
+ Slog.e(TAG_WM, "Error delivering docked stack exists changed event.", e);
+ }
+ }
+ mDockedStackListeners.finishBroadcast();
+ }
+
+ void registerDockedStackListener(IDockedStackListener listener) {
+ mDockedStackListeners.register(listener);
+ notifyDockedDividerVisibilityChanged(wasVisible());
+ notifyDockedStackExistsChanged(
+ mDisplayContent.mService.mStackIdToStack.get(DOCKED_STACK_ID) != null);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index be75335..155d37d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -20,6 +20,7 @@
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager.StackId;
import android.app.ActivityManagerNative;
import android.app.AppOpsManager;
import android.app.IActivityManager;
@@ -56,6 +57,7 @@
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.Process;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StrictMode;
@@ -83,7 +85,7 @@
import android.view.Gravity;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.IApplicationToken;
-import android.view.IDockDividerVisibilityListener;
+import android.view.IDockedStackListener;
import android.view.IInputFilter;
import android.view.IOnKeyguardExitResult;
import android.view.IRotationWatcher;
@@ -4653,6 +4655,10 @@
if (DEBUG_STACK) Slog.d(TAG_WM, "attachStack: stackId=" + stackId);
stack = new TaskStack(this, stackId);
mStackIdToStack.put(stackId, stack);
+ if (stackId == DOCKED_STACK_ID) {
+ getDefaultDisplayContentLocked().mDividerControllerLocked
+ .notifyDockedStackExistsChanged(true);
+ }
}
stack.attachDisplayContent(displayContent);
displayContent.attachStack(stack, onTop);
@@ -4678,6 +4684,10 @@
void detachStackLocked(DisplayContent displayContent, TaskStack stack) {
displayContent.detachStack(stack);
stack.detachDisplay();
+ if (stack.mStackId == DOCKED_STACK_ID) {
+ getDefaultDisplayContentLocked().mDividerControllerLocked
+ .notifyDockedStackExistsChanged(false);
+ }
}
public void detachStack(int stackId) {
@@ -10169,7 +10179,8 @@
synchronized (mWindowMap) {
appWindowToken = findAppWindowToken(token);
if (appWindowToken == null || !appWindowToken.isVisible()) {
- Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token " + token);
+ Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token "
+ + token);
return;
}
appWindowToken.setReplacingWindows(animate);
@@ -10216,26 +10227,14 @@
}
@Override
- public void registerDockDividerVisibilityListener(IDockDividerVisibilityListener listener) {
+ public void registerDockedStackListener(IDockedStackListener listener) {
if (!checkCallingPermission(android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS,
- "registerDockDividerVisibilityListener()")) {
+ "registerDockedStackListener()")) {
return;
}
// TODO(multi-display): The listener is registered on the default display only.
- final DockedStackDividerController controller =
- getDefaultDisplayContentLocked().getDockedDividerController();
- controller.registerDockDividerVisibilityListener(listener);
- try {
- listener.asBinder().linkToDeath(new IBinder.DeathRecipient() {
- @Override
- public void binderDied() {
- getDefaultDisplayContentLocked().getDockedDividerController()
- .registerDockDividerVisibilityListener(null);
- }
- }, 0);
- } catch (RemoteException e) {
- controller.registerDockDividerVisibilityListener(null);
- }
+ getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener(
+ listener);
}
private final class LocalService extends WindowManagerInternal {