Loading services/core/java/com/android/server/policy/DisplayFoldController.java +18 −0 Original line number Diff line number Diff line Loading @@ -35,10 +35,12 @@ import com.android.server.wm.WindowManagerInternal; /** * Controls the behavior of foldable devices whose screen can literally bend and fold. * TODO(b/126160895): Move DisplayFoldController from PhoneWindowManager to DisplayPolicy. */ class DisplayFoldController { private static final String TAG = "DisplayFoldController"; private final WindowManagerInternal mWindowManagerInternal; private final DisplayManagerInternal mDisplayManagerInternal; private final int mDisplayId; Loading @@ -52,6 +54,8 @@ class DisplayFoldController { private final DisplayInfo mNonOverrideDisplayInfo = new DisplayInfo(); private final RemoteCallbackList<IDisplayFoldListener> mListeners = new RemoteCallbackList<>(); private Boolean mFolded; private String mFocusedApp; private final DisplayFoldDurationLogger mDurationLogger = new DisplayFoldDurationLogger(); DisplayFoldController(WindowManagerInternal windowManagerInternal, DisplayManagerInternal displayManagerInternal, int displayId, Rect foldedArea, Loading @@ -63,6 +67,14 @@ class DisplayFoldController { mHandler = handler; } void finishedGoingToSleep() { mDurationLogger.onFinishedGoingToSleep(); } void finishedWakingUp() { mDurationLogger.onFinishedWakingUp(mFolded); } void requestDeviceFolded(boolean folded) { mHandler.post(() -> setDeviceFolded(folded)); } Loading Loading @@ -97,6 +109,8 @@ class DisplayFoldController { mWindowManagerInternal.clearForcedDisplaySize(mDisplayId); mDisplayManagerInternal.setDisplayOffsets(mDisplayId, 0, 0); } mDurationLogger.setDeviceFolded(folded); mDurationLogger.logFocusedAppWithFoldState(folded, mFocusedApp); mFolded = folded; final int n = mListeners.beginBroadcast(); Loading Loading @@ -167,6 +181,10 @@ class DisplayFoldController { return result; } void onDefaultDisplayFocusChanged(String pkg) { mFocusedApp = pkg; } static DisplayFoldController create(Context context, int displayId) { final DisplayManagerInternal displayService = LocalServices.getService(DisplayManagerInternal.class); Loading services/core/java/com/android/server/policy/DisplayFoldDurationLogger.java 0 → 100644 +117 −0 Original line number Diff line number Diff line /* * 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 com.android.server.policy; import android.annotation.IntDef; import android.metrics.LogMaker; import android.os.SystemClock; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Logger for tracking duration of usage in folded vs unfolded state. */ class DisplayFoldDurationLogger { static final int SCREEN_STATE_UNKNOWN = -1; static final int SCREEN_STATE_OFF = 0; static final int SCREEN_STATE_ON_UNFOLDED = 1; static final int SCREEN_STATE_ON_FOLDED = 2; @IntDef(flag = true, prefix = {"SCREEN_STATE_"}, value = { SCREEN_STATE_UNKNOWN, SCREEN_STATE_OFF, SCREEN_STATE_ON_UNFOLDED, SCREEN_STATE_ON_FOLDED }) @Retention(RetentionPolicy.SOURCE) public @interface ScreenState {} private @ScreenState int mScreenState = SCREEN_STATE_UNKNOWN; private Long mLastChanged = null; private static final int LOG_SUBTYPE_UNFOLDED = 0; private static final int LOG_SUBTYPE_FOLDED = 1; private static final int LOG_SUBTYPE_DURATION_MASK = 0x80000000; private final MetricsLogger mLogger = new MetricsLogger(); void onFinishedWakingUp(Boolean folded) { if (folded == null) { mScreenState = SCREEN_STATE_UNKNOWN; } else if (folded) { mScreenState = SCREEN_STATE_ON_FOLDED; } else { mScreenState = SCREEN_STATE_ON_UNFOLDED; } mLastChanged = SystemClock.uptimeMillis(); } void onFinishedGoingToSleep() { log(); mScreenState = SCREEN_STATE_OFF; mLastChanged = null; } void setDeviceFolded(boolean folded) { // This function is called even when the screen is in ADO mode, but we're only // interested in the case that the screen is actually on. if (!isOn()) { return; } log(); mScreenState = folded ? SCREEN_STATE_ON_FOLDED : SCREEN_STATE_ON_UNFOLDED; mLastChanged = SystemClock.uptimeMillis(); } void logFocusedAppWithFoldState(boolean folded, String packageName) { mLogger.write( new LogMaker(MetricsProto.MetricsEvent.ACTION_DISPLAY_FOLD) .setType(MetricsProto.MetricsEvent.TYPE_ACTION) .setSubtype(folded ? LOG_SUBTYPE_FOLDED : LOG_SUBTYPE_UNFOLDED) .setPackageName(packageName)); } private void log() { if (mLastChanged == null) { return; } int subtype; switch (mScreenState) { case SCREEN_STATE_ON_UNFOLDED: subtype = LOG_SUBTYPE_UNFOLDED | LOG_SUBTYPE_DURATION_MASK; break; case SCREEN_STATE_ON_FOLDED: subtype = LOG_SUBTYPE_FOLDED | LOG_SUBTYPE_DURATION_MASK; break; default: return; } mLogger.write( new LogMaker(MetricsProto.MetricsEvent.ACTION_DISPLAY_FOLD) .setType(MetricsProto.MetricsEvent.TYPE_ACTION) .setSubtype(subtype) .setLatency(SystemClock.uptimeMillis() - mLastChanged)); } private boolean isOn() { return mScreenState == SCREEN_STATE_ON_UNFOLDED || mScreenState == SCREEN_STATE_ON_FOLDED; } } services/core/java/com/android/server/policy/PhoneWindowManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -3240,6 +3240,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { return new Rect(); } @Override public void onDefaultDisplayFocusChangedLw(WindowState newFocus) { if (mDisplayFoldController != null) { mDisplayFoldController.onDefaultDisplayFocusChanged( newFocus != null ? newFocus.getOwningPackage() : null); } } @Override public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService) throws RemoteException { Loading Loading @@ -4440,6 +4448,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { mKeyguardDelegate.onFinishedGoingToSleep(why, mCameraGestureTriggeredDuringGoingToSleep); } if (mDisplayFoldController != null) { mDisplayFoldController.finishedGoingToSleep(); } mCameraGestureTriggeredDuringGoingToSleep = false; } Loading Loading @@ -4480,6 +4491,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mKeyguardDelegate != null) { mKeyguardDelegate.onFinishedWakingUp(); } if (mDisplayFoldController != null) { mDisplayFoldController.finishedWakingUp(); } } private void wakeUpFromPowerKey(long eventTime) { Loading services/core/java/com/android/server/policy/WindowManagerPolicy.java +5 −0 Original line number Diff line number Diff line Loading @@ -1488,6 +1488,11 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { return new Rect(); } /** * A new window on default display has been focused. */ default void onDefaultDisplayFocusChangedLw(WindowState newFocus) {} /** * Updates the flag about whether AOD is showing. * Loading services/core/java/com/android/server/wm/DisplayPolicy.java +3 −0 Original line number Diff line number Diff line Loading @@ -2787,6 +2787,9 @@ public class DisplayPolicy { public int focusChangedLw(WindowState lastFocus, WindowState newFocus) { mFocusedWindow = newFocus; mLastFocusedWindow = lastFocus; if (mDisplayContent.isDefaultDisplay) { mService.mPolicy.onDefaultDisplayFocusChangedLw(newFocus); } if ((updateSystemUiVisibilityLw() & SYSTEM_UI_CHANGING_LAYOUT) != 0) { // If the navigation bar has been hidden or shown, we need to do another // layout pass to update that window. Loading Loading
services/core/java/com/android/server/policy/DisplayFoldController.java +18 −0 Original line number Diff line number Diff line Loading @@ -35,10 +35,12 @@ import com.android.server.wm.WindowManagerInternal; /** * Controls the behavior of foldable devices whose screen can literally bend and fold. * TODO(b/126160895): Move DisplayFoldController from PhoneWindowManager to DisplayPolicy. */ class DisplayFoldController { private static final String TAG = "DisplayFoldController"; private final WindowManagerInternal mWindowManagerInternal; private final DisplayManagerInternal mDisplayManagerInternal; private final int mDisplayId; Loading @@ -52,6 +54,8 @@ class DisplayFoldController { private final DisplayInfo mNonOverrideDisplayInfo = new DisplayInfo(); private final RemoteCallbackList<IDisplayFoldListener> mListeners = new RemoteCallbackList<>(); private Boolean mFolded; private String mFocusedApp; private final DisplayFoldDurationLogger mDurationLogger = new DisplayFoldDurationLogger(); DisplayFoldController(WindowManagerInternal windowManagerInternal, DisplayManagerInternal displayManagerInternal, int displayId, Rect foldedArea, Loading @@ -63,6 +67,14 @@ class DisplayFoldController { mHandler = handler; } void finishedGoingToSleep() { mDurationLogger.onFinishedGoingToSleep(); } void finishedWakingUp() { mDurationLogger.onFinishedWakingUp(mFolded); } void requestDeviceFolded(boolean folded) { mHandler.post(() -> setDeviceFolded(folded)); } Loading Loading @@ -97,6 +109,8 @@ class DisplayFoldController { mWindowManagerInternal.clearForcedDisplaySize(mDisplayId); mDisplayManagerInternal.setDisplayOffsets(mDisplayId, 0, 0); } mDurationLogger.setDeviceFolded(folded); mDurationLogger.logFocusedAppWithFoldState(folded, mFocusedApp); mFolded = folded; final int n = mListeners.beginBroadcast(); Loading Loading @@ -167,6 +181,10 @@ class DisplayFoldController { return result; } void onDefaultDisplayFocusChanged(String pkg) { mFocusedApp = pkg; } static DisplayFoldController create(Context context, int displayId) { final DisplayManagerInternal displayService = LocalServices.getService(DisplayManagerInternal.class); Loading
services/core/java/com/android/server/policy/DisplayFoldDurationLogger.java 0 → 100644 +117 −0 Original line number Diff line number Diff line /* * 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 com.android.server.policy; import android.annotation.IntDef; import android.metrics.LogMaker; import android.os.SystemClock; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Logger for tracking duration of usage in folded vs unfolded state. */ class DisplayFoldDurationLogger { static final int SCREEN_STATE_UNKNOWN = -1; static final int SCREEN_STATE_OFF = 0; static final int SCREEN_STATE_ON_UNFOLDED = 1; static final int SCREEN_STATE_ON_FOLDED = 2; @IntDef(flag = true, prefix = {"SCREEN_STATE_"}, value = { SCREEN_STATE_UNKNOWN, SCREEN_STATE_OFF, SCREEN_STATE_ON_UNFOLDED, SCREEN_STATE_ON_FOLDED }) @Retention(RetentionPolicy.SOURCE) public @interface ScreenState {} private @ScreenState int mScreenState = SCREEN_STATE_UNKNOWN; private Long mLastChanged = null; private static final int LOG_SUBTYPE_UNFOLDED = 0; private static final int LOG_SUBTYPE_FOLDED = 1; private static final int LOG_SUBTYPE_DURATION_MASK = 0x80000000; private final MetricsLogger mLogger = new MetricsLogger(); void onFinishedWakingUp(Boolean folded) { if (folded == null) { mScreenState = SCREEN_STATE_UNKNOWN; } else if (folded) { mScreenState = SCREEN_STATE_ON_FOLDED; } else { mScreenState = SCREEN_STATE_ON_UNFOLDED; } mLastChanged = SystemClock.uptimeMillis(); } void onFinishedGoingToSleep() { log(); mScreenState = SCREEN_STATE_OFF; mLastChanged = null; } void setDeviceFolded(boolean folded) { // This function is called even when the screen is in ADO mode, but we're only // interested in the case that the screen is actually on. if (!isOn()) { return; } log(); mScreenState = folded ? SCREEN_STATE_ON_FOLDED : SCREEN_STATE_ON_UNFOLDED; mLastChanged = SystemClock.uptimeMillis(); } void logFocusedAppWithFoldState(boolean folded, String packageName) { mLogger.write( new LogMaker(MetricsProto.MetricsEvent.ACTION_DISPLAY_FOLD) .setType(MetricsProto.MetricsEvent.TYPE_ACTION) .setSubtype(folded ? LOG_SUBTYPE_FOLDED : LOG_SUBTYPE_UNFOLDED) .setPackageName(packageName)); } private void log() { if (mLastChanged == null) { return; } int subtype; switch (mScreenState) { case SCREEN_STATE_ON_UNFOLDED: subtype = LOG_SUBTYPE_UNFOLDED | LOG_SUBTYPE_DURATION_MASK; break; case SCREEN_STATE_ON_FOLDED: subtype = LOG_SUBTYPE_FOLDED | LOG_SUBTYPE_DURATION_MASK; break; default: return; } mLogger.write( new LogMaker(MetricsProto.MetricsEvent.ACTION_DISPLAY_FOLD) .setType(MetricsProto.MetricsEvent.TYPE_ACTION) .setSubtype(subtype) .setLatency(SystemClock.uptimeMillis() - mLastChanged)); } private boolean isOn() { return mScreenState == SCREEN_STATE_ON_UNFOLDED || mScreenState == SCREEN_STATE_ON_FOLDED; } }
services/core/java/com/android/server/policy/PhoneWindowManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -3240,6 +3240,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { return new Rect(); } @Override public void onDefaultDisplayFocusChangedLw(WindowState newFocus) { if (mDisplayFoldController != null) { mDisplayFoldController.onDefaultDisplayFocusChanged( newFocus != null ? newFocus.getOwningPackage() : null); } } @Override public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService) throws RemoteException { Loading Loading @@ -4440,6 +4448,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { mKeyguardDelegate.onFinishedGoingToSleep(why, mCameraGestureTriggeredDuringGoingToSleep); } if (mDisplayFoldController != null) { mDisplayFoldController.finishedGoingToSleep(); } mCameraGestureTriggeredDuringGoingToSleep = false; } Loading Loading @@ -4480,6 +4491,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mKeyguardDelegate != null) { mKeyguardDelegate.onFinishedWakingUp(); } if (mDisplayFoldController != null) { mDisplayFoldController.finishedWakingUp(); } } private void wakeUpFromPowerKey(long eventTime) { Loading
services/core/java/com/android/server/policy/WindowManagerPolicy.java +5 −0 Original line number Diff line number Diff line Loading @@ -1488,6 +1488,11 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { return new Rect(); } /** * A new window on default display has been focused. */ default void onDefaultDisplayFocusChangedLw(WindowState newFocus) {} /** * Updates the flag about whether AOD is showing. * Loading
services/core/java/com/android/server/wm/DisplayPolicy.java +3 −0 Original line number Diff line number Diff line Loading @@ -2787,6 +2787,9 @@ public class DisplayPolicy { public int focusChangedLw(WindowState lastFocus, WindowState newFocus) { mFocusedWindow = newFocus; mLastFocusedWindow = lastFocus; if (mDisplayContent.isDefaultDisplay) { mService.mPolicy.onDefaultDisplayFocusChangedLw(newFocus); } if ((updateSystemUiVisibilityLw() & SYSTEM_UI_CHANGING_LAYOUT) != 0) { // If the navigation bar has been hidden or shown, we need to do another // layout pass to update that window. Loading