diff options
7 files changed, 120 insertions, 4 deletions
diff --git a/Android.bp b/Android.bp index 95847673103e..eafb605d252e 100644 --- a/Android.bp +++ b/Android.bp @@ -376,6 +376,7 @@ java_defaults { "core/java/android/view/IApplicationToken.aidl", "core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl", "core/java/android/view/IDockedStackListener.aidl", + "core/java/android/view/IDisplayFoldListener.aidl", "core/java/android/view/IGraphicsStats.aidl", "core/java/android/view/IGraphicsStatsCallback.aidl", "core/java/android/view/IInputFilter.aidl", diff --git a/core/java/android/view/IDisplayFoldListener.aidl b/core/java/android/view/IDisplayFoldListener.aidl new file mode 100644 index 000000000000..2c91149dfc1b --- /dev/null +++ b/core/java/android/view/IDisplayFoldListener.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2019 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; + +/** + * {@hide} + */ +oneway interface IDisplayFoldListener +{ + /** Called when the foldedness of a display changes */ + void onDisplayFoldChanged(int displayId, boolean folded); +} diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 42ac8801629f..8ae4757f5de6 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -34,6 +34,7 @@ import android.os.ParcelFileDescriptor; import android.view.IApplicationToken; import android.view.IAppTransitionAnimationSpecsFuture; import android.view.IDockedStackListener; +import android.view.IDisplayFoldListener; import android.view.IOnKeyguardExitResult; import android.view.IPinnedStackListener; import android.view.RemoteAnimationAdapter; @@ -403,6 +404,16 @@ interface IWindowManager Region getCurrentImeTouchRegion(); /** + * Registers an IDisplayFoldListener. + */ + void registerDisplayFoldListener(IDisplayFoldListener listener); + + /** + * Unregisters an IDisplayFoldListener. + */ + void unregisterDisplayFoldListener(IDisplayFoldListener listener); + + /** * Starts a window trace. */ void startWindowTrace(); diff --git a/services/core/java/com/android/server/policy/DisplayFoldController.java b/services/core/java/com/android/server/policy/DisplayFoldController.java index 71d6dfc9c598..fdcafa77a378 100644 --- a/services/core/java/com/android/server/policy/DisplayFoldController.java +++ b/services/core/java/com/android/server/policy/DisplayFoldController.java @@ -23,8 +23,13 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.DisplayManagerInternal; +import android.os.Handler; +import android.os.RemoteCallbackList; +import android.os.RemoteException; import android.view.DisplayInfo; +import android.view.IDisplayFoldListener; +import com.android.server.DisplayThread; import com.android.server.LocalServices; import com.android.server.wm.WindowManagerInternal; @@ -40,16 +45,24 @@ class DisplayFoldController { /** The display area while device is folded. */ private final Rect mFoldedArea; + private final Handler mHandler; private final DisplayInfo mNonOverrideDisplayInfo = new DisplayInfo(); + private final RemoteCallbackList<IDisplayFoldListener> mListeners = new RemoteCallbackList<>(); private Boolean mFolded; DisplayFoldController(WindowManagerInternal windowManagerInternal, - DisplayManagerInternal displayManagerInternal, int displayId, Rect foldedArea) { + DisplayManagerInternal displayManagerInternal, int displayId, Rect foldedArea, + Handler handler) { mWindowManagerInternal = windowManagerInternal; mDisplayManagerInternal = displayManagerInternal; mDisplayId = displayId; mFoldedArea = new Rect(foldedArea); + mHandler = handler; + } + + void requestDeviceFolded(boolean folded) { + mHandler.post(() -> setDeviceFolded(folded)); } void setDeviceFolded(boolean folded) { @@ -71,6 +84,34 @@ class DisplayFoldController { mDisplayManagerInternal.setDisplayOffsets(mDisplayId, 0, 0); } mFolded = folded; + + final int n = mListeners.beginBroadcast(); + for (int i = 0; i < n; i++) { + try { + mListeners.getBroadcastItem(i).onDisplayFoldChanged(mDisplayId, folded); + } catch (RemoteException e) { + // Listener died. + } + } + mListeners.finishBroadcast(); + } + + void registerDisplayFoldListener(IDisplayFoldListener listener) { + mListeners.register(listener); + if (mFolded == null) { + return; + } + mHandler.post(() -> { + try { + listener.onDisplayFoldChanged(mDisplayId, mFolded); + } catch (RemoteException e) { + // Listener died. + } + }); + } + + void unregisterDisplayFoldListener(IDisplayFoldListener listener) { + mListeners.unregister(listener); } /** @@ -88,7 +129,7 @@ class DisplayFoldController { sensorManager.registerListener(new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { - result.setDeviceFolded(event.values[0] < 1f); + result.requestDeviceFolded(event.values[0] < 1f); } @Override @@ -109,6 +150,6 @@ class DisplayFoldController { displayInfo.logicalWidth, displayInfo.logicalHeight); return new DisplayFoldController(LocalServices.getService(WindowManagerInternal.class), - displayService, displayId, foldedArea); + displayService, displayId, foldedArea, DisplayThread.getHandler()); } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 25cfc7202bbb..0796a9c896a3 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -177,6 +177,7 @@ import android.util.SparseArray; import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.HapticFeedbackConstants; +import android.view.IDisplayFoldListener; import android.view.IWindowManager; import android.view.InputDevice; import android.view.KeyCharacterMap; @@ -3205,6 +3206,20 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override + public void registerDisplayFoldListener(IDisplayFoldListener listener) { + if (mDisplayFoldController != null) { + mDisplayFoldController.registerDisplayFoldListener(listener); + } + } + + @Override + public void unregisterDisplayFoldListener(IDisplayFoldListener listener) { + if (mDisplayFoldController != null) { + mDisplayFoldController.unregisterDisplayFoldListener(listener); + } + } + + @Override public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService) throws RemoteException { synchronized (mLock) { @@ -4984,7 +4999,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void applyLidSwitchState() { final int lidState = mDefaultDisplayPolicy.getLidState(); if (mLidControlsDisplayFold && mDisplayFoldController != null) { - mDisplayFoldController.setDeviceFolded(lidState == LID_CLOSED); + mDisplayFoldController.requestDeviceFolded(lidState == LID_CLOSED); } else if (lidState == LID_CLOSED && mLidControlsSleep) { goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index 1d829707f180..e18cd179b113 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -78,6 +78,7 @@ import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.IApplicationToken; +import android.view.IDisplayFoldListener; import android.view.IWindowManager; import android.view.InputEventReceiver; import android.view.KeyEvent; @@ -1457,6 +1458,16 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { public void requestUserActivityNotification(); /** + * Registers an IDisplayFoldListener. + */ + default void registerDisplayFoldListener(IDisplayFoldListener listener) {} + + /** + * Unregisters an IDisplayFoldListener. + */ + default void unregisterDisplayFoldListener(IDisplayFoldListener listener) {} + + /** * Updates the flag about whether AOD is showing. * * @return whether the value was changed. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 12b858c81ca0..8373b44112fe 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -192,6 +192,7 @@ import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; import android.view.IAppTransitionAnimationSpecsFuture; +import android.view.IDisplayFoldListener; import android.view.IDockedStackListener; import android.view.IInputFilter; import android.view.IOnKeyguardExitResult; @@ -3748,6 +3749,16 @@ public class WindowManagerService extends IWindowManager.Stub } @Override + public void registerDisplayFoldListener(IDisplayFoldListener listener) { + mPolicy.registerDisplayFoldListener(listener); + } + + @Override + public void unregisterDisplayFoldListener(IDisplayFoldListener listener) { + mPolicy.unregisterDisplayFoldListener(listener); + } + + @Override public int getPreferredOptionsPanelGravity(int displayId) { synchronized (mGlobalLock) { final DisplayContent displayContent = mRoot.getDisplayContent(displayId); |