summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt4
-rw-r--r--core/java/android/app/Activity.java5
-rw-r--r--core/java/android/app/ActivityThread.java7
-rw-r--r--core/java/android/app/ActivityTransitionCoordinator.java1
-rw-r--r--core/java/android/app/DirectAction.java3
-rw-r--r--core/java/android/app/WallpaperInfo.java22
-rw-r--r--core/java/android/app/servertransaction/ActivityResultItem.java19
-rw-r--r--core/java/android/app/servertransaction/LaunchActivityItem.java20
-rw-r--r--core/java/android/hardware/display/AmbientDisplayConfiguration.java7
-rw-r--r--core/java/android/hardware/display/BrightnessInfo.java21
-rw-r--r--core/java/android/text/TextLine.java2
-rw-r--r--core/res/AndroidManifest.xml2
-rw-r--r--core/res/res/anim-ldrtl/task_close_exit.xml7
-rw-r--r--core/res/res/anim-ldrtl/task_open_exit.xml7
-rw-r--r--core/res/res/anim/task_close_exit.xml7
-rw-r--r--core/res/res/anim/task_open_exit.xml7
-rw-r--r--core/res/res/values/attrs.xml8
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java2
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TestUtils.java8
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java1
-rw-r--r--core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java22
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java13
-rw-r--r--libs/WindowManager/Shell/res/color/unfold_transition_background.xml19
-rw-r--r--libs/WindowManager/Shell/res/layout/split_outline.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java46
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java (renamed from libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java)91
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java268
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineManager.java132
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineRoot.java62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineView.java60
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java73
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/ShellUnfoldProgressProvider.java44
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsController.java3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java151
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java6
-rw-r--r--packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java13
-rw-r--r--packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java7
-rw-r--r--packages/SystemUI/res/layout/global_screenshot_static.xml9
-rw-r--r--packages/SystemUI/res/values/config.xml25
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java26
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImpl.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java)9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/CallbackHandler.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java)20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetIcons.java)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetSignalController.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java)8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java)26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkController.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java)29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java)35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalController.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java)20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java)3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java)11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/unfold/ShellUnfoldProgressProvider.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt74
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/PostureDependentProximitySensor.java109
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ProximityCheck.java90
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java395
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensorImpl.java360
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java172
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensor.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorEvent.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/AccessPointControllerImplTest.kt)2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java)15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java)17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java)19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerEthernetTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java)20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java)233
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java)27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/PostureDependentProximitySensorTest.java114
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorImplDualTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java)8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorImplSingleTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorSingleTest.java)10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java2
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java145
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java34
-rw-r--r--services/core/java/com/android/server/display/HighBrightnessModeController.java11
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java8
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityClientController.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java40
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java19
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java20
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java2
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java5
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java29
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java3
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java10
-rw-r--r--services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java2
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java2
-rw-r--r--services/core/java/com/android/server/wm/PinnedTaskController.java2
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java2
-rw-r--r--services/core/java/com/android/server/wm/Task.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java11
-rw-r--r--services/core/java/com/android/server/wm/Transition.java9
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java2
-rw-r--r--services/core/java/com/android/server/wm/WallpaperWindowToken.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java18
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java26
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java218
-rw-r--r--services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java34
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java25
166 files changed, 3119 insertions, 1373 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 9a16390baf10..1d03370e698d 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1298,7 +1298,7 @@ package android {
field public static final int shortcutLongLabel = 16844074; // 0x101052a
field public static final int shortcutShortLabel = 16844073; // 0x1010529
field public static final int shouldDisableView = 16843246; // 0x10101ee
- field public static final int shouldUseDefaultDeviceStateChangeTransition;
+ field public static final int shouldUseDefaultDisplayStateChangeTransition;
field public static final int showAsAction = 16843481; // 0x10102d9
field public static final int showDefault = 16843258; // 0x10101fa
field public static final int showDividers = 16843561; // 0x1010329
@@ -6927,7 +6927,7 @@ package android.app {
method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager);
method public CharSequence loadLabel(android.content.pm.PackageManager);
method public android.graphics.drawable.Drawable loadThumbnail(android.content.pm.PackageManager);
- method public boolean shouldUseDefaultDeviceStateChangeTransition();
+ method public boolean shouldUseDefaultDisplayStateChangeTransition();
method public boolean supportsMultipleDisplays();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.WallpaperInfo> CREATOR;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 12025f98ada8..22091fcde86f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2507,12 +2507,11 @@ public class Activity extends ContextThemeWrapper
*
* <p>To get the voice interactor you need to call {@link #getVoiceInteractor()}
* which would return non <code>null</code> only if there is an ongoing voice
- * interaction session. You an also detect when the voice interactor is no
+ * interaction session. You can also detect when the voice interactor is no
* longer valid because the voice interaction session that is backing is finished
* by calling {@link VoiceInteractor#registerOnDestroyedCallback(Executor, Runnable)}.
*
- * <p>This method will be called only after {@link #onStart()} is being called and
- * before {@link #onStop()} is being called.
+ * <p>This method will be called only after {@link #onStart()} and before {@link #onStop()}.
*
* <p>You should pass to the callback the currently supported direct actions which
* cannot be <code>null</code> or contain <code>null</code> elements.
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 80554d7939f2..d0680f8c9268 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -526,9 +526,6 @@ public final class ActivityThread extends ClientTransactionHandler
// A reusable token for other purposes, e.g. content capture, translation. It shouldn't be
// used without security checks
public IBinder shareableActivityToken;
- // The token of the initial TaskFragment that embedded this activity. Do not rely on it
- // after creation because the activity could be reparented.
- @Nullable public IBinder mInitialTaskFragmentToken;
int ident;
@UnsupportedAppUsage
Intent intent;
@@ -622,8 +619,7 @@ public final class ActivityThread extends ClientTransactionHandler
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
boolean isForward, ProfilerInfo profilerInfo, ClientTransactionHandler client,
IBinder assistToken, FixedRotationAdjustments fixedRotationAdjustments,
- IBinder shareableActivityToken, boolean launchedFromBubble,
- IBinder initialTaskFragmentToken) {
+ IBinder shareableActivityToken, boolean launchedFromBubble) {
this.token = token;
this.assistToken = assistToken;
this.shareableActivityToken = shareableActivityToken;
@@ -645,7 +641,6 @@ public final class ActivityThread extends ClientTransactionHandler
mActivityOptions = activityOptions;
mPendingFixedRotationAdjustments = fixedRotationAdjustments;
mLaunchedFromBubble = launchedFromBubble;
- mInitialTaskFragmentToken = initialTaskFragmentToken;
init();
}
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 4b87a647a80b..f5b3b40d88d6 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -871,6 +871,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
if (view.isAttachedToWindow()) {
tempMatrix.reset();
mSharedElementParentMatrices.get(i).invert(tempMatrix);
+ decor.transformMatrixToLocal(tempMatrix);
GhostView.addGhost(view, decor, tempMatrix);
ViewGroup parent = (ViewGroup) view.getParent();
if (moveWithParent && !isInTransitionGroup(parent, decor)) {
diff --git a/core/java/android/app/DirectAction.java b/core/java/android/app/DirectAction.java
index b0ed490369ad..ac3868b2ece9 100644
--- a/core/java/android/app/DirectAction.java
+++ b/core/java/android/app/DirectAction.java
@@ -22,14 +22,13 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
-import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.util.Preconditions;
import java.util.Objects;
/**
- * Represents a abstract action that can be perform on this app. This are requested from
+ * Represents an abstract action that can be perform on this app. This are requested from
* outside the app's UI (eg by SystemUI or assistant). The semantics of these actions are
* not specified by the OS. This allows open-ended and scalable approach for defining how
* an app interacts with components that expose alternative interaction models to the user
diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java
index c552cb62749b..a969b10c15a3 100644
--- a/core/java/android/app/WallpaperInfo.java
+++ b/core/java/android/app/WallpaperInfo.java
@@ -81,7 +81,7 @@ public final class WallpaperInfo implements Parcelable {
final int mContextDescriptionResource;
final boolean mShowMetadataInPreview;
final boolean mSupportsAmbientMode;
- final boolean mShouldUseDefaultDeviceStateChangeTransition;
+ final boolean mShouldUseDefaultDisplayStateChangeTransition;
final String mSettingsSliceUri;
final boolean mSupportMultipleDisplays;
@@ -146,9 +146,9 @@ public final class WallpaperInfo implements Parcelable {
mSupportsAmbientMode = sa.getBoolean(
com.android.internal.R.styleable.Wallpaper_supportsAmbientMode,
false);
- mShouldUseDefaultDeviceStateChangeTransition = sa.getBoolean(
+ mShouldUseDefaultDisplayStateChangeTransition = sa.getBoolean(
com.android.internal.R.styleable
- .Wallpaper_shouldUseDefaultDeviceStateChangeTransition, true);
+ .Wallpaper_shouldUseDefaultDisplayStateChangeTransition, true);
mSettingsSliceUri = sa.getString(
com.android.internal.R.styleable.Wallpaper_settingsSliceUri);
mSupportMultipleDisplays = sa.getBoolean(
@@ -175,7 +175,7 @@ public final class WallpaperInfo implements Parcelable {
mSupportsAmbientMode = source.readInt() != 0;
mSettingsSliceUri = source.readString();
mSupportMultipleDisplays = source.readInt() != 0;
- mShouldUseDefaultDeviceStateChangeTransition = source.readInt() != 0;
+ mShouldUseDefaultDisplayStateChangeTransition = source.readInt() != 0;
mService = ResolveInfo.CREATOR.createFromParcel(source);
}
@@ -400,24 +400,24 @@ public final class WallpaperInfo implements Parcelable {
/**
* Returns whether this wallpaper should receive default zooming updates when the device
- * changes its state (e.g. when folding or unfolding a foldable device).
+ * changes its display state (e.g. when folding or unfolding a foldable device).
* If set to false the wallpaper will not receive zoom events when changing the device state,
* so it can implement its own transition instead.
* <p>
* This corresponds to the value {@link
- * android.R.styleable#Wallpaper_shouldUseDefaultDeviceStateChangeTransition} in the
+ * android.R.styleable#Wallpaper_shouldUseDefaultDisplayStateChangeTransition} in the
* XML description of the wallpaper.
* <p>
* The default value is {@code true}.
*
- * @see android.R.styleable#Wallpaper_shouldUseDefaultDeviceStateChangeTransition
+ * @see android.R.styleable#Wallpaper_shouldUseDefaultDisplayStateChangeTransition
* @return {@code true} if wallpaper should receive default device state change
* transition updates
*
- * @attr ref android.R.styleable#Wallpaper_shouldUseDefaultDeviceStateChangeTransition
+ * @attr ref android.R.styleable#Wallpaper_shouldUseDefaultDisplayStateChangeTransition
*/
- public boolean shouldUseDefaultDeviceStateChangeTransition() {
- return mShouldUseDefaultDeviceStateChangeTransition;
+ public boolean shouldUseDefaultDisplayStateChangeTransition() {
+ return mShouldUseDefaultDisplayStateChangeTransition;
}
public void dump(Printer pw, String prefix) {
@@ -450,7 +450,7 @@ public final class WallpaperInfo implements Parcelable {
dest.writeInt(mSupportsAmbientMode ? 1 : 0);
dest.writeString(mSettingsSliceUri);
dest.writeInt(mSupportMultipleDisplays ? 1 : 0);
- dest.writeInt(mShouldUseDefaultDeviceStateChangeTransition ? 1 : 0);
+ dest.writeInt(mShouldUseDefaultDisplayStateChangeTransition ? 1 : 0);
mService.writeToParcel(dest, flags);
}
diff --git a/core/java/android/app/servertransaction/ActivityResultItem.java b/core/java/android/app/servertransaction/ActivityResultItem.java
index e059f177e344..27d104b59284 100644
--- a/core/java/android/app/servertransaction/ActivityResultItem.java
+++ b/core/java/android/app/servertransaction/ActivityResultItem.java
@@ -16,6 +16,8 @@
package android.app.servertransaction;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
+import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import android.annotation.NonNull;
@@ -23,6 +25,9 @@ import android.annotation.Nullable;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.ResultInfo;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
@@ -41,11 +46,19 @@ public class ActivityResultItem extends ActivityTransactionItem {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private List<ResultInfo> mResultInfoList;
- /* TODO(b/78294732)
+ /**
+ * Correct the lifecycle of activity result after {@link android.os.Build.VERSION_CODES#S} to
+ * guarantee that an activity gets activity result just before resume.
+ */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S)
+ public static final long CALL_ACTIVITY_RESULT_BEFORE_RESUME = 78294732L;
+
@Override
public int getPostExecutionState() {
- return ON_RESUME;
- }*/
+ return CompatChanges.isChangeEnabled(CALL_ACTIVITY_RESULT_BEFORE_RESUME)
+ ? ON_RESUME : UNDEFINED;
+ }
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 37cbccb89735..34e4fcdb9140 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -73,7 +73,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
private IBinder mAssistToken;
private IBinder mShareableActivityToken;
private boolean mLaunchedFromBubble;
- private IBinder mTaskFragmentToken;
/**
* It is only non-null if the process is the first time to launch activity. It is only an
* optimization for quick look up of the interface so the field is ignored for comparison.
@@ -87,7 +86,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
client, mAssistToken, mFixedRotationAdjustments, mShareableActivityToken,
- mLaunchedFromBubble, mTaskFragmentToken);
+ mLaunchedFromBubble);
client.addLaunchingActivity(token, r);
client.updateProcessState(mProcState, false);
client.updatePendingConfiguration(mCurConfig);
@@ -125,7 +124,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken,
IActivityClientController activityClientController,
FixedRotationAdjustments fixedRotationAdjustments, IBinder shareableActivityToken,
- boolean launchedFromBubble, IBinder taskFragmentToken) {
+ boolean launchedFromBubble) {
LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
if (instance == null) {
instance = new LaunchActivityItem();
@@ -134,7 +133,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
voiceInteractor, procState, state, persistentState, pendingResults,
pendingNewIntents, activityOptions, isForward, profilerInfo, assistToken,
activityClientController, fixedRotationAdjustments, shareableActivityToken,
- launchedFromBubble, taskFragmentToken);
+ launchedFromBubble);
return instance;
}
@@ -142,7 +141,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
@Override
public void recycle() {
setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null,
- null, false, null, null, null, null, null, false, null);
+ null, false, null, null, null, null, null, false);
ObjectPool.recycle(this);
}
@@ -173,7 +172,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
dest.writeTypedObject(mFixedRotationAdjustments, flags);
dest.writeStrongBinder(mShareableActivityToken);
dest.writeBoolean(mLaunchedFromBubble);
- dest.writeStrongBinder(mTaskFragmentToken);
}
/** Read from Parcel. */
@@ -192,8 +190,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
in.readStrongBinder(),
IActivityClientController.Stub.asInterface(in.readStrongBinder()),
in.readTypedObject(FixedRotationAdjustments.CREATOR), in.readStrongBinder(),
- in.readBoolean(),
- in.readStrongBinder());
+ in.readBoolean());
}
public static final @NonNull Creator<LaunchActivityItem> CREATOR =
@@ -232,8 +229,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
&& Objects.equals(mProfilerInfo, other.mProfilerInfo)
&& Objects.equals(mAssistToken, other.mAssistToken)
&& Objects.equals(mFixedRotationAdjustments, other.mFixedRotationAdjustments)
- && Objects.equals(mShareableActivityToken, other.mShareableActivityToken)
- && Objects.equals(mTaskFragmentToken, other.mTaskFragmentToken);
+ && Objects.equals(mShareableActivityToken, other.mShareableActivityToken);
}
@Override
@@ -256,7 +252,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
result = 31 * result + Objects.hashCode(mAssistToken);
result = 31 * result + Objects.hashCode(mFixedRotationAdjustments);
result = 31 * result + Objects.hashCode(mShareableActivityToken);
- result = 31 * result + Objects.hashCode(mTaskFragmentToken);
return result;
}
@@ -306,7 +301,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
ActivityOptions activityOptions, boolean isForward, ProfilerInfo profilerInfo,
IBinder assistToken, IActivityClientController activityClientController,
FixedRotationAdjustments fixedRotationAdjustments, IBinder shareableActivityToken,
- boolean launchedFromBubble, IBinder taskFragmentToken) {
+ boolean launchedFromBubble) {
instance.mIntent = intent;
instance.mIdent = ident;
instance.mInfo = info;
@@ -328,6 +323,5 @@ public class LaunchActivityItem extends ClientTransactionItem {
instance.mFixedRotationAdjustments = fixedRotationAdjustments;
instance.mShareableActivityToken = shareableActivityToken;
instance.mLaunchedFromBubble = launchedFromBubble;
- instance.mTaskFragmentToken = taskFragmentToken;
}
}
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index 518b22bd5e10..f5b2ac586bd1 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -24,6 +24,8 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import java.util.Arrays;
+
import com.android.internal.R;
/**
@@ -258,10 +260,11 @@ public class AmbientDisplayConfiguration {
String defaultValue,
int posture) {
String sensorType = defaultValue;
- if (posture < postureMapping.length) {
+ if (postureMapping != null && posture < postureMapping.length) {
sensorType = postureMapping[posture];
} else {
- Log.e(TAG, "Unsupported doze posture " + posture);
+ Log.e(TAG, "Unsupported doze posture " + posture
+ + " postureMapping=" + Arrays.toString(postureMapping));
}
return TextUtils.isEmpty(sensorType) ? defaultValue : sensorType;
diff --git a/core/java/android/hardware/display/BrightnessInfo.java b/core/java/android/hardware/display/BrightnessInfo.java
index c5d37c2d0b90..0dc8f92967fb 100644
--- a/core/java/android/hardware/display/BrightnessInfo.java
+++ b/core/java/android/hardware/display/BrightnessInfo.java
@@ -60,12 +60,18 @@ public final class BrightnessInfo implements Parcelable {
/** Brightness */
public final float brightness;
+ /** Brightness after {@link DisplayPowerController} adjustments */
+ public final float adjustedBrightness;
+
/** Current minimum supported brightness. */
public final float brightnessMinimum;
/** Current maximum supported brightness. */
public final float brightnessMaximum;
+ /** Brightness values greater than this point are only used in High Brightness Mode. */
+ public final float highBrightnessTransitionPoint;
+
/**
* Current state of high brightness mode.
* Can be any of HIGH_BRIGHTNESS_MODE_* values.
@@ -73,11 +79,20 @@ public final class BrightnessInfo implements Parcelable {
public final int highBrightnessMode;
public BrightnessInfo(float brightness, float brightnessMinimum, float brightnessMaximum,
- @HighBrightnessMode int highBrightnessMode) {
+ @HighBrightnessMode int highBrightnessMode, float highBrightnessTransitionPoint) {
+ this(brightness, brightness, brightnessMinimum, brightnessMaximum, highBrightnessMode,
+ highBrightnessTransitionPoint);
+ }
+
+ public BrightnessInfo(float brightness, float adjustedBrightness, float brightnessMinimum,
+ float brightnessMaximum, @HighBrightnessMode int highBrightnessMode,
+ float highBrightnessTransitionPoint) {
this.brightness = brightness;
+ this.adjustedBrightness = adjustedBrightness;
this.brightnessMinimum = brightnessMinimum;
this.brightnessMaximum = brightnessMaximum;
this.highBrightnessMode = highBrightnessMode;
+ this.highBrightnessTransitionPoint = highBrightnessTransitionPoint;
}
/**
@@ -103,9 +118,11 @@ public final class BrightnessInfo implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeFloat(brightness);
+ dest.writeFloat(adjustedBrightness);
dest.writeFloat(brightnessMinimum);
dest.writeFloat(brightnessMaximum);
dest.writeInt(highBrightnessMode);
+ dest.writeFloat(highBrightnessTransitionPoint);
}
public static final @android.annotation.NonNull Creator<BrightnessInfo> CREATOR =
@@ -123,9 +140,11 @@ public final class BrightnessInfo implements Parcelable {
private BrightnessInfo(Parcel source) {
brightness = source.readFloat();
+ adjustedBrightness = source.readFloat();
brightnessMinimum = source.readFloat();
brightnessMaximum = source.readFloat();
highBrightnessMode = source.readInt();
+ highBrightnessTransitionPoint = source.readFloat();
}
}
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 1f11d10052fe..1a7ec7f99c95 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -782,7 +782,7 @@ public class TextLine {
int spanStart = runStart;
int spanLimit;
- if (mSpanned == null) {
+ if (mSpanned == null || runStart == runLimit) {
spanLimit = runLimit;
} else {
int target = after ? offset + 1 : offset;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3f530fe3432c..1255dad27eed 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -248,6 +248,8 @@
android:name="com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY" />
<protected-broadcast
android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED" />
<protected-broadcast
android:name="android.bluetooth.action.TETHERING_STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED" />
diff --git a/core/res/res/anim-ldrtl/task_close_exit.xml b/core/res/res/anim-ldrtl/task_close_exit.xml
index 76fbdffd1760..0887019ca608 100644
--- a/core/res/res/anim-ldrtl/task_close_exit.xml
+++ b/core/res/res/anim-ldrtl/task_close_exit.xml
@@ -28,9 +28,4 @@
android:startOffset="0"
android:duration="500"/>
- <!-- This is needed to keep the animation running while task_open_enter completes -->
- <alpha
- android:fromAlpha="1.0"
- android:toAlpha="1.0"
- android:duration="600"/>
-</set> \ No newline at end of file
+</set>
diff --git a/core/res/res/anim-ldrtl/task_open_exit.xml b/core/res/res/anim-ldrtl/task_open_exit.xml
index beb6fca5632a..88cdcceae415 100644
--- a/core/res/res/anim-ldrtl/task_open_exit.xml
+++ b/core/res/res/anim-ldrtl/task_open_exit.xml
@@ -28,9 +28,4 @@
android:startOffset="0"
android:duration="500"/>
- <!-- This is needed to keep the animation running while task_open_enter completes -->
- <alpha
- android:fromAlpha="1.0"
- android:toAlpha="1.0"
- android:duration="600"/>
-</set> \ No newline at end of file
+</set>
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index 736f3f2083e5..3a8dd934cd17 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -30,9 +30,4 @@
android:startOffset="0"
android:duration="500"/>
- <!-- This is needed to keep the animation running while task_open_enter completes -->
- <alpha
- android:fromAlpha="1.0"
- android:toAlpha="1.0"
- android:duration="600"/>
-</set> \ No newline at end of file
+</set>
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index d1703170e16f..21fec7f694bf 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -30,9 +30,4 @@
android:startOffset="0"
android:duration="500"/>
- <!-- This is needed to keep the animation running while task_open_enter completes -->
- <alpha
- android:fromAlpha="1.0"
- android:toAlpha="1.0"
- android:duration="600"/>
-</set> \ No newline at end of file
+</set>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 53396407904a..77820d1dfa38 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -8372,8 +8372,8 @@
<attr name="supportsAmbientMode" format="boolean" />
<!-- Indicates that this wallpaper service should receive zoom transition updates when
- changing the device state (e.g. when folding or unfolding a foldable device).
- When this value is set to true
+ changing the display state of the device (e.g. when folding or unfolding
+ a foldable device). When this value is set to true
{@link android.service.wallpaper.WallpaperService.Engine} could receive zoom updates
before or after changing the device state. Wallpapers receive zoom updates using
{@link android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float)} and
@@ -8381,8 +8381,8 @@
{@link android.service.wallpaper.WallpaperService.Engine} is created and not destroyed.
Default value is true.
Corresponds to
- {@link android.app.WallpaperInfo#shouldUseDefaultDeviceStateChangeTransition()} -->
- <attr name="shouldUseDefaultDeviceStateChangeTransition" format="boolean" />
+ {@link android.app.WallpaperInfo#shouldUseDefaultDisplayStateChangeTransition()} -->
+ <attr name="shouldUseDefaultDisplayStateChangeTransition" format="boolean" />
<!-- Uri that specifies a settings Slice for this wallpaper. -->
<attr name="settingsSliceUri" format="string"/>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e17daf09e4da..462b1883e29d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3221,7 +3221,7 @@
<eat-comment />
<staging-public-group type="attr" first-id="0x01ff0000">
- <public name="shouldUseDefaultDeviceStateChangeTransition" />
+ <public name="shouldUseDefaultDisplayStateChangeTransition" />
</staging-public-group>
<staging-public-group type="id" first-id="0x01fe0000">
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index 50639be57f22..3e261a7113ac 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -157,7 +157,7 @@ public class ObjectPoolTests {
.setPendingResults(resultInfoList()).setPendingNewIntents(referrerIntentList())
.setIsForward(true).setAssistToken(assistToken)
.setShareableActivityToken(shareableActivityToken)
- .setTaskFragmentToken(new Binder()).build();
+ .build();
LaunchActivityItem emptyItem = new LaunchActivityItemBuilder().build();
LaunchActivityItem item = itemSupplier.get();
diff --git a/core/tests/coretests/src/android/app/servertransaction/TestUtils.java b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java
index 1173c9210ed5..75da0bfba581 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TestUtils.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java
@@ -112,7 +112,6 @@ class TestUtils {
private IBinder mShareableActivityToken;
private FixedRotationAdjustments mFixedRotationAdjustments;
private boolean mLaunchedFromBubble;
- private IBinder mTaskFragmentToken;
LaunchActivityItemBuilder setIntent(Intent intent) {
mIntent = intent;
@@ -214,18 +213,13 @@ class TestUtils {
return this;
}
- LaunchActivityItemBuilder setTaskFragmentToken(IBinder taskFragmentToken) {
- mTaskFragmentToken = taskFragmentToken;
- return this;
- }
-
LaunchActivityItem build() {
return LaunchActivityItem.obtain(mIntent, mIdent, mInfo,
mCurConfig, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor,
mProcState, mState, mPersistentState, mPendingResults, mPendingNewIntents,
mActivityOptions, mIsForward, mProfilerInfo, mAssistToken,
null /* activityClientController */, mFixedRotationAdjustments,
- mShareableActivityToken, mLaunchedFromBubble, mTaskFragmentToken);
+ mShareableActivityToken, mLaunchedFromBubble);
}
}
}
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 98c9afd2eb6b..df0c64c810c6 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -209,7 +209,6 @@ public class TransactionParcelTests {
.setPendingNewIntents(referrerIntentList()).setIsForward(true)
.setAssistToken(new Binder()).setFixedRotationAdjustments(fixedRotationAdjustments)
.setShareableActivityToken(new Binder())
- .setTaskFragmentToken(new Binder())
.build();
writeAndPrepareForReading(item);
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 516a5d288c0f..269d8424a78f 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -299,7 +299,7 @@ public class ActivityThreadClientTest {
null /* activityOptions */, true /* isForward */, null /* profilerInfo */,
mThread /* client */, null /* asssitToken */,
null /* fixedRotationAdjustments */, null /* shareableActivityToken */,
- false /* launchedFromBubble */, null /* taskfragmentToken */);
+ false /* launchedFromBubble */);
}
@Override
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index e1c8b11a835c..42b438041d7a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -172,7 +172,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
void handleActivityCreated(@NonNull Activity launchedActivity) {
final List<EmbeddingRule> splitRules = getSplitRules();
final TaskFragmentContainer currentContainer = getContainerWithActivity(
- launchedActivity.getActivityToken(), launchedActivity);
+ launchedActivity.getActivityToken());
// Check if the activity is configured to always be expanded.
if (shouldExpand(launchedActivity, null, splitRules)) {
@@ -262,29 +262,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
*/
@Nullable
TaskFragmentContainer getContainerWithActivity(@NonNull IBinder activityToken) {
- return getContainerWithActivity(activityToken, null /* activityToAdd */);
- }
-
- /**
- * This method can only be called from {@link #onActivityCreated(Activity)}, use
- * {@link #getContainerWithActivity(IBinder) } otherwise.
- *
- * Returns a container that this activity is registered with. The activity could be created
- * before the container appeared, adding the activity to the container if so.
- */
- @Nullable
- private TaskFragmentContainer getContainerWithActivity(@NonNull IBinder activityToken,
- Activity activityToAdd) {
- final IBinder taskFragmentToken = ActivityThread.currentActivityThread().getActivityClient(
- activityToken).mInitialTaskFragmentToken;
for (TaskFragmentContainer container : mContainers) {
if (container.hasActivity(activityToken)) {
return container;
- } else if (container.getTaskFragmentToken().equals(taskFragmentToken)) {
- if (activityToAdd != null) {
- container.addPendingAppearedActivity(activityToAdd);
- }
- return container;
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 25292b905fe8..81be21cbd7aa 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -252,7 +252,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
// Getting the parent bounds using the updated container - it will have the recent value.
final Rect parentBounds = getParentContainerBounds(updatedContainer);
final SplitRule rule = splitContainer.getSplitRule();
- final Activity activity = splitContainer.getPrimaryContainer().getTopNonFinishingActivity();
+ final TaskFragmentContainer primaryContainer = splitContainer.getPrimaryContainer();
+ final Activity activity = primaryContainer.getTopNonFinishingActivity();
if (activity == null) {
return;
}
@@ -264,10 +265,12 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
// If the task fragments are not registered yet, the positions will be updated after they
// are created again.
- resizeTaskFragmentIfRegistered(wct, splitContainer.getPrimaryContainer(),
- primaryRectBounds);
- resizeTaskFragmentIfRegistered(wct, splitContainer.getSecondaryContainer(),
- secondaryRectBounds);
+ resizeTaskFragmentIfRegistered(wct, primaryContainer, primaryRectBounds);
+ final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
+ resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds);
+
+ setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
+ secondaryContainer.getTaskFragmentToken(), rule);
}
/**
diff --git a/libs/WindowManager/Shell/res/color/unfold_transition_background.xml b/libs/WindowManager/Shell/res/color/unfold_transition_background.xml
new file mode 100644
index 000000000000..63289a3f75d9
--- /dev/null
+++ b/libs/WindowManager/Shell/res/color/unfold_transition_background.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Matches taskbar color -->
+ <item android:color="@android:color/system_neutral2_500" android:lStar="35" />
+</selector>
diff --git a/libs/WindowManager/Shell/res/layout/split_outline.xml b/libs/WindowManager/Shell/res/layout/split_outline.xml
index 4e2a77f213a0..13a30f5a0423 100644
--- a/libs/WindowManager/Shell/res/layout/split_outline.xml
+++ b/libs/WindowManager/Shell/res/layout/split_outline.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.wm.shell.splitscreen.OutlineRoot
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -23,4 +23,4 @@
android:layout_height="match_parent"
android:layout_width="match_parent" />
-</com.android.wm.shell.splitscreen.OutlineRoot>
+</FrameLayout>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
index df4f2383c062..fa58fcda3d3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
@@ -27,6 +27,8 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.freeform.FreeformTaskListener;
+import com.android.wm.shell.fullscreen.FullscreenTaskListener;
+import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -52,6 +54,7 @@ public class ShellInitImpl {
private final Optional<AppPairsController> mAppPairsOptional;
private final Optional<PipTouchHandler> mPipTouchHandlerOptional;
private final FullscreenTaskListener mFullscreenTaskListener;
+ private final Optional<FullscreenUnfoldController> mFullscreenUnfoldController;
private final Optional<FreeformTaskListener> mFreeformTaskListenerOptional;
private final ShellExecutor mMainExecutor;
private final Transitions mTransitions;
@@ -71,6 +74,7 @@ public class ShellInitImpl {
Optional<AppPairsController> appPairsOptional,
Optional<PipTouchHandler> pipTouchHandlerOptional,
FullscreenTaskListener fullscreenTaskListener,
+ Optional<FullscreenUnfoldController> fullscreenUnfoldTransitionController,
Optional<Optional<FreeformTaskListener>> freeformTaskListenerOptional,
Transitions transitions,
StartingWindowController startingWindow,
@@ -86,6 +90,7 @@ public class ShellInitImpl {
mAppPairsOptional = appPairsOptional;
mFullscreenTaskListener = fullscreenTaskListener;
mPipTouchHandlerOptional = pipTouchHandlerOptional;
+ mFullscreenUnfoldController = fullscreenUnfoldTransitionController;
mFreeformTaskListenerOptional = freeformTaskListenerOptional.flatMap(f -> f);
mTransitions = transitions;
mMainExecutor = mainExecutor;
@@ -128,6 +133,8 @@ public class ShellInitImpl {
mFreeformTaskListenerOptional.ifPresent(f ->
mShellTaskOrganizer.addListenerForType(
f, ShellTaskOrganizer.TASK_LISTENER_TYPE_FREEFORM));
+
+ mFullscreenUnfoldController.ifPresent(FullscreenUnfoldController::init);
}
@ExternalThread
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
index c2cb72a530a3..10d7725b6184 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
@@ -27,7 +27,6 @@ import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_UNDEF
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
import android.app.ActivityManager;
-import android.graphics.Rect;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.window.WindowContainerToken;
@@ -40,6 +39,7 @@ import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.SurfaceUtils;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.split.SplitLayout;
@@ -69,6 +69,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
private final SyncTransactionQueue mSyncQueue;
private final DisplayController mDisplayController;
private final DisplayImeController mDisplayImeController;
+ private final DisplayInsetsController mDisplayInsetsController;
private SplitLayout mSplitLayout;
private final SplitWindowManager.ParentContainerCallbacks mParentContainerCallbacks =
@@ -80,7 +81,12 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
@Override
public void onLeashReady(SurfaceControl leash) {
- mSyncQueue.runInSync(t -> t.show(leash));
+ mSyncQueue.runInSync(t -> t
+ .show(leash)
+ .setLayer(leash, SPLIT_DIVIDER_LAYER)
+ .setPosition(leash,
+ mSplitLayout.getDividerBounds().left,
+ mSplitLayout.getDividerBounds().top));
}
};
@@ -89,6 +95,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
mSyncQueue = controller.getSyncTransactionQueue();
mDisplayController = controller.getDisplayController();
mDisplayImeController = controller.getDisplayImeController();
+ mDisplayInsetsController = controller.getDisplayInsetsController();
}
int getRootTaskId() {
@@ -125,6 +132,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
mRootTaskInfo.configuration, this /* layoutChangeListener */,
mParentContainerCallbacks, mDisplayImeController, mController.getTaskOrganizer());
+ mDisplayInsetsController.addInsetsChangedListener(mRootTaskInfo.displayId, mSplitLayout);
final WindowContainerToken token1 = task1.token;
final WindowContainerToken token2 = task2.token;
@@ -190,22 +198,17 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
if (mTaskLeash1 == null || mTaskLeash2 == null) return;
mSplitLayout.init();
- final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
- final Rect dividerBounds = mSplitLayout.getDividerBounds();
-
- // TODO: Is there more we need to do here?
- mSyncQueue.runInSync(t -> {
- t.setLayer(dividerLeash, SPLIT_DIVIDER_LAYER)
- .setPosition(mTaskLeash1, mTaskInfo1.positionInParent.x,
- mTaskInfo1.positionInParent.y)
- .setPosition(mTaskLeash2, mTaskInfo2.positionInParent.x,
- mTaskInfo2.positionInParent.y)
- .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
- .show(dividerLeash)
- .show(mRootTaskLeash)
- .show(mTaskLeash1)
- .show(mTaskLeash2);
- });
+
+ mSyncQueue.runInSync(t -> t
+ .show(mRootTaskLeash)
+ .show(mTaskLeash1)
+ .show(mTaskLeash2)
+ .setPosition(mTaskLeash1,
+ mTaskInfo1.positionInParent.x,
+ mTaskInfo1.positionInParent.y)
+ .setPosition(mTaskLeash2,
+ mTaskInfo2.positionInParent.x,
+ mTaskInfo2.positionInParent.y));
}
@Override
@@ -227,10 +230,9 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
}
mRootTaskInfo = taskInfo;
- if (mSplitLayout != null) {
- if (mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)) {
- onLayoutChanged(mSplitLayout);
- }
+ if (mSplitLayout != null
+ && mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)) {
+ onLayoutChanged(mSplitLayout);
}
} else if (taskInfo.taskId == getTaskId1()) {
mTaskInfo1 = taskInfo;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java
index b159333e9a0e..53234ab971d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java
@@ -29,6 +29,7 @@ import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
@@ -50,14 +51,17 @@ public class AppPairsController {
private final SparseArray<AppPair> mActiveAppPairs = new SparseArray<>();
private final DisplayController mDisplayController;
private final DisplayImeController mDisplayImeController;
+ private final DisplayInsetsController mDisplayInsetsController;
public AppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
DisplayController displayController, ShellExecutor mainExecutor,
- DisplayImeController displayImeController) {
+ DisplayImeController displayImeController,
+ DisplayInsetsController displayInsetsController) {
mTaskOrganizer = organizer;
mSyncQueue = syncQueue;
mDisplayController = displayController;
mDisplayImeController = displayImeController;
+ mDisplayInsetsController = displayInsetsController;
mMainExecutor = mainExecutor;
}
@@ -148,6 +152,10 @@ public class AppPairsController {
return mDisplayImeController;
}
+ DisplayInsetsController getDisplayInsetsController() {
+ return mDisplayInsetsController;
+ }
+
public void dump(@NonNull PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
final String childPrefix = innerPrefix + " ";
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 1c308a3daf34..596a2f4467c3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -189,24 +189,28 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
final int rotation = configuration.windowConfiguration.getRotation();
final Rect rootBounds = configuration.windowConfiguration.getBounds();
final int orientation = configuration.orientation;
- if (rotation != mRotation || !mRootBounds.equals(rootBounds)
- || orientation != mOrientation) {
- mContext = mContext.createConfigurationContext(configuration);
- mSplitWindowManager.setConfiguration(configuration);
- mOrientation = orientation;
- mTempRect.set(mRootBounds);
- mRootBounds.set(rootBounds);
- mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
- initDividerPosition(mTempRect);
- affectsLayout = true;
+
+ if (mOrientation == orientation
+ && rotation == mRotation
+ && mRootBounds.equals(rootBounds)) {
+ return false;
}
+ mContext = mContext.createConfigurationContext(configuration);
+ mSplitWindowManager.setConfiguration(configuration);
+ mOrientation = orientation;
+ mTempRect.set(mRootBounds);
+ mRootBounds.set(rootBounds);
+ mRotation = rotation;
+ mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+ initDividerPosition(mTempRect);
+
if (mInitialized) {
release();
init();
}
- return affectsLayout;
+ return true;
}
private void initDividerPosition(Rect oldBounds) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 006730d333eb..3f17f2ba9394 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -14,25 +14,31 @@
* limitations under the License.
*/
-package com.android.wm.shell;
+package com.android.wm.shell.fullscreen;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;
-import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.TaskInfo;
import android.graphics.Point;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.view.SurfaceControl;
import androidx.annotation.NonNull;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
+import java.util.Optional;
/**
* Organizes tasks presented in {@link android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN}.
@@ -43,13 +49,17 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
private final SyncTransactionQueue mSyncQueue;
private final SparseArray<TaskData> mDataByTaskId = new SparseArray<>();
+ private final AnimatableTasksListener mAnimatableTasksListener = new AnimatableTasksListener();
+ private final FullscreenUnfoldController mFullscreenUnfoldController;
- public FullscreenTaskListener(SyncTransactionQueue syncQueue) {
+ public FullscreenTaskListener(SyncTransactionQueue syncQueue,
+ Optional<FullscreenUnfoldController> unfoldController) {
mSyncQueue = syncQueue;
+ mFullscreenUnfoldController = unfoldController.orElse(null);
}
@Override
- public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
+ public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
if (mDataByTaskId.get(taskInfo.taskId) != null) {
throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId);
}
@@ -67,11 +77,16 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
t.setMatrix(leash, 1, 0, 0, 1);
t.show(leash);
});
+
+ mAnimatableTasksListener.onTaskAppeared(taskInfo);
}
@Override
- public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
+
+ mAnimatableTasksListener.onTaskInfoChanged(taskInfo);
+
final TaskData data = mDataByTaskId.get(taskInfo.taskId);
final Point positionInParent = taskInfo.positionInParent;
if (!positionInParent.equals(data.positionInParent)) {
@@ -83,12 +98,15 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
}
@Override
- public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onTaskVanished(RunningTaskInfo taskInfo) {
if (mDataByTaskId.get(taskInfo.taskId) == null) {
Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
return;
}
+
+ mAnimatableTasksListener.onTaskVanished(taskInfo);
mDataByTaskId.remove(taskInfo.taskId);
+
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d",
taskInfo.taskId);
}
@@ -125,4 +143,65 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
this.positionInParent = positionInParent;
}
}
+
+ class AnimatableTasksListener {
+ private final SparseBooleanArray mTaskIds = new SparseBooleanArray();
+
+ public void onTaskAppeared(RunningTaskInfo taskInfo) {
+ final boolean isApplicable = isAnimatable(taskInfo);
+ if (isApplicable) {
+ mTaskIds.put(taskInfo.taskId, true);
+
+ if (mFullscreenUnfoldController != null) {
+ SurfaceControl leash = mDataByTaskId.get(taskInfo.taskId).surface;
+ mFullscreenUnfoldController.onTaskAppeared(taskInfo, leash);
+ }
+ }
+ }
+
+ public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
+ final boolean isCurrentlyApplicable = mTaskIds.get(taskInfo.taskId);
+ final boolean isApplicable = isAnimatable(taskInfo);
+
+ if (isCurrentlyApplicable) {
+ if (isApplicable) {
+ // Still applicable, send update
+ if (mFullscreenUnfoldController != null) {
+ mFullscreenUnfoldController.onTaskInfoChanged(taskInfo);
+ }
+ } else {
+ // Became inapplicable
+ if (mFullscreenUnfoldController != null) {
+ mFullscreenUnfoldController.onTaskVanished(taskInfo);
+ }
+ mTaskIds.put(taskInfo.taskId, false);
+ }
+ } else {
+ if (isApplicable) {
+ // Became applicable
+ mTaskIds.put(taskInfo.taskId, true);
+
+ if (mFullscreenUnfoldController != null) {
+ SurfaceControl leash = mDataByTaskId.get(taskInfo.taskId).surface;
+ mFullscreenUnfoldController.onTaskAppeared(taskInfo, leash);
+ }
+ }
+ }
+ }
+
+ public void onTaskVanished(RunningTaskInfo taskInfo) {
+ final boolean isCurrentlyApplicable = mTaskIds.get(taskInfo.taskId);
+ if (isCurrentlyApplicable && mFullscreenUnfoldController != null) {
+ mFullscreenUnfoldController.onTaskVanished(taskInfo);
+ }
+ mTaskIds.put(taskInfo.taskId, false);
+ }
+
+ private boolean isAnimatable(TaskInfo taskInfo) {
+ // Filter all visible tasks that are not launcher tasks
+ // We do not animate launcher as it handles the animation by itself
+ return taskInfo != null && taskInfo.isVisible && taskInfo.getConfiguration()
+ .windowConfiguration.getActivityType() != ACTIVITY_TYPE_HOME;
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java
new file mode 100644
index 000000000000..08ab85cab97b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.fullscreen;
+
+import static android.graphics.Color.blue;
+import static android.graphics.Color.green;
+import static android.graphics.Color.red;
+import static android.util.MathUtils.lerp;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.animation.RectEvaluator;
+import android.animation.TypeEvaluator;
+import android.annotation.NonNull;
+import android.app.ActivityManager;
+import android.app.TaskInfo;
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.util.SparseArray;
+import android.view.InsetsSource;
+import android.view.InsetsState;
+import android.view.SurfaceControl;
+
+import com.android.internal.policy.ScreenDecorationsUtils;
+import com.android.wm.shell.R;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
+import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener;
+import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
+import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Controls full screen app unfold transition: animating cropping window and scaling when
+ * folding or unfolding a foldable device.
+ */
+public final class FullscreenUnfoldController implements UnfoldListener,
+ OnInsetsChangedListener {
+
+ private static final float[] FLOAT_9 = new float[9];
+ private static final TypeEvaluator<Rect> RECT_EVALUATOR = new RectEvaluator(new Rect());
+
+ private static final float HORIZONTAL_START_MARGIN = 0.08f;
+ private static final float VERTICAL_START_MARGIN = 0.03f;
+ private static final float END_SCALE = 1f;
+ private static final float START_SCALE = END_SCALE - VERTICAL_START_MARGIN * 2;
+ private static final int BACKGROUND_LAYER_Z_INDEX = -1;
+
+ private final Context mContext;
+ private final Executor mExecutor;
+ private final ShellUnfoldProgressProvider mProgressProvider;
+ private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
+ private final DisplayInsetsController mDisplayInsetsController;
+
+ private final SparseArray<AnimationContext> mAnimationContextByTaskId = new SparseArray<>();
+
+ private SurfaceControl mBackgroundLayer;
+ private InsetsSource mTaskbarInsetsSource;
+
+ private final float mWindowCornerRadiusPx;
+ private final float[] mBackgroundColor;
+ private final float mExpandedTaskBarHeight;
+
+ private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
+
+ public FullscreenUnfoldController(
+ @NonNull Context context,
+ @NonNull Executor executor,
+ @NonNull ShellUnfoldProgressProvider progressProvider,
+ @NonNull RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ @NonNull DisplayInsetsController displayInsetsController
+ ) {
+ mContext = context;
+ mExecutor = executor;
+ mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+ mProgressProvider = progressProvider;
+ mDisplayInsetsController = displayInsetsController;
+ mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(context);
+ mExpandedTaskBarHeight = context.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.taskbar_frame_height);
+ mBackgroundColor = getBackgroundColor();
+ }
+
+ /**
+ * Initializes the controller
+ */
+ public void init() {
+ mProgressProvider.addListener(mExecutor, this);
+ mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY, this);
+ }
+
+ @Override
+ public void onStateChangeProgress(float progress) {
+ if (mAnimationContextByTaskId.size() == 0) return;
+
+ ensureBackground();
+
+ for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
+ final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
+
+ context.mCurrentCropRect.set(RECT_EVALUATOR
+ .evaluate(progress, context.mStartCropRect, context.mEndCropRect));
+
+ float scale = lerp(START_SCALE, END_SCALE, progress);
+ context.mMatrix.setScale(scale, scale, context.mCurrentCropRect.exactCenterX(),
+ context.mCurrentCropRect.exactCenterY());
+
+ mTransaction.setWindowCrop(context.mLeash, context.mCurrentCropRect)
+ .setMatrix(context.mLeash, context.mMatrix, FLOAT_9)
+ .setCornerRadius(context.mLeash, mWindowCornerRadiusPx);
+ }
+
+ mTransaction.apply();
+ }
+
+ @Override
+ public void onStateChangeFinished() {
+ for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
+ final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
+ resetSurface(context);
+ }
+
+ removeBackground();
+ mTransaction.apply();
+ }
+
+ @Override
+ public void insetsChanged(InsetsState insetsState) {
+ mTaskbarInsetsSource = insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
+ for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
+ AnimationContext context = mAnimationContextByTaskId.valueAt(i);
+ context.update(mTaskbarInsetsSource, context.mTaskInfo);
+ }
+ }
+
+ /**
+ * Called when a new matching task appeared
+ */
+ public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
+ AnimationContext animationContext = new AnimationContext(leash, mTaskbarInsetsSource,
+ taskInfo);
+ mAnimationContextByTaskId.put(taskInfo.taskId, animationContext);
+ }
+
+ /**
+ * Called when matching task changed
+ */
+ public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ AnimationContext animationContext = mAnimationContextByTaskId.get(taskInfo.taskId);
+ if (animationContext != null) {
+ animationContext.update(mTaskbarInsetsSource, taskInfo);
+ }
+ }
+
+ /**
+ * Called when matching task vanished
+ */
+ public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ AnimationContext animationContext = mAnimationContextByTaskId.get(taskInfo.taskId);
+ if (animationContext != null) {
+ resetSurface(animationContext);
+ mAnimationContextByTaskId.remove(taskInfo.taskId);
+ }
+
+ if (mAnimationContextByTaskId.size() == 0) {
+ removeBackground();
+ }
+
+ mTransaction.apply();
+ }
+
+ private void resetSurface(AnimationContext context) {
+ mTransaction
+ .setWindowCrop(context.mLeash, null)
+ .setCornerRadius(context.mLeash, 0.0F)
+ .setMatrix(context.mLeash, 1.0F, 0.0F, 0.0F, 1.0F)
+ .setPosition(context.mLeash,
+ (float) context.mTaskInfo.positionInParent.x,
+ (float) context.mTaskInfo.positionInParent.y);
+ }
+
+ private void ensureBackground() {
+ if (mBackgroundLayer != null) return;
+
+ SurfaceControl.Builder colorLayerBuilder = new SurfaceControl.Builder()
+ .setName("app-unfold-background")
+ .setCallsite("AppUnfoldTransitionController")
+ .setColorLayer();
+ mRootTaskDisplayAreaOrganizer.attachToDisplayArea(DEFAULT_DISPLAY, colorLayerBuilder);
+ mBackgroundLayer = colorLayerBuilder.build();
+
+ mTransaction
+ .setColor(mBackgroundLayer, mBackgroundColor)
+ .show(mBackgroundLayer)
+ .setLayer(mBackgroundLayer, BACKGROUND_LAYER_Z_INDEX);
+ }
+
+ private void removeBackground() {
+ if (mBackgroundLayer == null) return;
+ if (mBackgroundLayer.isValid()) {
+ mTransaction.remove(mBackgroundLayer);
+ }
+ mBackgroundLayer = null;
+ }
+
+ private float[] getBackgroundColor() {
+ int colorInt = mContext.getResources().getColor(R.color.unfold_transition_background);
+ return new float[]{
+ (float) red(colorInt) / 255.0F,
+ (float) green(colorInt) / 255.0F,
+ (float) blue(colorInt) / 255.0F
+ };
+ }
+
+ private class AnimationContext {
+ final SurfaceControl mLeash;
+ final Rect mStartCropRect = new Rect();
+ final Rect mEndCropRect = new Rect();
+ final Rect mCurrentCropRect = new Rect();
+ final Matrix mMatrix = new Matrix();
+
+ TaskInfo mTaskInfo;
+
+ private AnimationContext(SurfaceControl leash,
+ InsetsSource taskBarInsetsSource,
+ TaskInfo taskInfo) {
+ this.mLeash = leash;
+ update(taskBarInsetsSource, taskInfo);
+ }
+
+ private void update(InsetsSource taskBarInsetsSource, TaskInfo taskInfo) {
+ mTaskInfo = taskInfo;
+ mStartCropRect.set(mTaskInfo.getConfiguration().windowConfiguration.getBounds());
+
+ if (taskBarInsetsSource != null) {
+ // Only insets the cropping window with task bar when it's expanded
+ if (taskBarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) {
+ mStartCropRect.inset(taskBarInsetsSource
+ .calculateVisibleInsets(mStartCropRect));
+ }
+ }
+
+ mEndCropRect.set(mStartCropRect);
+
+ int horizontalMargin = (int) (mEndCropRect.width() * HORIZONTAL_START_MARGIN);
+ mStartCropRect.left = mEndCropRect.left + horizontalMargin;
+ mStartCropRect.right = mEndCropRect.right - horizontalMargin;
+ int verticalMargin = (int) (mEndCropRect.height() * VERTICAL_START_MARGIN);
+ mStartCropRect.top = mEndCropRect.top + verticalMargin;
+ mStartCropRect.bottom = mEndCropRect.bottom - verticalMargin;
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineManager.java
index 0b763f2d05f7..a459c8dbfa34 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineManager.java
@@ -22,19 +22,23 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Binder;
import android.view.IWindow;
+import android.view.InsetsSource;
+import android.view.InsetsState;
import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
-import android.view.WindowInsets;
+import android.view.View;
+import android.view.ViewGroup;
import android.view.WindowManager;
-import android.view.WindowMetrics;
import android.view.WindowlessWindowManager;
+import android.widget.FrameLayout;
import com.android.wm.shell.R;
@@ -45,17 +49,22 @@ import com.android.wm.shell.R;
class OutlineManager extends WindowlessWindowManager {
private static final String WINDOW_NAME = "SplitOutlineLayer";
private final Context mContext;
- private final Rect mOutlineBounds = new Rect();
- private final Rect mTmpBounds = new Rect();
+ private final Rect mRootBounds = new Rect();
+ private final Rect mTempRect = new Rect();
+ private final Rect mLastOutlineBounds = new Rect();
+ private final InsetsState mInsetsState = new InsetsState();
+ private final int mExpandedTaskBarHeight;
+ private OutlineView mOutlineView;
private SurfaceControlViewHost mViewHost;
private SurfaceControl mHostLeash;
private SurfaceControl mLeash;
- private int mOutlineColor;
OutlineManager(Context context, Configuration configuration) {
super(configuration, null /* rootSurface */, null /* hostInputToken */);
mContext = context.createWindowContext(context.getDisplay(), TYPE_APPLICATION_OVERLAY,
null /* options */);
+ mExpandedTaskBarHeight = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.taskbar_frame_height);
}
@Override
@@ -63,65 +72,110 @@ class OutlineManager extends WindowlessWindowManager {
b.setParent(mHostLeash);
}
- boolean drawOutlineBounds(Rect rootBounds) {
- if (mLeash == null || mViewHost == null) return false;
-
- computeOutlineBounds(mContext, rootBounds, mTmpBounds);
- if (mOutlineBounds.equals(mTmpBounds)) {
- return false;
- }
- mOutlineBounds.set(mTmpBounds);
-
- ((OutlineRoot) mViewHost.getView()).updateOutlineBounds(mOutlineBounds, mOutlineColor);
- final WindowManager.LayoutParams lp =
- (WindowManager.LayoutParams) mViewHost.getView().getLayoutParams();
- lp.width = rootBounds.width();
- lp.height = rootBounds.height();
- mViewHost.relayout(lp);
-
- return true;
- }
-
- void inflate(SurfaceControl.Transaction t, SurfaceControl hostLeash, int color) {
+ void inflate(SurfaceControl rootLeash, Rect rootBounds) {
if (mLeash != null || mViewHost != null) return;
- mHostLeash = hostLeash;
- mOutlineColor = color;
+ mHostLeash = rootLeash;
+ mRootBounds.set(rootBounds);
mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
- final OutlineRoot rootView = (OutlineRoot) LayoutInflater.from(mContext)
+
+ final FrameLayout rootLayout = (FrameLayout) LayoutInflater.from(mContext)
.inflate(R.layout.split_outline, null);
+ mOutlineView = rootLayout.findViewById(R.id.split_outline);
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
0 /* width */, 0 /* height */, TYPE_APPLICATION_OVERLAY,
FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
+ lp.width = mRootBounds.width();
+ lp.height = mRootBounds.height();
lp.token = new Binder();
lp.setTitle(WINDOW_NAME);
lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
// TODO(b/189839391): Set INPUT_FEATURE_NO_INPUT_CHANNEL after WM supports
// TRUSTED_OVERLAY for windowless window without input channel.
- mViewHost.setView(rootView, lp);
+ mViewHost.setView(rootLayout, lp);
mLeash = getSurfaceControl(mViewHost.getWindowToken());
- t.setLayer(mLeash, Integer.MAX_VALUE);
+
+ drawOutline();
}
void release() {
if (mViewHost != null) {
mViewHost.release();
+ mViewHost = null;
}
+ mRootBounds.setEmpty();
+ mLastOutlineBounds.setEmpty();
+ mOutlineView = null;
+ mHostLeash = null;
+ mLeash = null;
+ }
+
+ @Nullable
+ SurfaceControl getOutlineLeash() {
+ return mLeash;
}
- private static void computeOutlineBounds(Context context, Rect rootBounds, Rect outBounds) {
- computeDisplayStableBounds(context, outBounds);
- outBounds.intersect(rootBounds);
+ void setVisibility(boolean visible) {
+ if (mOutlineView != null) {
+ mOutlineView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+ }
+ }
+
+ void setRootBounds(Rect rootBounds) {
+ if (mViewHost == null || mViewHost.getView() == null) {
+ return;
+ }
+
+ if (!mRootBounds.equals(rootBounds)) {
+ WindowManager.LayoutParams lp =
+ (WindowManager.LayoutParams) mViewHost.getView().getLayoutParams();
+ lp.width = rootBounds.width();
+ lp.height = rootBounds.height();
+ mViewHost.relayout(lp);
+ mRootBounds.set(rootBounds);
+ drawOutline();
+ }
+ }
+
+ void onInsetsChanged(InsetsState insetsState) {
+ if (!mInsetsState.equals(insetsState)) {
+ mInsetsState.set(insetsState);
+ drawOutline();
+ }
+ }
+
+ private void computeOutlineBounds(Rect rootBounds, InsetsState insetsState, Rect outBounds) {
+ outBounds.set(rootBounds);
+ final InsetsSource taskBarInsetsSource =
+ insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
+ // Only insets the divider bar with task bar when it's expanded so that the rounded corners
+ // will be drawn against task bar.
+ if (taskBarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) {
+ outBounds.inset(taskBarInsetsSource.calculateVisibleInsets(outBounds));
+ }
+
// Offset the coordinate from screen based to surface based.
outBounds.offset(-rootBounds.left, -rootBounds.top);
}
- private static void computeDisplayStableBounds(Context context, Rect outBounds) {
- final WindowMetrics windowMetrics =
- context.getSystemService(WindowManager.class).getMaximumWindowMetrics();
- outBounds.set(windowMetrics.getBounds());
- outBounds.inset(windowMetrics.getWindowInsets().getInsets(
- WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout()));
+ void drawOutline() {
+ if (mOutlineView == null) {
+ return;
+ }
+
+ computeOutlineBounds(mRootBounds, mInsetsState, mTempRect);
+ if (mTempRect.equals(mLastOutlineBounds)) {
+ return;
+ }
+
+ ViewGroup.MarginLayoutParams lp =
+ (ViewGroup.MarginLayoutParams) mOutlineView.getLayoutParams();
+ lp.leftMargin = mTempRect.left;
+ lp.topMargin = mTempRect.top;
+ lp.width = mTempRect.width();
+ lp.height = mTempRect.height();
+ mOutlineView.setLayoutParams(lp);
+ mLastOutlineBounds.set(mTempRect);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineRoot.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineRoot.java
deleted file mode 100644
index 71d48eeca71d..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineRoot.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2021 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.wm.shell.splitscreen;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.wm.shell.R;
-
-/** Root layout for holding split outline. */
-public class OutlineRoot extends FrameLayout {
- public OutlineRoot(@NonNull Context context) {
- super(context);
- }
-
- public OutlineRoot(@NonNull Context context,
- @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- public OutlineRoot(@NonNull Context context, @Nullable AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public OutlineRoot(@NonNull Context context, @Nullable AttributeSet attrs,
- int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- private OutlineView mOutlineView;
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mOutlineView = findViewById(R.id.split_outline);
- }
-
- void updateOutlineBounds(Rect bounds, int color) {
- mOutlineView.updateOutlineBounds(bounds, color);
- }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineView.java
index ea66180e3dd2..94dd9b24875a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/OutlineView.java
@@ -16,13 +16,17 @@
package com.android.wm.shell.splitscreen;
+import static android.view.RoundedCorner.POSITION_BOTTOM_LEFT;
+import static android.view.RoundedCorner.POSITION_BOTTOM_RIGHT;
+import static android.view.RoundedCorner.POSITION_TOP_LEFT;
+import static android.view.RoundedCorner.POSITION_TOP_RIGHT;
+
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
-import android.graphics.Rect;
-import android.graphics.Region;
import android.util.AttributeSet;
+import android.view.RoundedCorner;
import android.view.View;
import androidx.annotation.NonNull;
@@ -33,44 +37,46 @@ import com.android.internal.R;
/** View for drawing split outline. */
public class OutlineView extends View {
private final Paint mPaint = new Paint();
- private final Rect mBounds = new Rect();
-
- public OutlineView(@NonNull Context context) {
- super(context);
- }
+ private final Path mPath = new Path();
+ private final float[] mRadii = new float[8];
- public OutlineView(@NonNull Context context,
- @Nullable AttributeSet attrs) {
+ public OutlineView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setStrokeWidth(
+ getResources().getDimension(R.dimen.accessibility_focus_highlight_stroke_width));
+ mPaint.setColor(getResources().getColor(R.color.system_accent1_100, null));
}
- public OutlineView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
+ @Override
+ protected void onAttachedToWindow() {
+ // TODO(b/200850654): match the screen corners with the actual display decor.
+ mRadii[0] = mRadii[1] = getCornerRadius(POSITION_TOP_LEFT);
+ mRadii[2] = mRadii[3] = getCornerRadius(POSITION_TOP_RIGHT);
+ mRadii[4] = mRadii[5] = getCornerRadius(POSITION_BOTTOM_RIGHT);
+ mRadii[6] = mRadii[7] = getCornerRadius(POSITION_BOTTOM_LEFT);
}
- public OutlineView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
+ private int getCornerRadius(@RoundedCorner.Position int position) {
+ final RoundedCorner roundedCorner = getDisplay().getRoundedCorner(position);
+ return roundedCorner == null ? 0 : roundedCorner.getRadius();
}
@Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mPaint.setStyle(Paint.Style.STROKE);
- mPaint.setStrokeWidth(getResources()
- .getDimension(R.dimen.accessibility_focus_highlight_stroke_width));
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ if (changed) {
+ mPath.reset();
+ mPath.addRoundRect(0, 0, getWidth(), getHeight(), mRadii, Path.Direction.CW);
+ }
}
- void updateOutlineBounds(Rect bounds, int color) {
- if (mBounds.equals(bounds) && mPaint.getColor() == color) return;
- mBounds.set(bounds);
- mPaint.setColor(color);
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawPath(mPath, mPaint);
}
@Override
- protected void onDraw(Canvas canvas) {
- if (mBounds.isEmpty()) return;
- final Path path = new Region(mBounds).getBoundaryPath();
- canvas.drawPath(path, mPaint);
+ public boolean hasOverlappingRendering() {
+ return false;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
index 2b19bb965fed..0e7ccd3515c4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
@@ -17,15 +17,19 @@
package com.android.wm.shell.splitscreen;
import android.annotation.CallSuper;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Context;
-import android.graphics.Color;
import android.graphics.Rect;
+import android.view.InsetsSourceControl;
+import android.view.InsetsState;
+import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.SyncTransactionQueue;
/**
@@ -34,7 +38,8 @@ import com.android.wm.shell.common.SyncTransactionQueue;
*
* @see StageCoordinator
*/
-class SideStage extends StageTaskListener {
+class SideStage extends StageTaskListener implements
+ DisplayInsetsController.OnInsetsChangedListener {
private static final String TAG = SideStage.class.getSimpleName();
private final Context mContext;
private OutlineManager mOutlineManager;
@@ -77,33 +82,61 @@ class SideStage extends StageTaskListener {
return true;
}
+ @Nullable
+ public SurfaceControl getOutlineLeash() {
+ return mOutlineManager.getOutlineLeash();
+ }
+
+ @Override
+ @CallSuper
+ public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
+ super.onTaskAppeared(taskInfo, leash);
+ if (isRootTask(taskInfo)) {
+ mOutlineManager = new OutlineManager(mContext, taskInfo.configuration);
+ enableOutline(true);
+ }
+ }
+
+ @Override
+ @CallSuper
+ public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ super.onTaskInfoChanged(taskInfo);
+ if (isRootTask(taskInfo)) {
+ mOutlineManager.setRootBounds(taskInfo.configuration.windowConfiguration.getBounds());
+ }
+ }
+
+ private boolean isRootTask(ActivityManager.RunningTaskInfo taskInfo) {
+ return mRootTaskInfo != null && mRootTaskInfo.taskId == taskInfo.taskId;
+ }
+
void enableOutline(boolean enable) {
+ if (mOutlineManager == null) {
+ return;
+ }
+
if (enable) {
- if (mOutlineManager == null && mRootTaskInfo != null) {
- mOutlineManager = new OutlineManager(mContext, mRootTaskInfo.configuration);
- mSyncQueue.runInSync(t -> mOutlineManager.inflate(t, mRootLeash, Color.YELLOW));
- updateOutlineBounds();
+ if (mRootTaskInfo != null) {
+ mOutlineManager.inflate(mRootLeash,
+ mRootTaskInfo.configuration.windowConfiguration.getBounds());
}
} else {
- if (mOutlineManager != null) {
- mOutlineManager.release();
- mOutlineManager = null;
- }
+ mOutlineManager.release();
}
}
- private void updateOutlineBounds() {
- if (mOutlineManager == null || mRootTaskInfo == null || !mRootTaskInfo.isVisible) return;
- mOutlineManager.drawOutlineBounds(
- mRootTaskInfo.configuration.windowConfiguration.getBounds());
+ void setOutlineVisibility(boolean visible) {
+ mOutlineManager.setVisibility(visible);
}
@Override
- @CallSuper
- public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
- super.onTaskInfoChanged(taskInfo);
- if (mRootTaskInfo != null && mRootTaskInfo.taskId == taskInfo.taskId) {
- updateOutlineBounds();
- }
+ public void insetsChanged(InsetsState insetsState) {
+ mOutlineManager.onInsetsChanged(insetsState);
+ }
+
+ @Override
+ public void insetsControlChanged(InsetsState insetsState,
+ InsetsSourceControl[] activeControls) {
+ insetsChanged(insetsState);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 6527cabb0d34..ac68b3b8a6a9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -257,11 +257,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
}
- final RemoteAnimationTarget divider = mStageCoordinator.getDividerBarLegacyTarget();
- if (divider.leash != null) {
- t.show(divider.leash);
- }
-
t.apply();
if (finishedCallback != null) {
try {
@@ -300,7 +295,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
transaction.apply();
transaction.close();
- return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
+ return new RemoteAnimationTarget[]{
+ mStageCoordinator.getDividerBarLegacyTarget(),
+ mStageCoordinator.getOutlineLegacyTarget()};
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index a046c42b2391..d7a6cfff6c6f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -201,6 +201,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSurfaceSession);
mDisplayImeController = displayImeController;
mDisplayInsetsController = displayInsetsController;
+ mDisplayInsetsController.addInsetsChangedListener(mDisplayId, mSideStage);
mRootTDAOrganizer.registerListener(displayId, this);
final DeviceStateManager deviceStateManager =
mContext.getSystemService(DeviceStateManager.class);
@@ -682,6 +683,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
t.setVisibility(mSideStage.mRootLeash, bothStageVisible)
.setVisibility(mMainStage.mRootLeash, bothStageVisible);
applyDividerVisibility(t);
+ applyOutlineVisibility(t);
}
});
}
@@ -703,6 +705,19 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
+ private void applyOutlineVisibility(SurfaceControl.Transaction t) {
+ final SurfaceControl outlineLeash = mSideStage.getOutlineLeash();
+ if (outlineLeash == null) {
+ return;
+ }
+
+ if (mDividerVisible) {
+ t.show(outlineLeash).setLayer(outlineLeash, SPLIT_DIVIDER_LAYER);
+ } else {
+ t.hide(outlineLeash);
+ }
+ }
+
private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
final boolean hasChildren = stageListener.mHasChildren;
final boolean isSideStage = stageListener == mSideStageListener;
@@ -762,6 +777,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@Override
public void onLayoutChanging(SplitLayout layout) {
mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t));
+ mSideStage.setOutlineVisibility(false);
}
@Override
@@ -770,6 +786,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
updateWindowBounds(layout, wct);
mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t));
+ mSideStage.setOutlineVisibility(true);
mLogger.logResize(mSplitLayout.getDividerPositionAsFraction());
}
@@ -1145,6 +1162,18 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
null /* taskInfo */, false /* allowEnterPip */, TYPE_DOCK_DIVIDER);
}
+ RemoteAnimationTarget getOutlineLegacyTarget() {
+ final Rect bounds = mSideStage.mRootTaskInfo.configuration.windowConfiguration.getBounds();
+ // Leverage TYPE_DOCK_DIVIDER type when wrapping outline remote animation target in order to
+ // distinguish as a split auxiliary target in Launcher.
+ return new RemoteAnimationTarget(-1 /* taskId */, -1 /* mode */,
+ mSideStage.getOutlineLeash(), false /* isTranslucent */, null /* clipRect */,
+ null /* contentInsets */, Integer.MAX_VALUE /* prefixOrderIndex */,
+ new android.graphics.Point(0, 0) /* position */, bounds, bounds,
+ new WindowConfiguration(), true, null /* startLeash */, null /* startBounds */,
+ null /* taskInfo */, false /* allowEnterPip */, TYPE_DOCK_DIVIDER);
+ }
+
@Override
public void dump(@NonNull PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 15b4ff970203..4140332f50a3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -138,8 +138,11 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
mRootTaskInfo = taskInfo;
mCallbacks.onRootTaskAppeared();
sendStatusChanged();
- mSyncQueue.runInSync(t -> mDimLayer =
- SurfaceUtils.makeDimLayer(t, mRootLeash, "Dim layer", mSurfaceSession));
+ mSyncQueue.runInSync(t -> {
+ t.hide(mRootLeash);
+ mDimLayer =
+ SurfaceUtils.makeDimLayer(t, mRootLeash, "Dim layer", mSurfaceSession);
+ });
} else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
final int taskId = taskInfo.taskId;
mChildrenLeashes.put(taskId, leash);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/ShellUnfoldProgressProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/ShellUnfoldProgressProvider.java
new file mode 100644
index 000000000000..74e48120bf1a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/ShellUnfoldProgressProvider.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.unfold;
+
+import android.annotation.FloatRange;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Wrapper interface for unfold transition progress provider for the Shell
+ * @see com.android.systemui.unfold.UnfoldTransitionProgressProvider
+ */
+public interface ShellUnfoldProgressProvider {
+
+ /**
+ * Adds a transition listener
+ */
+ void addListener(Executor executor, UnfoldListener listener);
+
+ /**
+ * Listener for receiving unfold updates
+ */
+ interface UnfoldListener {
+ default void onStateChangeStarted() {}
+
+ default void onStateChangeProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {}
+
+ default void onStateChangeFinished() {}
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsController.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsController.java
index 27c626170a4b..294bc1276291 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsController.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsController.java
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
@@ -30,7 +31,7 @@ public class TestAppPairsController extends AppPairsController {
public TestAppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
DisplayController displayController) {
super(organizer, syncQueue, displayController, mock(ShellExecutor.class),
- mock(DisplayImeController.class));
+ mock(DisplayImeController.class), mock(DisplayInsetsController.class));
mPool = new TestAppPairsPool(this);
setPairsPool(mPool);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java
new file mode 100644
index 000000000000..d6f7e54ae369
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.fullscreen;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.WindowConfiguration;
+import android.content.res.Configuration;
+import android.graphics.Point;
+import android.view.SurfaceControl;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+@SmallTest
+public class FullscreenTaskListenerTest {
+
+ @Mock
+ private SyncTransactionQueue mSyncQueue;
+ @Mock
+ private FullscreenUnfoldController mUnfoldController;
+ @Mock
+ private SurfaceControl mSurfaceControl;
+
+ private Optional<FullscreenUnfoldController> mFullscreenUnfoldController;
+
+ private FullscreenTaskListener mListener;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mFullscreenUnfoldController = Optional.of(mUnfoldController);
+ mListener = new FullscreenTaskListener(mSyncQueue, mFullscreenUnfoldController);
+ }
+
+ @Test
+ public void testAnimatableTaskAppeared_notifiesUnfoldController() {
+ RunningTaskInfo info = createTaskInfo(/* visible */ true, /* taskId */ 0);
+
+ mListener.onTaskAppeared(info, mSurfaceControl);
+
+ verify(mUnfoldController).onTaskAppeared(eq(info), any());
+ }
+
+ @Test
+ public void testMultipleAnimatableTasksAppeared_notifiesUnfoldController() {
+ RunningTaskInfo animatable1 = createTaskInfo(/* visible */ true, /* taskId */ 0);
+ RunningTaskInfo animatable2 = createTaskInfo(/* visible */ true, /* taskId */ 1);
+
+ mListener.onTaskAppeared(animatable1, mSurfaceControl);
+ mListener.onTaskAppeared(animatable2, mSurfaceControl);
+
+ InOrder order = inOrder(mUnfoldController);
+ order.verify(mUnfoldController).onTaskAppeared(eq(animatable1), any());
+ order.verify(mUnfoldController).onTaskAppeared(eq(animatable2), any());
+ }
+
+ @Test
+ public void testNonAnimatableTaskAppeared_doesNotNotifyUnfoldController() {
+ RunningTaskInfo info = createTaskInfo(/* visible */ false, /* taskId */ 0);
+
+ mListener.onTaskAppeared(info, mSurfaceControl);
+
+ verifyNoMoreInteractions(mUnfoldController);
+ }
+
+ @Test
+ public void testNonAnimatableTaskChanged_doesNotNotifyUnfoldController() {
+ RunningTaskInfo info = createTaskInfo(/* visible */ false, /* taskId */ 0);
+ mListener.onTaskAppeared(info, mSurfaceControl);
+
+ mListener.onTaskInfoChanged(info);
+
+ verifyNoMoreInteractions(mUnfoldController);
+ }
+
+ @Test
+ public void testNonAnimatableTaskVanished_doesNotNotifyUnfoldController() {
+ RunningTaskInfo info = createTaskInfo(/* visible */ false, /* taskId */ 0);
+ mListener.onTaskAppeared(info, mSurfaceControl);
+
+ mListener.onTaskVanished(info);
+
+ verifyNoMoreInteractions(mUnfoldController);
+ }
+
+ @Test
+ public void testAnimatableTaskBecameInactive_notifiesUnfoldController() {
+ RunningTaskInfo animatableTask = createTaskInfo(/* visible */ true, /* taskId */ 0);
+ mListener.onTaskAppeared(animatableTask, mSurfaceControl);
+ RunningTaskInfo notAnimatableTask = createTaskInfo(/* visible */ false, /* taskId */ 0);
+
+ mListener.onTaskInfoChanged(notAnimatableTask);
+
+ verify(mUnfoldController).onTaskVanished(eq(notAnimatableTask));
+ }
+
+ @Test
+ public void testAnimatableTaskVanished_notifiesUnfoldController() {
+ RunningTaskInfo taskInfo = createTaskInfo(/* visible */ true, /* taskId */ 0);
+ mListener.onTaskAppeared(taskInfo, mSurfaceControl);
+
+ mListener.onTaskVanished(taskInfo);
+
+ verify(mUnfoldController).onTaskVanished(eq(taskInfo));
+ }
+
+ private RunningTaskInfo createTaskInfo(boolean visible, int taskId) {
+ final RunningTaskInfo info = spy(new RunningTaskInfo());
+ info.isVisible = visible;
+ info.positionInParent = new Point();
+ when(info.getWindowingMode()).thenReturn(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+ final Configuration configuration = new Configuration();
+ configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD);
+ when(info.getConfiguration()).thenReturn(configuration);
+ info.taskId = taskId;
+ return info;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
index 69ead3ac9cf9..3a2516ec9366 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
@@ -29,6 +29,7 @@ import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.window.WindowContainerTransaction;
+import androidx.test.annotation.UiThreadTest;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -58,6 +59,7 @@ public class SideStageTests extends ShellTestCase {
private SideStage mSideStage;
@Before
+ @UiThreadTest
public void setup() {
MockitoAnnotations.initMocks(this);
mRootTask = new TestRunningTaskInfoBuilder().build();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index d357e778fe35..8dce454eb078 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -51,6 +51,7 @@ import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;
+import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -96,6 +97,7 @@ public class SplitTransitionTests extends ShellTestCase {
private ActivityManager.RunningTaskInfo mSideChild;
@Before
+ @UiThreadTest
public void setup() {
MockitoAnnotations.initMocks(this);
final ShellExecutor mockExecutor = mock(ShellExecutor.class);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
index 1a30f164f9a8..0916dd1f71bd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
@@ -62,6 +62,7 @@ public final class StageTaskListenerTests {
@Mock private SyncTransactionQueue mSyncQueue;
@Captor private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
private SurfaceSession mSurfaceSession = new SurfaceSession();
+ private SurfaceControl mSurfaceControl;
private ActivityManager.RunningTaskInfo mRootTask;
private StageTaskListener mStageTaskListener;
@@ -76,7 +77,8 @@ public final class StageTaskListenerTests {
mSurfaceSession);
mRootTask = new TestRunningTaskInfoBuilder().build();
mRootTask.parentTaskId = INVALID_TASK_ID;
- mStageTaskListener.onTaskAppeared(mRootTask, new SurfaceControl());
+ mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession).setName("test").build();
+ mStageTaskListener.onTaskAppeared(mRootTask, mSurfaceControl);
}
@Test
@@ -103,7 +105,7 @@ public final class StageTaskListenerTests {
final ActivityManager.RunningTaskInfo childTask =
new TestRunningTaskInfoBuilder().setParentTaskId(mRootTask.taskId).build();
- mStageTaskListener.onTaskAppeared(childTask, new SurfaceControl());
+ mStageTaskListener.onTaskAppeared(childTask, mSurfaceControl);
assertThat(mStageTaskListener.mChildrenTaskInfo.contains(childTask.taskId)).isTrue();
verify(mCallbacks).onStatusChanged(eq(mRootTask.isVisible), eq(true));
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
index 8f3e4bd87aa7..220cf6b5c38a 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
@@ -18,6 +18,7 @@ package com.android.settingslib.drawer;
import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_ORDER;
import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_PROFILE;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_NEW_TASK;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
@@ -329,6 +330,18 @@ public abstract class Tile implements Parcelable {
}
/**
+ * Whether the {@link Activity} should be launched in a separate task.
+ */
+ public boolean isNewTask(Context context) {
+ ensureMetadataNotStale(context);
+ if (mMetaData != null
+ && mMetaData.containsKey(META_DATA_NEW_TASK)) {
+ return mMetaData.getBoolean(META_DATA_NEW_TASK);
+ }
+ return false;
+ }
+
+ /**
* Ensures metadata is not stale for this tile.
*/
private void ensureMetadataNotStale(Context context) {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index a2bec334f206..acc0087f6dcf 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -230,6 +230,13 @@ public class TileUtils {
public static final String META_DATA_KEY_PROFILE = "com.android.settings.profile";
/**
+ * Name of the meta-data item that should be set in the AndroidManifest.xml
+ * to specify whether the {@link android.app.Activity} should be launched in a separate task.
+ * This should be a boolean value {@code true} or {@code false}, set using {@code android:value}
+ */
+ public static final String META_DATA_NEW_TASK = "com.android.settings.new_task";
+
+ /**
* Build a list of DashboardCategory.
*/
public static List<DashboardCategory> getCategories(Context context,
diff --git a/packages/SystemUI/res/layout/global_screenshot_static.xml b/packages/SystemUI/res/layout/global_screenshot_static.xml
index 6a9254cad8f4..21c5ab04eb9a 100644
--- a/packages/SystemUI/res/layout/global_screenshot_static.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_static.xml
@@ -130,13 +130,4 @@
app:layout_constraintStart_toStartOf="@id/global_screenshot_preview"
app:layout_constraintTop_toTopOf="@id/global_screenshot_preview"
android:elevation="@dimen/screenshot_preview_elevation"/>
- <View
- android:id="@+id/screenshot_transition_view"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="invisible"
- app:layout_constraintStart_toStartOf="@id/global_screenshot_preview"
- app:layout_constraintTop_toTopOf="@id/global_screenshot_preview"
- app:layout_constraintEnd_toEndOf="@id/global_screenshot_preview"
- app:layout_constraintBottom_toBottomOf="@id/global_screenshot_preview"/>
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index c3ac19a46ee6..d0de876a6b27 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -224,15 +224,23 @@
display brightness, suitable to listen to while the device is asleep (e.g. during
always-on display) -->
<string-array name="doze_brightness_sensor_name_posture_mapping" translatable="false">
- <item></item> <!-- UNKNOWN -->
- <item></item> <!-- CLOSED -->
- <item></item> <!-- HALF_OPENED -->
- <item></item> <!-- OPENED -->
+ <!-- UNKNOWN -->
+ <!-- CLOSED -->
+ <!-- HALF_OPENED -->
+ <!-- OPENED -->
</string-array>
<!-- Override value to use for proximity sensor. -->
<string name="proximity_sensor_type" translatable="false"></string>
+ <!-- Sensor type per posture state to use for proximity sensor -->
+ <string-array name="proximity_sensor_posture_mapping" translatable="false">
+ <!-- UNKNOWN -->
+ <!-- CLOSED -->
+ <!-- HALF_OPENED -->
+ <!-- OPENED -->
+ </string-array>
+
<!-- If using proximity_sensor_type, specifies a threshold value to distinguish near and
far break points. A sensor value less than this is considered "near". -->
<item name="proximity_sensor_threshold" translatable="false" format="float" type="dimen"></item>
@@ -246,6 +254,15 @@
<!-- Override value to use for proximity sensor as confirmation for proximity_sensor_type. -->
<string name="proximity_sensor_secondary_type" translatable="false"></string>
+ <!-- Sensor type per posture state to use for proximity sensor as a confirmation for
+ proximity_sensor_type. -->
+ <string-array name="proximity_sensor_secondary_posture_mapping" translatable="false">
+ <!-- UNKNOWN -->
+ <!-- CLOSED -->
+ <!-- HALF_OPENED -->
+ <!-- OPENED -->
+ </string-array>
+
<!-- If using proximity_sensor_secondary_type, specifies a threshold value to distinguish
near and far break points. A sensor value less than this is considered "near". -->
<item name="proximity_sensor_secondary_threshold" translatable="false" format="float"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 8f14cd858f1e..f81f0b9ca2c3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -11,6 +11,7 @@ import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnPreDrawListener;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
@@ -93,6 +94,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
private int[] mColorPalette;
private int mClockSwitchYAmount;
+ @VisibleForTesting boolean mChildrenAreLaidOut = false;
public KeyguardClockSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -284,11 +286,31 @@ public class KeyguardClockSwitch extends RelativeLayout {
if (mDisplayedClockSize != null && clockSize == mDisplayedClockSize) {
return false;
}
- animateClockChange(clockSize == LARGE);
- mDisplayedClockSize = clockSize;
+
+ // let's make sure clock is changed only after all views were laid out so we can
+ // translate them properly
+ if (mChildrenAreLaidOut) {
+ animateClockChange(clockSize == LARGE);
+ mDisplayedClockSize = clockSize;
+ } else {
+ getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ switchToClock(clockSize);
+ getViewTreeObserver().removeOnPreDrawListener(this);
+ return true;
+ }
+ });
+ }
return true;
}
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ mChildrenAreLaidOut = true;
+ }
+
public Paint getPaint() {
return mClockView.getPaint();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
index 62411dbff5fd..11eeac2272ff 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
@@ -153,6 +153,10 @@ public class KeyguardMessageArea extends TextView implements SecurityMessageDisp
colorState = mNextMessageColorState;
mNextMessageColorState = ColorStateList.valueOf(DEFAULT_COLOR);
}
+ if (mAltBouncerShowing) {
+ // alt bouncer has a black scrim, so always show the text in white
+ colorState = ColorStateList.valueOf(Color.WHITE);
+ }
setTextColor(colorState);
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index 14e5991f35d2..be326da8d3bf 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -37,6 +37,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.sensors.ThresholdSensor;
+import com.android.systemui.util.sensors.ThresholdSensorEvent;
import com.android.systemui.util.time.SystemClock;
import java.util.Collections;
@@ -405,7 +406,7 @@ class FalsingCollectorImpl implements FalsingCollector {
mProximitySensor.unregister(mSensorEventListener);
}
- private void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
+ private void onProximityEvent(ThresholdSensorEvent proximityEvent) {
// TODO: some of these classifiers might allow us to abort early, meaning we don't have to
// make these calls.
mFalsingManager.onProximityEvent(new ProximityEventImpl(proximityEvent));
@@ -423,9 +424,9 @@ class FalsingCollectorImpl implements FalsingCollector {
}
private static class ProximityEventImpl implements FalsingManager.ProximityEvent {
- private ThresholdSensor.ThresholdSensorEvent mThresholdSensorEvent;
+ private ThresholdSensorEvent mThresholdSensorEvent;
- ProximityEventImpl(ThresholdSensor.ThresholdSensorEvent thresholdSensorEvent) {
+ ProximityEventImpl(ThresholdSensorEvent thresholdSensorEvent) {
mThresholdSensorEvent = thresholdSensorEvent;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 2d873f26c0c2..fa2384268b15 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -24,8 +24,6 @@ import android.app.INotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.om.OverlayManager;
-import android.hardware.SensorManager;
-import android.hardware.devicestate.DeviceStateManager;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.display.ColorDisplayManager;
import android.os.Handler;
@@ -56,22 +54,18 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.keyguard.LifecycleScreenStatusProvider;
import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.shared.system.WindowManagerWrapper;
+import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DataSaverController;
-import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.theme.ThemeOverlayApplier;
-import com.android.systemui.unfold.UnfoldTransitionFactory;
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
-import com.android.systemui.unfold.config.UnfoldTransitionConfig;
import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.util.settings.SecureSettings;
@@ -287,37 +281,6 @@ public class DependencyProvider {
/** */
@Provides
@SysUISingleton
- public UnfoldTransitionProgressProvider provideUnfoldTransitionProgressProvider(
- Context context,
- UnfoldTransitionConfig config,
- LifecycleScreenStatusProvider screenStatusProvider,
- DeviceStateManager deviceStateManager,
- SensorManager sensorManager,
- @Main Executor executor,
- @Main Handler handler
- ) {
- return UnfoldTransitionFactory
- .createUnfoldTransitionProgressProvider(
- context,
- config,
- screenStatusProvider,
- deviceStateManager,
- sensorManager,
- handler,
- executor
- );
- }
-
- /** */
- @Provides
- @SysUISingleton
- public UnfoldTransitionConfig provideUnfoldTransitionConfig(Context context) {
- return UnfoldTransitionFactory.createConfig(context);
- }
-
- /** */
- @Provides
- @SysUISingleton
public Choreographer providesChoreographer() {
return Choreographer.getInstance();
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
index 648f345205db..18f85196aa0b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
@@ -24,6 +24,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.systemui.dagger.qualifiers.TestHarness;
import com.android.systemui.plugins.PluginsModule;
+import com.android.systemui.unfold.UnfoldTransitionModule;
import com.android.systemui.util.concurrency.GlobalConcurrencyModule;
import javax.inject.Singleton;
@@ -49,6 +50,7 @@ import dagger.Provides;
@Module(includes = {
FrameworkServicesModule.class,
GlobalConcurrencyModule.class,
+ UnfoldTransitionModule.class,
PluginsModule.class,
})
public class GlobalModule {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 1e7f0d9dc630..b17f078e24ef 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -46,6 +46,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.Assert;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.sensors.AsyncSensorManager;
+import com.android.systemui.util.sensors.ProximityCheck;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.wakelock.WakeLock;
@@ -90,7 +91,7 @@ public class DozeTriggers implements DozeMachine.Part {
private final TriggerReceiver mBroadcastReceiver = new TriggerReceiver();
private final DockEventListener mDockEventListener = new DockEventListener();
private final DockManager mDockManager;
- private final ProximitySensor.ProximityCheck mProxCheck;
+ private final ProximityCheck mProxCheck;
private final BroadcastDispatcher mBroadcastDispatcher;
private final AuthController mAuthController;
private final DelayableExecutor mMainExecutor;
@@ -181,7 +182,8 @@ public class DozeTriggers implements DozeMachine.Part {
AmbientDisplayConfiguration config,
DozeParameters dozeParameters, AsyncSensorManager sensorManager,
WakeLock wakeLock, DockManager dockManager,
- ProximitySensor proximitySensor, ProximitySensor.ProximityCheck proxCheck,
+ ProximitySensor proximitySensor,
+ ProximityCheck proxCheck,
DozeLog dozeLog, BroadcastDispatcher broadcastDispatcher,
SecureSettings secureSettings, AuthController authController,
@Main DelayableExecutor mainExecutor,
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
index b0f3959119c8..21a1b75224b2 100644
--- a/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
@@ -18,11 +18,11 @@ package com.android.systemui.dump
import android.util.ArrayMap
import com.android.systemui.Dumpable
-import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import java.io.FileDescriptor
import java.io.PrintWriter
import javax.inject.Inject
+import javax.inject.Singleton
/**
* Maintains a registry of things that should be dumped when a bug report is taken
@@ -33,7 +33,7 @@ import javax.inject.Inject
*
* See [DumpHandler] for more information on how and when this information is dumped.
*/
-@SysUISingleton
+@Singleton
open class DumpManager @Inject constructor() {
private val dumpables: MutableMap<String, RegisteredDumpable<Dumpable>> = ArrayMap()
private val buffers: MutableMap<String, RegisteredDumpable<LogBuffer>> = ArrayMap()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
index f25ec5591e3a..044a57ced3fc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
@@ -15,12 +15,12 @@
*/
package com.android.systemui.keyguard
-import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
import javax.inject.Inject
+import javax.inject.Singleton
-@SysUISingleton
+@Singleton
class LifecycleScreenStatusProvider @Inject constructor(screenLifecycle: ScreenLifecycle) :
ScreenStatusProvider, ScreenLifecycle.Observer {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
index 30983aacd7d2..d17c39a81dae 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
@@ -19,18 +19,18 @@ package com.android.systemui.keyguard;
import android.os.Trace;
import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import javax.inject.Inject;
+import javax.inject.Singleton;
/**
* Tracks the screen lifecycle.
*/
-@SysUISingleton
+@Singleton
public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> implements Dumpable {
public static final int SCREEN_OFF = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index a1a630aca94c..7622d663301d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -195,7 +195,8 @@ public class NavigationBarController implements
mNavigationModeController.addListener(this);
mTaskbarDelegate = taskbarDelegate;
mTaskbarDelegate.setOverviewProxyService(commandQueue, overviewProxyService,
- navigationBarA11yHelper, navigationModeController, sysUiFlagsContainer);
+ navigationBarA11yHelper, navigationModeController, sysUiFlagsContainer,
+ dumpManager);
mIsTablet = isTablet(mContext);
mUserTracker = userTracker;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index fa6169210609..4d29612951cc 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -46,8 +46,12 @@ import android.view.InsetsVisibilities;
import android.view.View;
import android.view.WindowInsetsController.Behavior;
+import androidx.annotation.NonNull;
+
import com.android.internal.view.AppearanceRegion;
import com.android.systemui.Dependency;
+import com.android.systemui.Dumpable;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.recents.OverviewProxyService;
@@ -55,13 +59,16 @@ import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.CommandQueue;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class TaskbarDelegate implements CommandQueue.Callbacks,
OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener,
- ComponentCallbacks {
+ ComponentCallbacks, Dumpable {
private final EdgeBackGestureHandler mEdgeBackGestureHandler;
@@ -93,13 +100,14 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
OverviewProxyService overviewProxyService,
NavigationBarA11yHelper navigationBarA11yHelper,
NavigationModeController navigationModeController,
- SysUiState sysUiState) {
+ SysUiState sysUiState, DumpManager dumpManager) {
// TODO: adding this in the ctor results in a dagger dependency cycle :(
mCommandQueue = commandQueue;
mOverviewProxyService = overviewProxyService;
mNavigationBarA11yHelper = navigationBarA11yHelper;
mNavigationModeController = navigationModeController;
mSysUiState = sysUiState;
+ dumpManager.registerDumpable(this);
}
public void destroy() {
@@ -220,4 +228,14 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
@Override
public void onLowMemory() {}
+
+ @Override
+ public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ pw.println("TaskbarDelegate (displayId=" + mDisplayId + "):");
+ pw.println(" mNavigationIconHints=" + mNavigationIconHints);
+ pw.println(" mDisabledFlags=" + mDisabledFlags);
+ pw.println(" mTaskBarWindowState=" + mTaskBarWindowState);
+ pw.println(" mBehavior=" + mBehavior);
+ mEdgeBackGestureHandler.dump(pw);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index bf1a98fa39e6..c6da3420ffe9 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -101,8 +101,8 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
private static final int MAX_NUM_LOGGED_PREDICTIONS = 10;
private static final int MAX_NUM_LOGGED_GESTURES = 10;
- // Temporary log until b/176302696 is resolved
- static final boolean DEBUG_MISSING_GESTURE = false;
+ // Temporary log until b/201642126 is resolved
+ static final boolean DEBUG_MISSING_GESTURE = true;
static final String DEBUG_MISSING_GESTURE_TAG = "NoBackGesture";
private static final boolean ENABLE_PER_WINDOW_INPUT_ROTATION =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
index 953f9fb10657..fec61d911577 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
@@ -42,8 +42,8 @@ import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
import com.android.systemui.util.CarrierConfigTracker;
import java.util.function.Consumer;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 04f089d31664..9de6ceb2de4b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -51,13 +51,13 @@ import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.WifiIndicators;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
import java.util.ArrayList;
import java.util.LinkedHashMap;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index b1af8416e06d..35dadd45eb3e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -56,11 +56,11 @@ import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.SignalTileView;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
import com.android.systemui.statusbar.phone.SystemUIDialog;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index 530804ed09e7..98d0a72685ba 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -52,13 +52,13 @@ import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.qs.tiles.dialog.InternetDialogFactory;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
-import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
-import com.android.systemui.statusbar.policy.WifiIcons;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.AccessPointController;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.connectivity.NetworkController.WifiIndicators;
+import com.android.systemui.statusbar.connectivity.WifiIcons;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 41a3020191a6..e6e7e21263bb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -52,11 +52,11 @@ import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSIconViewImpl;
import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
-import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
-import com.android.systemui.statusbar.policy.WifiIcons;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.AccessPointController;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.connectivity.NetworkController.WifiIndicators;
+import com.android.systemui.statusbar.connectivity.WifiIcons;
import com.android.wifitrackerlib.WifiEntry;
import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index aaba5efc92f6..b9cd08e8ac77 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -75,9 +75,9 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.AccessPointController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
import com.android.systemui.toast.SystemUIToast;
import com.android.systemui.toast.ToastFactory;
import com.android.systemui.util.CarrierConfigTracker;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 31d51f1d1a60..a42b34cf23d0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -326,18 +326,11 @@ public class LongScreenshotActivity extends Activity {
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
mTransitionView.setImageBitmap(mOutputBitmap);
+ mTransitionView.setVisibility(View.VISIBLE);
mTransitionView.setTransitionName(
ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME);
// TODO: listen for transition completing instead of finishing onStop
mTransitionStarted = true;
- int[] locationOnScreen = new int[2];
- mTransitionView.getLocationOnScreen(locationOnScreen);
- int[] locationInWindow = new int[2];
- mTransitionView.getLocationInWindow(locationInWindow);
- int deltaX = locationOnScreen[0] - locationInWindow[0];
- int deltaY = locationOnScreen[1] - locationInWindow[1];
- mTransitionView.setX(mTransitionView.getX() - deltaX);
- mTransitionView.setY(mTransitionView.getY() - deltaY);
startActivity(intent,
ActivityOptions.makeSceneTransitionAnimation(this, mTransitionView,
ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME).toBundle());
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 8def475c192c..5b4db1449b34 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -940,12 +940,10 @@ public class ScreenshotController {
*/
private Supplier<ActionTransition> getActionTransitionSupplier() {
return () -> {
- View preview = mScreenshotView.getTransitionView();
- preview.setX(preview.getX() - mScreenshotView.getStaticLeftMargin());
Pair<ActivityOptions, ExitTransitionCoordinator> transition =
ActivityOptions.startSharedElementAnimation(
mWindow, new ScreenshotExitTransitionCallbacksSupplier(true).get(),
- null, Pair.create(mScreenshotView.getTransitionView(),
+ null, Pair.create(mScreenshotView.getScreenshotPreview(),
ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME));
transition.second.startExit();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index dfb39e300450..7222b0313fb4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -137,13 +137,11 @@ public class ScreenshotView extends FrameLayout implements
private int mNavMode;
private boolean mOrientationPortrait;
private boolean mDirectionLTR;
- private int mStaticLeftMargin;
private ScreenshotSelectorView mScreenshotSelectorView;
private ImageView mScrollingScrim;
private View mScreenshotStatic;
private ImageView mScreenshotPreview;
- private View mTransitionView;
private View mScreenshotPreviewBorder;
private ImageView mScrollablePreview;
private ImageView mScreenshotFlash;
@@ -341,7 +339,6 @@ public class ScreenshotView extends FrameLayout implements
mScrollingScrim = requireNonNull(findViewById(R.id.screenshot_scrolling_scrim));
mScreenshotStatic = requireNonNull(findViewById(R.id.global_screenshot_static));
mScreenshotPreview = requireNonNull(findViewById(R.id.global_screenshot_preview));
- mTransitionView = requireNonNull(findViewById(R.id.screenshot_transition_view));
mScreenshotPreviewBorder = requireNonNull(
findViewById(R.id.global_screenshot_preview_border));
mScreenshotPreview.setClipToOutline(true);
@@ -387,12 +384,8 @@ public class ScreenshotView extends FrameLayout implements
requestFocus();
}
- View getTransitionView() {
- return mTransitionView;
- }
-
- int getStaticLeftMargin() {
- return mStaticLeftMargin;
+ View getScreenshotPreview() {
+ return mScreenshotPreview;
}
/**
@@ -442,7 +435,6 @@ public class ScreenshotView extends FrameLayout implements
Math.max(navBarInsets.bottom, waterfall.bottom));
}
}
- mStaticLeftMargin = p.leftMargin;
mScreenshotStatic.setLayoutParams(p);
mScreenshotStatic.requestLayout();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java
index e49f48f2cf49..bcba5cc09c5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java
@@ -26,7 +26,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.demomode.DemoModeCommandReceiver;
import com.android.systemui.plugins.DarkIconDispatcher;
-import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.ViewController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImpl.java
index 6d6320e6962d..a23d73d7ed84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImpl.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import android.content.Context;
import android.content.Intent;
@@ -55,6 +55,7 @@ import java.util.concurrent.Executor;
import javax.inject.Inject;
+/** */
public class AccessPointControllerImpl
implements NetworkController.AccessPointController,
WifiPickerTracker.WifiPickerTrackerCallback, LifecycleOwner {
@@ -116,17 +117,19 @@ public class AccessPointControllerImpl
super.finalize();
}
+ /** */
public boolean canConfigWifi() {
return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI,
new UserHandle(mCurrentUser));
}
+ /** */
public boolean canConfigMobileData() {
return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
UserHandle.of(mCurrentUser)) && mUserTracker.getUserInfo().isAdmin();
}
- public void onUserSwitched(int newUserId) {
+ void onUserSwitched(int newUserId) {
mCurrentUser = newUserId;
}
@@ -225,7 +228,7 @@ public class AccessPointControllerImpl
}
}
- public void dump(PrintWriter pw) {
+ void dump(PrintWriter pw) {
IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
ipw.println("AccessPointControllerImpl:");
ipw.increaseIndent();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/CallbackHandler.java
index 7ac6d63430d6..052a789200e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/CallbackHandler.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import android.os.Handler;
import android.os.Looper;
@@ -22,11 +22,11 @@ import android.telephony.SubscriptionInfo;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
-import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.EmergencyListener;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.connectivity.NetworkController.WifiIndicators;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
@@ -235,7 +235,7 @@ public class CallbackHandler extends Handler implements EmergencyListener, Signa
.append("icon=").append(icon)
.toString();
recordLastCallback(log);
- obtainMessage(MSG_ETHERNET_CHANGED, icon).sendToTarget();;
+ obtainMessage(MSG_ETHERNET_CHANGED, icon).sendToTarget();
}
@Override
@@ -252,14 +252,14 @@ public class CallbackHandler extends Handler implements EmergencyListener, Signa
.toString();
recordLastCallback(log);
}
- obtainMessage(MSG_AIRPLANE_MODE_CHANGED, icon).sendToTarget();;
+ obtainMessage(MSG_AIRPLANE_MODE_CHANGED, icon).sendToTarget();
}
- public void setListening(EmergencyListener listener, boolean listening) {
+ void setListening(EmergencyListener listener, boolean listening) {
obtainMessage(MSG_ADD_REMOVE_EMERGENCY, listening ? 1 : 0, 0, listener).sendToTarget();
}
- public void setListening(SignalCallback listener, boolean listening) {
+ void setListening(SignalCallback listener, boolean listening) {
obtainMessage(MSG_ADD_REMOVE_SIGNAL, listening ? 1 : 0, 0, listener).sendToTarget();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java
index b391bd9cf651..196aad99dcb5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import com.android.systemui.R;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetSignalController.java
index 80b75a740965..c9d40adde644 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetSignalController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import android.content.Context;
import android.net.NetworkCapabilities;
@@ -21,12 +21,12 @@ import android.net.NetworkCapabilities;
import com.android.settingslib.AccessibilityContentDescriptions;
import com.android.settingslib.SignalIcon.IconGroup;
import com.android.settingslib.SignalIcon.State;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
import java.util.BitSet;
-
+/** */
public class EthernetSignalController extends
SignalController<State, IconGroup> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
index a543c7c95d16..20ef4eec0b97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import static com.android.settingslib.mobile.MobileMappings.getDefaultIcons;
import static com.android.settingslib.mobile.MobileMappings.getIconKey;
@@ -58,9 +58,9 @@ import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.net.SignalStrengthUtil;
import com.android.systemui.R;
import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
import com.android.systemui.util.CarrierConfigTracker;
import java.io.PrintWriter;
@@ -245,7 +245,7 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
mProviderModelSetting = featureFlags.isProviderModelSettingEnabled();
}
- public void setConfiguration(Config config) {
+ void setConfiguration(Config config) {
mConfig = config;
updateInflateSignalStrength();
mNetworkToIconLookup = mapIconSets(mConfig);
@@ -253,12 +253,12 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
updateTelephony();
}
- public void setAirplaneMode(boolean airplaneMode) {
+ void setAirplaneMode(boolean airplaneMode) {
mCurrentState.airplaneMode = airplaneMode;
notifyListenersIfNecessary();
}
- public void setUserSetupComplete(boolean userSetup) {
+ void setUserSetupComplete(boolean userSetup) {
mCurrentState.userSetup = userSetup;
notifyListenersIfNecessary();
}
@@ -272,7 +272,7 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
notifyListenersIfNecessary();
}
- public void setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode) {
+ void setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode) {
mCurrentState.carrierNetworkChangeMode = carrierNetworkChangeMode;
updateTelephony();
}
@@ -413,7 +413,7 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
if (mCurrentState.dataSim) {
// If using provider model behavior, only show QS icons if the state is also default
if (pm && !mCurrentState.isDefault) {
- return new QsInfo(qsTypeIcon, qsIcon, qsDescription);
+ return new QsInfo(qsTypeIcon, qsIcon, qsDescription);
}
if (mCurrentState.showQuickSettingsRatIcon() || mConfig.alwaysShowDataRatIcon) {
@@ -501,7 +501,7 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
return mCurrentState.carrierNetworkChangeMode;
}
- public void handleBroadcast(Intent intent) {
+ void handleBroadcast(Intent intent) {
String action = intent.getAction();
if (action.equals(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED)) {
updateNetworkName(intent.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false),
@@ -740,10 +740,10 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
* mTelephonyDisplayInfo, and mSimState. It should be called any time one of these is updated.
* This will call listeners if necessary.
*/
- private final void updateTelephony() {
+ private void updateTelephony() {
if (Log.isLoggable(mTag, Log.DEBUG)) {
- Log.d(mTag, "updateTelephonySignalStrength: hasService=" +
- Utils.isInService(mServiceState) + " ss=" + mSignalStrength
+ Log.d(mTag, "updateTelephonySignalStrength: hasService="
+ + Utils.isInService(mServiceState) + " ss=" + mSignalStrength
+ " displayInfo=" + mTelephonyDisplayInfo);
}
checkDefaultData();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkController.java
index 9aec9038fadb..143309658779 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import android.content.Context;
import android.content.Intent;
@@ -22,29 +22,44 @@ import android.telephony.SubscriptionInfo;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.demomode.DemoMode;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.policy.CallbackController;
+import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.wifitrackerlib.MergedCarrierEntry;
import com.android.wifitrackerlib.WifiEntry;
import java.util.List;
+/** */
public interface NetworkController extends CallbackController<SignalCallback>, DemoMode {
-
+ /** */
boolean hasMobileDataFeature();
+ /** */
void setWifiEnabled(boolean enabled);
+ /** */
AccessPointController getAccessPointController();
+ /** */
DataUsageController getMobileDataController();
+ /** */
DataSaverController getDataSaverController();
+ /** */
String getMobileDataNetworkName();
+ /** */
boolean isMobileDataNetworkInService();
+ /** */
int getNumberSubscriptions();
+ /** */
boolean hasVoiceCallingFeature();
+ /** */
void addEmergencyListener(EmergencyListener listener);
+ /** */
void removeEmergencyListener(EmergencyListener listener);
+ /** */
boolean hasEmergencyCryptKeeperText();
+ /** */
boolean isRadioOn();
/**
@@ -143,7 +158,8 @@ public interface NetworkController extends CallbackController<SignalCallback>, D
}
}
- public interface SignalCallback {
+ /** */
+ interface SignalCallback {
/**
* Callback for listeners to be able to update the state of any UI tracking connectivity of
* WiFi networks.
@@ -156,14 +172,19 @@ public interface NetworkController extends CallbackController<SignalCallback>, D
*/
default void setMobileDataIndicators(MobileDataIndicators mobileDataIndicators) {}
+ /** */
default void setSubs(List<SubscriptionInfo> subs) {}
+ /** */
default void setNoSims(boolean show, boolean simDetected) {}
+ /** */
default void setEthernetIndicators(IconState icon) {}
+ /** */
default void setIsAirplaneMode(IconState icon) {}
+ /** */
default void setMobileDataEnabled(boolean enabled) {}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
index 156def5a6183..d9b0ee7e9921 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -76,7 +76,12 @@ import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.qs.tiles.dialog.InternetDialogFactory;
import com.android.systemui.qs.tiles.dialog.InternetDialogUtil;
import com.android.systemui.settings.CurrentUserTracker;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DataSaverController;
+import com.android.systemui.statusbar.policy.DataSaverControllerImpl;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
+import com.android.systemui.statusbar.policy.EncryptionHelper;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.util.CarrierConfigTracker;
@@ -376,11 +381,10 @@ public class NetworkControllerImpl extends BroadcastReceiver
@Override
public void onCapabilitiesChanged(
- Network network, NetworkCapabilities networkCapabilities) {
- boolean lastValidated = (mLastNetworkCapabilities != null) &&
- mLastNetworkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
- boolean validated =
- networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
+ Network network, NetworkCapabilities networkCapabilities) {
+ boolean lastValidated = (mLastNetworkCapabilities != null)
+ && mLastNetworkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
+ boolean validated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
// This callback is invoked a lot (i.e. when RSSI changes), so avoid updating
// icons when connectivity state has remained the same.
@@ -544,19 +548,23 @@ public class NetworkControllerImpl extends BroadcastReceiver
return mDataUsageController;
}
+ /** */
public void addEmergencyListener(EmergencyListener listener) {
mCallbackHandler.setListening(listener, true);
mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly());
}
+ /** */
public void removeEmergencyListener(EmergencyListener listener) {
mCallbackHandler.setListening(listener, false);
}
+ /** */
public boolean hasMobileDataFeature() {
return mHasMobileDataFeature;
}
+ /** */
public boolean hasVoiceCallingFeature() {
return mPhone.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
}
@@ -661,7 +669,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
}
}
- public boolean isEmergencyOnly() {
+ boolean isEmergencyOnly() {
if (mMobileSignalControllers.size() == 0) {
// When there are no active subscriptions, determine emengency state from last
// broadcast.
@@ -690,8 +698,10 @@ public class NetworkControllerImpl extends BroadcastReceiver
if (mMobileSignalControllers.size() == 1) {
mEmergencySource = EMERGENCY_ASSUMED_VOICE_CONTROLLER
+ mMobileSignalControllers.keyAt(0);
- if (DEBUG) Log.d(TAG, "Getting assumed emergency from "
- + mMobileSignalControllers.keyAt(0));
+ if (DEBUG) {
+ Log.d(TAG, "Getting assumed emergency from "
+ + mMobileSignalControllers.keyAt(0));
+ }
return mMobileSignalControllers.valueAt(0).getState().isEmergency;
}
if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
@@ -915,7 +925,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
@GuardedBy("mLock")
@VisibleForTesting
- public void setCurrentSubscriptionsLocked(List<SubscriptionInfo> subscriptions) {
+ void setCurrentSubscriptionsLocked(List<SubscriptionInfo> subscriptions) {
Collections.sort(subscriptions, new Comparator<SubscriptionInfo>() {
@Override
public int compare(SubscriptionInfo lhs, SubscriptionInfo rhs) {
@@ -1125,6 +1135,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
mEthernetSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
}
+ /** */
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("NetworkController state:");
@@ -1178,7 +1189,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
mCallbackHandler.dump(pw);
}
- private static final String emergencyToString(int emergencySource) {
+ private static String emergencyToString(int emergencySource) {
if (emergencySource > EMERGENCY_NO_SUB) {
return "ASSUMED_VOICE_CONTROLLER(" + (emergencySource - EMERGENCY_VOICE_CONTROLLER)
+ ")";
@@ -1423,10 +1434,12 @@ public class NetworkControllerImpl extends BroadcastReceiver
return info;
}
+ /** */
public boolean hasEmergencyCryptKeeperText() {
return EncryptionHelper.IS_DATA_ENCRYPTED;
}
+ /** */
public boolean isRadioOn() {
return !mAirplaneMode;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalController.java
index 4b6722c17b85..d23dba579be6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalController.java
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
-import static com.android.systemui.statusbar.policy.NetworkControllerImpl.TAG;
+import static com.android.systemui.statusbar.connectivity.NetworkControllerImpl.TAG;
import android.annotation.NonNull;
import android.content.Context;
@@ -23,8 +23,8 @@ import android.util.Log;
import com.android.settingslib.SignalIcon.IconGroup;
import com.android.settingslib.SignalIcon.State;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
import java.io.PrintWriter;
import java.util.BitSet;
@@ -83,7 +83,7 @@ public abstract class SignalController<T extends State, I extends IconGroup> {
return mCurrentState;
}
- public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) {
+ void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) {
mCurrentState.inetCondition = validatedTransports.get(mTransportType) ? 1 : 0;
notifyListenersIfNecessary();
}
@@ -114,7 +114,7 @@ public abstract class SignalController<T extends State, I extends IconGroup> {
return false;
}
- public void saveLastState() {
+ void saveLastState() {
if (RECORD_HISTORY) {
recordLastState();
}
@@ -161,7 +161,7 @@ public abstract class SignalController<T extends State, I extends IconGroup> {
}
}
- public void notifyListenersIfNecessary() {
+ void notifyListenersIfNecessary() {
if (isDirty()) {
saveLastState();
notifyListeners();
@@ -192,7 +192,7 @@ public abstract class SignalController<T extends State, I extends IconGroup> {
mHistoryIndex = (mHistoryIndex + 1) % HISTORY_SIZE;
}
- public void dump(PrintWriter pw) {
+ void dump(PrintWriter pw) {
pw.println(" - " + mTag + " -----");
pw.println(" Current State: " + mCurrentState);
if (RECORD_HISTORY) {
@@ -210,7 +210,7 @@ public abstract class SignalController<T extends State, I extends IconGroup> {
}
}
- public final void notifyListeners() {
+ final void notifyListeners() {
notifyListeners(mCallbackHandler);
}
@@ -219,7 +219,7 @@ public abstract class SignalController<T extends State, I extends IconGroup> {
* based on current state, and only need to be called in the scenario where
* mCurrentState != mLastState.
*/
- public abstract void notifyListeners(SignalCallback callback);
+ abstract void notifyListeners(SignalCallback callback);
/**
* Generate a blank T.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java
index 577cc4fd16b6..3c449ad270ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java
@@ -14,12 +14,13 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import com.android.settingslib.AccessibilityContentDescriptions;
import com.android.settingslib.R;
import com.android.settingslib.SignalIcon.IconGroup;
+/** */
public class WifiIcons {
static final int[] WIFI_FULL_ICONS = {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
index 3f7ddc6c1538..3622a66767a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN;
import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT;
@@ -37,14 +37,15 @@ import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.wifi.WifiStatusTracker;
import com.android.systemui.R;
import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
-import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.connectivity.NetworkController.WifiIndicators;
import java.io.PrintWriter;
import java.util.Objects;
+/** */
public class WifiSignalController extends
SignalController<WifiSignalController.WifiState, IconGroup> {
private final boolean mHasMobileDataFeature;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
index ea00d920c9b0..6730afaafdef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
@@ -252,11 +252,12 @@ public interface StatusBarDependenciesModule {
ActivityStarter activityStarter,
@Main Executor mainExecutor,
IActivityManager iActivityManager,
- OngoingCallLogger logger) {
+ OngoingCallLogger logger,
+ DumpManager dumpManager) {
OngoingCallController ongoingCallController =
new OngoingCallController(
notifCollection, featureFlags, systemClock, activityStarter, mainExecutor,
- iActivityManager, logger);
+ iActivityManager, logger, dumpManager);
ongoingCallController.init();
return ongoingCallController;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 4400909d0bff..278f09b45b4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -254,6 +254,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private boolean mExpandedInThisMotion;
private boolean mShouldShowShelfOnly;
protected boolean mScrollingEnabled;
+ private boolean mIsCurrentUserSetup;
protected FooterView mFooterView;
protected EmptyShadeView mEmptyShadeView;
private boolean mDismissAllInProgress;
@@ -693,6 +694,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
boolean showDismissView = mClearAllEnabled &&
mController.hasActiveClearableNotifications(ROWS_ALL);
boolean showFooterView = (showDismissView || getVisibleNotificationCount() > 0)
+ && mIsCurrentUserSetup // see: b/193149550
&& mStatusBarState != StatusBarState.KEYGUARD
&& !mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()
&& !mIsRemoteInputActive;
@@ -5621,6 +5623,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
/**
+ * Sets whether the current user is set up, which is required to show the footer (b/193149550)
+ */
+ public void setCurrentUserSetup(boolean isCurrentUserSetup) {
+ if (mIsCurrentUserSetup != isCurrentUserSetup) {
+ mIsCurrentUserSetup = isCurrentUserSetup;
+ updateFooter();
+ }
+ }
+
+ /**
* A listener that is notified when the empty space below the notifications is clicked on
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 75eb88fbcfc8..9fe06a0ddbdc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -119,6 +119,8 @@ import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
@@ -146,6 +148,7 @@ public class NotificationStackScrollLayoutController {
private final HeadsUpManagerPhone mHeadsUpManager;
private final NotificationRoundnessManager mNotificationRoundnessManager;
private final TunerService mTunerService;
+ private final DeviceProvisionedController mDeviceProvisionedController;
private final DynamicPrivacyController mDynamicPrivacyController;
private final ConfigurationController mConfigurationController;
private final ZenModeController mZenModeController;
@@ -226,6 +229,28 @@ public class NotificationStackScrollLayoutController {
}
};
+ private final DeviceProvisionedListener mDeviceProvisionedListener =
+ new DeviceProvisionedListener() {
+ @Override
+ public void onDeviceProvisionedChanged() {
+ updateCurrentUserIsSetup();
+ }
+
+ @Override
+ public void onUserSwitched() {
+ updateCurrentUserIsSetup();
+ }
+
+ @Override
+ public void onUserSetupChanged() {
+ updateCurrentUserIsSetup();
+ }
+
+ private void updateCurrentUserIsSetup() {
+ mView.setCurrentUserSetup(mDeviceProvisionedController.isCurrentUserSetup());
+ }
+ };
+
private final DynamicPrivacyController.Listener mDynamicPrivacyControllerListener = () -> {
if (mView.isExpanded()) {
// The bottom might change because we're using the final actual height of the view
@@ -600,6 +625,7 @@ public class NotificationStackScrollLayoutController {
HeadsUpManagerPhone headsUpManager,
NotificationRoundnessManager notificationRoundnessManager,
TunerService tunerService,
+ DeviceProvisionedController deviceProvisionedController,
DynamicPrivacyController dynamicPrivacyController,
ConfigurationController configurationController,
SysuiStatusBarStateController statusBarStateController,
@@ -636,6 +662,7 @@ public class NotificationStackScrollLayoutController {
mHeadsUpManager = headsUpManager;
mNotificationRoundnessManager = notificationRoundnessManager;
mTunerService = tunerService;
+ mDeviceProvisionedController = deviceProvisionedController;
mDynamicPrivacyController = dynamicPrivacyController;
mConfigurationController = configurationController;
mStatusBarStateController = statusBarStateController;
@@ -787,6 +814,9 @@ public class NotificationStackScrollLayoutController {
return Unit.INSTANCE;
});
+ // callback is invoked synchronously, updating mView immediately
+ mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
+
if (mView.isAttachedToWindow()) {
mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index c16cc125aece..989f6b85668b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -46,6 +46,8 @@ import com.android.systemui.statusbar.DisableFlagsLogger.DisableState;
import com.android.systemui.statusbar.OperatorNameView;
import com.android.systemui.statusbar.OperatorNameViewController;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
@@ -53,8 +55,6 @@ import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
import com.android.systemui.statusbar.policy.EncryptionHelper;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import org.jetbrains.annotations.NotNull;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index 893aa6d6bc45..5feb4053f833 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -101,8 +101,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
@Override
public void onOverlayChanged() {
- KeyguardStatusBarViewController.this.onThemeChanged();
mView.onOverlayChanged();
+ KeyguardStatusBarViewController.this.onThemeChanged();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 3bdc08be63e6..2130e028e863 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -199,6 +199,7 @@ import com.android.systemui.statusbar.PowerButtonReveal;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
@@ -226,7 +227,6 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.tuner.TunerService;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 5bc97a5b316d..18fd9d3c6651 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -1149,7 +1149,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
public void showBouncerMessage(String message, ColorStateList colorState) {
if (isShowingAlternateAuth()) {
if (mKeyguardMessageAreaController != null) {
- mKeyguardMessageAreaController.setNextMessageColor(colorState);
mKeyguardMessageAreaController.setMessage(message);
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 71364320839c..fbd9ef7e3707 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -26,11 +26,11 @@ import com.android.settingslib.mobile.TelephonyIcons;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
-import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
-import com.android.systemui.statusbar.policy.NetworkControllerImpl;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.WifiIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkControllerImpl;
import com.android.systemui.statusbar.policy.SecurityController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 0d43b9323a39..568970790a18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -62,6 +62,7 @@ import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.OperatorNameViewController;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -104,7 +105,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.tuner.TunerService;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index eeff010e0bdf..ab6ee89627ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -26,10 +26,12 @@ import android.util.Log
import android.view.View
import androidx.annotation.VisibleForTesting
import com.android.internal.jank.InteractionJankMonitor
+import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -37,6 +39,8 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.Co
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.statusbar.policy.CallbackController
import com.android.systemui.util.time.SystemClock
+import java.io.FileDescriptor
+import java.io.PrintWriter
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -51,13 +55,14 @@ class OngoingCallController @Inject constructor(
private val activityStarter: ActivityStarter,
@Main private val mainExecutor: Executor,
private val iActivityManager: IActivityManager,
- private val logger: OngoingCallLogger
-) : CallbackController<OngoingCallListener> {
+ private val logger: OngoingCallLogger,
+ private val dumpManager: DumpManager,
+) : CallbackController<OngoingCallListener>, Dumpable {
/** Non-null if there's an active call notification. */
private var callNotificationInfo: CallNotificationInfo? = null
/** True if the application managing the call is visible to the user. */
- private var isCallAppVisible: Boolean = true
+ private var isCallAppVisible: Boolean = false
private var chipView: View? = null
private var uidObserver: IUidObserver.Stub? = null
@@ -103,16 +108,7 @@ class OngoingCallController @Inject constructor(
}
}
- // Fix for b/199600334
- override fun onEntryCleanUp(entry: NotificationEntry) {
- removeChipIfNeeded(entry)
- }
-
override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
- removeChipIfNeeded(entry)
- }
-
- private fun removeChipIfNeeded(entry: NotificationEntry) {
if (entry.sbn.key == callNotificationInfo?.key) {
removeChip()
}
@@ -120,6 +116,7 @@ class OngoingCallController @Inject constructor(
}
fun init() {
+ dumpManager.registerDumpable(this)
if (featureFlags.isOngoingCallStatusBarChipEnabled) {
notifCollection.addCollectionListener(notifListener)
}
@@ -299,6 +296,11 @@ class OngoingCallController @Inject constructor(
*/
fun hasValidStartTime(): Boolean = callStartTime > 0
}
+
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
+ pw.println("Active call notification: $callNotificationInfo")
+ pw.println("Call app visible: $isCallAppVisible")
+ }
}
private fun isCallNotification(entry: NotificationEntry): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java
index 85968753d54f..bbba19d61b5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java
@@ -46,6 +46,7 @@ public interface DevicePostureController extends CallbackController<Callback> {
int DEVICE_POSTURE_HALF_OPENED = 2;
int DEVICE_POSTURE_OPENED = 3;
int DEVICE_POSTURE_FLIPPED = 4;
+ int SUPPORTED_POSTURES_SIZE = DEVICE_POSTURE_FLIPPED + 1;
/** Return the current device posture. */
@DevicePostureInt int getDevicePosture();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
index 1eec639670ee..92908790770a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
@@ -23,7 +23,9 @@ import com.android.internal.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.settings.UserTracker;
-import com.android.systemui.statusbar.policy.AccessPointControllerImpl;
+import com.android.systemui.statusbar.connectivity.AccessPointControllerImpl;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkControllerImpl;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
import com.android.systemui.statusbar.policy.CastController;
@@ -42,8 +44,6 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.KeyguardStateControllerImpl;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.LocationControllerImpl;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkControllerImpl;
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.NextAlarmControllerImpl;
import com.android.systemui.statusbar.policy.RotationLockController;
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/ShellUnfoldProgressProvider.kt b/packages/SystemUI/src/com/android/systemui/unfold/ShellUnfoldProgressProvider.kt
new file mode 100644
index 000000000000..4a884359d315
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/unfold/ShellUnfoldProgressProvider.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 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.systemui.unfold
+
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.wm.shell.unfold.ShellUnfoldProgressProvider
+import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener
+import java.util.concurrent.Executor
+
+class ShellUnfoldProgressProvider(
+ private val unfoldProgressProvider: UnfoldTransitionProgressProvider
+) : ShellUnfoldProgressProvider {
+
+ override fun addListener(executor: Executor, listener: UnfoldListener) {
+ unfoldProgressProvider.addCallback(object : TransitionProgressListener {
+ override fun onTransitionStarted() {
+ executor.execute {
+ listener.onStateChangeStarted()
+ }
+ }
+
+ override fun onTransitionProgress(progress: Float) {
+ executor.execute {
+ listener.onStateChangeProgress(progress)
+ }
+ }
+
+ override fun onTransitionFinished() {
+ executor.execute {
+ listener.onStateChangeFinished()
+ }
+ }
+ })
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
new file mode 100644
index 000000000000..b23aa20dcaa4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2021 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.systemui.unfold
+
+import android.content.Context
+import android.hardware.SensorManager
+import android.hardware.devicestate.DeviceStateManager
+import android.os.Handler
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyguard.LifecycleScreenStatusProvider
+import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.wm.shell.unfold.ShellUnfoldProgressProvider
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import java.util.Optional
+import java.util.concurrent.Executor
+import javax.inject.Singleton
+
+@Module
+class UnfoldTransitionModule {
+
+ @Provides
+ @Singleton
+ fun provideUnfoldTransitionProgressProvider(
+ context: Context,
+ config: UnfoldTransitionConfig,
+ screenStatusProvider: LifecycleScreenStatusProvider,
+ deviceStateManager: DeviceStateManager,
+ sensorManager: SensorManager,
+ @Main executor: Executor,
+ @Main handler: Handler
+ ): UnfoldTransitionProgressProvider =
+ createUnfoldTransitionProgressProvider(
+ context,
+ config,
+ screenStatusProvider,
+ deviceStateManager,
+ sensorManager,
+ handler,
+ executor
+ )
+
+ @Provides
+ @Singleton
+ fun provideUnfoldTransitionConfig(context: Context): UnfoldTransitionConfig =
+ createConfig(context)
+
+ @Provides
+ @Singleton
+ fun provideShellProgressProvider(
+ config: UnfoldTransitionConfig,
+ provider: Lazy<UnfoldTransitionProgressProvider>
+ ): Optional<ShellUnfoldProgressProvider> =
+ if (config.isEnabled) {
+ Optional.ofNullable(ShellUnfoldProgressProvider(provider.get()))
+ } else {
+ Optional.empty()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt b/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt
index a9810458fe90..2c01a7003a16 100644
--- a/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt
@@ -40,8 +40,8 @@ class WallpaperController @Inject constructor(private val wallpaperManager: Wall
this.wallpaperInfo = wallpaperInfo
}
- private val shouldUseDefaultDeviceStateChangeTransition: Boolean
- get() = wallpaperInfo?.shouldUseDefaultDeviceStateChangeTransition()
+ private val shouldUseDefaultDisplayStateChangeTransition: Boolean
+ get() = wallpaperInfo?.shouldUseDefaultDisplayStateChangeTransition()
?: true
fun setNotificationShadeZoom(zoomOut: Float) {
@@ -50,7 +50,7 @@ class WallpaperController @Inject constructor(private val wallpaperManager: Wall
}
fun setUnfoldTransitionZoom(zoomOut: Float) {
- if (shouldUseDefaultDeviceStateChangeTransition) {
+ if (shouldUseDefaultDisplayStateChangeTransition) {
unfoldTransitionZoomOut = zoomOut
updateZoom()
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/PostureDependentProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/PostureDependentProximitySensor.java
new file mode 100644
index 000000000000..28cba8e16970
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/PostureDependentProximitySensor.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 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.systemui.util.sensors;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import com.android.systemui.statusbar.policy.DevicePostureController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.android.systemui.util.concurrency.Execution;
+
+import javax.inject.Inject;
+
+/**
+ * Proximity sensor that changes proximity sensor usage based on the current posture.
+ * Posture -> prox sensor mapping can be found in SystemUI config overlays at:
+ * - proximity_sensor_posture_mapping
+ * - proximity_sensor_secondary_posture_mapping.
+ * where the array indices correspond to the following postures:
+ * [UNKNOWN, CLOSED, HALF_OPENED, OPENED]
+ */
+class PostureDependentProximitySensor extends ProximitySensorImpl {
+ private final ThresholdSensor[] mPostureToPrimaryProxSensorMap;
+ private final ThresholdSensor[] mPostureToSecondaryProxSensorMap;
+
+ @Inject
+ PostureDependentProximitySensor(
+ @PrimaryProxSensor ThresholdSensor[] postureToPrimaryProxSensorMap,
+ @SecondaryProxSensor ThresholdSensor[] postureToSecondaryProxSensorMap,
+ @NonNull DelayableExecutor delayableExecutor,
+ @NonNull Execution execution,
+ @NonNull DevicePostureController devicePostureController
+ ) {
+ super(
+ postureToPrimaryProxSensorMap[0],
+ postureToSecondaryProxSensorMap[0],
+ delayableExecutor,
+ execution
+ );
+ mPostureToPrimaryProxSensorMap = postureToPrimaryProxSensorMap;
+ mPostureToSecondaryProxSensorMap = postureToSecondaryProxSensorMap;
+ mDevicePosture = devicePostureController.getDevicePosture();
+ devicePostureController.addCallback(mDevicePostureCallback);
+
+ chooseSensors();
+ }
+ private void chooseSensors() {
+ if (mDevicePosture >= mPostureToPrimaryProxSensorMap.length
+ || mDevicePosture >= mPostureToSecondaryProxSensorMap.length) {
+ Log.e("PostureDependentProxSensor",
+ "unsupported devicePosture=" + mDevicePosture);
+ return;
+ }
+
+ ThresholdSensor newPrimaryProx = mPostureToPrimaryProxSensorMap[mDevicePosture];
+ ThresholdSensor newSecondaryProx = mPostureToSecondaryProxSensorMap[mDevicePosture];
+
+ if (newPrimaryProx != mPrimaryThresholdSensor
+ || newSecondaryProx != mSecondaryThresholdSensor) {
+ logDebug("Register new proximity sensors newPosture="
+ + DevicePostureController.devicePostureToString(mDevicePosture));
+ unregisterInternal();
+
+ if (mPrimaryThresholdSensor != null) {
+ mPrimaryThresholdSensor.unregister(mPrimaryEventListener);
+ }
+ if (mSecondaryThresholdSensor != null) {
+ mSecondaryThresholdSensor.unregister(mSecondaryEventListener);
+ }
+
+ mPrimaryThresholdSensor = newPrimaryProx;
+ mSecondaryThresholdSensor = newSecondaryProx;
+
+ mInitializedListeners = false;
+ registerInternal();
+ }
+ }
+
+ private final DevicePostureController.Callback mDevicePostureCallback =
+ posture -> {
+ if (mDevicePosture == posture) {
+ return;
+ }
+
+ mDevicePosture = posture;
+ chooseSensors();
+ };
+
+ @Override
+ public String toString() {
+ return String.format("{posture=%s, proximitySensor=%s}",
+ DevicePostureController.devicePostureToString(mDevicePosture), super.toString());
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximityCheck.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximityCheck.java
new file mode 100644
index 000000000000..a8a6341cc5ee
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximityCheck.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 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.systemui.util.sensors;
+
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+
+import javax.inject.Inject;
+
+/**
+ * Convenience class allowing for briefly checking the proximity sensor.
+ */
+public class ProximityCheck implements Runnable {
+
+ private final ProximitySensor mSensor;
+ private final DelayableExecutor mDelayableExecutor;
+ private List<Consumer<Boolean>> mCallbacks = new ArrayList<>();
+ private final ThresholdSensor.Listener mListener;
+ private final AtomicBoolean mRegistered = new AtomicBoolean();
+
+ @Inject
+ public ProximityCheck(
+ ProximitySensor sensor,
+ @Main DelayableExecutor delayableExecutor) {
+ mSensor = sensor;
+ mSensor.setTag("prox_check");
+ mDelayableExecutor = delayableExecutor;
+ mListener = this::onProximityEvent;
+ }
+
+ /** Set a descriptive tag for the sensors registration. */
+ public void setTag(String tag) {
+ mSensor.setTag(tag);
+ }
+
+ @Override
+ public void run() {
+ unregister();
+ onProximityEvent(null);
+ }
+
+ /**
+ * Query the proximity sensor, timing out if no result.
+ */
+ public void check(long timeoutMs, Consumer<Boolean> callback) {
+ if (!mSensor.isLoaded()) {
+ callback.accept(null);
+ return;
+ }
+ mCallbacks.add(callback);
+ if (!mRegistered.getAndSet(true)) {
+ mSensor.register(mListener);
+ mDelayableExecutor.executeDelayed(this, timeoutMs);
+ }
+ }
+
+ private void unregister() {
+ mSensor.unregister(mListener);
+ mRegistered.set(false);
+ }
+
+ private void onProximityEvent(ThresholdSensorEvent proximityEvent) {
+ mCallbacks.forEach(
+ booleanConsumer ->
+ booleanConsumer.accept(
+ proximityEvent == null ? null : proximityEvent.getBelow()));
+ mCallbacks.clear();
+ unregister();
+ mRegistered.set(false);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
index bd1103982017..d3f1c93195a1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,149 +16,24 @@
package com.android.systemui.util.sensors;
-import android.hardware.SensorManager;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.android.systemui.util.concurrency.Execution;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
-
-import javax.inject.Inject;
-
/**
- * Wrapper around SensorManager customized for the Proximity sensor.
- *
- * The ProximitySensor supports the concept of a primary and a
- * secondary hardware sensor. The primary sensor is used for a first
- * pass check if the phone covered. When triggered, it then checks
- * the secondary sensor for confirmation (if there is one). It does
- * not send a proximity event until the secondary sensor confirms (or
- * rejects) the reading. The secondary sensor is, in fact, the source
- * of truth.
- *
- * This is necessary as sometimes keeping the secondary sensor on for
- * extends periods is undesirable. It may, however, result in increased
- * latency for proximity readings.
- *
- * Phones should configure this via a config.xml overlay. If no
- * proximity sensor is set (primary or secondary) we fall back to the
- * default Sensor.TYPE_PROXIMITY. If proximity_sensor_type is set in
- * config.xml, that will be used as the primary sensor. If
- * proximity_sensor_secondary_type is set, that will function as the
- * secondary sensor. If no secondary is set, only the primary will be
- * used.
+ * Wrapper class for a dual ProximitySensor which supports a secondary sensor gated upon the
+ * primary).
*/
-public class ProximitySensor implements ThresholdSensor {
- private static final String TAG = "ProxSensor";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final long SECONDARY_PING_INTERVAL_MS = 5000;
-
- private final ThresholdSensor mPrimaryThresholdSensor;
- private final ThresholdSensor mSecondaryThresholdSensor;
- private final DelayableExecutor mDelayableExecutor;
- private final Execution mExecution;
- private final List<ThresholdSensor.Listener> mListeners = new ArrayList<>();
- private String mTag = null;
- @VisibleForTesting protected boolean mPaused;
- private ThresholdSensorEvent mLastPrimaryEvent;
- @VisibleForTesting
- ThresholdSensorEvent mLastEvent;
- private boolean mRegistered;
- private final AtomicBoolean mAlerting = new AtomicBoolean();
- private Runnable mCancelSecondaryRunnable;
- private boolean mInitializedListeners = false;
- private boolean mSecondarySafe = false;
-
- private final ThresholdSensor.Listener mPrimaryEventListener = this::onPrimarySensorEvent;
-
- private final ThresholdSensor.Listener mSecondaryEventListener =
- new ThresholdSensor.Listener() {
- @Override
- public void onThresholdCrossed(ThresholdSensorEvent event) {
- // If we no longer have a "below" signal and the secondary sensor is not
- // considered "safe", then we need to turn it off.
- if (!mSecondarySafe
- && (mLastPrimaryEvent == null
- || !mLastPrimaryEvent.getBelow()
- || !event.getBelow())) {
- chooseSensor();
- if (mLastPrimaryEvent == null || !mLastPrimaryEvent.getBelow()) {
- // Only check the secondary as long as the primary thinks we're near.
- if (mCancelSecondaryRunnable != null) {
- mCancelSecondaryRunnable.run();
- mCancelSecondaryRunnable = null;
- }
- return;
- } else {
- // Check this sensor again in a moment.
- mCancelSecondaryRunnable = mDelayableExecutor.executeDelayed(() -> {
- // This is safe because we know that mSecondaryThresholdSensor
- // is loaded, otherwise we wouldn't be here.
- mPrimaryThresholdSensor.pause();
- mSecondaryThresholdSensor.resume();
- },
- SECONDARY_PING_INTERVAL_MS);
- }
- }
- logDebug("Secondary sensor event: " + event.getBelow() + ".");
-
- if (!mPaused) {
- onSensorEvent(event);
- }
- }
- };
-
- @Inject
- public ProximitySensor(
- @PrimaryProxSensor ThresholdSensor primary,
- @SecondaryProxSensor ThresholdSensor secondary,
- @Main DelayableExecutor delayableExecutor,
- Execution execution) {
- mPrimaryThresholdSensor = primary;
- mSecondaryThresholdSensor = secondary;
- mDelayableExecutor = delayableExecutor;
- mExecution = execution;
- }
-
- @Override
- public void setTag(String tag) {
- mTag = tag;
- mPrimaryThresholdSensor.setTag(tag + ":primary");
- mSecondaryThresholdSensor.setTag(tag + ":secondary");
- }
-
- @Override
- public void setDelay(int delay) {
- mExecution.assertIsMainThread();
- mPrimaryThresholdSensor.setDelay(delay);
- mSecondaryThresholdSensor.setDelay(delay);
- }
-
+public interface ProximitySensor extends ThresholdSensor {
/**
- * Unregister with the {@link SensorManager} without unsetting listeners on this object.
+ * Returns true if we are registered with the SensorManager.
*/
- @Override
- public void pause() {
- mExecution.assertIsMainThread();
- mPaused = true;
- unregisterInternal();
- }
+ boolean isRegistered();
/**
- * Register with the {@link SensorManager}. No-op if no listeners are registered on this object.
+ * Whether the proximity sensor reports near. Can return null if no information has been
+ * received yet.
*/
- @Override
- public void resume() {
- mExecution.assertIsMainThread();
- mPaused = false;
- registerInternal();
- }
+ Boolean isNear();
+
+ /** Update all listeners with the last value this class received from the sensor. */
+ void alertListeners();
/**
* Sets that it is safe to leave the secondary sensor on indefinitely.
@@ -166,249 +41,5 @@ public class ProximitySensor implements ThresholdSensor {
* The secondary sensor will be turned on if there are any registered listeners, regardless
* of what is reported by the primary sensor.
*/
- public void setSecondarySafe(boolean safe) {
- mSecondarySafe = mSecondaryThresholdSensor.isLoaded() && safe;
- chooseSensor();
- }
-
- /**
- * Returns true if we are registered with the SensorManager.
- */
- public boolean isRegistered() {
- return mRegistered;
- }
-
- /**
- * Returns {@code false} if a Proximity sensor is not available.
- */
- @Override
- public boolean isLoaded() {
- return mPrimaryThresholdSensor.isLoaded();
- }
-
- /**
- * Add a listener.
- *
- * Registers itself with the {@link SensorManager} if this is the first listener
- * added. If the ProximitySensor is paused, it will be registered when resumed.
- */
- @Override
- public void register(ThresholdSensor.Listener listener) {
- mExecution.assertIsMainThread();
- if (!isLoaded()) {
- return;
- }
-
- if (mListeners.contains(listener)) {
- logDebug("ProxListener registered multiple times: " + listener);
- } else {
- mListeners.add(listener);
- }
- registerInternal();
- }
-
- protected void registerInternal() {
- mExecution.assertIsMainThread();
- if (mRegistered || mPaused || mListeners.isEmpty()) {
- return;
- }
- if (!mInitializedListeners) {
- mPrimaryThresholdSensor.pause();
- mSecondaryThresholdSensor.pause();
- mPrimaryThresholdSensor.register(mPrimaryEventListener);
- mSecondaryThresholdSensor.register(mSecondaryEventListener);
- mInitializedListeners = true;
- }
- logDebug("Registering sensor listener");
-
- mRegistered = true;
- chooseSensor();
- }
-
- private void chooseSensor() {
- mExecution.assertIsMainThread();
- if (!mRegistered || mPaused || mListeners.isEmpty()) {
- return;
- }
- if (mSecondarySafe) {
- mSecondaryThresholdSensor.resume();
- mPrimaryThresholdSensor.pause();
- } else {
- mPrimaryThresholdSensor.resume();
- mSecondaryThresholdSensor.pause();
- }
- }
-
- /**
- * Remove a listener.
- *
- * If all listeners are removed from an instance of this class,
- * it will unregister itself with the SensorManager.
- */
- @Override
- public void unregister(ThresholdSensor.Listener listener) {
- mExecution.assertIsMainThread();
- mListeners.remove(listener);
- if (mListeners.size() == 0) {
- unregisterInternal();
- }
- }
-
- protected void unregisterInternal() {
- mExecution.assertIsMainThread();
- if (!mRegistered) {
- return;
- }
- logDebug("unregistering sensor listener");
- mPrimaryThresholdSensor.pause();
- mSecondaryThresholdSensor.pause();
- if (mCancelSecondaryRunnable != null) {
- mCancelSecondaryRunnable.run();
- mCancelSecondaryRunnable = null;
- }
- mLastPrimaryEvent = null; // Forget what we know.
- mLastEvent = null;
- mRegistered = false;
- }
-
- public Boolean isNear() {
- return isLoaded() && mLastEvent != null ? mLastEvent.getBelow() : null;
- }
-
- /** Update all listeners with the last value this class received from the sensor. */
- public void alertListeners() {
- mExecution.assertIsMainThread();
- if (mAlerting.getAndSet(true)) {
- return;
- }
- if (mLastEvent != null) {
- ThresholdSensorEvent lastEvent = mLastEvent; // Listeners can null out mLastEvent.
- List<ThresholdSensor.Listener> listeners = new ArrayList<>(mListeners);
- listeners.forEach(proximitySensorListener ->
- proximitySensorListener.onThresholdCrossed(lastEvent));
- }
-
- mAlerting.set(false);
- }
-
- private void onPrimarySensorEvent(ThresholdSensorEvent event) {
- mExecution.assertIsMainThread();
- if (mLastPrimaryEvent != null && event.getBelow() == mLastPrimaryEvent.getBelow()) {
- return;
- }
-
- mLastPrimaryEvent = event;
-
- if (mSecondarySafe && mSecondaryThresholdSensor.isLoaded()) {
- logDebug("Primary sensor reported " + (event.getBelow() ? "near" : "far")
- + ". Checking secondary.");
- if (mCancelSecondaryRunnable == null) {
- mSecondaryThresholdSensor.resume();
- }
- return;
- }
-
-
- if (!mSecondaryThresholdSensor.isLoaded()) { // No secondary
- logDebug("Primary sensor event: " + event.getBelow() + ". No secondary.");
- onSensorEvent(event);
- } else if (event.getBelow()) { // Covered? Check secondary.
- logDebug("Primary sensor event: " + event.getBelow() + ". Checking secondary.");
- if (mCancelSecondaryRunnable != null) {
- mCancelSecondaryRunnable.run();
- }
- mSecondaryThresholdSensor.resume();
- } else { // Uncovered. Report immediately.
- onSensorEvent(event);
- }
- }
-
- private void onSensorEvent(ThresholdSensorEvent event) {
- mExecution.assertIsMainThread();
- if (mLastEvent != null && event.getBelow() == mLastEvent.getBelow()) {
- return;
- }
-
- if (!mSecondarySafe && !event.getBelow()) {
- chooseSensor();
- }
-
- mLastEvent = event;
- alertListeners();
- }
-
- @Override
- public String toString() {
- return String.format("{registered=%s, paused=%s, near=%s, primarySensor=%s, "
- + "secondarySensor=%s secondarySafe=%s}",
- isRegistered(), mPaused, isNear(), mPrimaryThresholdSensor,
- mSecondaryThresholdSensor, mSecondarySafe);
- }
-
- /**
- * Convenience class allowing for briefly checking the proximity sensor.
- */
- public static class ProximityCheck implements Runnable {
-
- private final ProximitySensor mSensor;
- private final DelayableExecutor mDelayableExecutor;
- private List<Consumer<Boolean>> mCallbacks = new ArrayList<>();
- private final ThresholdSensor.Listener mListener;
- private final AtomicBoolean mRegistered = new AtomicBoolean();
-
- @Inject
- public ProximityCheck(ProximitySensor sensor, @Main DelayableExecutor delayableExecutor) {
- mSensor = sensor;
- mSensor.setTag("prox_check");
- mDelayableExecutor = delayableExecutor;
- mListener = this::onProximityEvent;
- }
-
- /** Set a descriptive tag for the sensors registration. */
- public void setTag(String tag) {
- mSensor.setTag(tag);
- }
-
- @Override
- public void run() {
- unregister();
- onProximityEvent(null);
- }
-
- /**
- * Query the proximity sensor, timing out if no result.
- */
- public void check(long timeoutMs, Consumer<Boolean> callback) {
- if (!mSensor.isLoaded()) {
- callback.accept(null);
- return;
- }
- mCallbacks.add(callback);
- if (!mRegistered.getAndSet(true)) {
- mSensor.register(mListener);
- mDelayableExecutor.executeDelayed(this, timeoutMs);
- }
- }
-
- private void unregister() {
- mSensor.unregister(mListener);
- mRegistered.set(false);
- }
-
- private void onProximityEvent(ThresholdSensorEvent proximityEvent) {
- mCallbacks.forEach(
- booleanConsumer ->
- booleanConsumer.accept(
- proximityEvent == null ? null : proximityEvent.getBelow()));
- mCallbacks.clear();
- unregister();
- mRegistered.set(false);
- }
- }
-
- private void logDebug(String msg) {
- if (DEBUG) {
- Log.d(TAG, (mTag != null ? "[" + mTag + "] " : "") + msg);
- }
- }
+ void setSecondarySafe(boolean safe);
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensorImpl.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensorImpl.java
new file mode 100644
index 000000000000..e639313ac649
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensorImpl.java
@@ -0,0 +1,360 @@
+/*
+ * 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.systemui.util.sensors;
+
+import android.hardware.SensorManager;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.statusbar.policy.DevicePostureController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.android.systemui.util.concurrency.Execution;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.inject.Inject;
+
+/**
+ * Wrapper around SensorManager customized for the Proximity sensor.
+ *
+ * The ProximitySensor supports the concept of a primary and a
+ * secondary hardware sensor. The primary sensor is used for a first
+ * pass check if the phone covered. When triggered, it then checks
+ * the secondary sensor for confirmation (if there is one). It does
+ * not send a proximity event until the secondary sensor confirms (or
+ * rejects) the reading. The secondary sensor is, in fact, the source
+ * of truth.
+ *
+ * This is necessary as sometimes keeping the secondary sensor on for
+ * extends periods is undesirable. It may, however, result in increased
+ * latency for proximity readings.
+ *
+ * Phones should configure this via a config.xml overlay. If no
+ * proximity sensor is set (primary or secondary) we fall back to the
+ * default Sensor.TYPE_PROXIMITY. If proximity_sensor_type is set in
+ * config.xml, that will be used as the primary sensor. If
+ * proximity_sensor_secondary_type is set, that will function as the
+ * secondary sensor. If no secondary is set, only the primary will be
+ * used.
+ */
+class ProximitySensorImpl implements ProximitySensor {
+ private static final String TAG = "ProxSensor";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final long SECONDARY_PING_INTERVAL_MS = 5000;
+
+ ThresholdSensor mPrimaryThresholdSensor;
+ ThresholdSensor mSecondaryThresholdSensor;
+ private final DelayableExecutor mDelayableExecutor;
+ private final Execution mExecution;
+ private final List<ThresholdSensor.Listener> mListeners = new ArrayList<>();
+ private String mTag = null;
+ @VisibleForTesting protected boolean mPaused;
+ private ThresholdSensorEvent mLastPrimaryEvent;
+ @VisibleForTesting
+ ThresholdSensorEvent mLastEvent;
+ private boolean mRegistered;
+ private final AtomicBoolean mAlerting = new AtomicBoolean();
+ private Runnable mCancelSecondaryRunnable;
+ boolean mInitializedListeners = false;
+ private boolean mSecondarySafe = false; // safe to skip primary sensor check and use secondary
+ protected @DevicePostureController.DevicePostureInt int mDevicePosture;
+
+ final ThresholdSensor.Listener mPrimaryEventListener = this::onPrimarySensorEvent;
+
+ final ThresholdSensor.Listener mSecondaryEventListener =
+ new ThresholdSensor.Listener() {
+ @Override
+ public void onThresholdCrossed(ThresholdSensorEvent event) {
+ // If we no longer have a "below" signal and the secondary sensor is not
+ // considered "safe", then we need to turn it off.
+ if (!mSecondarySafe
+ && (mLastPrimaryEvent == null
+ || !mLastPrimaryEvent.getBelow()
+ || !event.getBelow())) {
+ chooseSensor();
+ if (mLastPrimaryEvent == null || !mLastPrimaryEvent.getBelow()) {
+ // Only check the secondary as long as the primary thinks we're near.
+ if (mCancelSecondaryRunnable != null) {
+ mCancelSecondaryRunnable.run();
+ mCancelSecondaryRunnable = null;
+ }
+ return;
+ } else {
+ // Check this sensor again in a moment.
+ mCancelSecondaryRunnable = mDelayableExecutor.executeDelayed(() -> {
+ // This is safe because we know that mSecondaryThresholdSensor
+ // is loaded, otherwise we wouldn't be here.
+ mPrimaryThresholdSensor.pause();
+ mSecondaryThresholdSensor.resume();
+ },
+ SECONDARY_PING_INTERVAL_MS);
+ }
+ }
+ logDebug("Secondary sensor event: " + event.getBelow() + ".");
+
+ if (!mPaused) {
+ onSensorEvent(event);
+ }
+ }
+ };
+
+ @Inject
+ ProximitySensorImpl(
+ @PrimaryProxSensor ThresholdSensor primary,
+ @SecondaryProxSensor ThresholdSensor secondary,
+ @Main DelayableExecutor delayableExecutor,
+ Execution execution) {
+ mPrimaryThresholdSensor = primary;
+ mSecondaryThresholdSensor = secondary;
+ mDelayableExecutor = delayableExecutor;
+ mExecution = execution;
+ }
+
+ @Override
+ public void setTag(String tag) {
+ mTag = tag;
+ mPrimaryThresholdSensor.setTag(tag + ":primary");
+ mSecondaryThresholdSensor.setTag(tag + ":secondary");
+ }
+
+ @Override
+ public void setDelay(int delay) {
+ mExecution.assertIsMainThread();
+ mPrimaryThresholdSensor.setDelay(delay);
+ mSecondaryThresholdSensor.setDelay(delay);
+ }
+
+ /**
+ * Unregister with the {@link SensorManager} without unsetting listeners on this object.
+ */
+ @Override
+ public void pause() {
+ mExecution.assertIsMainThread();
+ mPaused = true;
+ unregisterInternal();
+ }
+
+ /**
+ * Register with the {@link SensorManager}. No-op if no listeners are registered on this object.
+ */
+ @Override
+ public void resume() {
+ mExecution.assertIsMainThread();
+ mPaused = false;
+ registerInternal();
+ }
+
+ @Override
+ public void setSecondarySafe(boolean safe) {
+ mSecondarySafe = mSecondaryThresholdSensor.isLoaded() && safe;
+ chooseSensor();
+ }
+
+ /**
+ * Returns true if we are registered with the SensorManager.
+ */
+ @Override
+ public boolean isRegistered() {
+ return mRegistered;
+ }
+
+ /**
+ * Returns {@code false} if a Proximity sensor is not available.
+ */
+ @Override
+ public boolean isLoaded() {
+ return mPrimaryThresholdSensor.isLoaded();
+ }
+
+ /**
+ * Add a listener.
+ *
+ * Registers itself with the {@link SensorManager} if this is the first listener
+ * added. If the ProximitySensor is paused, it will be registered when resumed.
+ */
+ @Override
+ public void register(ThresholdSensor.Listener listener) {
+ mExecution.assertIsMainThread();
+ if (!isLoaded()) {
+ return;
+ }
+
+ if (mListeners.contains(listener)) {
+ logDebug("ProxListener registered multiple times: " + listener);
+ } else {
+ mListeners.add(listener);
+ }
+ registerInternal();
+ }
+
+ protected void registerInternal() {
+ mExecution.assertIsMainThread();
+ if (mRegistered || mPaused || mListeners.isEmpty()) {
+ return;
+ }
+ if (!mInitializedListeners) {
+ mPrimaryThresholdSensor.pause();
+ mSecondaryThresholdSensor.pause();
+ mPrimaryThresholdSensor.register(mPrimaryEventListener);
+ mSecondaryThresholdSensor.register(mSecondaryEventListener);
+ mInitializedListeners = true;
+ }
+
+ mRegistered = true;
+ chooseSensor();
+ }
+
+ private void chooseSensor() {
+ mExecution.assertIsMainThread();
+ if (!mRegistered || mPaused || mListeners.isEmpty()) {
+ return;
+ }
+ if (mSecondarySafe) {
+ mSecondaryThresholdSensor.resume();
+ mPrimaryThresholdSensor.pause();
+ } else {
+ mPrimaryThresholdSensor.resume();
+ mSecondaryThresholdSensor.pause();
+ }
+ }
+
+ /**
+ * Remove a listener.
+ *
+ * If all listeners are removed from an instance of this class,
+ * it will unregister itself with the SensorManager.
+ */
+ @Override
+ public void unregister(ThresholdSensor.Listener listener) {
+ mExecution.assertIsMainThread();
+ mListeners.remove(listener);
+ if (mListeners.size() == 0) {
+ unregisterInternal();
+ }
+ }
+
+ @Override
+ public String getName() {
+ return mPrimaryThresholdSensor.getName();
+ }
+
+ @Override
+ public String getType() {
+ return mPrimaryThresholdSensor.getType();
+ }
+
+ protected void unregisterInternal() {
+ mExecution.assertIsMainThread();
+ if (!mRegistered) {
+ return;
+ }
+ logDebug("unregistering sensor listener");
+ mPrimaryThresholdSensor.pause();
+ mSecondaryThresholdSensor.pause();
+ if (mCancelSecondaryRunnable != null) {
+ mCancelSecondaryRunnable.run();
+ mCancelSecondaryRunnable = null;
+ }
+ mLastPrimaryEvent = null; // Forget what we know.
+ mLastEvent = null;
+ mRegistered = false;
+ }
+
+ @Override
+ public Boolean isNear() {
+ return isLoaded() && mLastEvent != null ? mLastEvent.getBelow() : null;
+ }
+
+ @Override
+ public void alertListeners() {
+ mExecution.assertIsMainThread();
+ if (mAlerting.getAndSet(true)) {
+ return;
+ }
+ if (mLastEvent != null) {
+ ThresholdSensorEvent lastEvent = mLastEvent; // Listeners can null out mLastEvent.
+ List<ThresholdSensor.Listener> listeners = new ArrayList<>(mListeners);
+ listeners.forEach(proximitySensorListener ->
+ proximitySensorListener.onThresholdCrossed(lastEvent));
+ }
+
+ mAlerting.set(false);
+ }
+
+ private void onPrimarySensorEvent(ThresholdSensorEvent event) {
+ mExecution.assertIsMainThread();
+ if (mLastPrimaryEvent != null && event.getBelow() == mLastPrimaryEvent.getBelow()) {
+ return;
+ }
+
+ mLastPrimaryEvent = event;
+
+ if (mSecondarySafe && mSecondaryThresholdSensor.isLoaded()) {
+ logDebug("Primary sensor reported " + (event.getBelow() ? "near" : "far")
+ + ". Checking secondary.");
+ if (mCancelSecondaryRunnable == null) {
+ mSecondaryThresholdSensor.resume();
+ }
+ return;
+ }
+
+
+ if (!mSecondaryThresholdSensor.isLoaded()) { // No secondary
+ logDebug("Primary sensor event: " + event.getBelow() + ". No secondary.");
+ onSensorEvent(event);
+ } else if (event.getBelow()) { // Covered? Check secondary.
+ logDebug("Primary sensor event: " + event.getBelow() + ". Checking secondary.");
+ if (mCancelSecondaryRunnable != null) {
+ mCancelSecondaryRunnable.run();
+ }
+ mSecondaryThresholdSensor.resume();
+ } else { // Uncovered. Report immediately.
+ onSensorEvent(event);
+ }
+ }
+
+ private void onSensorEvent(ThresholdSensorEvent event) {
+ mExecution.assertIsMainThread();
+ if (mLastEvent != null && event.getBelow() == mLastEvent.getBelow()) {
+ return;
+ }
+
+ if (!mSecondarySafe && !event.getBelow()) {
+ chooseSensor();
+ }
+
+ mLastEvent = event;
+ alertListeners();
+ }
+
+ @Override
+ public String toString() {
+ return String.format("{registered=%s, paused=%s, near=%s, posture=%s, primarySensor=%s, "
+ + "secondarySensor=%s secondarySafe=%s}",
+ isRegistered(), mPaused, isNear(), mDevicePosture, mPrimaryThresholdSensor,
+ mSecondaryThresholdSensor, mSecondarySafe);
+ }
+
+ void logDebug(String msg) {
+ if (DEBUG) {
+ Log.d(TAG, (mTag != null ? "[" + mTag + "] " : "") + msg);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java
index 11e7df8bd85f..0be6068c22a4 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java
@@ -16,11 +16,23 @@
package com.android.systemui.util.sensors;
+import android.content.res.Resources;
import android.hardware.Sensor;
import android.hardware.SensorManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.statusbar.policy.DevicePostureController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+
+import java.util.HashMap;
+import java.util.Map;
+import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
@@ -31,8 +43,10 @@ import dagger.Provides;
public class SensorModule {
@Provides
@PrimaryProxSensor
- static ThresholdSensor providePrimaryProxSensor(SensorManager sensorManager,
- ThresholdSensorImpl.Builder thresholdSensorBuilder) {
+ static ThresholdSensor providePrimaryProximitySensor(
+ SensorManager sensorManager,
+ ThresholdSensorImpl.Builder thresholdSensorBuilder
+ ) {
try {
return thresholdSensorBuilder
.setSensorDelay(SensorManager.SENSOR_DELAY_NORMAL)
@@ -52,8 +66,9 @@ public class SensorModule {
@Provides
@SecondaryProxSensor
- static ThresholdSensor provideSecondaryProxSensor(
- ThresholdSensorImpl.Builder thresholdSensorBuilder) {
+ static ThresholdSensor provideSecondaryProximitySensor(
+ ThresholdSensorImpl.Builder thresholdSensorBuilder
+ ) {
try {
return thresholdSensorBuilder
.setSensorResourceId(R.string.proximity_sensor_secondary_type, true)
@@ -64,4 +79,153 @@ public class SensorModule {
return thresholdSensorBuilder.setSensor(null).setThresholdValue(0).build();
}
}
+
+ /**
+ * If postures are supported on the device, returns a posture dependent proximity sensor
+ * which switches proximity sensors based on the current posture.
+ *
+ * If postures are not supported the regular {@link ProximitySensorImpl} will be returned.
+ */
+ @Provides
+ static ProximitySensor provideProximitySensor(
+ @Main Resources resources,
+ Lazy<PostureDependentProximitySensor> postureDependentProximitySensorProvider,
+ Lazy<ProximitySensorImpl> proximitySensorProvider
+ ) {
+ if (hasPostureSupport(
+ resources.getStringArray(R.array.proximity_sensor_posture_mapping))) {
+ return postureDependentProximitySensorProvider.get();
+ } else {
+ return proximitySensorProvider.get();
+ }
+ }
+
+ @Provides
+ static ProximityCheck provideProximityCheck(
+ ProximitySensor proximitySensor,
+ @Main DelayableExecutor delayableExecutor
+ ) {
+ return new ProximityCheck(
+ proximitySensor,
+ delayableExecutor
+ );
+ }
+
+ @Provides
+ @PrimaryProxSensor
+ @NonNull
+ static ThresholdSensor[] providePostureToProximitySensorMapping(
+ ThresholdSensorImpl.BuilderFactory thresholdSensorImplBuilderFactory,
+ @Main Resources resources
+ ) {
+ return createPostureToSensorMapping(
+ thresholdSensorImplBuilderFactory,
+ resources.getStringArray(R.array.proximity_sensor_posture_mapping),
+ R.dimen.proximity_sensor_threshold,
+ R.dimen.proximity_sensor_threshold_latch
+ );
+ }
+
+ @Provides
+ @SecondaryProxSensor
+ @NonNull
+ static ThresholdSensor[] providePostureToSecondaryProximitySensorMapping(
+ ThresholdSensorImpl.BuilderFactory thresholdSensorImplBuilderFactory,
+ @Main Resources resources
+ ) {
+ return createPostureToSensorMapping(
+ thresholdSensorImplBuilderFactory,
+ resources.getStringArray(R.array.proximity_sensor_secondary_posture_mapping),
+ R.dimen.proximity_sensor_secondary_threshold,
+ R.dimen.proximity_sensor_secondary_threshold_latch
+ );
+ }
+
+ /**
+ * Builds sensors to use per posture.
+ *
+ * @param sensorTypes an array where the index represents
+ * {@link DevicePostureController.DevicePostureInt} and the value
+ * at the given index is the sensorType. Empty values represent
+ * no sensor desired.
+ * @param proximitySensorThresholdResourceId resource id for the threshold for all sensor
+ * postures. This currently only supports one value.
+ * This needs to be updated in the future if postures
+ * use different sensors with differing thresholds.
+ * @param proximitySensorThresholdLatchResourceId resource id for the latch for all sensor
+ * postures. This currently only supports one
+ * value. This needs to be updated in the future
+ * if postures use different sensors with
+ * differing latches.
+ * @return an array where the index represents the device posture
+ * {@link DevicePostureController.DevicePostureInt} and the value at the index is the sensor to
+ * use when the device is in that posture.
+ */
+ @NonNull
+ private static ThresholdSensor[] createPostureToSensorMapping(
+ ThresholdSensorImpl.BuilderFactory thresholdSensorImplBuilderFactory,
+ String[] sensorTypes,
+ int proximitySensorThresholdResourceId,
+ int proximitySensorThresholdLatchResourceId
+
+ ) {
+ ThresholdSensor noProxSensor = thresholdSensorImplBuilderFactory
+ .createBuilder()
+ .setSensor(null).setThresholdValue(0).build();
+
+
+ // length and index of sensorMap correspond to DevicePostureController.DevicePostureInt:
+ final ThresholdSensor[] sensorMap =
+ new ThresholdSensor[DevicePostureController.SUPPORTED_POSTURES_SIZE];
+ for (int i = 0; i < DevicePostureController.SUPPORTED_POSTURES_SIZE; i++) {
+ sensorMap[i] = noProxSensor;
+ }
+
+ if (!hasPostureSupport(sensorTypes)) {
+ Log.e("SensorModule", "config doesn't support postures,"
+ + " but attempting to retrieve proxSensorMapping");
+ return sensorMap;
+ }
+
+ // Map of sensorType => Sensor, so we reuse the same sensor if it's the same between
+ // postures
+ Map<String, ThresholdSensor> typeToSensorMap = new HashMap<>();
+ for (int i = 0; i < sensorTypes.length; i++) {
+ try {
+ final String sensorType = sensorTypes[i];
+ if (typeToSensorMap.containsKey(sensorType)) {
+ sensorMap[i] = typeToSensorMap.get(sensorType);
+ } else {
+ sensorMap[i] = thresholdSensorImplBuilderFactory
+ .createBuilder()
+ .setSensorType(sensorTypes[i], true)
+ .setThresholdResourceId(proximitySensorThresholdResourceId)
+ .setThresholdLatchResourceId(proximitySensorThresholdLatchResourceId)
+ .build();
+ typeToSensorMap.put(sensorType, sensorMap[i]);
+ }
+ } catch (IllegalStateException e) {
+ // do nothing, sensor at this posture is already set to noProxSensor
+ }
+ }
+
+ return sensorMap;
+ }
+
+ /**
+ * Returns true if there's at least one non-empty sensor type in the given array.
+ */
+ private static boolean hasPostureSupport(String[] postureToSensorTypeMapping) {
+ if (postureToSensorTypeMapping == null || postureToSensorTypeMapping.length == 0) {
+ return false;
+ }
+
+ for (String sensorType : postureToSensorTypeMapping) {
+ if (!TextUtils.isEmpty(sensorType)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensor.java
index 363a734a6ae5..d81a8d5991d1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensor.java
@@ -16,8 +16,6 @@
package com.android.systemui.util.sensors;
-import java.util.Locale;
-
/**
* A wrapper class for sensors that have a boolean state - above/below.
*/
@@ -77,6 +75,16 @@ public interface ThresholdSensor {
void unregister(Listener listener);
/**
+ * Name of the sensor.
+ */
+ String getName();
+
+ /**
+ * Type of the sensor.
+ */
+ String getType();
+
+ /**
* Interface for listening to events on {@link ThresholdSensor}
*/
interface Listener {
@@ -85,34 +93,4 @@ public interface ThresholdSensor {
*/
void onThresholdCrossed(ThresholdSensorEvent event);
}
-
- /**
- * Returned when the below/above state of a {@link ThresholdSensor} changes.
- */
- class ThresholdSensorEvent {
- private final boolean mBelow;
- private final long mTimestampNs;
-
- public ThresholdSensorEvent(boolean below, long timestampNs) {
- mBelow = below;
- mTimestampNs = timestampNs;
- }
-
- public boolean getBelow() {
- return mBelow;
- }
-
- public long getTimestampNs() {
- return mTimestampNs;
- }
-
- public long getTimestampMs() {
- return mTimestampNs / 1000000;
- }
-
- @Override
- public String toString() {
- return String.format((Locale) null, "{near=%s, timestamp_ns=%d}", mBelow, mTimestampNs);
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorEvent.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorEvent.java
new file mode 100644
index 000000000000..afce09fbe6d0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorEvent.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 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.systemui.util.sensors;
+
+import java.util.Locale;
+
+/**
+ * Returned when the below/above state of a {@link ThresholdSensor} changes.
+ */
+public class ThresholdSensorEvent {
+ private final boolean mBelow;
+ private final long mTimestampNs;
+
+ public ThresholdSensorEvent(boolean below, long timestampNs) {
+ mBelow = below;
+ mTimestampNs = timestampNs;
+ }
+
+ public boolean getBelow() {
+ return mBelow;
+ }
+
+ public long getTimestampNs() {
+ return mTimestampNs;
+ }
+
+ public long getTimestampMs() {
+ return mTimestampNs / 1000000;
+ }
+
+ @Override
+ public String toString() {
+ return String.format((Locale) null, "{near=%s, timestamp_ns=%d}", mBelow, mTimestampNs);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java
index d10cf9b180c3..a9086b140a3c 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java
@@ -21,6 +21,7 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -32,7 +33,10 @@ import java.util.List;
import javax.inject.Inject;
-class ThresholdSensorImpl implements ThresholdSensor {
+/**
+ * Sensor that will only trigger beyond some lower and upper threshold.
+ */
+public class ThresholdSensorImpl implements ThresholdSensor {
private static final String TAG = "ThresholdSensor";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -198,6 +202,15 @@ class ThresholdSensorImpl implements ThresholdSensor {
alertListenersInternal(belowThreshold, timestampNs);
}
+ @Override
+ public String getName() {
+ return mSensor != null ? mSensor.getName() : null;
+ }
+
+ @Override
+ public String getType() {
+ return mSensor != null ? mSensor.getStringType() : null;
+ }
@Override
public String toString() {
@@ -211,7 +224,12 @@ class ThresholdSensorImpl implements ThresholdSensor {
}
}
- static class Builder {
+ /**
+ * Use to build a ThresholdSensor. Should only be used once per sensor built, since
+ * parameters are not reset after calls to build(). For ease of retrievingnew Builders, use
+ * {@link BuilderFactory}.
+ */
+ public static class Builder {
private final Resources mResources;
private final AsyncSensorManager mSensorManager;
private final Execution mExecution;
@@ -318,7 +336,7 @@ class ThresholdSensorImpl implements ThresholdSensor {
@VisibleForTesting
Sensor findSensorByType(String sensorType, boolean requireWakeUp) {
- if (sensorType.isEmpty()) {
+ if (TextUtils.isEmpty(sensorType)) {
return null;
}
@@ -336,4 +354,29 @@ class ThresholdSensorImpl implements ThresholdSensor {
return sensor;
}
}
+
+ /**
+ * Factory that creates a new ThresholdSensorImpl.Builder. In general, Builders should not be
+ * reused after creating a ThresholdSensor or else there may be default threshold and sensor
+ * values set from the previous built sensor.
+ */
+ public static class BuilderFactory {
+ private final Resources mResources;
+ private final AsyncSensorManager mSensorManager;
+ private final Execution mExecution;
+
+ @Inject
+ BuilderFactory(
+ @Main Resources resources,
+ AsyncSensorManager sensorManager,
+ Execution execution) {
+ mResources = resources;
+ mSensorManager = sensorManager;
+ mExecution = execution;
+ }
+
+ ThresholdSensorImpl.Builder createBuilder() {
+ return new Builder(mResources, mSensorManager, mExecution);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index f420a85c8bf6..ff263109d555 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -28,7 +28,6 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.dagger.WMComponent;
import com.android.systemui.dagger.WMSingleton;
-import com.android.wm.shell.FullscreenTaskListener;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellCommandHandler;
import com.android.wm.shell.ShellCommandHandlerImpl;
@@ -57,6 +56,8 @@ import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.common.annotations.ShellSplashscreenThread;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.freeform.FreeformTaskListener;
+import com.android.wm.shell.fullscreen.FullscreenTaskListener;
+import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
@@ -79,6 +80,7 @@ import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper;
import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelperController;
import com.android.wm.shell.transition.ShellTransitions;
import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
import java.util.Optional;
@@ -218,8 +220,28 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
- static FullscreenTaskListener provideFullscreenTaskListener(SyncTransactionQueue syncQueue) {
- return new FullscreenTaskListener(syncQueue);
+ static FullscreenTaskListener provideFullscreenTaskListener(
+ SyncTransactionQueue syncQueue, Optional<FullscreenUnfoldController> controller) {
+ return new FullscreenTaskListener(syncQueue, controller);
+ }
+
+ //
+ // Unfold transition
+ //
+
+ @WMSingleton
+ @Provides
+ static Optional<FullscreenUnfoldController> provideFullscreenUnfoldController(
+ Context context,
+ Optional<ShellUnfoldProgressProvider> progressProvider,
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ DisplayInsetsController displayInsetsController,
+ @ShellMainThread ShellExecutor mainExecutor
+ ) {
+ return progressProvider.map(shellUnfoldTransitionProgressProvider ->
+ new FullscreenUnfoldController(context, mainExecutor,
+ shellUnfoldTransitionProgressProvider, rootTaskDisplayAreaOrganizer,
+ displayInsetsController));
}
//
@@ -474,6 +496,7 @@ public abstract class WMShellBaseModule {
Optional<AppPairsController> appPairsOptional,
Optional<PipTouchHandler> pipTouchHandlerOptional,
FullscreenTaskListener fullscreenTaskListener,
+ Optional<FullscreenUnfoldController> appUnfoldTransitionController,
Optional<Optional<FreeformTaskListener>> freeformTaskListener,
Transitions transitions,
StartingWindowController startingWindow,
@@ -489,6 +512,7 @@ public abstract class WMShellBaseModule {
appPairsOptional,
pipTouchHandlerOptional,
fullscreenTaskListener,
+ appUnfoldTransitionController,
freeformTaskListener,
transitions,
startingWindow,
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
index 83c2a9b1be33..a7c5ad2e3716 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
@@ -126,9 +126,10 @@ public class WMShellModule {
static AppPairsController provideAppPairs(ShellTaskOrganizer shellTaskOrganizer,
SyncTransactionQueue syncQueue, DisplayController displayController,
@ShellMainThread ShellExecutor mainExecutor,
- DisplayImeController displayImeController) {
+ DisplayImeController displayImeController,
+ DisplayInsetsController displayInsetsController) {
return new AppPairsController(shellTaskOrganizer, syncQueue, displayController,
- mainExecutor, displayImeController);
+ mainExecutor, displayImeController, displayInsetsController);
}
//
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index ce02b8339422..e4336fe07dbb 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -97,6 +97,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
mLargeClockFrame = mKeyguardClockSwitch.findViewById(R.id.lockscreen_clock_view_large);
mLargeClockView = mKeyguardClockSwitch.findViewById(R.id.animatable_clock_view_large);
mBigClock = new TextClock(getContext());
+ mKeyguardClockSwitch.mChildrenAreLaidOut = true;
MockitoAnnotations.initMocks(this);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index b688fcc50373..31fa3f841b19 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -53,7 +53,8 @@ import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.sensors.FakeProximitySensor;
import com.android.systemui.util.sensors.FakeSensorManager;
import com.android.systemui.util.sensors.FakeThresholdSensor;
-import com.android.systemui.util.sensors.ProximitySensor;
+import com.android.systemui.util.sensors.ProximityCheck;
+import com.android.systemui.util.sensors.ThresholdSensorEvent;
import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.wakelock.WakeLock;
@@ -80,7 +81,7 @@ public class DozeTriggersTest extends SysuiTestCase {
@Mock
private DockManager mDockManager;
@Mock
- private ProximitySensor.ProximityCheck mProximityCheck;
+ private ProximityCheck mProximityCheck;
@Mock
private AuthController mAuthController;
@Mock
@@ -136,14 +137,14 @@ public class DozeTriggersTest extends SysuiTestCase {
mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
clearInvocations(mMachine);
- mProximitySensor.setLastEvent(new ProximitySensor.ThresholdSensorEvent(true, 1));
+ mProximitySensor.setLastEvent(new ThresholdSensorEvent(true, 1));
captor.getValue().onNotificationAlerted(null /* pulseSuppressedListener */);
mProximitySensor.alertListeners();
verify(mMachine, never()).requestState(any());
verify(mMachine, never()).requestPulse(anyInt());
- mProximitySensor.setLastEvent(new ProximitySensor.ThresholdSensorEvent(false, 2));
+ mProximitySensor.setLastEvent(new ThresholdSensorEvent(false, 2));
mProximitySensor.alertListeners();
waitForSensorManager();
captor.getValue().onNotificationAlerted(null /* pulseSuppressedListener */);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
index a1b72104509b..8ae7100e2e60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
@@ -39,8 +39,8 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.CarrierTextManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
import com.android.systemui.util.CarrierConfigTracker;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import com.android.systemui.utils.os.FakeHandler;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
index e939411e4a2a..f0bd06571eb9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
@@ -43,12 +43,12 @@ import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.WifiIndicators;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
index f9d5be6c4807..fe328395b89f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
@@ -48,9 +48,9 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.AccessPointController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
import com.android.systemui.toast.SystemUIToast;
import com.android.systemui.toast.ToastFactory;
import com.android.systemui.util.CarrierConfigTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/AccessPointControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
index 4068f93f5ee3..7896a26badbe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/AccessPointControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy
+package com.android.systemui.statusbar.connectivity
import android.os.UserManager
import android.test.suitebuilder.annotation.SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java
index 3c55df934f76..11a53c55c024 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
@@ -28,11 +28,11 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.settingslib.mobile.TelephonyIcons;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
-import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.EmergencyListener;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.connectivity.NetworkController.WifiIndicators;
import com.android.systemui.tests.R;
import org.junit.Before;
@@ -182,7 +182,8 @@ public class CallbackHandlerTest extends SysuiTestCase {
@Test
public void testSignalCallback_setIsAirplaneMode() {
- IconState state = new IconState(true, R.drawable.stat_sys_airplane_mode, "Test Description");
+ IconState state =
+ new IconState(true, R.drawable.stat_sys_airplane_mode, "Test Description");
mHandler.setIsAirplaneMode(state);
waitForCallbacks();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
index c488ee95aa3c..67cab7413f1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
@@ -72,10 +72,11 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.MobileDataIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.util.CarrierConfigTracker;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -268,7 +269,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
setSubscriptions(mSubId);
mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
ArgumentCaptor<ConnectivityManager.NetworkCallback> callbackArg =
- ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+ ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
verify(mMockCm, atLeastOnce())
.registerDefaultNetworkCallback(callbackArg.capture(), isA(Handler.class));
int captureSize = callbackArg.getAllValues().size();
@@ -404,7 +405,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
}
private static void setConnectivityCommon(NetworkCapabilities.Builder builder,
- int networkType, boolean validated, boolean isConnected){
+ int networkType, boolean validated, boolean isConnected) {
// TODO: Separate out into several NetworkCapabilities.
if (isConnected) {
builder.addTransportType(networkType);
@@ -538,7 +539,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
}
protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
- boolean roaming, boolean inet) {
+ boolean roaming, boolean inet) {
ArgumentCaptor<MobileDataIndicators> indicatorsArg =
ArgumentCaptor.forClass(MobileDataIndicators.class);
@@ -646,7 +647,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
}
protected void assertNetworkNameEquals(String expected) {
- assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
+ assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
}
protected void assertDataNetworkNameEquals(String expected) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
index 3433a14f54e7..00dedd961074 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
@@ -1,4 +1,20 @@
-package com.android.systemui.statusbar.policy;
+/*
+ * Copyright (C) 2021 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.systemui.statusbar.connectivity;
import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
@@ -22,6 +38,7 @@ import android.testing.TestableLooper.RunWithLooper;
import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.CarrierConfigTracker;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerEthernetTest.java
index 6aab9c762a95..675d755ad3e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerEthernetTest.java
@@ -1,4 +1,20 @@
-package com.android.systemui.statusbar.policy;
+/*
+ * Copyright (C) 2021 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.systemui.statusbar.connectivity;
import static junit.framework.Assert.assertEquals;
@@ -7,7 +23,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
+import com.android.systemui.statusbar.connectivity.NetworkController.IconState;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
index 4ff13011567b..73eddd166f88 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.connectivity;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -42,6 +42,7 @@ import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.R;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.CarrierConfigTracker;
import org.junit.Test;
@@ -280,7 +281,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
// TODO: Put this somewhere else, maybe in its own file.
@Test
public void testHasCorrectMobileControllers() {
- int[] testSubscriptions = new int[] { 1, 5, 3 };
+ int[] testSubscriptions = new int[]{1, 5, 3};
int notTestSubscription = 0;
MobileSignalController mobileSignalController = Mockito.mock(MobileSignalController.class);
@@ -312,8 +313,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
// We will not add one subscription to make sure it's controller gets removed.
int indexToSkipSubscription = 1;
- int[] testSubscriptions = new int[] { 1, 5, 3 };
- MobileSignalController[] mobileSignalControllers = new MobileSignalController[] {
+ int[] testSubscriptions = new int[]{1, 5, 3};
+ MobileSignalController[] mobileSignalControllers = new MobileSignalController[]{
Mockito.mock(MobileSignalController.class),
Mockito.mock(MobileSignalController.class),
Mockito.mock(MobileSignalController.class),
@@ -401,24 +402,24 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
@Test
public void testOnReceive_stringsUpdatedAction_bothFalse() {
Intent intent = createStringsUpdatedIntent(false /* showSpn */,
- "Irrelevant" /* spn */,
- false /* showPlmn */,
- "Irrelevant" /* plmn */);
+ "Irrelevant" /* spn */,
+ false /* showPlmn */,
+ "Irrelevant" /* plmn */);
mNetworkController.onReceive(mContext, intent);
String defaultNetworkName = mMobileSignalController
.getTextIfExists(
- com.android.internal.R.string.lockscreen_carrier_default).toString();
+ com.android.internal.R.string.lockscreen_carrier_default).toString();
assertNetworkNameEquals(defaultNetworkName);
}
@Test
public void testOnReceive_stringsUpdatedAction_bothTrueAndNull() {
Intent intent = createStringsUpdatedIntent(true /* showSpn */,
- null /* spn */,
- true /* showPlmn */,
- null /* plmn */);
+ null /* spn */,
+ true /* showPlmn */,
+ null /* plmn */);
mNetworkController.onReceive(mContext, intent);
@@ -433,15 +434,15 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
String plmn = "Test2";
Intent intent = createStringsUpdatedIntent(true /* showSpn */,
- spn /* spn */,
- true /* showPlmn */,
- plmn /* plmn */);
+ spn /* spn */,
+ true /* showPlmn */,
+ plmn /* plmn */);
mNetworkController.onReceive(mContext, intent);
assertNetworkNameEquals(plmn
+ mMobileSignalController.getTextIfExists(
- R.string.status_bar_network_name_separator).toString()
+ R.string.status_bar_network_name_separator).toString()
+ spn);
}
@@ -477,145 +478,149 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
@Test
public void testOnUpdateDataActivity_dataOut() {
- setupDefaultSignal();
+ setupDefaultSignal();
- updateDataActivity(TelephonyManager.DATA_ACTIVITY_OUT);
+ updateDataActivity(TelephonyManager.DATA_ACTIVITY_OUT);
- verifyLastQsMobileDataIndicators(true /* visible */,
- DEFAULT_LEVEL /* icon */,
- DEFAULT_QS_ICON /* typeIcon */,
- false /* dataIn */,
- true /* dataOut */);
+ verifyLastQsMobileDataIndicators(true /* visible */,
+ DEFAULT_LEVEL /* icon */,
+ DEFAULT_QS_ICON /* typeIcon */,
+ false /* dataIn */,
+ true /* dataOut */);
}
@Test
public void testOnUpdateDataActivity_dataInOut() {
- setupDefaultSignal();
+ setupDefaultSignal();
- updateDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT);
+ updateDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT);
- verifyLastQsMobileDataIndicators(true /* visible */,
- DEFAULT_LEVEL /* icon */,
- DEFAULT_QS_ICON /* typeIcon */,
- true /* dataIn */,
- true /* dataOut */);
+ verifyLastQsMobileDataIndicators(true /* visible */,
+ DEFAULT_LEVEL /* icon */,
+ DEFAULT_QS_ICON /* typeIcon */,
+ true /* dataIn */,
+ true /* dataOut */);
}
@Test
public void testOnUpdateDataActivity_dataActivityNone() {
- setupDefaultSignal();
+ setupDefaultSignal();
- updateDataActivity(TelephonyManager.DATA_ACTIVITY_NONE);
+ updateDataActivity(TelephonyManager.DATA_ACTIVITY_NONE);
- verifyLastQsMobileDataIndicators(true /* visible */,
- DEFAULT_LEVEL /* icon */,
- DEFAULT_QS_ICON /* typeIcon */,
- false /* dataIn */,
- false /* dataOut */);
+ verifyLastQsMobileDataIndicators(true /* visible */,
+ DEFAULT_LEVEL /* icon */,
+ DEFAULT_QS_ICON /* typeIcon */,
+ false /* dataIn */,
+ false /* dataOut */);
}
@Test
public void testCarrierNetworkChange_carrierNetworkChange() {
- int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+ int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
- setupDefaultSignal();
- setLevel(strength);
+ setupDefaultSignal();
+ setLevel(strength);
- // Verify baseline
- verifyLastMobileDataIndicators(true /* visible */,
- strength /* strengthIcon */,
- DEFAULT_ICON /* typeIcon */);
+ // Verify baseline
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */);
- // API call is made
- setCarrierNetworkChange(true /* enabled */);
+ // API call is made
+ setCarrierNetworkChange(true /* enabled */);
- // Carrier network change is true, show special indicator
- verifyLastMobileDataIndicators(true /* visible */,
- SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()),
- 0 /* typeIcon */);
+ // Carrier network change is true, show special indicator
+ verifyLastMobileDataIndicators(true /* visible */,
+ SignalDrawable.getCarrierChangeState(
+ CellSignalStrength.getNumSignalStrengthLevels()),
+ 0 /* typeIcon */);
- // Revert back
- setCarrierNetworkChange(false /* enabled */);
+ // Revert back
+ setCarrierNetworkChange(false /* enabled */);
- // Verify back in previous state
- verifyLastMobileDataIndicators(true /* visible */,
- strength /* strengthIcon */,
- DEFAULT_ICON /* typeIcon */);
+ // Verify back in previous state
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */);
}
@Test
public void testCarrierNetworkChange_roamingBeforeNetworkChange() {
- int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+ int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
- setupDefaultSignal();
- setLevel(strength);
- setGsmRoaming(true);
+ setupDefaultSignal();
+ setLevel(strength);
+ setGsmRoaming(true);
- // Verify baseline
- verifyLastMobileDataIndicators(true /* visible */,
- strength /* strengthIcon */,
- DEFAULT_ICON /* typeIcon */,
- true /* roaming */);
+ // Verify baseline
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */,
+ true /* roaming */);
- // API call is made
- setCarrierNetworkChange(true /* enabled */);
+ // API call is made
+ setCarrierNetworkChange(true /* enabled */);
- // Carrier network change is true, show special indicator, no roaming.
- verifyLastMobileDataIndicators(true /* visible */,
- SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()),
- 0 /* typeIcon */,
- false /* roaming */);
+ // Carrier network change is true, show special indicator, no roaming.
+ verifyLastMobileDataIndicators(true /* visible */,
+ SignalDrawable.getCarrierChangeState(
+ CellSignalStrength.getNumSignalStrengthLevels()),
+ 0 /* typeIcon */,
+ false /* roaming */);
- // Revert back
- setCarrierNetworkChange(false /* enabled */);
+ // Revert back
+ setCarrierNetworkChange(false /* enabled */);
- // Verify back in previous state
- verifyLastMobileDataIndicators(true /* visible */,
- strength /* strengthIcon */,
- DEFAULT_ICON /* typeIcon */,
- true /* roaming */);
+ // Verify back in previous state
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */,
+ true /* roaming */);
}
@Test
public void testCarrierNetworkChange_roamingAfterNetworkChange() {
- int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
-
- setupDefaultSignal();
- setLevel(strength);
-
- // Verify baseline
- verifyLastMobileDataIndicators(true /* visible */,
- strength /* strengthIcon */,
- DEFAULT_ICON /* typeIcon */,
- false /* roaming */);
-
- // API call is made
- setCarrierNetworkChange(true /* enabled */);
-
- // Carrier network change is true, show special indicator, no roaming.
- verifyLastMobileDataIndicators(true /* visible */,
- SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()),
- 0 /* typeIcon */,
- false /* roaming */);
-
- setGsmRoaming(true);
-
- // Roaming should not show.
- verifyLastMobileDataIndicators(true /* visible */,
- SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()),
- 0 /* typeIcon */,
- false /* roaming */);
-
- // Revert back
- setCarrierNetworkChange(false /* enabled */);
-
- // Verify back in previous state
- verifyLastMobileDataIndicators(true /* visible */,
- strength /* strengthIcon */,
- DEFAULT_ICON /* typeIcon */,
- true /* roaming */);
+ int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+ setupDefaultSignal();
+ setLevel(strength);
+
+ // Verify baseline
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */,
+ false /* roaming */);
+
+ // API call is made
+ setCarrierNetworkChange(true /* enabled */);
+
+ // Carrier network change is true, show special indicator, no roaming.
+ verifyLastMobileDataIndicators(true /* visible */,
+ SignalDrawable.getCarrierChangeState(
+ CellSignalStrength.getNumSignalStrengthLevels()),
+ 0 /* typeIcon */,
+ false /* roaming */);
+
+ setGsmRoaming(true);
+
+ // Roaming should not show.
+ verifyLastMobileDataIndicators(true /* visible */,
+ SignalDrawable.getCarrierChangeState(
+ CellSignalStrength.getNumSignalStrengthLevels()),
+ 0 /* typeIcon */,
+ false /* roaming */);
+
+ // Revert back
+ setCarrierNetworkChange(false /* enabled */);
+
+ // Verify back in previous state
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */,
+ true /* roaming */);
}
private void verifyEmergencyOnly(boolean isEmergencyOnly) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
index 4a5770d12239..ffeaf207942b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
@@ -1,10 +1,25 @@
-package com.android.systemui.statusbar.policy;
+/*
+ * Copyright (C) 2021 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.systemui.statusbar.connectivity;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -21,7 +36,7 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import com.android.settingslib.mobile.TelephonyIcons;
-import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
+import com.android.systemui.statusbar.connectivity.NetworkController.WifiIndicators;
import org.junit.Before;
import org.junit.Test;
@@ -165,7 +180,7 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
}
@Test
- public void testWifiIconDisconnectedViaCallback(){
+ public void testWifiIconDisconnectedViaCallback() {
// Setup normal connection
String testSsid = "Test SSID";
int testLevel = 2;
@@ -183,7 +198,7 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
}
@Test
- public void testVpnWithUnderlyingWifi(){
+ public void testVpnWithUnderlyingWifi() {
String testSsid = "Test SSID";
int testLevel = 2;
setWifiEnabled(true);
@@ -299,7 +314,7 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
protected void setWifiLevel(int level) {
float amountPerLevel = (MAX_RSSI - MIN_RSSI) / (WifiIcons.WIFI_LEVEL_COUNT - 1);
- int rssi = (int)(MIN_RSSI + level * amountPerLevel);
+ int rssi = (int) (MIN_RSSI + level * amountPerLevel);
// Put RSSI in the middle of the range.
rssi += amountPerLevel / 2;
when(mWifiInfo.getRssi()).thenReturn(rssi);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 07ebaea8bdda..baed694e6fa0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -75,6 +75,7 @@ import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
@@ -99,6 +100,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@Mock private HeadsUpManagerPhone mHeadsUpManager;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private TunerService mTunerService;
+ @Mock private DeviceProvisionedController mDeviceProvisionedController;
@Mock private DynamicPrivacyController mDynamicPrivacyController;
@Mock private ConfigurationController mConfigurationController;
@Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
@@ -152,6 +154,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mHeadsUpManager,
mNotificationRoundnessManager,
mTunerService,
+ mDeviceProvisionedController,
mDynamicPrivacyController,
mConfigurationController,
mSysuiStatusBarStateController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 4e76b1695f0b..9f42fa4d2ae7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -280,6 +280,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Test
public void testUpdateFooter_noNotifications() {
setBarStateForTest(StatusBarState.SHADE);
+ mStackScroller.setCurrentUserSetup(true);
+
FooterView view = mock(FooterView.class);
mStackScroller.setFooterView(view);
mStackScroller.updateFooter();
@@ -289,6 +291,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Test
public void testUpdateFooter_remoteInput() {
setBarStateForTest(StatusBarState.SHADE);
+ mStackScroller.setCurrentUserSetup(true);
ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
when(row.canViewBeDismissed()).thenReturn(true);
@@ -308,6 +311,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Test
public void testUpdateFooter_oneClearableNotification() {
setBarStateForTest(StatusBarState.SHADE);
+ mStackScroller.setCurrentUserSetup(true);
when(mEmptyShadeView.getVisibility()).thenReturn(GONE);
when(mStackScrollLayoutController.hasActiveClearableNotifications(ROWS_ALL))
@@ -321,8 +325,25 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
+ public void testUpdateFooter_oneClearableNotification_beforeUserSetup() {
+ setBarStateForTest(StatusBarState.SHADE);
+ mStackScroller.setCurrentUserSetup(false);
+
+ when(mEmptyShadeView.getVisibility()).thenReturn(GONE);
+ when(mStackScrollLayoutController.hasActiveClearableNotifications(ROWS_ALL))
+ .thenReturn(true);
+ when(mStackScrollLayoutController.hasActiveNotifications()).thenReturn(true);
+
+ FooterView view = mock(FooterView.class);
+ mStackScroller.setFooterView(view);
+ mStackScroller.updateFooter();
+ verify(mStackScroller).updateFooterView(false, true, true);
+ }
+
+ @Test
public void testUpdateFooter_oneNonClearableNotification() {
setBarStateForTest(StatusBarState.SHADE);
+ mStackScroller.setCurrentUserSetup(true);
ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
when(row.canViewBeDismissed()).thenReturn(false);
@@ -341,6 +362,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Test
public void testUpdateFooter_atEnd() {
+ mStackScroller.setCurrentUserSetup(true);
+
// add footer
mStackScroller.inflateFooterView();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
index b08dbee687e6..f23f14801484 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
@@ -45,10 +45,10 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
import com.android.systemui.statusbar.OperatorNameViewController;
+import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.NetworkController;
import org.junit.Before;
import org.junit.Ignore;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index fdda76df64d7..6868e1855c65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -112,6 +112,7 @@ import com.android.systemui.statusbar.OperatorNameViewController;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
+import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -137,7 +138,6 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.tuner.TunerService;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index efe2c1774b08..fe7ec68f77b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -33,6 +33,7 @@ import androidx.test.filters.SmallTest
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -105,7 +106,9 @@ class OngoingCallControllerTest : SysuiTestCase() {
mockActivityStarter,
mainExecutor,
mockIActivityManager,
- OngoingCallLogger(uiEventLoggerFake))
+ OngoingCallLogger(uiEventLoggerFake),
+ DumpManager(),
+ )
controller.init()
controller.addCallback(mockOngoingCallListener)
controller.setChipView(chipView)
@@ -221,18 +224,6 @@ class OngoingCallControllerTest : SysuiTestCase() {
verify(mockOngoingCallListener).onOngoingCallStateChanged(anyBoolean())
}
- /** Regression test for b/201097913. */
- @Test
- fun onEntryCleanUp_callNotifAddedThenRemoved_listenerNotified() {
- val ongoingCallNotifEntry = createOngoingCallNotifEntry()
- notifCollectionListener.onEntryAdded(ongoingCallNotifEntry)
- reset(mockOngoingCallListener)
-
- notifCollectionListener.onEntryCleanUp(ongoingCallNotifEntry)
-
- verify(mockOngoingCallListener).onOngoingCallStateChanged(anyBoolean())
- }
-
/** Regression test for b/188491504. */
@Test
fun onEntryRemoved_removedNotifHasSameKeyAsAddedNotif_listenerNotified() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt
index de86821c0535..b54aadb8228f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt
@@ -138,7 +138,7 @@ class WallpaperControllerTest : SysuiTestCase() {
private fun createWallpaperInfo(useDefaultTransition: Boolean = true): WallpaperInfo {
val info = mock(WallpaperInfo::class.java)
- whenever(info.shouldUseDefaultDeviceStateChangeTransition())
+ whenever(info.shouldUseDefaultDisplayStateChangeTransition())
.thenReturn(useDefaultTransition)
return info
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java
index 50947ab0ee86..22cf744c726b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeProximitySensor.java
@@ -19,14 +19,21 @@ package com.android.systemui.util.sensors;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.FakeExecution;
-public class FakeProximitySensor extends ProximitySensor {
+public class FakeProximitySensor extends ProximitySensorImpl {
private boolean mAvailable;
private boolean mRegistered;
- public FakeProximitySensor(ThresholdSensor primary, ThresholdSensor secondary,
- DelayableExecutor delayableExecutor) {
- super(primary, secondary == null ? new FakeThresholdSensor() : secondary,
- delayableExecutor, new FakeExecution());
+ public FakeProximitySensor(
+ ThresholdSensor primary,
+ ThresholdSensor secondary,
+ DelayableExecutor delayableExecutor
+ ) {
+ super(
+ primary,
+ secondary == null ? new FakeThresholdSensor() : secondary,
+ delayableExecutor,
+ new FakeExecution()
+ );
mAvailable = true;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java
index d9f978944cde..0d4a6c7023fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeThresholdSensor.java
@@ -59,6 +59,16 @@ public class FakeThresholdSensor implements ThresholdSensor {
mListeners.remove(listener);
}
+ @Override
+ public String getName() {
+ return "FakeThresholdSensorName";
+ }
+
+ @Override
+ public String getType() {
+ return "FakeThresholdSensorType";
+ }
+
public void setLoaded(boolean loaded) {
mIsLoaded = loaded;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/PostureDependentProximitySensorTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/PostureDependentProximitySensorTest.java
new file mode 100644
index 000000000000..075f393df15a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/PostureDependentProximitySensorTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2021 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.systemui.util.sensors;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.verify;
+
+import android.content.res.Resources;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.policy.DevicePostureController;
+import com.android.systemui.util.concurrency.FakeExecution;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class PostureDependentProximitySensorTest extends SysuiTestCase {
+ @Mock private Resources mResources;
+ @Mock private DevicePostureController mDevicePostureController;
+ @Mock private AsyncSensorManager mSensorManager;
+
+ @Captor private ArgumentCaptor<DevicePostureController.Callback> mPostureListenerCaptor =
+ ArgumentCaptor.forClass(DevicePostureController.Callback.class);
+ private DevicePostureController.Callback mPostureListener;
+
+ private PostureDependentProximitySensor mProximitySensor;
+ private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ allowTestableLooperAsMainThread();
+
+ mProximitySensor = new PostureDependentProximitySensor(
+ new ThresholdSensor[DevicePostureController.SUPPORTED_POSTURES_SIZE],
+ new ThresholdSensor[DevicePostureController.SUPPORTED_POSTURES_SIZE],
+ mFakeExecutor,
+ new FakeExecution(),
+ mDevicePostureController
+ );
+ }
+
+ @Test
+ public void testPostureChangeListenerAdded() {
+ capturePostureListener();
+ }
+
+ @Test
+ public void testPostureChangeListenerUpdatesPosture() {
+ // GIVEN posture listener is registered
+ capturePostureListener();
+
+ // WHEN the posture changes to DEVICE_POSTURE_OPENED
+ mPostureListener.onPostureChanged(DevicePostureController.DEVICE_POSTURE_OPENED);
+
+ // THEN device posture is updated to DEVICE_POSTURE_OPENED
+ assertEquals(DevicePostureController.DEVICE_POSTURE_OPENED,
+ mProximitySensor.mDevicePosture);
+
+ // WHEN the posture changes to DEVICE_POSTURE_CLOSED
+ mPostureListener.onPostureChanged(DevicePostureController.DEVICE_POSTURE_CLOSED);
+
+ // THEN device posture is updated to DEVICE_POSTURE_CLOSED
+ assertEquals(DevicePostureController.DEVICE_POSTURE_CLOSED,
+ mProximitySensor.mDevicePosture);
+
+ // WHEN the posture changes to DEVICE_POSTURE_FLIPPED
+ mPostureListener.onPostureChanged(DevicePostureController.DEVICE_POSTURE_FLIPPED);
+
+ // THEN device posture is updated to DEVICE_POSTURE_FLIPPED
+ assertEquals(DevicePostureController.DEVICE_POSTURE_FLIPPED,
+ mProximitySensor.mDevicePosture);
+
+ // WHEN the posture changes to DEVICE_POSTURE_HALF_OPENED
+ mPostureListener.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED);
+
+ // THEN device posture is updated to DEVICE_POSTURE_HALF_OPENED
+ assertEquals(DevicePostureController.DEVICE_POSTURE_HALF_OPENED,
+ mProximitySensor.mDevicePosture);
+ }
+
+ private void capturePostureListener() {
+ verify(mDevicePostureController).addCallback(mPostureListenerCaptor.capture());
+ mPostureListener = mPostureListenerCaptor.getValue();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java
index 242fe9f5fffe..19dbf9aa3c13 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java
@@ -49,7 +49,7 @@ public class ProximityCheckTest extends SysuiTestCase {
private TestableCallback mTestableCallback = new TestableCallback();
- private ProximitySensor.ProximityCheck mProximityCheck;
+ private ProximityCheck mProximityCheck;
@Before
public void setUp() throws Exception {
@@ -58,7 +58,7 @@ public class ProximityCheckTest extends SysuiTestCase {
thresholdSensor.setLoaded(true);
mFakeProximitySensor = new FakeProximitySensor(thresholdSensor, null, mFakeExecutor);
- mProximityCheck = new ProximitySensor.ProximityCheck(mFakeProximitySensor, mFakeExecutor);
+ mProximityCheck = new ProximityCheck(mFakeProximitySensor, mFakeExecutor);
}
@Test
@@ -67,7 +67,7 @@ public class ProximityCheckTest extends SysuiTestCase {
assertNull(mTestableCallback.mLastResult);
- mFakeProximitySensor.setLastEvent(new ProximitySensor.ThresholdSensorEvent(true, 0));
+ mFakeProximitySensor.setLastEvent(new ThresholdSensorEvent(true, 0));
mFakeProximitySensor.alertListeners();
assertTrue(mTestableCallback.mLastResult);
@@ -103,7 +103,7 @@ public class ProximityCheckTest extends SysuiTestCase {
mProximityCheck.check(100, mTestableCallback);
- mFakeProximitySensor.setLastEvent(new ProximitySensor.ThresholdSensorEvent(true, 0));
+ mFakeProximitySensor.setLastEvent(new ThresholdSensorEvent(true, 0));
mFakeProximitySensor.alertListeners();
assertThat(mTestableCallback.mLastResult).isNotNull();
@@ -123,7 +123,7 @@ public class ProximityCheckTest extends SysuiTestCase {
assertNull(mTestableCallback.mLastResult);
- mFakeProximitySensor.setLastEvent(new ProximitySensor.ThresholdSensorEvent(true, 0));
+ mFakeProximitySensor.setLastEvent(new ThresholdSensorEvent(true, 0));
mFakeProximitySensor.alertListeners();
assertTrue(mTestableCallback.mLastResult);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorImplDualTest.java
index 0e9d96c61e54..5e7557896145 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorImplDualTest.java
@@ -42,7 +42,7 @@ import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
-public class ProximitySensorDualTest extends SysuiTestCase {
+public class ProximitySensorImplDualTest extends SysuiTestCase {
private ProximitySensor mProximitySensor;
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
private FakeThresholdSensor mThresholdSensorPrimary;
@@ -57,7 +57,7 @@ public class ProximitySensorDualTest extends SysuiTestCase {
mThresholdSensorSecondary = new FakeThresholdSensor();
mThresholdSensorSecondary.setLoaded(true);
- mProximitySensor = new ProximitySensor(
+ mProximitySensor = new ProximitySensorImpl(
mThresholdSensorPrimary, mThresholdSensorSecondary, mFakeExecutor,
new FakeExecution());
}
@@ -430,11 +430,11 @@ public class ProximitySensorDualTest extends SysuiTestCase {
}
private static class TestableListener implements ThresholdSensor.Listener {
- ThresholdSensor.ThresholdSensorEvent mLastEvent;
+ ThresholdSensorEvent mLastEvent;
int mCallCount = 0;
@Override
- public void onThresholdCrossed(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
+ public void onThresholdCrossed(ThresholdSensorEvent proximityEvent) {
mLastEvent = proximityEvent;
mCallCount++;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorSingleTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorImplSingleTest.java
index 6c6d355d7866..752cd3211161 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorSingleTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorImplSingleTest.java
@@ -42,7 +42,7 @@ import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
-public class ProximitySensorSingleTest extends SysuiTestCase {
+public class ProximitySensorImplSingleTest extends SysuiTestCase {
private ProximitySensor mProximitySensor;
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
private FakeThresholdSensor mThresholdSensor;
@@ -54,7 +54,7 @@ public class ProximitySensorSingleTest extends SysuiTestCase {
mThresholdSensor = new FakeThresholdSensor();
mThresholdSensor.setLoaded(true);
- mProximitySensor = new ProximitySensor(
+ mProximitySensor = new ProximitySensorImpl(
mThresholdSensor, new FakeThresholdSensor(), mFakeExecutor, new FakeExecution());
}
@@ -215,7 +215,7 @@ public class ProximitySensorSingleTest extends SysuiTestCase {
public void testPreventRecursiveAlert() {
TestableListener listenerA = new TestableListener() {
@Override
- public void onThresholdCrossed(ProximitySensor.ThresholdSensorEvent proximityEvent) {
+ public void onThresholdCrossed(ThresholdSensorEvent proximityEvent) {
super.onThresholdCrossed(proximityEvent);
if (mCallCount < 2) {
mProximitySensor.alertListeners();
@@ -231,11 +231,11 @@ public class ProximitySensorSingleTest extends SysuiTestCase {
}
private static class TestableListener implements ThresholdSensor.Listener {
- ThresholdSensor.ThresholdSensorEvent mLastEvent;
+ ThresholdSensorEvent mLastEvent;
int mCallCount = 0;
@Override
- public void onThresholdCrossed(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
+ public void onThresholdCrossed(ThresholdSensorEvent proximityEvent) {
mLastEvent = proximityEvent;
mCallCount++;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java
index 125063a7adc4..b10f16c963ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java
@@ -380,7 +380,7 @@ public class ThresholdSensorImplTest extends SysuiTestCase {
int mCallCount;
@Override
- public void onThresholdCrossed(ThresholdSensor.ThresholdSensorEvent event) {
+ public void onThresholdCrossed(ThresholdSensorEvent event) {
mBelow = event.getBelow();
mTimestampNs = event.getTimestampNs();
mCallCount++;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
index e7acfae24f30..8ea9da6f4d0e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
@@ -18,9 +18,9 @@ import android.os.Bundle;
import android.testing.LeakCheck;
import com.android.settingslib.net.DataUsageController;
+import com.android.systemui.statusbar.connectivity.NetworkController;
+import com.android.systemui.statusbar.connectivity.NetworkController.SignalCallback;
import com.android.systemui.statusbar.policy.DataSaverController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
public class FakeNetworkController extends BaseLeakChecker<SignalCallback>
implements NetworkController {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
index fedc08d93bc7..dc6a8fb9a4c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
@@ -19,6 +19,7 @@ import android.util.ArrayMap;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.phone.ManagedProfileController;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -29,7 +30,6 @@ import com.android.systemui.statusbar.policy.FlashlightController;
import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.LocationController;
-import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.SecurityController;
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index 904def0af2cf..6bd1fa6c335d 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -190,6 +190,9 @@ final class ContentCapturePerUserService
Slog.w(TAG, "remote service died: " + service);
synchronized (mLock) {
mZombie = true;
+ writeServiceEvent(
+ FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__ON_REMOTE_SERVICE_DIED,
+ getServiceComponentName());
}
}
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 5fc301e60b9d..0a22f2fdfdf8 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -17,6 +17,7 @@
package com.android.server.display;
import static android.hardware.display.DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE;
+import static android.os.PowerManager.BRIGHTNESS_INVALID;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -40,6 +41,7 @@ import android.os.IThermalEventListener;
import android.os.IThermalService;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -60,6 +62,7 @@ import android.view.DisplayInfo;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
import com.android.server.display.utils.AmbientFilter;
@@ -155,7 +158,7 @@ public class DisplayModeDirector {
mAppRequestObserver = new AppRequestObserver();
mSettingsObserver = new SettingsObserver(context, handler);
mDisplayObserver = new DisplayObserver(context, handler);
- mBrightnessObserver = new BrightnessObserver(context, handler);
+ mBrightnessObserver = new BrightnessObserver(context, handler, injector);
mUdfpsObserver = new UdfpsObserver();
final BallotBox ballotBox = (displayId, priority, vote) -> {
synchronized (mLock) {
@@ -1427,8 +1430,6 @@ public class DisplayModeDirector {
@Override
public void onDisplayChanged(int displayId) {
updateDisplayModes(displayId);
- // TODO: Break the coupling between DisplayObserver and BrightnessObserver.
- mBrightnessObserver.onDisplayChanged(displayId);
}
private void updateDisplayModes(int displayId) {
@@ -1465,7 +1466,7 @@ public class DisplayModeDirector {
* {@link R.array#config_ambientThresholdsOfPeakRefreshRate}.
*/
@VisibleForTesting
- public class BrightnessObserver extends ContentObserver {
+ public class BrightnessObserver implements DisplayManager.DisplayListener {
private final static int LIGHT_SENSOR_RATE_MS = 250;
private int[] mLowDisplayBrightnessThresholds;
private int[] mLowAmbientBrightnessThresholds;
@@ -1488,6 +1489,8 @@ public class DisplayModeDirector {
private int mBrightness = -1;
private final Context mContext;
+ private final Injector mInjector;
+ private final Handler mHandler;
// Enable light sensor only when mShouldObserveAmbientLowChange is true or
// mShouldObserveAmbientHighChange is true, screen is on, peak refresh rate
@@ -1500,9 +1503,11 @@ public class DisplayModeDirector {
private int mRefreshRateInLowZone;
private int mRefreshRateInHighZone;
- BrightnessObserver(Context context, Handler handler) {
- super(handler);
+ BrightnessObserver(Context context, Handler handler, Injector injector) {
mContext = context;
+ mHandler = handler;
+ mInjector = injector;
+
mLowDisplayBrightnessThresholds = context.getResources().getIntArray(
R.array.config_brightnessThresholdsOfPeakRefreshRate);
mLowAmbientBrightnessThresholds = context.getResources().getIntArray(
@@ -1569,8 +1574,7 @@ public class DisplayModeDirector {
public void observe(SensorManager sensorManager) {
mSensorManager = sensorManager;
final ContentResolver cr = mContext.getContentResolver();
- mBrightness = Settings.System.getIntForUser(cr,
- Settings.System.SCREEN_BRIGHTNESS, -1 /*default*/, cr.getUserId());
+ mBrightness = getBrightness(Display.DEFAULT_DISPLAY);
// DeviceConfig is accessible after system ready.
int[] lowDisplayBrightnessThresholds =
@@ -1603,6 +1607,10 @@ public class DisplayModeDirector {
restartObserver();
mDeviceConfigDisplaySettings.startListening();
+
+ mInjector.registerDisplayListener(this, mHandler,
+ DisplayManager.EVENT_FLAG_DISPLAY_CHANGED |
+ DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS);
}
public void setLoggingEnabled(boolean loggingEnabled) {
@@ -1718,28 +1726,30 @@ public class DisplayModeDirector {
}
}
+ @Override
+ public void onDisplayAdded(int displayId) {}
+
+ @Override
+ public void onDisplayRemoved(int displayId) {}
+
+ @Override
public void onDisplayChanged(int displayId) {
if (displayId == Display.DEFAULT_DISPLAY) {
updateDefaultDisplayState();
- }
- }
- @Override
- public void onChange(boolean selfChange, Uri uri, int userId) {
- synchronized (mLock) {
- final ContentResolver cr = mContext.getContentResolver();
- int brightness = Settings.System.getIntForUser(cr,
- Settings.System.SCREEN_BRIGHTNESS, -1 /*default*/, cr.getUserId());
- if (brightness != mBrightness) {
- mBrightness = brightness;
- onBrightnessChangedLocked();
+ // We don't support multiple display blocking zones yet, so only handle
+ // brightness changes for the default display for now.
+ int brightness = getBrightness(displayId);
+ synchronized (mLock) {
+ if (brightness != mBrightness) {
+ mBrightness = brightness;
+ onBrightnessChangedLocked();
+ }
}
}
}
private void restartObserver() {
- final ContentResolver cr = mContext.getContentResolver();
-
if (mRefreshRateInLowZone > 0) {
mShouldObserveDisplayLowChange = hasValidThreshold(
mLowDisplayBrightnessThresholds);
@@ -1760,15 +1770,6 @@ public class DisplayModeDirector {
mShouldObserveAmbientHighChange = false;
}
- if (mShouldObserveDisplayLowChange || mShouldObserveDisplayHighChange) {
- // Content Service does not check if an listener has already been registered.
- // To ensure only one listener is registered, force an unregistration first.
- mInjector.unregisterBrightnessObserver(cr, this);
- mInjector.registerBrightnessObserver(cr, this);
- } else {
- mInjector.unregisterBrightnessObserver(cr, this);
- }
-
if (mShouldObserveAmbientLowChange || mShouldObserveAmbientHighChange) {
Resources resources = mContext.getResources();
String lightSensorType = resources.getString(
@@ -1968,6 +1969,15 @@ public class DisplayModeDirector {
return mDefaultDisplayState == Display.STATE_ON;
}
+ private int getBrightness(int displayId) {
+ final BrightnessInfo info = mInjector.getBrightnessInfo(displayId);
+ if (info != null) {
+ return BrightnessSynchronizer.brightnessFloatToInt(info.adjustedBrightness);
+ }
+
+ return BRIGHTNESS_INVALID;
+ }
+
private final class LightSensorEventListener implements SensorEventListener {
final private static int INJECT_EVENTS_INTERVAL_MS = LIGHT_SENSOR_RATE_MS;
private float mLastSensorData;
@@ -2283,6 +2293,7 @@ public class DisplayModeDirector {
private final BallotBox mBallotBox;
private final Handler mHandler;
private final SparseIntArray mHbmMode = new SparseIntArray();
+ private final SparseBooleanArray mHbmActive = new SparseBooleanArray();
private final Injector mInjector;
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
private int mRefreshRateInHbmSunlight;
@@ -2351,6 +2362,7 @@ public class DisplayModeDirector {
public void onDisplayRemoved(int displayId) {
mBallotBox.vote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, null);
mHbmMode.delete(displayId);
+ mHbmActive.delete(displayId);
}
@Override
@@ -2360,12 +2372,17 @@ public class DisplayModeDirector {
// Display no longer there. Assume we'll get an onDisplayRemoved very soon.
return;
}
+
final int hbmMode = info.highBrightnessMode;
- if (hbmMode == mHbmMode.get(displayId)) {
+ final boolean isHbmActive = hbmMode != BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF &&
+ info.adjustedBrightness > info.highBrightnessTransitionPoint;
+ if (hbmMode == mHbmMode.get(displayId) &&
+ isHbmActive == mHbmActive.get(displayId)) {
// no change, ignore.
return;
}
mHbmMode.put(displayId, hbmMode);
+ mHbmActive.put(displayId, isHbmActive);
recalculateVotesForDisplay(displayId);
}
@@ -2379,28 +2396,36 @@ public class DisplayModeDirector {
}
private void recalculateVotesForDisplay(int displayId) {
- final int hbmMode = mHbmMode.get(displayId, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF);
Vote vote = null;
- if (hbmMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT) {
- // Device resource properties take priority over DisplayDeviceConfig
- if (mRefreshRateInHbmSunlight > 0) {
- vote = Vote.forRefreshRates(mRefreshRateInHbmSunlight,
- mRefreshRateInHbmSunlight);
- } else {
- final List<RefreshRateLimitation> limits =
- mDisplayManagerInternal.getRefreshRateLimitations(displayId);
- for (int i = 0; limits != null && i < limits.size(); i++) {
- final RefreshRateLimitation limitation = limits.get(i);
- if (limitation.type == REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE) {
- vote = Vote.forRefreshRates(limitation.range.min, limitation.range.max);
- break;
+ if (mHbmActive.get(displayId, false)) {
+ final int hbmMode =
+ mHbmMode.get(displayId, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF);
+ if (hbmMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT) {
+ // Device resource properties take priority over DisplayDeviceConfig
+ if (mRefreshRateInHbmSunlight > 0) {
+ vote = Vote.forRefreshRates(mRefreshRateInHbmSunlight,
+ mRefreshRateInHbmSunlight);
+ } else {
+ final List<RefreshRateLimitation> limits =
+ mDisplayManagerInternal.getRefreshRateLimitations(displayId);
+ for (int i = 0; limits != null && i < limits.size(); i++) {
+ final RefreshRateLimitation limitation = limits.get(i);
+ if (limitation.type == REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE) {
+ vote = Vote.forRefreshRates(limitation.range.min,
+ limitation.range.max);
+ break;
+ }
}
}
+ } else if (hbmMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR &&
+ mRefreshRateInHbmHdr > 0) {
+ // HBM for HDR vote isn't supported through DisplayDeviceConfig yet, so look for
+ // a vote from Device properties
+ vote = Vote.forRefreshRates(mRefreshRateInHbmHdr, mRefreshRateInHbmHdr);
+ } else {
+ Slog.w(TAG, "Unexpected HBM mode " + hbmMode + " for display ID " + displayId);
}
- }
- if (hbmMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
- && mRefreshRateInHbmHdr > 0) {
- vote = Vote.forRefreshRates(mRefreshRateInHbmHdr, mRefreshRateInHbmHdr);
+
}
mBallotBox.vote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, vote);
}
@@ -2408,6 +2433,7 @@ public class DisplayModeDirector {
void dumpLocked(PrintWriter pw) {
pw.println(" HbmObserver");
pw.println(" mHbmMode: " + mHbmMode);
+ pw.println(" mHbmActive: " + mHbmActive);
pw.println(" mRefreshRateInHbmSunlight: " + mRefreshRateInHbmSunlight);
pw.println(" mRefreshRateInHbmHdr: " + mRefreshRateInHbmHdr);
}
@@ -2630,19 +2656,11 @@ public class DisplayModeDirector {
}
interface Injector {
- // TODO: brightnessfloat: change this to the float setting
- Uri DISPLAY_BRIGHTNESS_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
Uri PEAK_REFRESH_RATE_URI = Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
@NonNull
DeviceConfigInterface getDeviceConfig();
- void registerBrightnessObserver(@NonNull ContentResolver cr,
- @NonNull ContentObserver observer);
-
- void unregisterBrightnessObserver(@NonNull ContentResolver cr,
- @NonNull ContentObserver observer);
-
void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer);
@@ -2672,19 +2690,6 @@ public class DisplayModeDirector {
}
@Override
- public void registerBrightnessObserver(@NonNull ContentResolver cr,
- @NonNull ContentObserver observer) {
- cr.registerContentObserver(DISPLAY_BRIGHTNESS_URI, false /*notifyDescendants*/,
- observer, UserHandle.USER_SYSTEM);
- }
-
- @Override
- public void unregisterBrightnessObserver(@NonNull ContentResolver cr,
- @NonNull ContentObserver observer) {
- cr.unregisterContentObserver(observer);
- }
-
- @Override
public void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer) {
cr.registerContentObserver(PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/,
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 1063481d6788..bf5208aed3f7 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1259,10 +1259,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
putScreenBrightnessSetting(brightnessState, /* updateCurrent */ true);
}
- // We save the brightness info *after* the brightness setting has been changed so that
- // the brightness info reflects the latest value.
- saveBrightnessInfo(getScreenBrightnessSetting());
-
// Apply dimming by at least some minimum amount when user activity
// timeout is about to expire.
if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
@@ -1393,6 +1389,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
hadUserBrightnessPoint);
}
+ // We save the brightness info *after* the brightness setting has been changed and
+ // adjustments made so that the brightness info reflects the latest value.
+ saveBrightnessInfo(getScreenBrightnessSetting(), animateValue);
+ } else {
+ saveBrightnessInfo(getScreenBrightnessSetting());
}
// Log any changes to what is currently driving the brightness setting.
@@ -1509,18 +1510,27 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
synchronized (mCachedBrightnessInfo) {
return new BrightnessInfo(
mCachedBrightnessInfo.brightness,
+ mCachedBrightnessInfo.adjustedBrightness,
mCachedBrightnessInfo.brightnessMin,
mCachedBrightnessInfo.brightnessMax,
- mCachedBrightnessInfo.hbmMode);
+ mCachedBrightnessInfo.hbmMode,
+ mCachedBrightnessInfo.highBrightnessTransitionPoint);
}
}
private void saveBrightnessInfo(float brightness) {
+ saveBrightnessInfo(brightness, brightness);
+ }
+
+ private void saveBrightnessInfo(float brightness, float adjustedBrightness) {
synchronized (mCachedBrightnessInfo) {
mCachedBrightnessInfo.brightness = brightness;
+ mCachedBrightnessInfo.adjustedBrightness = adjustedBrightness;
mCachedBrightnessInfo.brightnessMin = mHbmController.getCurrentBrightnessMin();
mCachedBrightnessInfo.brightnessMax = mHbmController.getCurrentBrightnessMax();
mCachedBrightnessInfo.hbmMode = mHbmController.getHighBrightnessMode();
+ mCachedBrightnessInfo.highBrightnessTransitionPoint =
+ mHbmController.getTransitionPoint();
}
}
@@ -2195,6 +2205,18 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
pw.println(" mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp);
pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
pw.println(" mColorFadeEnabled=" + mColorFadeEnabled);
+ synchronized (mCachedBrightnessInfo) {
+ pw.println(" mCachedBrightnessInfo.brightness=" + mCachedBrightnessInfo.brightness);
+ pw.println(" mCachedBrightnessInfo.adjustedBrightness=" +
+ mCachedBrightnessInfo.adjustedBrightness);
+ pw.println(" mCachedBrightnessInfo.brightnessMin=" +
+ mCachedBrightnessInfo.brightnessMin);
+ pw.println(" mCachedBrightnessInfo.brightnessMax=" +
+ mCachedBrightnessInfo.brightnessMax);
+ pw.println(" mCachedBrightnessInfo.hbmMode=" + mCachedBrightnessInfo.hbmMode);
+ pw.println(" mCachedBrightnessInfo.highBrightnessTransitionPoint=" +
+ mCachedBrightnessInfo.highBrightnessTransitionPoint);
+ }
pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
@@ -2606,8 +2628,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
static class CachedBrightnessInfo {
public float brightness;
+ public float adjustedBrightness;
public float brightnessMin;
public float brightnessMax;
public int hbmMode;
+ public float highBrightnessTransitionPoint;
}
}
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java
index 2791f6a409be..1e1cfeb5b9dd 100644
--- a/services/core/java/com/android/server/display/HighBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java
@@ -59,6 +59,9 @@ class HighBrightnessModeController {
private static final float HDR_PERCENT_OF_SCREEN_REQUIRED = 0.50f;
+ @VisibleForTesting
+ static final float HBM_TRANSITION_POINT_INVALID = Float.POSITIVE_INFINITY;
+
private final float mBrightnessMin;
private final float mBrightnessMax;
private final Handler mHandler;
@@ -214,6 +217,14 @@ class HighBrightnessModeController {
return mHbmMode;
}
+ float getTransitionPoint() {
+ if (deviceSupportsHbm()) {
+ return mHbmData.transitionPoint;
+ } else {
+ return HBM_TRANSITION_POINT_INVALID;
+ }
+ }
+
void stop() {
registerHdrListener(null /*displayToken*/);
mSkinThermalStatusObserver.stopObserving();
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index dd2583a0ce1a..5acff2b6c743 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1816,7 +1816,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public int onAppTransitionStartingLocked(boolean keyguardGoingAway, long duration,
long statusBarAnimationStartTime, long statusBarAnimationDuration) {
- return handleStartTransitionForKeyguardLw(keyguardGoingAway, duration);
+ // When remote animation is enabled for KEYGUARD_GOING_AWAY transition, SysUI
+ // receives IRemoteAnimationRunner#onAnimationStart to start animation, so we don't
+ // need to call IKeyguardService#keyguardGoingAway here.
+ return handleStartTransitionForKeyguardLw(keyguardGoingAway
+ && !WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation, duration);
}
@Override
@@ -3064,7 +3068,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private int handleStartTransitionForKeyguardLw(boolean keyguardGoingAway, long duration) {
final int res = applyKeyguardOcclusionChange();
if (res != 0) return res;
- if (!WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation && keyguardGoingAway) {
+ if (keyguardGoingAway) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation");
startKeyguardExitAnimation(SystemClock.uptimeMillis(), duration);
}
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index d1906785994a..86ff33e8cc42 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -410,8 +410,7 @@ public class KeyguardServiceDelegate {
}
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
- if (!WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation
- && mKeyguardService != null) {
+ if (mKeyguardService != null) {
mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index cc0db1d12e7b..ee72fc8622a5 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -1072,7 +1072,7 @@ class ActivityClientController extends IActivityClientController.Stub {
r.mDisplayContent.mAppTransition.overridePendingAppTransition(
packageName, enterAnim, exitAnim, null, null,
r.mOverrideTaskTransition);
- mService.getTransitionController().setOverrideAnimation(
+ r.mTransitionController.setOverrideAnimation(
TransitionInfo.AnimationOptions.makeCustomAnimOptions(packageName,
enterAnim, exitAnim, r.mOverrideTaskTransition),
null /* startCallback */, null /* finishCallback */);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c1fcf71b38d2..3b1da1d0053d 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1531,7 +1531,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
// TODO(b/169035022): move to a more-appropriate place.
- mAtmService.getTransitionController().collect(this);
+ mTransitionController.collect(this);
if (prevDc.mOpeningApps.remove(this)) {
// Transfer opening transition to new display.
mDisplayContent.mOpeningApps.add(this);
@@ -3096,9 +3096,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mAtmService.deferWindowLayout();
try {
- final Transition newTransition = (!mAtmService.getTransitionController().isCollecting()
- && mAtmService.getTransitionController().getTransitionPlayer() != null)
- ? mAtmService.getTransitionController().createTransition(TRANSIT_CLOSE) : null;
+ final Transition newTransition = (!mTransitionController.isCollecting()
+ && mTransitionController.getTransitionPlayer() != null)
+ ? mTransitionController.createTransition(TRANSIT_CLOSE) : null;
mTaskSupervisor.mNoHistoryActivities.remove(this);
makeFinishingLocked();
// Make a local reference to its task since this.task could be set to null once this
@@ -3131,7 +3131,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final boolean endTask = task.getTopNonFinishingActivity() == null
&& !task.isClearingToReuseTask();
if (newTransition != null) {
- mAtmService.getTransitionController().requestStartTransition(newTransition,
+ mTransitionController.requestStartTransition(newTransition,
endTask ? task : null, null /* remote */);
}
if (isState(RESUMED)) {
@@ -3559,12 +3559,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (stopped) {
abortAndClearOptionsAnimation();
}
- if (mAtmService.getTransitionController().isCollecting()) {
+ if (mTransitionController.isCollecting()) {
// We don't want the finishing to change the transition ready state since there will not
// be corresponding setReady for finishing.
- mAtmService.getTransitionController().collectExistenceChange(this);
+ mTransitionController.collectExistenceChange(this);
} else {
- mAtmService.getTransitionController().requestTransitionIfNeeded(TRANSIT_CLOSE, this);
+ mTransitionController.requestTransitionIfNeeded(TRANSIT_CLOSE, this);
}
}
@@ -3816,7 +3816,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
} else if (getDisplayContent().mAppTransition.isTransitionSet()) {
getDisplayContent().mClosingApps.add(this);
delayed = true;
- } else if (mAtmService.getTransitionController().inTransition()) {
+ } else if (mTransitionController.inTransition()) {
delayed = true;
}
@@ -3828,7 +3828,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
// TODO(b/169035022): move to a more-appropriate place.
- mAtmService.getTransitionController().collect(this);
+ mTransitionController.collect(this);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"Removing app %s delayed=%b animation=%s animating=%b", this, delayed,
@@ -4029,7 +4029,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
ProtoLog.v(WM_DEBUG_ADD_REMOVE,
"Removing starting %s from %s", tStartingWindow, fromActivity);
- mAtmService.getTransitionController().collect(tStartingWindow);
+ mTransitionController.collect(tStartingWindow);
tStartingWindow.reparent(this, POSITION_TOP);
// Propagate other interesting state between the tokens. If the old token is displayed,
@@ -4055,7 +4055,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// the token we transfer the animation over. Thus, set this flag to indicate
// we've transferred the animation.
mUseTransferredAnimation = true;
- } else if (mAtmService.getTransitionController().getTransitionPlayer() != null) {
+ } else if (mTransitionController.getTransitionPlayer() != null) {
// In the new transit system, just set this every time we transfer the window
mUseTransferredAnimation = true;
}
@@ -4552,8 +4552,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
if (options != null) {
- mAtmService.getTransitionController().setOverrideAnimation(options,
- startCallback, finishCallback);
+ mTransitionController.setOverrideAnimation(options, startCallback, finishCallback);
}
}
@@ -4784,7 +4783,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
Debug.getCallers(6));
// Before setting mVisibleRequested so we can track changes.
- mAtmService.getTransitionController().collect(this);
+ mTransitionController.collect(this);
onChildVisibilityRequested(visible);
@@ -4856,7 +4855,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
// If in a transition, defer commits for activities that are going invisible
- if (!visible && mAtmService.getTransitionController().inTransition(this)) {
+ if (!visible && inTransition()) {
return;
}
// If we are preparing an app transition, then delay changing
@@ -4983,8 +4982,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* this has become invisible.
*/
private void postApplyAnimation(boolean visible) {
- final boolean usingShellTransitions =
- mAtmService.getTransitionController().getTransitionPlayer() != null;
+ final boolean usingShellTransitions = mTransitionController.isShellTransitionsEnabled();
final boolean delayed = isAnimating(TRANSITION | PARENTS | CHILDREN,
ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_WINDOW_ANIMATION
| ANIMATION_TYPE_RECENTS);
@@ -5434,7 +5432,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// returns. Just need to confirm this reasoning makes sense.
final boolean deferHidingClient = canEnterPictureInPicture
&& !isState(STARTED, STOPPING, STOPPED, PAUSED);
- if (!mAtmService.getTransitionController().isShellTransitionsEnabled()
+ if (!mTransitionController.isShellTransitionsEnabled()
&& deferHidingClient && pictureInPictureArgs.isAutoEnterEnabled()) {
// Go ahead and just put the activity in pip if it supports auto-pip.
mAtmService.enterPictureInPictureMode(this, pictureInPictureArgs);
@@ -5956,7 +5954,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
void startFreezingScreen(int overrideOriginalDisplayRotation) {
- if (mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ if (mTransitionController.isShellTransitionsEnabled()) {
return;
}
ProtoLog.i(WM_DEBUG_ORIENTATION,
@@ -7602,7 +7600,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
boolean isInTransition() {
- return mAtmService.getTransitionController().inTransition() // Shell transitions.
+ return mTransitionController.inTransition() // Shell transitions.
|| isAnimating(PARENTS | TRANSITION); // Legacy transitions.
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 980ebf0646e8..170789569b3f 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1564,14 +1564,15 @@ class ActivityStarter {
// startActivityInner. Otherwise, logic in startActivityInner could start a different
// transition based on a sub-action.
// Only do the create here (and defer requestStart) since startActivityInner might abort.
- final Transition newTransition = (!mService.getTransitionController().isCollecting()
- && mService.getTransitionController().getTransitionPlayer() != null)
- ? mService.getTransitionController().createTransition(TRANSIT_OPEN) : null;
+ final TransitionController transitionController = r.mTransitionController;
+ final Transition newTransition = (!transitionController.isCollecting()
+ && transitionController.getTransitionPlayer() != null)
+ ? transitionController.createTransition(TRANSIT_OPEN) : null;
RemoteTransition remoteTransition = r.takeRemoteTransition();
if (newTransition != null && remoteTransition != null) {
newTransition.setRemoteTransition(remoteTransition);
}
- mService.getTransitionController().collect(r);
+ transitionController.collect(r);
final boolean isTransient = r.getOptions() != null && r.getOptions().getTransientLaunch();
try {
mService.deferWindowLayout();
@@ -1618,19 +1619,19 @@ class ActivityStarter {
if (started) {
// The activity is started new rather than just brought forward, so record
// it as an existence change.
- mService.getTransitionController().collectExistenceChange(r);
+ transitionController.collectExistenceChange(r);
}
if (isTransient) {
// `r` isn't guaranteed to be the actual relevant activity, so we must wait
// until after we launched to identify the relevant activity.
- mService.getTransitionController().setTransientLaunch(mLastStartActivityRecord);
+ transitionController.setTransientLaunch(mLastStartActivityRecord);
}
if (newTransition != null) {
- mService.getTransitionController().requestStartTransition(newTransition,
+ transitionController.requestStartTransition(newTransition,
mTargetTask, remoteTransition);
} else if (started) {
// Make the collecting transition wait until this request is ready.
- mService.getTransitionController().setReady(r, false);
+ transitionController.setReady(r, false);
}
}
}
@@ -2769,7 +2770,7 @@ class ActivityStarter {
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
- mService.getTransitionController().collectExistenceChange(task);
+ task.mTransitionController.collectExistenceChange(task);
addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s",
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 11936b21bd4e..ba305929d808 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -853,10 +853,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
proc.getThread(), r.appToken);
final boolean isTransitionForward = r.isTransitionForward();
- IBinder fragmentToken = null;
- if (r.getTaskFragment().getTaskFragmentOrganizerPid() == r.getPid()) {
- fragmentToken = r.getTaskFragment().getFragmentToken();
- }
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
@@ -868,7 +864,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
results, newIntents, r.takeOptions(), isTransitionForward,
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
- r.getLaunchedFromBubble(), fragmentToken));
+ r.getLaunchedFromBubble()));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
@@ -1391,7 +1387,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
mUserLeaving = true;
}
- mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_TO_FRONT,
+ task.mTransitionController.requestTransitionIfNeeded(TRANSIT_TO_FRONT,
0 /* flags */, task, task /* readyGroupRef */,
options != null ? options.getRemoteTransition() : null);
reason = reason + " findTaskToMoveToFront";
@@ -1567,17 +1563,17 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
return;
}
if (task.isVisible()) {
- if (mService.getTransitionController().isCollecting()) {
+ if (task.mTransitionController.isCollecting()) {
// We don't want the finishing to change the transition ready state since there will
// not be corresponding setReady for finishing.
- mService.getTransitionController().collectExistenceChange(task);
+ task.mTransitionController.collectExistenceChange(task);
} else {
- mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_CLOSE, task);
+ task.mTransitionController.requestTransitionIfNeeded(TRANSIT_CLOSE, task);
}
} else {
// Removing a non-visible task doesn't require a transition, but if there is one
// collecting, this should be a member just in case.
- mService.getTransitionController().collect(task);
+ task.mTransitionController.collect(task);
}
task.mInRemoveTask = true;
try {
@@ -1891,7 +1887,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
final ActivityRecord s = mStoppingActivities.get(i);
final boolean animating = s.isAnimating(TRANSITION | PARENTS,
ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)
- || mService.getTransitionController().inTransition(s);
+ || s.inTransition();
ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
+ "finishing=%s", s, s.nowVisible, animating, s.finishing);
if (!animating || mService.mShuttingDown) {
@@ -2192,7 +2188,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
if (!task.supportsSplitScreenWindowingMode() || forceNonResizable) {
- if (mService.getTransitionController().getTransitionPlayer() != null) return;
+ if (task.mTransitionController.isShellTransitionsEnabled()) return;
// Dismiss docked root task. If task appeared to be in docked root task but is not
// resizable - we need to move it to top of fullscreen root task, otherwise it will
// be covered.
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 929ac56f740e..e21a00b4aec6 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -1547,7 +1547,7 @@ public class AppTransition implements Dump {
}
boolean prepareAppTransition(@TransitionType int transit, @TransitionFlags int flags) {
- if (mService.mAtmService.getTransitionController().getTransitionPlayer() != null) {
+ if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
return false;
}
mNextAppTransitionRequests.add(transit);
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 9561de09971b..0e04c426ce1e 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -1108,6 +1108,11 @@ public class AppTransitionController {
// the same transition.
for (int i = rootTasks.size() - 1; i >= 0; i--) {
final Task rootTask = rootTasks.valueAt(i);
+ if (rootTask == null) {
+ // It is possible that one activity may have been removed from the hierarchy. No
+ // need to check for this case.
+ continue;
+ }
final boolean notReady = rootTask.forAllLeafTaskFragments(taskFragment -> {
if (!taskFragment.isReadyToTransit()) {
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Organized TaskFragment is not ready= %s",
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f800f0e395de..1db4c1da2023 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1064,7 +1064,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mAppTransition = new AppTransition(mWmService.mContext, mWmService, this);
mAppTransition.registerListenerLocked(mWmService.mActivityManagerAppTransitionNotifier);
- mAtmService.getTransitionController().registerLegacyListener(
+ mTransitionController.registerLegacyListener(
mWmService.mActivityManagerAppTransitionNotifier);
mAppTransition.registerListenerLocked(mFixedRotationTransitionListener);
mAppTransitionController = new AppTransitionController(mWmService, this);
@@ -1395,7 +1395,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (configChanged) {
mWaitingForConfig = true;
- if (mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ if (mTransitionController.isShellTransitionsEnabled()) {
requestChangeTransitionIfNeeded(changes);
} else {
mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */, this);
@@ -1515,7 +1515,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
} else if (currentConfig != null
// If waiting for a remote rotation, don't prematurely update configuration.
&& !(mDisplayRotation.isWaitingForRemoteRotation()
- || mAtmService.getTransitionController().isCollecting(this))) {
+ || mTransitionController.isCollecting(this))) {
// No obvious action we need to take, but if our current state mismatches the
// activity manager's, update it, disregarding font scale, which should remain set
// to the value of the previous configuration.
@@ -1914,8 +1914,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
private void applyRotation(final int oldRotation, final int rotation) {
mDisplayRotation.applyCurrentRotation(rotation);
- final boolean shellTransitions =
- mWmService.mAtmService.getTransitionController().getTransitionPlayer() != null;
+ final boolean shellTransitions = mTransitionController.getTransitionPlayer() != null;
final boolean rotateSeamlessly =
mDisplayRotation.isRotatingSeamlessly() && !shellTransitions;
final Transaction transaction =
@@ -3070,7 +3069,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (isAnimating(TRANSITION | PARENTS)
// isAnimating is a legacy transition query and will be removed, so also add a
// check for whether this is in a shell-transition when not using legacy.
- || mAtmService.getTransitionController().inTransition()) {
+ || mTransitionController.inTransition()) {
mDeferredRemoval = true;
return;
}
@@ -3176,7 +3175,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* be non-zero. This method is no-op if the display has been collected.
*/
void requestChangeTransitionIfNeeded(@ActivityInfo.Config int changes) {
- final TransitionController controller = mAtmService.getTransitionController();
+ final TransitionController controller = mTransitionController;
if (controller.isCollecting()) {
if (!controller.isCollecting(this)) {
controller.collect(this);
@@ -3215,8 +3214,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
screenRotationAnimation.dumpDebug(proto, SCREEN_ROTATION_ANIMATION);
}
mDisplayFrames.dumpDebug(proto, DISPLAY_FRAMES);
- if (mAtmService.getTransitionController().isShellTransitionsEnabled()) {
- mAtmService.getTransitionController().dumpDebugLegacy(proto, APP_TRANSITION);
+ if (mTransitionController.isShellTransitionsEnabled()) {
+ mTransitionController.dumpDebugLegacy(proto, APP_TRANSITION);
} else {
mAppTransition.dumpDebug(proto, APP_TRANSITION);
}
@@ -5109,7 +5108,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
void requestTransitionAndLegacyPrepare(@WindowManager.TransitionType int transit,
@WindowManager.TransitionFlags int flags) {
prepareAppTransition(transit, flags);
- mAtmService.getTransitionController().requestTransitionIfNeeded(transit, flags,
+ mTransitionController.requestTransitionIfNeeded(transit, flags,
null /* trigger */, this);
}
@@ -5117,12 +5116,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
void requestTransitionAndLegacyPrepare(@WindowManager.TransitionType int transit,
@Nullable WindowContainer trigger) {
prepareAppTransition(transit);
- mAtmService.getTransitionController().requestTransitionIfNeeded(transit, 0 /* flags */,
+ mTransitionController.requestTransitionIfNeeded(transit, 0 /* flags */,
trigger, this);
}
void executeAppTransition() {
- mAtmService.getTransitionController().setReady(this);
+ mTransitionController.setReady(this);
if (mAppTransition.isTransitionSet()) {
ProtoLog.w(WM_DEBUG_APP_TRANSITIONS,
"Execute app transition: %s, displayId: %d Callers=%s",
@@ -5171,9 +5170,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
/** Check if pending app transition is for activity / task launch. */
boolean isNextTransitionForward() {
// TODO(b/191375840): decouple "forwardness" from transition system.
- if (mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ if (mTransitionController.isShellTransitionsEnabled()) {
@WindowManager.TransitionType int type =
- mAtmService.getTransitionController().getCollectingTransitionType();
+ mTransitionController.getCollectingTransitionType();
return type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT;
}
return mAppTransition.containsTransitRequest(TRANSIT_OPEN)
@@ -5748,7 +5747,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
mWmService.mDisplayNotificationController.dispatchDisplayChanged(
this, getConfiguration());
- if (isReady() && mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ if (isReady() && mTransitionController.isShellTransitionsEnabled()) {
requestChangeTransitionIfNeeded(changes);
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index aa26d4faf854..ccfb174e3d16 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -641,8 +641,7 @@ public class DisplayPolicy {
}
};
displayContent.mAppTransition.registerListenerLocked(mAppTransitionListener);
- mService.mAtmService.getTransitionController().registerLegacyListener(
- mAppTransitionListener);
+ displayContent.mTransitionController.registerLegacyListener(mAppTransitionListener);
mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext, looper,
mService.mVrModeEnabled);
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 225a6ea20f3d..34e81498b1c3 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -413,7 +413,7 @@ public class DisplayRotation {
*/
boolean updateRotationUnchecked(boolean forceUpdate) {
final boolean useShellTransitions =
- mService.mAtmService.getTransitionController().getTransitionPlayer() != null;
+ mDisplayContent.mTransitionController.isShellTransitionsEnabled();
final int displayId = mDisplayContent.getDisplayId();
if (!forceUpdate && !useShellTransitions) {
@@ -586,17 +586,17 @@ public class DisplayRotation {
mService.mH.removeCallbacks(mDisplayRotationHandlerTimeout);
mIsWaitingForRemoteRotation = false;
- if (mService.mAtmService.getTransitionController().getTransitionPlayer() != null) {
- if (!mService.mAtmService.getTransitionController().isCollecting()) {
+ if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
+ if (!mDisplayContent.mTransitionController.isCollecting()) {
throw new IllegalStateException("Trying to rotate outside a transition");
}
- mService.mAtmService.getTransitionController().collect(mDisplayContent);
+ mDisplayContent.mTransitionController.collect(mDisplayContent);
// Go through all tasks and collect them before the rotation
// TODO(shell-transitions): move collect() to onConfigurationChange once wallpaper
// handling is synchronized.
mDisplayContent.forAllTasks(task -> {
if (task.isVisible()) {
- mService.mAtmService.getTransitionController().collect(task);
+ mDisplayContent.mTransitionController.collect(task);
}
});
mDisplayContent.getInsetsStateController().addProvidersToTransition();
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index 6560d15ca744..cddb1e7edb3b 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -135,7 +135,7 @@ class EnsureActivitiesVisibleHelper {
setActivityVisibilityState(child.asActivityRecord(), starting, resumeTopActivity);
}
}
- if (mTaskFragment.mAtmService.getTransitionController().getTransitionPlayer() != null) {
+ if (mTaskFragment.mTransitionController.isShellTransitionsEnabled()) {
mTaskFragment.getDisplayContent().mWallpaperController.adjustWallpaperWindows();
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 2c4adcbf1404..c4ca8e364011 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -254,7 +254,7 @@ class InsetsStateController {
if (p == null) continue;
final WindowContainer wc = p.mWin;
if (wc == null) continue;
- mDisplayContent.mAtmService.getTransitionController().collect(wc);
+ mDisplayContent.mTransitionController.collect(wc);
}
}
diff --git a/services/core/java/com/android/server/wm/PinnedTaskController.java b/services/core/java/com/android/server/wm/PinnedTaskController.java
index 6014a87ae8f7..b4963c5b9f1c 100644
--- a/services/core/java/com/android/server/wm/PinnedTaskController.java
+++ b/services/core/java/com/android/server/wm/PinnedTaskController.java
@@ -211,7 +211,7 @@ class PinnedTaskController {
}
mFreezingTaskConfig = true;
mDestRotatedBounds = new Rect(bounds);
- if (!mService.mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ if (!mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
continueOrientationChange();
}
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 40207882d73c..97ea41c2f228 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2211,7 +2211,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// display area, so reparent.
rootTask.reparent(taskDisplayArea, true /* onTop */);
}
- mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_PIP, rootTask);
+ rootTask.mTransitionController.requestTransitionIfNeeded(TRANSIT_PIP, rootTask);
// Defer the windowing mode change until after the transition to prevent the activity
// from doing work and changing the activity visuals while animating
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index d89d212bab1f..0819549ad8df 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -4582,7 +4582,7 @@ class Task extends TaskFragment {
// From fullscreen to PiP.
if (topActivity != null && currentMode == WINDOWING_MODE_FULLSCREEN
&& windowingMode == WINDOWING_MODE_PINNED
- && !mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ && !mTransitionController.isShellTransitionsEnabled()) {
mDisplayContent.mPinnedTaskController
.deferOrientationChangeForEnteringPipFromFullScreenIfNeeded();
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 2b5a8203d33b..44b22c643347 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1394,7 +1394,8 @@ class TaskFragment extends WindowContainer<WindowContainer> {
ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSING: %s", prev);
mPausingActivity = prev;
mLastPausedActivity = prev;
- if (prev.isNoHistory() && !mTaskSupervisor.mNoHistoryActivities.contains(prev)) {
+ if (!prev.finishing && prev.isNoHistory()
+ && !mTaskSupervisor.mNoHistoryActivities.contains(prev)) {
mTaskSupervisor.mNoHistoryActivities.add(prev);
}
prev.setState(PAUSING, "startPausingLocked");
@@ -1478,7 +1479,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
} else {
prev.schedulePauseTimeout();
// Unset readiness since we now need to wait until this pause is complete.
- mAtmService.getTransitionController().setReady(this, false /* ready */);
+ mTransitionController.setReady(this, false /* ready */);
return true;
}
@@ -2151,10 +2152,6 @@ class TaskFragment extends WindowContainer<WindowContainer> {
}
}
- int getTaskFragmentOrganizerPid() {
- return mTaskFragmentOrganizerPid;
- }
-
/**
* Returns a {@link TaskFragmentInfo} with information from this TaskFragment. Should not be
* called from {@link Task}.
@@ -2286,7 +2283,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
return false;
}
return isAnimating(TRANSITION | CHILDREN, WindowState.EXIT_ANIMATING_TYPES)
- || mAtmService.getTransitionController().inTransition(this);
+ || inTransition();
}
@Override
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 1909875565f6..e50e8ef56778 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -758,8 +758,13 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
(flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0,
(flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0,
(flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) != 0);
- mController.mAtm.mWindowManager.mPolicy.startKeyguardExitAnimation(
- SystemClock.uptimeMillis(), 0 /* duration */);
+ if (!WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation) {
+ // When remote animation is enabled for KEYGUARD_GOING_AWAY transition, SysUI
+ // receives IRemoteAnimationRunner#onAnimationStart to start animation, so we don't
+ // need to call IKeyguardService#keyguardGoingAway here.
+ mController.mAtm.mWindowManager.mPolicy.startKeyguardExitAnimation(
+ SystemClock.uptimeMillis(), 0 /* duration */);
+ }
}
if ((flags & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0) {
mController.mAtm.mWindowManager.mPolicy.applyKeyguardOcclusionChange();
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 7893612b5725..0909462585af 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -128,7 +128,7 @@ class WallpaperController {
}
mFindResults.resetTopWallpaper = true;
- if (mService.mAtmService.getTransitionController().getTransitionPlayer() == null) {
+ if (!w.mTransitionController.isShellTransitionsEnabled()) {
if (w.mActivityRecord != null && !w.mActivityRecord.isVisible()
&& !w.mActivityRecord.isAnimating(TRANSITION | PARENTS)) {
// If this window's app token is hidden and not animating, it is of no interest.
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index b54e8b7a7b4e..75c84c44c48e 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -112,7 +112,7 @@ class WallpaperWindowToken extends WindowToken {
setVisibility(visible);
}
final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
- if (mWmService.mAtmService.getTransitionController().getTransitionPlayer() != null) {
+ if (mTransitionController.isShellTransitionsEnabled()) {
return;
}
@@ -157,12 +157,12 @@ class WallpaperWindowToken extends WindowToken {
*/
void setVisibility(boolean visible) {
// Before setting mVisibleRequested so we can track changes.
- mWmService.mAtmService.getTransitionController().collect(this);
+ mTransitionController.collect(this);
setVisibleRequested(visible);
// If in a transition, defer commits for activities that are going invisible
- if (!visible && (mWmService.mAtmService.getTransitionController().inTransition()
+ if (!visible && (mTransitionController.inTransition()
|| getDisplayContent().mAppTransition.isRunning())) {
return;
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 38e20555f236..841783d6b8cd 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -197,10 +197,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* Applied as part of the animation pass in "prepareSurfaces".
*/
protected final SurfaceAnimator mSurfaceAnimator;
- private boolean mAnyParentAnimating;
final SurfaceFreezer mSurfaceFreezer;
protected final WindowManagerService mWmService;
+ final TransitionController mTransitionController;
/**
* Sources which triggered a surface animation on this container. An animation target can be
@@ -331,6 +331,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
WindowContainer(WindowManagerService wms) {
mWmService = wms;
+ mTransitionController = mWmService.mAtmService.getTransitionController();
mPendingTransaction = wms.mTransactionFactory.get();
mSyncTransaction = wms.mTransactionFactory.get();
mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, wms);
@@ -1008,7 +1009,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
boolean inTransition() {
- return mWmService.mAtmService.getTransitionController().inTransition(this);
+ return mTransitionController.inTransition(this);
}
void sendAppVisibilityToClients() {
@@ -2310,7 +2311,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
void assignLayer(Transaction t, int layer) {
// Don't assign layers while a transition animation is playing
// TODO(b/173528115): establish robust best-practices around z-order fighting.
- if (mWmService.mAtmService.getTransitionController().isPlaying()) return;
+ if (mTransitionController.isPlaying()) return;
final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null;
if (mSurfaceControl != null && changed) {
setLayer(t, layer);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0e99c0f1bad0..c77cd509ca4f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1804,7 +1804,7 @@ public class WindowManagerService extends IWindowManager.Stub
winAnimator.mEnterAnimationPending = true;
winAnimator.mEnteringAnimation = true;
// Check if we need to prepare a transition for replacing window first.
- if (mAtmService.getTransitionController().getTransitionPlayer() == null
+ if (!win.mTransitionController.isShellTransitionsEnabled()
&& activity != null && activity.isVisible()
&& !prepareWindowReplacementTransition(activity)) {
// If not, check if need to set up a dummy transition during display freeze
@@ -2569,7 +2569,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
- if (mAtmService.getTransitionController().inTransition(win)) {
+ if (win.inTransition()) {
focusMayChange = true;
win.mAnimatingExit = true;
} else if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
@@ -4051,7 +4051,7 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean pendingRemoteRotation = rotationChanged
&& (displayContent.getDisplayRotation().isWaitingForRemoteRotation()
- || mAtmService.getTransitionController().isCollecting());
+ || displayContent.mTransitionController.isCollecting());
// Even if alwaysSend, we are waiting for a transition or remote to provide
// rotated configuration, so we can't update configuration yet.
if (!pendingRemoteRotation) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 3adecf3474eb..5f9d4f5182bc 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1175,8 +1175,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (WindowManager.LayoutParams.isSystemAlertWindowType(mAttrs.type)) {
return TouchOcclusionMode.USE_OPACITY;
}
- if (isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_ALL)
- || mWmService.mAtmService.getTransitionController().inTransition(this)) {
+ if (isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_ALL) || inTransition()) {
return TouchOcclusionMode.USE_OPACITY;
}
return TouchOcclusionMode.BLOCK_UNTRUSTED;
@@ -2326,7 +2325,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
&& (mWindowFrames.mRelFrame.top != mWindowFrames.mLastRelFrame.top
|| mWindowFrames.mRelFrame.left != mWindowFrames.mLastRelFrame.left)
&& (!mIsChildWindow || !getParentWindow().hasMoved())
- && !mWmService.mAtmService.getTransitionController().isCollecting();
+ && !mTransitionController.isCollecting();
}
boolean isObscuringDisplay() {
@@ -2712,8 +2711,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// Don't allow transient-launch activities to take IME.
if (rootTask != null && mActivityRecord != null
- && mWmService.mAtmService.getTransitionController().isTransientLaunch(
- mActivityRecord)) {
+ && mTransitionController.isTransientLaunch(mActivityRecord)) {
return false;
}
@@ -5679,9 +5677,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
boolean needsRelativeLayeringToIme() {
- // We only use the relative layering mode in split screen, as part of elevating the IME
- // and windows above it's target above the docked divider.
- if (!inSplitScreenWindowingMode()) {
+ // We use the relative layering when IME isn't attached to the app. Such as part of
+ // elevating the IME and windows above it's target above the docked divider in
+ // split-screen, or make the popupMenu to be above the IME when the parent window is the
+ // IME layering target in bubble/freeform mode.
+ if (mDisplayContent.isImeAttachedToApp()) {
return false;
}
@@ -6073,7 +6073,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
if (mActivityRecord != null
- && mWmService.mAtmService.getTransitionController().isShellTransitionsEnabled()
+ && mTransitionController.isShellTransitionsEnabled()
&& mAttrs.type == TYPE_APPLICATION_STARTING) {
mWmService.mAtmService.mTaskSupervisor.getActivityMetricsLogger()
.notifyStartingWindowDrawn(mActivityRecord);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 02497a4de250..14970ceb13d2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -10632,19 +10632,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
final String adminPkg = admin.getPackageName();
- try {
- // Install the profile owner if not present.
- if (!mIPackageManager.isPackageAvailable(adminPkg, userId)) {
- mIPackageManager.installExistingPackageAsUser(adminPkg, userId,
- PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
- PackageManager.INSTALL_REASON_POLICY,
- /* allowlistedRestrictedPermissions= */ null);
+ mInjector.binderWithCleanCallingIdentity(() -> {
+ try {
+ // Install the profile owner if not present.
+ if (!mIPackageManager.isPackageAvailable(adminPkg, userId)) {
+ mIPackageManager.installExistingPackageAsUser(adminPkg, userId,
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_POLICY,
+ /* allowlistedRestrictedPermissions= */ null);
+ }
+ } catch (RemoteException e) {
+ // Does not happen, same process
+ Slogf.wtf(LOG_TAG, e, "Failed to install admin package %s for user %d",
+ adminPkg, userId);
}
- } catch (RemoteException e) {
- // Does not happen, same process
- Slogf.wtf(LOG_TAG, e, "Failed to install admin package %s for user %d",
- adminPkg, userId);
- }
+ });
// Set admin.
setActiveAdmin(profileOwner, /* refreshing= */ true, userId);
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index 0dd5c61121db..418831f47c1a 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -26,6 +26,7 @@ import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_R
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE;
import static com.android.server.display.DisplayModeDirector.Vote.INVALID_SIZE;
+import static com.android.server.display.HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID;
import static com.google.common.truth.Truth.assertThat;
@@ -74,6 +75,7 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
@@ -110,6 +112,7 @@ public class DisplayModeDirectorTest {
private static final boolean DEBUG = false;
private static final float FLOAT_TOLERANCE = 0.01f;
private static final int DISPLAY_ID = 0;
+ private static final float TRANSITION_POINT = 0.763f;
private Context mContext;
private FakesInjector mInjector;
@@ -751,19 +754,27 @@ public class DisplayModeDirectorTest {
director.start(sensorManager);
- ArgumentCaptor<SensorEventListener> listenerCaptor =
+ ArgumentCaptor<DisplayListener> displayListenerCaptor =
+ ArgumentCaptor.forClass(DisplayListener.class);
+ verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
+ any(Handler.class),
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
+ | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ DisplayListener displayListener = displayListenerCaptor.getValue();
+
+ ArgumentCaptor<SensorEventListener> sensorListenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
.registerListener(
- listenerCaptor.capture(),
+ sensorListenerCaptor.capture(),
eq(lightSensor),
anyInt(),
any(Handler.class));
- SensorEventListener listener = listenerCaptor.getValue();
+ SensorEventListener sensorListener = sensorListenerCaptor.getValue();
- setBrightness(10);
+ setBrightness(10, 10, displayListener);
// Sensor reads 20 lux,
- listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 20 /*lux*/));
+ sensorListener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 20 /*lux*/));
Vote vote = director.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_FLICKER_REFRESH_RATE);
assertVoteForRefreshRate(vote, 90 /*fps*/);
@@ -771,9 +782,11 @@ public class DisplayModeDirectorTest {
assertThat(vote).isNotNull();
assertThat(vote.disableRefreshRateSwitching).isTrue();
- setBrightness(125);
+ // We expect DisplayModeDirector to act on BrightnessInfo.adjustedBrightness; set only this
+ // parameter to the necessary threshold
+ setBrightness(10, 125, displayListener);
// Sensor reads 1000 lux,
- listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 1000 /*lux*/));
+ sensorListener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 1000 /*lux*/));
vote = director.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_FLICKER_REFRESH_RATE);
assertThat(vote).isNull();
@@ -799,6 +812,14 @@ public class DisplayModeDirectorTest {
director.start(sensorManager);
+ ArgumentCaptor<DisplayListener> displayListenerCaptor =
+ ArgumentCaptor.forClass(DisplayListener.class);
+ verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
+ any(Handler.class),
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
+ | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ DisplayListener displayListener = displayListenerCaptor.getValue();
+
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
@@ -807,20 +828,22 @@ public class DisplayModeDirectorTest {
eq(lightSensor),
anyInt(),
any(Handler.class));
- SensorEventListener listener = listenerCaptor.getValue();
+ SensorEventListener sensorListener = listenerCaptor.getValue();
- setBrightness(100);
+ setBrightness(100, 100, displayListener);
// Sensor reads 2000 lux,
- listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 2000));
+ sensorListener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 2000));
Vote vote = director.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_FLICKER_REFRESH_RATE);
assertThat(vote).isNull();
vote = director.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_FLICKER_REFRESH_RATE_SWITCH);
assertThat(vote).isNull();
- setBrightness(255);
+ // We expect DisplayModeDirector to act on BrightnessInfo.adjustedBrightness; set only this
+ // parameter to the necessary threshold
+ setBrightness(100, 255, displayListener);
// Sensor reads 9000 lux,
- listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 9000));
+ sensorListener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 9000));
vote = director.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_FLICKER_REFRESH_RATE);
assertVoteForRefreshRate(vote, 60 /*fps*/);
@@ -1435,16 +1458,58 @@ public class DisplayModeDirectorTest {
Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertNull(vote);
- // Turn on HBM
+ // Turn on HBM, with brightness in the HBM range
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
- new BrightnessInfo(0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR));
+ new BrightnessInfo(TRANSITION_POINT + FLOAT_TOLERANCE, 0.0f, 1.0f,
+ BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR, TRANSITION_POINT));
listener.onDisplayChanged(DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertVoteForRefreshRate(vote, hbmRefreshRate);
+ // Turn on HBM, with brightness below the HBM range
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(TRANSITION_POINT - FLOAT_TOLERANCE, 0.0f, 1.0f,
+ BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR, TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
// Turn off HBM
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
- new BrightnessInfo(0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
+ new BrightnessInfo(0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn on HBM, with brightness in the HBM range
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(TRANSITION_POINT + FLOAT_TOLERANCE, 0.0f, 1.0f,
+ BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR, TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertVoteForRefreshRate(vote, hbmRefreshRate);
+
+ // Turn off HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn on HBM, with brightness below the HBM range
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(TRANSITION_POINT - FLOAT_TOLERANCE, 0.0f, 1.0f,
+ BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR, TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn off HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ TRANSITION_POINT));
listener.onDisplayChanged(DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertNull(vote);
@@ -1514,7 +1579,8 @@ public class DisplayModeDirectorTest {
// Turn on HBM
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
- new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+ TRANSITION_POINT));
listener.onDisplayChanged(DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertVoteForRefreshRate(vote, initialRefreshRate);
@@ -1531,14 +1597,16 @@ public class DisplayModeDirectorTest {
// Turn off HBM
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
- new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
+ new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ TRANSITION_POINT));
listener.onDisplayChanged(DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertNull(vote);
// Turn HBM on again and ensure the updated vote value stuck
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
- new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+ TRANSITION_POINT));
listener.onDisplayChanged(DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertVoteForRefreshRate(vote, updatedRefreshRate);
@@ -1553,7 +1621,8 @@ public class DisplayModeDirectorTest {
// Turn off HBM
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
- new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
+ new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ TRANSITION_POINT));
listener.onDisplayChanged(DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertNull(vote);
@@ -1584,14 +1653,82 @@ public class DisplayModeDirectorTest {
// Turn on HBM
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
- new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+ TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn off HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+ }
+
+ @Test
+ public void testHbmVoting_HbmUnsupported() {
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0);
+ director.start(createMockSensorManager());
+
+ ArgumentCaptor<DisplayListener> captor =
+ ArgumentCaptor.forClass(DisplayListener.class);
+ verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+ | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ DisplayListener listener = captor.getValue();
+
+ // Specify Limitation
+ when(mDisplayManagerInternalMock.getRefreshRateLimitations(DISPLAY_ID)).thenReturn(
+ List.of(new RefreshRateLimitation(
+ DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
+ 60.0f, 60.0f)));
+
+ // Verify that there is no HBM vote initially
+ Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn on HBM when HBM is supported; expect a valid transition point and a vote.
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+ TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertVoteForRefreshRate(vote, 60.0f);
+
+ // Turn off HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn on Sunlight HBM when HBM is unsupported; expect an invalid transition point and
+ // no vote.
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+ HBM_TRANSITION_POINT_INVALID));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn on HDR HBM when HBM is unsupported; expect an invalid transition point and
+ // no vote.
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR,
+ HBM_TRANSITION_POINT_INVALID));
listener.onDisplayChanged(DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertNull(vote);
// Turn off HBM
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
- new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ TRANSITION_POINT));
listener.onDisplayChanged(DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertNull(vote);
@@ -1600,7 +1737,7 @@ public class DisplayModeDirectorTest {
private void setHbmAndAssertRefreshRate(
DisplayModeDirector director, DisplayListener listener, int mode, float rr) {
when(mInjector.getBrightnessInfo(DISPLAY_ID))
- .thenReturn(new BrightnessInfo(1.0f, 0.0f, 1.0f, mode));
+ .thenReturn(new BrightnessInfo(1.0f, 0.0f, 1.0f, mode, TRANSITION_POINT));
listener.onDisplayChanged(DISPLAY_ID);
final Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
@@ -1679,7 +1816,8 @@ public class DisplayModeDirectorTest {
// Turn on HBM
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
- new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+ TRANSITION_POINT));
listener.onDisplayChanged(DISPLAY_ID);
vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
assertVoteForRefreshRate(vote, 60.f);
@@ -1834,11 +1972,14 @@ public class DisplayModeDirectorTest {
}
}
- private void setBrightness(int brightness) {
- Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS,
- brightness);
- mInjector.notifyBrightnessChanged();
- waitForIdleSync();
+ private void setBrightness(int brightness, int adjustedBrightness, DisplayListener listener) {
+ float floatBri = BrightnessSynchronizer.brightnessIntToFloat(brightness);
+ float floatAdjBri = BrightnessSynchronizer.brightnessIntToFloat(adjustedBrightness);
+
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(floatBri, floatAdjBri, 0.0f, 1.0f,
+ BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF, TRANSITION_POINT));
+ listener.onDisplayChanged(DISPLAY_ID);
}
private void setPeakRefreshRate(float fps) {
@@ -1902,27 +2043,6 @@ public class DisplayModeDirectorTest {
}
@Override
- public void registerBrightnessObserver(@NonNull ContentResolver cr,
- @NonNull ContentObserver observer) {
- if (mBrightnessObserver != null) {
- throw new IllegalStateException("Tried to register a second brightness observer");
- }
- mBrightnessObserver = observer;
- }
-
- @Override
- public void unregisterBrightnessObserver(@NonNull ContentResolver cr,
- @NonNull ContentObserver observer) {
- mBrightnessObserver = null;
- }
-
- void notifyBrightnessChanged() {
- if (mBrightnessObserver != null) {
- mBrightnessObserver.dispatchChange(false /*selfChange*/, DISPLAY_BRIGHTNESS_URI);
- }
- }
-
- @Override
public void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer) {
mPeakRefreshRateObserver = observer;
diff --git a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
index cc3591c89560..aca863299b33 100644
--- a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
@@ -20,6 +20,8 @@ import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR;
import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT;
+import static com.android.server.display.HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.spy;
@@ -124,6 +126,7 @@ public class HighBrightnessModeControllerTest {
mInjectorMock, mHandler, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayToken, DEFAULT_MIN,
DEFAULT_MAX, null, () -> {}, mContextSpy);
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
+ assertEquals(hbmc.getTransitionPoint(), HBM_TRANSITION_POINT_INVALID, 0.0f);
}
@Test
@@ -135,6 +138,7 @@ public class HighBrightnessModeControllerTest {
hbmc.setAutoBrightnessEnabled(true);
hbmc.onAmbientLuxChange(MINIMUM_LUX - 1); // below allowed range
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
+ assertEquals(hbmc.getTransitionPoint(), HBM_TRANSITION_POINT_INVALID, 0.0f);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 5fa76bb2e25b..82140f4d965c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -922,6 +922,40 @@ public class AppTransitionControllerTest extends WindowTestsBase {
verify(mDisplayContent.mAppTransition).goodToGo(anyInt(), any());
}
+ @Test
+ public void testTransitionGoodToGoForTaskFragments_detachedApp() {
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ final Task task = createTask(mDisplayContent);
+ final TaskFragment changeTaskFragment =
+ createTaskFragmentWithEmbeddedActivity(task, organizer);
+ final TaskFragment emptyTaskFragment = new TaskFragmentBuilder(mAtm)
+ .setParentTask(task)
+ .setOrganizer(organizer)
+ .build();
+ changeTaskFragment.getTopMostActivity().allDrawn = true;
+ // To make sure that having a detached activity won't cause any issue.
+ final ActivityRecord detachedActivity = createActivityRecord(task);
+ detachedActivity.removeImmediately();
+ assertNull(detachedActivity.getRootTask());
+ spyOn(mDisplayContent.mAppTransition);
+ spyOn(emptyTaskFragment);
+
+ prepareAndTriggerAppTransition(
+ null /* openingActivity */, detachedActivity, changeTaskFragment);
+
+ // Transition not ready because there is an empty non-finishing TaskFragment.
+ verify(mDisplayContent.mAppTransition, never()).goodToGo(anyInt(), any());
+
+ doReturn(true).when(emptyTaskFragment).hasChild();
+ emptyTaskFragment.remove(false /* withTransition */, "test");
+
+ mDisplayContent.mAppTransitionController.handleAppTransitionReady();
+
+ // Transition ready because the empty (no running activity) TaskFragment is requested to be
+ // removed.
+ verify(mDisplayContent.mAppTransition).goodToGo(anyInt(), any());
+ }
+
/** Registers remote animation for the organizer. */
private void setupTaskFragmentRemoteAnimation(TaskFragmentOrganizer organizer,
RemoteAnimationAdapter adapter) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index b17ea5e48db5..e6ad68aafaec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.view.InsetsState.ITYPE_IME;
@@ -835,8 +836,7 @@ public class WindowStateTests extends WindowTestsBase {
WindowState sameTokenWindow = createWindow(null, TYPE_BASE_APPLICATION, mAppWindow.mToken,
"SameTokenWindow");
mDisplayContent.setImeLayeringTarget(mAppWindow);
- sameTokenWindow.mActivityRecord.getRootTask().setWindowingMode(
- WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ sameTokenWindow.mActivityRecord.getRootTask().setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
assertTrue(sameTokenWindow.needsRelativeLayeringToIme());
sameTokenWindow.removeImmediately();
assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
@@ -848,8 +848,7 @@ public class WindowStateTests extends WindowTestsBase {
WindowState sameTokenWindow = createWindow(null, TYPE_APPLICATION_STARTING,
mAppWindow.mToken, "SameTokenWindow");
mDisplayContent.setImeLayeringTarget(mAppWindow);
- sameTokenWindow.mActivityRecord.getRootTask().setWindowingMode(
- WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ sameTokenWindow.mActivityRecord.getRootTask().setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index d967891fdb76..22ea3d5be71b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
@@ -37,6 +38,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.WindowStateAnimator.PRESERVED_SURFACE_LAYER;
import static com.google.common.truth.Truth.assertThat;
@@ -493,4 +495,27 @@ public class ZOrderingTests extends WindowTestsBase {
assertZOrderGreaterThan(mTransaction, mNavBarWindow.mToken.getSurfaceControl(),
mDisplayContent.getImeContainer().getSurfaceControl());
}
+
+ @Test
+ public void testPopupWindowAndParentIsImeTarget_expectHigherThanIme_inMultiWindow() {
+ // Simulate the app window is in multi windowing mode and being IME target
+ mAppWindow.getConfiguration().windowConfiguration.setWindowingMode(
+ WINDOWING_MODE_MULTI_WINDOW);
+ mDisplayContent.setImeLayeringTarget(mAppWindow);
+ mDisplayContent.setImeInputTarget(mAppWindow);
+
+ // Create a popupWindow
+ assertWindowHigher(mImeWindow, mAppWindow);
+ final WindowState popupWindow = createWindow(mAppWindow, TYPE_APPLICATION_PANEL,
+ mDisplayContent, "PopupWindow");
+ spyOn(popupWindow);
+
+ mDisplayContent.assignChildLayers(mTransaction);
+
+ // Verify the surface layer of the popupWindow should higher than IME
+ verify(popupWindow).needsRelativeLayeringToIme();
+ assertThat(popupWindow.needsRelativeLayeringToIme()).isTrue();
+ assertZOrderGreaterThan(mTransaction, popupWindow.getSurfaceControl(),
+ mDisplayContent.getImeContainer().getSurfaceControl());
+ }
}