diff options
| author | 2015-11-30 23:37:02 +0000 | |
|---|---|---|
| committer | 2015-11-30 23:37:02 +0000 | |
| commit | 9a3f84ced75249be19fe3d771cc4e59ffdc3a7cd (patch) | |
| tree | e84728d9e5c03b261c96db972313a8e38e219bd6 | |
| parent | 1f3341de8bf85f934d0ab9ba2ce1b5df80509d5a (diff) | |
| parent | 64cdc1458bcf0d09781463a6e421b9b870b09687 (diff) | |
Merge "Remove dock divider surface when it's not visible."
12 files changed, 142 insertions, 12 deletions
diff --git a/Android.mk b/Android.mk index f5d5a113ff0a..d22273c6b75d 100644 --- a/Android.mk +++ b/Android.mk @@ -261,6 +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/IGraphicsStats.aidl \ core/java/android/view/IInputFilter.aidl \ core/java/android/view/IInputFilterHost.aidl \ diff --git a/core/java/android/view/IDockDividerVisibilityListener.aidl b/core/java/android/view/IDockDividerVisibilityListener.aidl new file mode 100644 index 000000000000..a7d5cda9b44f --- /dev/null +++ b/core/java/android/view/IDockDividerVisibilityListener.aidl @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2015, 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 android.view; + +/** + * Listener for showing/hiding of the dock divider. Will fire when an app is shown in side by side + * mode and a divider should be shown. + * + * @hide + */ +oneway interface IDockDividerVisibilityListener { + void onDockDividerVisibilityChanged(boolean visible); +} diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 64a046ec7c06..bd6553297929 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -29,6 +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.IOnKeyguardExitResult; import android.view.IRotationWatcher; import android.view.IWindowSession; @@ -290,10 +291,10 @@ interface IWindowManager /** * Create a screenshot of the applications currently displayed. * - * @param frameScale the scale to apply to the frame, only used when width = -1 and + * @param frameScale the scale to apply to the frame, only used when width = -1 and * height = -1 */ - Bitmap screenshotApplications(IBinder appToken, int displayId, int maxWidth, int maxHeight, + Bitmap screenshotApplications(IBinder appToken, int displayId, int maxWidth, int maxHeight, float frameScale); /** @@ -348,4 +349,9 @@ interface IWindowManager * stack size. */ void setDockedStackResizing(boolean resizing); + + /** + * Registers a listener that will be called when the dock divider changes its visibility. + */ + void registerDockDividerVisibilityListener(IDockDividerVisibilityListener listener); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 57338bee6366..568b60162875 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1877,6 +1877,11 @@ <permission android:name="android.permission.MANAGE_APP_TOKENS" android:protectionLevel="signature" /> + <!-- Allows System UI to register listeners for events from Window Manager. + @hide --> + <permission android:name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS" + android:protectionLevel="signature" /> + <!-- @hide Allows the application to temporarily freeze the screen for a full-screen transition. --> <permission android:name="android.permission.FREEZE_SCREEN" diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 6fda2c69b4ac..2f79adfcb8e8 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -87,6 +87,7 @@ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.READ_FRAME_BUFFER" /> <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" /> + <uses-permission android:name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS" /> <uses-permission android:name="android.permission.SET_ORIENTATION" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> 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 55d983bf9cc2..2b20c07d8be0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -56,6 +56,7 @@ import android.util.Log; import android.util.MutableBoolean; import android.util.Pair; import android.view.Display; +import android.view.IDockDividerVisibilityListener; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; @@ -851,4 +852,15 @@ public class SystemServicesProxy { e.printStackTrace(); } } + + public void registerDockDividerVisibilityListener(IDockDividerVisibilityListener listener) { + if (mWm == null) return; + + try { + WindowManagerGlobal.getWindowManagerService().registerDockDividerVisibilityListener( + listener); + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java index 50e010fc2928..6ff7a3e08159 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java @@ -17,10 +17,14 @@ package com.android.systemui.stackdivider; import android.content.res.Configuration; +import android.view.IDockDividerVisibilityListener; import android.view.LayoutInflater; +import android.view.View; import com.android.systemui.R; import com.android.systemui.SystemUI; +import com.android.systemui.recents.Recents; +import com.android.systemui.recents.misc.SystemServicesProxy; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; @@ -33,6 +37,8 @@ public class Divider extends SystemUI { private int mDividerWindowWidth; private DividerWindowManager mWindowManager; private DividerView mView; + private DockDividerVisibilityListener mDockDividerVisibilityListener; + private boolean mVisible = false; @Override public void start() { @@ -41,6 +47,9 @@ public class Divider extends SystemUI { com.android.internal.R.dimen.docked_stack_divider_thickness); update(mContext.getResources().getConfiguration()); putComponent(Divider.class, this); + mDockDividerVisibilityListener = new DockDividerVisibilityListener(); + SystemServicesProxy ssp = Recents.getSystemServices(); + ssp.registerDockDividerVisibilityListener(mDockDividerVisibilityListener); } @Override @@ -56,6 +65,7 @@ public class Divider extends SystemUI { private void addDivider(Configuration configuration) { mView = (DividerView) LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null); + mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE); final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE; final int width = landscape ? mDividerWindowWidth : MATCH_PARENT; final int height = landscape ? MATCH_PARENT : mDividerWindowWidth; @@ -71,4 +81,23 @@ public class Divider extends SystemUI { removeDivider(); addDivider(configuration); } + + private void updateVisibility(final boolean visible) { + mView.post(new Runnable() { + @Override + public void run() { + if (mVisible != visible) { + mVisible = visible; + mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); + } + } + }); + } + + class DockDividerVisibilityListener extends IDockDividerVisibilityListener.Stub { + @Override + public void onDockDividerVisibilityChanged(boolean visible) { + updateVisibility(visible); + } + } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index ae6874f720b1..639753a13b16 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -2533,7 +2533,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } } else if (win.getAttrs().type == TYPE_DOCK_DIVIDER) { - if (transit == TRANSIT_ENTER) { + if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) { return R.anim.fade_in; } else if (transit == TRANSIT_EXIT) { return R.anim.fade_out; diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index 6b6246760b39..df8d5d6f6e9b 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -18,7 +18,11 @@ package com.android.server.wm; import android.content.Context; import android.graphics.Rect; +import android.os.RemoteException; import android.util.Slog; +import android.util.SparseArray; +import android.util.SparseIntArray; +import android.view.IDockDividerVisibilityListener; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.view.WindowManager.DOCKED_BOTTOM; @@ -40,6 +44,8 @@ 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; DockedStackDividerController(Context context, DisplayContent displayContent) { mDisplayContent = displayContent; @@ -67,12 +73,21 @@ public class DockedStackDividerController { } void reevaluateVisibility() { - if (mWindow == null) return; + if (mWindow == null) { + return; + } TaskStack stack = mDisplayContent.mService.mStackIdToStack.get(DOCKED_STACK_ID); - if (stack != null && stack.isVisibleLocked()) { - mWindow.showLw(true /* doAnimation */); - } else { - mWindow.hideLw(true /* doAnimation */); + final boolean visible = stack != null && stack.isVisibleLocked(); + if (mLastVisibility == visible) { + return; + } + mLastVisibility = visible; + if (mListener != null) { + try { + mListener.onDockDividerVisibilityChanged(visible); + } catch (RemoteException e) { + Slog.e(TAG, "visibility call failed: " + e); + } } } @@ -110,4 +125,11 @@ 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!"); + } + mListener = listener; + } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index ac90daf97b90..395962c920ae 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -121,6 +121,7 @@ import android.view.DropPermissionHolder; import android.view.Gravity; import android.view.IApplicationToken; import android.view.IAppTransitionAnimationSpecsFuture; +import android.view.IDockDividerVisibilityListener; import android.view.IInputFilter; import android.view.IOnKeyguardExitResult; import android.view.IRotationWatcher; @@ -2689,8 +2690,7 @@ public class WindowManagerService extends IWindowManager.Stub // need to see about starting one. final boolean notExitingOrAnimating = !win.mExiting && !win.isAnimatingWithSavedSurface(); - result |= notExitingOrAnimating - ? RELAYOUT_RES_SURFACE_CHANGED : 0; + result |= notExitingOrAnimating ? RELAYOUT_RES_SURFACE_CHANGED : 0; if (notExitingOrAnimating) { focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay, focusMayChange); @@ -3075,7 +3075,7 @@ public class WindowManagerService extends IWindowManager.Stub // TODO: } - boolean checkCallingPermission(String permission, String func) { + private boolean checkCallingPermission(String permission, String func) { // Quick check: if the calling permission is me, it's all okay. if (Binder.getCallingPid() == Process.myPid()) { return true; @@ -10211,6 +10211,29 @@ public class WindowManagerService extends IWindowManager.Stub mDestroySurface.add(win); } + @Override + public void registerDockDividerVisibilityListener(IDockDividerVisibilityListener listener) { + if (!checkCallingPermission(android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS, + "registerDockDividerVisibilityListener()")) { + 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); + } + } + private final class LocalService extends WindowManagerInternal { @Override public void requestTraversalFromDisplayManager() { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 064b4128a2ce..29cadf3e67c4 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -730,7 +730,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { mVisibleFrame.set(mContentFrame); mStableFrame.set(mContentFrame); } else if (mAttrs.type == TYPE_DOCK_DIVIDER) { - if (isVisibleLw()) { + if (isVisibleLw() || mWinAnimator.isAnimating()) { // We don't adjust the dock divider frame for reasons other than performance. The // real reason is that if it gets adjusted before it is shown for the first time, // it would get size (0, 0). This causes a problem when we finally show the dock diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index 6951ede681e1..eea254bb8fcf 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -541,4 +541,8 @@ public class IWindowManagerImpl implements IWindowManager { @Override public void endProlongedAnimations() { } + + @Override + public void registerDockDividerVisibilityListener(IDockDividerVisibilityListener listener) { + } } |