OSDN Git Service

Use different asset when docked stack exists
authorJorim Jaggi <jjaggi@google.com>
Mon, 21 Dec 2015 12:22:31 +0000 (13:22 +0100)
committerJorim Jaggi <jjaggi@google.com>
Tue, 5 Jan 2016 12:49:41 +0000 (13:49 +0100)
- 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

Android.mk
core/java/android/view/IDockedStackListener.aidl [moved from core/java/android/view/IDockDividerVisibilityListener.aidl with 70% similarity]
core/java/android/view/IWindowManager.aidl
packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked.png [new file with mode: 0644]
packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
services/core/java/com/android/server/wm/DockedStackDividerController.java
services/core/java/com/android/server/wm/WindowManagerService.java

index aff6cf2..c1c74ea 100644 (file)
@@ -261,7 +261,7 @@ LOCAL_SRC_FILES += \
        core/java/android/view/IApplicationToken.aidl \
        core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl \
        core/java/android/view/IAssetAtlas.aidl \
-       core/java/android/view/IDockDividerVisibilityListener.aidl \
+       core/java/android/view/IDockedStackListener.aidl \
        core/java/android/view/IGraphicsStats.aidl \
        core/java/android/view/IInputFilter.aidl \
        core/java/android/view/IInputFilterHost.aidl \
@@ -22,6 +22,15 @@ package android.view;
   *
   * @hide
   */
-oneway interface IDockDividerVisibilityListener {
-    void onDockDividerVisibilityChanged(boolean visible);
+oneway interface IDockedStackListener {
+
+    /**
+     * Will fire when an app is shown in side by side mode and a divider should be shown.
+     */
+    void onDividerVisibilityChanged(boolean visible);
+
+    /**
+     * Called when the docked stack gets created or removed.
+     */
+    void onDockedStackExistsChanged(boolean exists);
 }
index 2ef082c..ae823cf 100644 (file)
@@ -29,7 +29,7 @@ import android.os.Bundle;
 import android.os.IRemoteCallback;
 import android.view.IApplicationToken;
 import android.view.IAppTransitionAnimationSpecsFuture;
-import android.view.IDockDividerVisibilityListener;
+import android.view.IDockedStackListener;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
 import android.view.IWindowSession;
@@ -357,7 +357,8 @@ interface IWindowManager
     void setDockedStackResizing(boolean resizing);
 
     /**
-     * Registers a listener that will be called when the dock divider changes its visibility.
+     * Registers a listener that will be called when the dock divider changes its visibility or when
+     * the docked stack gets added/removed.
      */
-    void registerDockDividerVisibilityListener(IDockDividerVisibilityListener listener);
+    void registerDockedStackListener(IDockedStackListener listener);
 }
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked.png
new file mode 100644 (file)
index 0000000..f3be2ee
Binary files /dev/null and b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked.png differ
index c86a885..362c206 100644 (file)
@@ -58,7 +58,7 @@ import android.util.Log;
 import android.util.MutableBoolean;
 import android.util.Pair;
 import android.view.Display;
-import android.view.IDockDividerVisibilityListener;
+import android.view.IDockedStackListener;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityManager;
@@ -879,12 +879,11 @@ public class SystemServicesProxy {
         }
     }
 
-    public void registerDockDividerVisibilityListener(IDockDividerVisibilityListener listener) {
+    public void registerDockedStackListener(IDockedStackListener listener) {
         if (mWm == null) return;
 
         try {
-            WindowManagerGlobal.getWindowManagerService().registerDockDividerVisibilityListener(
-                    listener);
+            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(listener);
         } catch (Exception e) {
             e.printStackTrace();
         }
index 6ff7a3e..189e651 100644 (file)
@@ -17,7 +17,8 @@
 package com.android.systemui.stackdivider;
 
 import android.content.res.Configuration;
-import android.view.IDockDividerVisibilityListener;
+import android.os.RemoteException;
+import android.view.IDockedStackListener;
 import android.view.LayoutInflater;
 import android.view.View;
 
@@ -49,7 +50,7 @@ public class Divider extends SystemUI {
         putComponent(Divider.class, this);
         mDockDividerVisibilityListener = new DockDividerVisibilityListener();
         SystemServicesProxy ssp = Recents.getSystemServices();
-        ssp.registerDockDividerVisibilityListener(mDockDividerVisibilityListener);
+        ssp.registerDockedStackListener(mDockDividerVisibilityListener);
     }
 
     @Override
@@ -94,10 +95,15 @@ public class Divider extends SystemUI {
         });
     }
 
-    class DockDividerVisibilityListener extends IDockDividerVisibilityListener.Stub {
+    class DockDividerVisibilityListener extends IDockedStackListener.Stub {
+
         @Override
-        public void onDockDividerVisibilityChanged(boolean visible) {
+        public void onDividerVisibilityChanged(boolean visible) throws RemoteException {
             updateVisibility(visible);
         }
+
+        @Override
+        public void onDockedStackExistsChanged(boolean exists) throws RemoteException {
+        }
     }
 }
index cddb1fc..eade753 100644 (file)
@@ -36,11 +36,13 @@ import android.util.AttributeSet;
 import android.util.Log;
 import android.view.Display;
 import android.view.Gravity;
+import android.view.IDockedStackListener.Stub;
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -227,8 +229,8 @@ public class NavigationBarView extends LinearLayout {
         return mCurrentView;
     }
 
-    public View getRecentsButton() {
-        return mCurrentView.findViewById(R.id.recent_apps);
+    public KeyButtonView getRecentsButton() {
+        return (KeyButtonView) mCurrentView.findViewById(R.id.recent_apps);
     }
 
     public View getMenuButton() {
@@ -455,6 +457,27 @@ public class NavigationBarView extends LinearLayout {
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
         updateRTLOrder();
+
+        try {
+            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(new Stub() {
+                @Override
+                public void onDividerVisibilityChanged(boolean visible) throws RemoteException {
+                }
+
+                @Override
+                public void onDockedStackExistsChanged(boolean exists) throws RemoteException {
+                    updateRecentsIcon(exists);
+                }
+            });
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed registering docked stack exists listener", e);
+        }
+    }
+
+    private void updateRecentsIcon(boolean dockedStackExists) {
+        getRecentsButton().setImageResource(dockedStackExists
+                ? R.drawable.ic_sysbar_docked
+                : R.drawable.ic_sysbar_recent);
     }
 
     public boolean isVertical() {
index 8f3d3e3..dd8774f 100644 (file)
@@ -18,9 +18,10 @@ package com.android.server.wm;
 
 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 @@ public class DockedStackDividerController {
     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 @@ public class DockedStackDividerController {
             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 @@ public class DockedStackDividerController {
         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);
     }
 }
index be75335..155d37d 100644 (file)
@@ -20,6 +20,7 @@ import android.Manifest;
 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.ParcelFileDescriptor;
 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.DisplayInfo;
 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 @@ public class WindowManagerService extends IWindowManager.Stub
                         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 @@ public class WindowManagerService extends IWindowManager.Stub
     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 @@ public class WindowManagerService extends IWindowManager.Stub
         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 @@ public class WindowManagerService extends IWindowManager.Stub
     }
 
     @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 {