summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java49
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl2
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java57
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java128
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl37
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/SearchResults.java142
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java71
-rw-r--r--cmds/statsd/OWNERS10
-rw-r--r--core/api/current.txt10
-rw-r--r--core/api/system-current.txt12
-rw-r--r--core/java/android/app/ActivityThread.java15
-rw-r--r--core/java/android/app/IApplicationThread.aidl4
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java136
-rw-r--r--core/java/android/bluetooth/BluetoothLeAudio.java451
-rw-r--r--core/java/android/bluetooth/BluetoothProfile.java9
-rw-r--r--core/java/android/hardware/hdmi/HdmiDeviceInfo.java15
-rw-r--r--core/java/android/net/CaptivePortal.java16
-rw-r--r--core/java/android/net/ConnectivityManager.java2
-rw-r--r--core/java/android/os/PowerManager.java2
-rw-r--r--core/java/android/service/autofill/TEST_MAPPING7
-rw-r--r--core/java/android/view/autofill/TEST_MAPPING7
-rw-r--r--core/java/android/webkit/WebViewFactory.java15
-rw-r--r--core/java/android/widget/TextView.java3
-rw-r--r--core/res/AndroidManifest.xml10
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java4
-rw-r--r--core/tests/hdmitests/Android.bp1
-rwxr-xr-xcore/tests/hdmitests/src/android/hardware/hdmi/HdmiDeviceInfoTest.java75
-rw-r--r--graphics/java/android/graphics/Typeface.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java42
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairLayout.java63
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java31
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OpenAppToSplitScreenTest.kt6
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateOneLaunchedAppTest.kt95
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateTwoLaunchedAppTest.kt104
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairLayoutTests.java89
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsController.java5
-rw-r--r--media/java/android/media/metrics/IPlaybackMetricsManager.aidl3
-rw-r--r--media/java/android/media/metrics/PlaybackMetricsManager.java19
-rw-r--r--media/java/android/media/metrics/PlaybackSession.java74
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java10
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java14
-rw-r--r--packages/SystemUI/res/layout/global_screenshot.xml14
-rw-r--r--packages/SystemUI/res/layout/global_screenshot_static.xml19
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java)54
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/DiagonalClassifier.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java)8
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java)8
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/DoubleTapClassifier.java)14
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java)6
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/PointerCountClassifier.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java)9
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java)10
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/SingleTapClassifier.java)13
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java)7
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/ZigZagClassifier.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java)8
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/qualifiers/TestHarness.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java153
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java148
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java164
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/DiagonalClassifierTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java)6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java)6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DoubleTapClassifierTest.java)7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/PointerCountClassifierTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java)6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java)6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/SingleTapClassifierTest.java)7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBufferTest.java)4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java)7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java)5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java4
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java9
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java25
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java112
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java18
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java108
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java92
-rw-r--r--services/autofill/java/com/android/server/autofill/TEST_MAPPING15
-rw-r--r--services/core/Android.bp1
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java70
-rw-r--r--services/core/java/com/android/server/TestNetworkService.java45
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java11
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java97
-rw-r--r--services/core/java/com/android/server/graphics/fonts/FontManagerInternal.java27
-rw-r--r--services/core/java/com/android/server/graphics/fonts/FontManagerService.java85
-rw-r--r--services/core/java/com/android/server/hdmi/CecMessageBuffer.java103
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecConfig.java134
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java75
-rw-r--r--services/core/java/com/android/server/media/MediaKeyDispatcher.java3
-rw-r--r--services/core/java/com/android/server/media/MediaServerUtils.java19
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java3
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java30
-rw-r--r--services/core/java/com/android/server/media/SessionPolicyProvider.java3
-rw-r--r--services/core/java/com/android/server/media/metrics/PlaybackMetricsManagerService.java15
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java168
-rw-r--r--services/core/java/com/android/server/pm/PreferredComponent.java31
-rw-r--r--services/core/java/com/android/server/pm/PreferredIntentResolver.java21
-rw-r--r--services/core/java/com/android/server/pm/Settings.java137
-rw-r--r--services/core/java/com/android/server/powerstats/PowerStatsDataStorage.java24
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java14
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java193
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java53
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java68
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java119
-rw-r--r--services/core/java/com/android/server/wm/CompatModePackages.java4
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java48
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java6
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java4
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java6
-rw-r--r--services/core/java/com/android/server/wm/LaunchParamsController.java2
-rw-r--r--services/core/java/com/android/server/wm/LockTaskController.java6
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java6
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimation.java50
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java2
-rw-r--r--services/core/java/com/android/server/wm/ResetTargetTaskHelper.java4
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java288
-rw-r--r--services/core/java/com/android/server/wm/RunningTasks.java2
-rw-r--r--services/core/java/com/android/server/wm/Task.java80
-rw-r--r--services/core/java/com/android/server/wm/TaskChangeNotificationController.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java451
-rw-r--r--services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java4
-rw-r--r--services/core/java/com/android/server/wm/TaskOrganizerController.java6
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java5
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java180
-rw-r--r--services/java/com/android/server/SystemServer.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java33
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java111
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java70
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java15
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java107
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java32
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java24
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java98
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java34
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java32
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java27
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java1
-rw-r--r--telephony/java/android/telephony/ims/ImsCallProfile.java76
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt2
-rw-r--r--tests/RollbackTest/RollbackTest/AndroidManifest.xml2
-rw-r--r--tests/StagedInstallTest/app/AndroidManifest.xml2
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java117
-rw-r--r--tests/net/java/com/android/server/connectivity/VpnTest.java105
-rw-r--r--tools/aapt2/cmd/Link.h5
-rw-r--r--tools/aapt2/link/ManifestFixer.cpp10
-rw-r--r--tools/aapt2/link/ManifestFixer.h4
-rw-r--r--tools/aapt2/link/ManifestFixer_test.cpp60
-rw-r--r--wifi/aidl-export/android/net/wifi/CoexUnsafeChannel.aidl19
-rw-r--r--wifi/api/system-current.txt24
-rw-r--r--wifi/java/android/net/wifi/CoexUnsafeChannel.java176
-rw-r--r--wifi/java/android/net/wifi/ICoexCallback.aidl26
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl12
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java234
-rw-r--r--wifi/tests/src/android/net/wifi/CoexUnsafeChannelTest.java97
-rw-r--r--wifi/tests/src/android/net/wifi/WifiManagerTest.java147
184 files changed, 5197 insertions, 2467 deletions
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
index e57359fbf50e..5fd45eadbda9 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -141,6 +141,25 @@ public class AppSearchManager {
}
/**
+ * Creates a new {@link GlobalSearchSession}.
+ *
+ * <p>This process requires an AppSearch native indexing file system for each user. If it's not
+ * created for this user, the initialization process will create one under user's directory.
+ *
+ * @param executor Executor on which to invoke the callback.
+ * @param callback The {@link AppSearchResult}&lt;{@link GlobalSearchSession}&gt; of
+ * performing this operation. Or a {@link AppSearchResult} with failure
+ * reason code and error information.
+ */
+ public void createGlobalSearchSession(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ GlobalSearchSession.createGlobalSearchSession(mService, executor, callback);
+ }
+
+ /**
* Sets the schema being used by documents provided to the {@link #putDocuments} method.
*
* <p>The schema provided here is compared to the stored copy of the schema previously supplied
@@ -383,22 +402,26 @@ public class AppSearchManager {
@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
// TODO(b/146386470): Transmit the result documents as a RemoteStream instead of sending
// them in one big list.
- AndroidFuture<AppSearchResult> searchResultsFuture = new AndroidFuture<>();
+ AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
try {
- mService.query(DEFAULT_DATABASE_NAME, queryExpression,
- searchSpec.getBundle(), searchResultsFuture);
+ mService.query(DEFAULT_DATABASE_NAME, queryExpression, searchSpec.getBundle(),
+ new IAppSearchResultCallback.Stub() {
+ public void onResult(AppSearchResult result) {
+ future.complete(result);
+ }
+ });
+ AppSearchResult<Bundle> bundleResult = getFutureOrThrow(future);
+ if (!bundleResult.isSuccess()) {
+ return AppSearchResult.newFailedResult(bundleResult.getResultCode(),
+ bundleResult.getErrorMessage());
+ }
+ SearchResultPage searchResultPage = new SearchResultPage(bundleResult.getResultValue());
+ return AppSearchResult.newSuccessfulResult(searchResultPage.getResults());
} catch (RemoteException e) {
- searchResultsFuture.completeExceptionally(e);
- }
-
- // Translate the Bundle into a searchResultPage.
- AppSearchResult<Bundle> bundleResult = getFutureOrThrow(searchResultsFuture);
- if (!bundleResult.isSuccess()) {
- return AppSearchResult.newFailedResult(bundleResult.getResultCode(),
- bundleResult.getErrorMessage());
+ throw e.rethrowFromSystemServer();
+ } catch (Throwable t) {
+ return AppSearchResult.throwableToFailedResult(t);
}
- SearchResultPage searchResultPage = new SearchResultPage(bundleResult.getResultValue());
- return AppSearchResult.newSuccessfulResult(searchResultPage.getResults());
}
/**
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl
index f0b29964b895..37ce990b97c4 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl
@@ -16,4 +16,4 @@
package android.app.appsearch;
/** {@hide} */
-parcelable AppSearchResult; \ No newline at end of file
+parcelable AppSearchResult<ValueType>; \ No newline at end of file
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
index fd4b1060bcd1..9c7ccea4c43b 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -270,6 +270,61 @@ public final class AppSearchSession {
}
/**
+ * Searches a document based on a given query string.
+ *
+ * <p>Currently we support following features in the raw query format:
+ * <ul>
+ * <li>AND
+ * <p>AND joins (e.g. “match documents that have both the terms ‘dog’ and
+ * ‘cat’”).
+ * Example: hello world matches documents that have both ‘hello’ and ‘world’
+ * <li>OR
+ * <p>OR joins (e.g. “match documents that have either the term ‘dog’ or
+ * ‘cat’”).
+ * Example: dog OR puppy
+ * <li>Exclusion
+ * <p>Exclude a term (e.g. “match documents that do
+ * not have the term ‘dog’”).
+ * Example: -dog excludes the term ‘dog’
+ * <li>Grouping terms
+ * <p>Allow for conceptual grouping of subqueries to enable hierarchical structures (e.g.
+ * “match documents that have either ‘dog’ or ‘puppy’, and either ‘cat’ or ‘kitten’”).
+ * Example: (dog puppy) (cat kitten) two one group containing two terms.
+ * <li>Property restricts
+ * <p> Specifies which properties of a document to specifically match terms in (e.g.
+ * “match documents where the ‘subject’ property contains ‘important’”).
+ * Example: subject:important matches documents with the term ‘important’ in the
+ * ‘subject’ property
+ * <li>Schema type restricts
+ * <p>This is similar to property restricts, but allows for restricts on top-level document
+ * fields, such as schema_type. Clients should be able to limit their query to documents of
+ * a certain schema_type (e.g. “match documents that are of the ‘Email’ schema_type”).
+ * Example: { schema_type_filters: “Email”, “Video”,query: “dog” } will match documents
+ * that contain the query term ‘dog’ and are of either the ‘Email’ schema type or the
+ * ‘Video’ schema type.
+ * </ul>
+ *
+ * <p> This method is lightweight. The heavy work will be done in
+ * {@link SearchResults#getNextPage}.
+ *
+ * @param queryExpression Query String to search.
+ * @param searchSpec Spec for setting filters, raw query etc.
+ * @param executor Executor on which to invoke the callback of the following request
+ * {@link SearchResults#getNextPage}.
+ * @return The search result of performing this operation.
+ */
+ @NonNull
+ public SearchResults query(
+ @NonNull String queryExpression,
+ @NonNull SearchSpec searchSpec,
+ @NonNull @CallbackExecutor Executor executor) {
+ Objects.requireNonNull(queryExpression);
+ Objects.requireNonNull(searchSpec);
+ Objects.requireNonNull(executor);
+ return new SearchResults(mService, mDatabaseName, queryExpression, searchSpec, executor);
+ }
+
+ /**
* Removes {@link GenericDocument}s from the index by URI.
*
* @param request Request containing URIs to be removed.
@@ -342,6 +397,4 @@ public final class AppSearchSession {
throw e.rethrowFromSystemServer();
}
}
-
- // TODO(b/162450968) port query() and SearchResults.java to platform.
}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
new file mode 100644
index 000000000000..d2aa8eab4708
--- /dev/null
+++ b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.appsearch;
+
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.os.RemoteException;
+
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * This class provides global access to the centralized AppSearch index maintained by the system.
+ *
+ * <p>Apps can retrieve indexed documents through the query API.
+ * @hide
+ */
+public class GlobalSearchSession {
+
+ private final IAppSearchManager mService;
+
+ static void createGlobalSearchSession(
+ @NonNull IAppSearchManager service,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
+ GlobalSearchSession globalSearchSession = new GlobalSearchSession(service);
+ globalSearchSession.initialize(executor, callback);
+ }
+
+ // NOTE: No instance of this class should be created or returned except via initialize().
+ // Once the callback.accept has been called here, the class is ready to use.
+ private void initialize(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) {
+ try {
+ mService.initialize(new IAppSearchResultCallback.Stub() {
+ public void onResult(AppSearchResult result) {
+ executor.execute(() -> {
+ if (result.isSuccess()) {
+ callback.accept(
+ AppSearchResult.newSuccessfulResult(GlobalSearchSession.this));
+ } else {
+ callback.accept(result);
+ }
+ });
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ private GlobalSearchSession(@NonNull IAppSearchManager service) {
+ mService = service;
+ }
+
+ /**
+ * Searches across all documents in the storage based on a given query string.
+ *
+ * <p>Currently we support following features in the raw query format:
+ * <ul>
+ * <li>AND
+ * <p>AND joins (e.g. “match documents that have both the terms ‘dog’ and
+ * ‘cat’”).
+ * Example: hello world matches documents that have both ‘hello’ and ‘world’
+ * <li>OR
+ * <p>OR joins (e.g. “match documents that have either the term ‘dog’ or
+ * ‘cat’”).
+ * Example: dog OR puppy
+ * <li>Exclusion
+ * <p>Exclude a term (e.g. “match documents that do
+ * not have the term ‘dog’”).
+ * Example: -dog excludes the term ‘dog’
+ * <li>Grouping terms
+ * <p>Allow for conceptual grouping of subqueries to enable hierarchical structures (e.g.
+ * “match documents that have either ‘dog’ or ‘puppy’, and either ‘cat’ or ‘kitten’”).
+ * Example: (dog puppy) (cat kitten) two one group containing two terms.
+ * <li>Property restricts
+ * <p> Specifies which properties of a document to specifically match terms in (e.g.
+ * “match documents where the ‘subject’ property contains ‘important’”).
+ * Example: subject:important matches documents with the term ‘important’ in the
+ * ‘subject’ property
+ * <li>Schema type restricts
+ * <p>This is similar to property restricts, but allows for restricts on top-level document
+ * fields, such as schema_type. Clients should be able to limit their query to documents of
+ * a certain schema_type (e.g. “match documents that are of the ‘Email’ schema_type”).
+ * Example: { schema_type_filters: “Email”, “Video”,query: “dog” } will match documents
+ * that contain the query term ‘dog’ and are of either the ‘Email’ schema type or the
+ * ‘Video’ schema type.
+ * </ul>
+ *
+ * <p> This method is lightweight. The heavy work will be done in
+ * {@link SearchResults#getNextPage}.
+ *
+ * @param queryExpression Query String to search.
+ * @param searchSpec Spec for setting filters, raw query etc.
+ * @param executor Executor on which to invoke the callback of the following request
+ * {@link SearchResults#getNextPage}.
+ * @return The search result of performing this operation.
+ */
+ @NonNull
+ public SearchResults globalQuery(
+ @NonNull String queryExpression,
+ @NonNull SearchSpec searchSpec,
+ @NonNull @CallbackExecutor Executor executor) {
+ Objects.requireNonNull(queryExpression);
+ Objects.requireNonNull(searchSpec);
+ Objects.requireNonNull(executor);
+ return new SearchResults(mService, /*databaseName=*/null, queryExpression,
+ searchSpec, executor);
+ }
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
index 62e60d7f4ab5..22e00f2cdfdc 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -85,13 +85,46 @@ interface IAppSearchManager {
* @param databaseName The databaseName this query for.
* @param queryExpression String to search for
* @param searchSpecBundle SearchSpec bundle
- * @param callback {@link AndroidFuture}&lt;{@link AppSearchResult}&lt;{@link SearchResults}&gt;&gt;
+ * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
+ * operation.
*/
void query(
in String databaseName,
in String queryExpression,
in Bundle searchSpecBundle,
- in AndroidFuture<AppSearchResult> callback);
+ in IAppSearchResultCallback callback);
+
+ /**
+ * Executes a global query, i.e. over all permitted databases, against the AppSearch index and
+ * returns results.
+ *
+ * @param queryExpression String to search for
+ * @param searchSpecBundle SearchSpec bundle
+ * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
+ * operation.
+ */
+ void globalQuery(
+ in String queryExpression,
+ in Bundle searchSpecBundle,
+ in IAppSearchResultCallback callback);
+
+ /**
+ * Fetches the next page of results of a previously executed query. Results can be empty if
+ * next-page token is invalid or all pages have been returned.
+ *
+ * @param nextPageToken The token of pre-loaded results of previously executed query.
+ * @param callback {@link AppSearchResult}&lt;{@link Bundle}&gt; of performing this
+ * operation.
+ */
+ void getNextPage(in long nextPageToken, in IAppSearchResultCallback callback);
+
+ /**
+ * Invalidates the next-page token so that no more results of the related query can be returned.
+ *
+ * @param nextPageToken The token of pre-loaded results of previously executed query to be
+ * Invalidated.
+ */
+ void invalidateNextPageToken(in long nextPageToken);
/**
* Removes documents by URI.
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
index 9f376250f1a6..8548d209c787 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright 2020 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,63 +16,123 @@
package android.app.appsearch;
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
-import java.util.ArrayList;
+import com.android.internal.util.Preconditions;
+
+import java.io.Closeable;
import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
- * Structure for transmitting a page of search results across binder.
+ * SearchResults are a returned object from a query API.
+ *
+ * <p>Each {@link SearchResult} contains a document and may contain other fields like snippets
+ * based on request.
+ *
+ * <p>Should close this object after finish fetching results.
+ *
+ * <p>This class is not thread safe.
* @hide
*/
-public final class SearchResults implements Parcelable {
- final List<SearchResult> mResults;
- final long mNextPageToken;
+public class SearchResults implements Closeable {
+ private static final String TAG = "SearchResults";
+
+ private final IAppSearchManager mService;
+
+ @Nullable
+ private final String mDatabaseName;
+
+ private final String mQueryExpression;
+
+ private final SearchSpec mSearchSpec;
+
+ private final Executor mExecutor;
- public SearchResults(@NonNull List<SearchResult> results, long nextPageToken) {
- mResults = results;
- mNextPageToken = nextPageToken;
+ private long mNextPageToken;
+
+ private boolean mIsFirstLoad = true;
+
+ SearchResults(@NonNull IAppSearchManager service,
+ @Nullable String databaseName,
+ @NonNull String queryExpression,
+ @NonNull SearchSpec searchSpec,
+ @NonNull @CallbackExecutor Executor executor) {
+ mService = Preconditions.checkNotNull(service);
+ mExecutor = Preconditions.checkNotNull(executor);
+ mDatabaseName = databaseName;
+ mQueryExpression = Preconditions.checkNotNull(queryExpression);
+ mSearchSpec = Preconditions.checkNotNull(searchSpec);
}
- private SearchResults(@NonNull Parcel in) {
- List<Bundle> resultBundles = in.readArrayList(/*loader=*/ null);
- mResults = new ArrayList<>(resultBundles.size());
- for (int i = 0; i < resultBundles.size(); i++) {
- SearchResult searchResult = new SearchResult(resultBundles.get(i));
- mResults.add(searchResult);
+ /**
+ * Gets a whole page of {@link SearchResult}s.
+ *
+ * <p>Re-call this method to get next page of {@link SearchResult}, until it returns an
+ * empty list.
+ *
+ * <p>The page size is set by {@link SearchSpec.Builder#setNumPerPage}.
+ *
+ * @param callback Callback to receive the pending result of performing this operation.
+ */
+ public void getNextPage(@NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) {
+ try {
+ if (mIsFirstLoad) {
+ mIsFirstLoad = false;
+ if (mDatabaseName == null) {
+ mService.globalQuery(mQueryExpression, mSearchSpec.getBundle(),
+ wrapCallback(callback));
+ } else {
+ mService.query(mDatabaseName, mQueryExpression, mSearchSpec.getBundle(),
+ wrapCallback(callback));
+ }
+ } else {
+ mService.getNextPage(mNextPageToken, wrapCallback(callback));
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- mNextPageToken = in.readLong();
}
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- List<Bundle> resultBundles = new ArrayList<>(mResults.size());
- for (int i = 0; i < mResults.size(); i++) {
- resultBundles.add(mResults.get(i).getBundle());
+ private void invokeCallback(AppSearchResult result,
+ @NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) {
+ if (result.isSuccess()) {
+ try {
+ SearchResultPage searchResultPage =
+ new SearchResultPage((Bundle) result.getResultValue());
+ mNextPageToken = searchResultPage.getNextPageToken();
+ callback.accept(AppSearchResult.newSuccessfulResult(
+ searchResultPage.getResults()));
+ } catch (Throwable t) {
+ callback.accept(AppSearchResult.throwableToFailedResult(t));
+ }
+ } else {
+ callback.accept(result);
}
- dest.writeList(resultBundles);
- dest.writeLong(mNextPageToken);
}
-
@Override
- public int describeContents() {
- return 0;
+ public void close() {
+ mExecutor.execute(() -> {
+ try {
+ mService.invalidateNextPageToken(mNextPageToken);
+ } catch (RemoteException e) {
+ Log.d(TAG, "Unable to close the SearchResults", e);
+ }
+ });
}
- public static final Creator<SearchResults> CREATOR = new Creator<SearchResults>() {
- @NonNull
- @Override
- public SearchResults createFromParcel(@NonNull Parcel in) {
- return new SearchResults(in);
- }
-
- @NonNull
- @Override
- public SearchResults[] newArray(int size) {
- return new SearchResults[size];
- }
- };
+ private IAppSearchResultCallback wrapCallback(
+ @NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) {
+ return new IAppSearchResultCallback.Stub() {
+ public void onResult(AppSearchResult result) {
+ mExecutor.execute(() -> invokeCallback(result, callback));
+ }
+ };
+ }
}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index c9dd89c3b6d1..d5146dd75c3b 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -36,7 +36,6 @@ import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Log;
-import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
@@ -69,6 +68,7 @@ public class AppSearchManagerService extends SystemService {
@NonNull IAppSearchResultCallback callback) {
Preconditions.checkNotNull(databaseName);
Preconditions.checkNotNull(schemaBundles);
+ Preconditions.checkNotNull(callback);
int callingUid = Binder.getCallingUidOrThrow();
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
@@ -158,13 +158,12 @@ public class AppSearchManagerService extends SystemService {
}
// TODO(sidchhabra): Do this in a threadpool.
- // TODO(b/162450968) handle pagination after getNextPage and SearchResults is ready.
@Override
public void query(
@NonNull String databaseName,
@NonNull String queryExpression,
@NonNull Bundle searchSpecBundle,
- @NonNull AndroidFuture<AppSearchResult> callback) {
+ @NonNull IAppSearchResultCallback callback) {
Preconditions.checkNotNull(databaseName);
Preconditions.checkNotNull(queryExpression);
Preconditions.checkNotNull(searchSpecBundle);
@@ -179,10 +178,70 @@ public class AppSearchManagerService extends SystemService {
databaseName,
queryExpression,
new SearchSpec(searchSpecBundle));
- callback.complete(
+ invokeCallbackOnResult(callback,
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
} catch (Throwable t) {
- callback.complete(throwableToFailedResult(t));
+ invokeCallbackOnError(callback, t);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+
+ public void globalQuery(
+ @NonNull String queryExpression,
+ @NonNull Bundle searchSpecBundle,
+ @NonNull IAppSearchResultCallback callback) {
+ Preconditions.checkNotNull(queryExpression);
+ Preconditions.checkNotNull(searchSpecBundle);
+ Preconditions.checkNotNull(callback);
+ int callingUid = Binder.getCallingUidOrThrow();
+ int callingUserId = UserHandle.getUserId(callingUid);
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
+ SearchResultPage searchResultPage = impl.globalQuery(
+ queryExpression,
+ new SearchSpec(searchSpecBundle));
+ invokeCallbackOnResult(callback,
+ AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
+ } catch (Throwable t) {
+ invokeCallbackOnError(callback, t);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+
+ @Override
+ public void getNextPage(long nextPageToken,
+ @NonNull IAppSearchResultCallback callback) {
+ Preconditions.checkNotNull(callback);
+ int callingUid = Binder.getCallingUidOrThrow();
+ int callingUserId = UserHandle.getUserId(callingUid);
+ final long callingIdentity = Binder.clearCallingIdentity();
+ // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
+ // opened it
+ try {
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
+ SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
+ invokeCallbackOnResult(callback,
+ AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
+ } catch (Throwable t) {
+ invokeCallbackOnError(callback, t);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+
+ @Override
+ public void invalidateNextPageToken(long nextPageToken) {
+ int callingUid = Binder.getCallingUidOrThrow();
+ int callingUserId = UserHandle.getUserId(callingUid);
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
+ impl.invalidateNextPageToken(nextPageToken);
+ } catch (Throwable t) {
+ Log.d(TAG, "Unable to invalidate the query page token", t);
} finally {
Binder.restoreCallingIdentity(callingIdentity);
}
@@ -229,6 +288,7 @@ public class AppSearchManagerService extends SystemService {
Preconditions.checkNotNull(databaseName);
Preconditions.checkNotNull(queryExpression);
Preconditions.checkNotNull(searchSpecBundle);
+ Preconditions.checkNotNull(callback);
int callingUid = Binder.getCallingUidOrThrow();
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
@@ -247,6 +307,7 @@ public class AppSearchManagerService extends SystemService {
@Override
public void initialize(@NonNull IAppSearchResultCallback callback) {
+ Preconditions.checkNotNull(callback);
int callingUid = Binder.getCallingUidOrThrow();
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
diff --git a/cmds/statsd/OWNERS b/cmds/statsd/OWNERS
index a61babf32e58..4e4e11988b62 100644
--- a/cmds/statsd/OWNERS
+++ b/cmds/statsd/OWNERS
@@ -1,9 +1 @@
-jeffreyhuang@google.com
-joeo@google.com
-jtnguyen@google.com
-muhammadq@google.com
-ruchirr@google.com
-singhtejinder@google.com
-tsaichristine@google.com
-yaochen@google.com
-yro@google.com
+baligh@google.com
diff --git a/core/api/current.txt b/core/api/current.txt
index 49ebc385c965..b61bc2fde0e9 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9098,6 +9098,15 @@ package android.bluetooth {
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHidDeviceAppSdpSettings> CREATOR;
}
+ public final class BluetoothLeAudio implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void close();
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) protected void finalize();
+ method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
+ method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
+ field public static final String ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED = "android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED";
+ }
+
public final class BluetoothManager {
method public android.bluetooth.BluetoothAdapter getAdapter();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(int);
@@ -45403,6 +45412,7 @@ package android.telephony {
}
public static final class CarrierConfigManager.Ims {
+ field public static final String KEY_ENABLE_PRESENCE_PUBLISH_BOOL = "ims.enable_presence_publish_bool";
field public static final String KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL = "ims.ims_single_registration_required_bool";
field public static final String KEY_PREFIX = "ims.";
field public static final String KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT = "ims.wifi_off_deferring_time_millis_int";
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 8ba5a94179ea..a5f2b6ac3af8 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -248,7 +248,9 @@ package android {
field public static final String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK";
field public static final String WHITELIST_AUTO_REVOKE_PERMISSIONS = "android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS";
field public static final String WHITELIST_RESTRICTED_PERMISSIONS = "android.permission.WHITELIST_RESTRICTED_PERMISSIONS";
+ field public static final String WIFI_ACCESS_COEX_UNSAFE_CHANNELS = "android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS";
field public static final String WIFI_SET_DEVICE_MOBILITY_STATE = "android.permission.WIFI_SET_DEVICE_MOBILITY_STATE";
+ field public static final String WIFI_UPDATE_COEX_UNSAFE_CHANNELS = "android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS";
field public static final String WIFI_UPDATE_USABILITY_STATS_SCORE = "android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE";
field public static final String WRITE_DEVICE_CONFIG = "android.permission.WRITE_DEVICE_CONFIG";
field public static final String WRITE_DREAM_STATE = "android.permission.WRITE_DREAM_STATE";
@@ -6504,6 +6506,7 @@ package android.net {
field @Deprecated public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
field @Deprecated public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
field public static final int TYPE_NONE = -1; // 0xffffffff
+ field @Deprecated public static final int TYPE_PROXY = 16; // 0x10
field @Deprecated public static final int TYPE_WIFI_P2P = 13; // 0xd
}
@@ -10829,6 +10832,7 @@ package android.telephony {
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean isIccLockEnabled();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMobileDataPolicyEnabled(int);
method public boolean isNrDualConnectivityEnabled();
@@ -11525,6 +11529,7 @@ package android.telephony.ims {
method public boolean getCallExtraBoolean(String, boolean);
method public int getCallExtraInt(String);
method public int getCallExtraInt(String, int);
+ method @Nullable public <T extends android.os.Parcelable> T getCallExtraParcelable(@Nullable String);
method public android.os.Bundle getCallExtras();
method public int getCallType();
method public static int getCallTypeFromVideoState(int);
@@ -11547,6 +11552,7 @@ package android.telephony.ims {
method public void setCallExtra(String, String);
method public void setCallExtraBoolean(String, boolean);
method public void setCallExtraInt(String, int);
+ method public void setCallExtraParcelable(@NonNull String, @NonNull android.os.Parcelable);
method public void setCallRestrictCause(int);
method public void setCallerNumberVerificationStatus(int);
method public void setEmergencyCallRouting(int);
@@ -11581,6 +11587,7 @@ package android.telephony.ims {
field public static final String EXTRA_CALL_DISCONNECT_CAUSE = "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE";
field public static final String EXTRA_CALL_NETWORK_TYPE = "android.telephony.ims.extra.CALL_NETWORK_TYPE";
field @Deprecated public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
+ field public static final String EXTRA_CALL_SUBJECT = "android.telephony.ims.extra.CALL_SUBJECT";
field public static final String EXTRA_CHILD_NUMBER = "ChildNum";
field public static final String EXTRA_CNA = "cna";
field public static final String EXTRA_CNAP = "cnap";
@@ -11590,8 +11597,11 @@ package android.telephony.ims {
field public static final String EXTRA_EMERGENCY_CALL = "e_call";
field public static final String EXTRA_FORWARDED_NUMBER = "android.telephony.ims.extra.FORWARDED_NUMBER";
field public static final String EXTRA_IS_CALL_PULL = "CallPull";
+ field public static final String EXTRA_LOCATION = "android.telephony.ims.extra.LOCATION";
field public static final String EXTRA_OI = "oi";
field public static final String EXTRA_OIR = "oir";
+ field public static final String EXTRA_PICTURE_URL = "android.telephony.ims.extra.PICTURE_URL";
+ field public static final String EXTRA_PRIORITY = "android.telephony.ims.extra.PRIORITY";
field public static final String EXTRA_REMOTE_URI = "remote_uri";
field public static final String EXTRA_USSD = "ussd";
field public static final int OIR_DEFAULT = 0; // 0x0
@@ -11599,6 +11609,8 @@ package android.telephony.ims {
field public static final int OIR_PRESENTATION_PAYPHONE = 4; // 0x4
field public static final int OIR_PRESENTATION_RESTRICTED = 1; // 0x1
field public static final int OIR_PRESENTATION_UNKNOWN = 3; // 0x3
+ field public static final int PRIORITY_NORMAL = 0; // 0x0
+ field public static final int PRIORITY_URGENT = 1; // 0x1
field public static final int SERVICE_TYPE_EMERGENCY = 2; // 0x2
field public static final int SERVICE_TYPE_NONE = 0; // 0x0
field public static final int SERVICE_TYPE_NORMAL = 1; // 0x1
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 2211807a422b..d9c0c71d44ae 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -85,6 +85,7 @@ import android.database.sqlite.SQLiteDebug.DbStats;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.HardwareRenderer;
+import android.graphics.Typeface;
import android.hardware.display.DisplayManagerGlobal;
import android.inputmethodservice.InputMethodService;
import android.media.MediaFrameworkInitializer;
@@ -117,6 +118,7 @@ import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SharedMemory;
import android.os.StatsFrameworkInitializer;
import android.os.StatsServiceManager;
import android.os.StrictMode;
@@ -844,6 +846,8 @@ public final class ActivityThread extends ClientTransactionHandler {
long[] disabledCompatChanges;
+ SharedMemory mSerializedSystemFontMap;
+
@Override
public String toString() {
return "AppBindData{appInfo=" + appInfo + "}";
@@ -1054,7 +1058,8 @@ public final class ActivityThread extends ClientTransactionHandler {
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions,
- ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
+ ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges,
+ SharedMemory serializedSystemFontMap) {
if (services != null) {
if (false) {
// Test code to make sure the app could see the passed-in services.
@@ -1103,6 +1108,7 @@ public final class ActivityThread extends ClientTransactionHandler {
data.autofillOptions = autofillOptions;
data.contentCaptureOptions = contentCaptureOptions;
data.disabledCompatChanges = disabledCompatChanges;
+ data.mSerializedSystemFontMap = serializedSystemFontMap;
sendMessage(H.BIND_APPLICATION, data);
}
@@ -6411,6 +6417,13 @@ public final class ActivityThread extends ClientTransactionHandler {
*/
LocaleList.setDefault(data.config.getLocales());
+ try {
+ Typeface.setSystemFontMap(data.mSerializedSystemFontMap);
+ } catch (IOException | ErrnoException e) {
+ Slog.e(TAG, "Failed to parse serialized system font map");
+ Typeface.loadPreinstalledSystemFontMap();
+ }
+
synchronized (mResourcesManager) {
/*
* Update the system configuration since its preloaded and might not
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 22ca42eb9cf4..890e957bdff4 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -43,6 +43,7 @@ import android.os.IInterface;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
+import android.os.SharedMemory;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
@@ -75,7 +76,8 @@ oneway interface IApplicationThread {
boolean restrictedBackupMode, boolean persistent, in Configuration config,
in CompatibilityInfo compatInfo, in Map services,
in Bundle coreSettings, in String buildSerial, in AutofillOptions autofillOptions,
- in ContentCaptureOptions contentCaptureOptions, in long[] disabledCompatChanges);
+ in ContentCaptureOptions contentCaptureOptions, in long[] disabledCompatChanges,
+ in SharedMemory serializedSystemFontMap);
void runIsolatedEntryPoint(in String entryPoint, in String[] entryPointArgs);
void scheduleExit();
void scheduleServiceArgs(IBinder token, in ParceledListSlice args);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 8e305e0b9784..5eb1922a163c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -5240,9 +5240,22 @@ public class DevicePolicyManager {
}
/**
- * Called by a device or profile owner, or delegated certificate installer, to install a
- * certificate and corresponding private key. All apps within the profile will be able to access
- * the certificate and use the private key, given direct user approval.
+ * This API can be called by the following to install a certificate and corresponding
+ * private key:
+ * <ul>
+ * <li>Device owner</li>
+ * <li>Profile owner</li>
+ * <li>Delegated certificate installer</li>
+ * <li>Credential management app</li>
+ * </ul>
+ * All apps within the profile will be able to access the certificate and use the private key,
+ * given direct user approval.
+ *
+ * <p>From Android {@link android.os.Build.VERSION_CODES#S}, the credential management app
+ * can call this API. However, this API sets the key pair as user selectable by default,
+ * which is not permitted when called by the credential management app. Instead,
+ * {@link #installKeyPair(ComponentName, PrivateKey, Certificate[], String, int)} should be
+ * called with {@link #INSTALLKEY_SET_USER_SELECTABLE} not set as a flag.
*
* <p>Access to the installed credentials will not be granted to the caller of this API without
* direct user approval. This is for security - should a certificate installer become
@@ -5273,10 +5286,23 @@ public class DevicePolicyManager {
}
/**
- * Called by a device or profile owner, or delegated certificate installer, to install a
- * certificate chain and corresponding private key for the leaf certificate. All apps within the
- * profile will be able to access the certificate chain and use the private key, given direct
- * user approval.
+ * This API can be called by the following to install a certificate chain and corresponding
+ * private key for the leaf certificate:
+ * <ul>
+ * <li>Device owner</li>
+ * <li>Profile owner</li>
+ * <li>Delegated certificate installer</li>
+ * <li>Credential management app</li>
+ * </ul>
+ * All apps within the profile will be able to access the certificate chain and use the private
+ * key, given direct user approval.
+ *
+ * <p>From Android {@link android.os.Build.VERSION_CODES#S}, the credential management app
+ * can call this API. However, this API sets the key pair as user selectable by default,
+ * which is not permitted when called by the credential management app. Instead,
+ * {@link #installKeyPair(ComponentName, PrivateKey, Certificate[], String, int)} should be
+ * called with {@link #INSTALLKEY_SET_USER_SELECTABLE} not set as a flag.
+ * Note, there can only be a credential management app on an unmanaged device.
*
* <p>The caller of this API may grant itself access to the certificate and private key
* immediately, without user approval. It is a best practice not to request this unless strictly
@@ -5314,10 +5340,26 @@ public class DevicePolicyManager {
}
/**
- * Called by a device or profile owner, or delegated certificate installer, to install a
- * certificate chain and corresponding private key for the leaf certificate. All apps within the
- * profile will be able to access the certificate chain and use the private key, given direct
- * user approval (if the user is allowed to select the private key).
+ * This API can be called by the following to install a certificate chain and corresponding
+ * private key for the leaf certificate:
+ * <ul>
+ * <li>Device owner</li>
+ * <li>Profile owner</li>
+ * <li>Delegated certificate installer</li>
+ * <li>Credential management app</li>
+ * </ul>
+ * All apps within the profile will be able to access the certificate chain and use the
+ * private key, given direct user approval (if the user is allowed to select the private key).
+ *
+ * <p>From Android {@link android.os.Build.VERSION_CODES#S}, the credential management app
+ * can call this API. If called by the credential management app:
+ * <ul>
+ * <li>The componentName must be {@code null}r</li>
+ * <li>The alias must exist in the credential management app's
+ * {@link android.security.AppUriAuthenticationPolicy}</li>
+ * <li>The key pair must not be user selectable</li>
+ * </ul>
+ * Note, there can only be a credential management app on an unmanaged device.
*
* <p>The caller of this API may grant itself access to the certificate and private key
* immediately, without user approval. It is a best practice not to request this unless strictly
@@ -5343,7 +5385,8 @@ public class DevicePolicyManager {
* {@link #INSTALLKEY_REQUEST_CREDENTIALS_ACCESS}.
* @return {@code true} if the keys were installed, {@code false} otherwise.
* @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
- * owner.
+ * owner, or {@code admin} is null but the calling application is not a delegated
+ * certificate installer or credential management app.
* @see android.security.KeyChain#getCertificateChain
* @see #setDelegatedScopes
* @see #DELEGATION_CERT_INSTALL
@@ -5376,15 +5419,26 @@ public class DevicePolicyManager {
}
/**
- * Called by a device or profile owner, or delegated certificate installer, to remove a
- * certificate and private key pair installed under a given alias.
+ * This API can be called by the following to remove a certificate and private key pair
+ * installed under a given alias:
+ * <ul>
+ * <li>Device owner</li>
+ * <li>Profile owner</li>
+ * <li>Delegated certificate installer</li>
+ * <li>Credential management app</li>
+ * </ul>
+ *
+ * <p>From Android {@link android.os.Build.VERSION_CODES#S}, the credential management app
+ * can call this API. If called by the credential management app, the componentName must be
+ * {@code null}. Note, there can only be a credential management app on an unmanaged device.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
* {@code null} if calling from a delegated certificate installer.
* @param alias The private key alias under which the certificate is installed.
* @return {@code true} if the private key alias no longer exists, {@code false} otherwise.
* @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
- * owner.
+ * owner, or {@code admin} is null but the calling application is not a delegated
+ * certificate installer or credential management app.
* @see #setDelegatedScopes
* @see #DELEGATION_CERT_INSTALL
*/
@@ -5419,10 +5473,20 @@ public class DevicePolicyManager {
}
/**
- * Called by a device or profile owner, or delegated certificate installer, to generate a
- * new private/public key pair. If the device supports key generation via secure hardware,
- * this method is useful for creating a key in KeyChain that never left the secure hardware.
- * Access to the key is controlled the same way as in {@link #installKeyPair}.
+ * This API can be called by the following to generate a new private/public key pair:
+ * <ul>
+ * <li>Device owner</li>
+ * <li>Profile owner</li>
+ * <li>Delegated certificate installer</li>
+ * <li>Credential management app</li>
+ * </ul>
+ * If the device supports key generation via secure hardware, this method is useful for
+ * creating a key in KeyChain that never left the secure hardware. Access to the key is
+ * controlled the same way as in {@link #installKeyPair}.
+ *
+ * <p>From Android {@link android.os.Build.VERSION_CODES#S}, the credential management app
+ * can call this API. If called by the credential management app, the componentName must be
+ * {@code null}. Note, there can only be a credential management app on an unmanaged device.
*
* <p>Because this method might take several seconds to complete, it should only be called from
* a worker thread. This method returns {@code null} when called from the main thread.
@@ -5445,9 +5509,10 @@ public class DevicePolicyManager {
* supports these features, refer to {@link #isDeviceIdAttestationSupported()} and
* {@link #isUniqueDeviceAttestationSupported()}.
*
- * <p>Device owner, profile owner and their delegated certificate installer can use
- * {@link #ID_TYPE_BASE_INFO} to request inclusion of the general device information
- * including manufacturer, model, brand, device and product in the attestation record.
+ * <p>Device owner, profile owner, their delegated certificate installer and the credential
+ * management app can use {@link #ID_TYPE_BASE_INFO} to request inclusion of the general device
+ * information including manufacturer, model, brand, device and product in the attestation
+ * record.
* Only device owner, profile owner on an organization-owned device and their delegated
* certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and
* {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial number,
@@ -5482,9 +5547,11 @@ public class DevicePolicyManager {
* {@code keySpec}.
* @return A non-null {@code AttestedKeyPair} if the key generation succeeded, null otherwise.
* @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
- * owner. If Device ID attestation is requested (using {@link #ID_TYPE_SERIAL},
- * {@link #ID_TYPE_IMEI} or {@link #ID_TYPE_MEID}), the caller must be the Device Owner
- * or the Certificate Installer delegate.
+ * owner, or {@code admin} is null but the calling application is not a delegated
+ * certificate installer or credential management app. If Device ID attestation is
+ * requested (using {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} or
+ * {@link #ID_TYPE_MEID}), the caller must be the Device Owner or the Certificate
+ * Installer delegate.
* @throws IllegalArgumentException in the following cases:
* <p>
* <ul>
@@ -5647,10 +5714,19 @@ public class DevicePolicyManager {
}
/**
- * Called by a device or profile owner, or delegated certificate installer, to associate
- * certificates with a key pair that was generated using {@link #generateKeyPair}, and
- * set whether the key is available for the user to choose in the certificate selection
- * prompt.
+ * This API can be called by the following to associate certificates with a key pair that was
+ * generated using {@link #generateKeyPair}, and set whether the key is available for the user
+ * to choose in the certificate selection prompt:
+ * <ul>
+ * <li>Device owner</li>
+ * <li>Profile owner</li>
+ * <li>Delegated certificate installer</li>
+ * <li>Credential management app</li>
+ * </ul>
+ *
+ * <p>From Android {@link android.os.Build.VERSION_CODES#S}, the credential management app
+ * can call this API. If called by the credential management app, the componentName must be
+ * {@code null}. Note, there can only be a credential management app on an unmanaged device.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
* {@code null} if calling from a delegated certificate installer.
@@ -5668,7 +5744,7 @@ public class DevicePolicyManager {
* successfully associated with it, {@code false} otherwise.
* @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
* owner, or {@code admin} is null but the calling application is not a delegated
- * certificate installer.
+ * certificate installer or credential management app.
*/
public boolean setKeyPairCertificate(@Nullable ComponentName admin,
@NonNull String alias, @NonNull List<Certificate> certs, boolean isUserSelectable) {
diff --git a/core/java/android/bluetooth/BluetoothLeAudio.java b/core/java/android/bluetooth/BluetoothLeAudio.java
new file mode 100644
index 000000000000..3f00fa6f4181
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothLeAudio.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2020 HIMSA II K/S - www.himsa.com.
+ * Represented by EHIMA - www.ehima.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.CloseGuard;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides the public APIs to control the LeAudio profile.
+ *
+ * <p>BluetoothLeAudio is a proxy object for controlling the Bluetooth LE Audio
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothLeAudio proxy object.
+ *
+ * <p> Android only supports one set of connected Bluetooth LeAudio device at a time. Each
+ * method is protected with its appropriate permission.
+ */
+public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
+ private static final String TAG = "BluetoothLeAudio";
+ private static final boolean DBG = false;
+ private static final boolean VDBG = false;
+
+ private CloseGuard mCloseGuard;
+
+ /**
+ * Intent used to broadcast the change in connection state of the LeAudio
+ * profile. Please note that in the binaural case, there will be two different LE devices for
+ * the left and right side and each device will have their own connection state changes.
+ *
+ * <p>This intent will have 3 extras:
+ * <ul>
+ * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+ * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ *
+ * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+ * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED =
+ "android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED";
+
+ /**
+ * Intent used to broadcast the selection of a connected device as active.
+ *
+ * <p>This intent will have one extra:
+ * <ul>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
+ * be null if no device is active. </li>
+ * </ul>
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED =
+ "android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED";
+
+ /**
+ * This represents an invalid group ID.
+ *
+ * @hide
+ */
+ public static final int GROUP_ID_INVALID = IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;
+
+ private BluetoothAdapter mAdapter;
+ private final BluetoothProfileConnector<IBluetoothLeAudio> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.LE_AUDIO, "BluetoothLeAudio",
+ IBluetoothLeAudio.class.getName()) {
+ @Override
+ public IBluetoothLeAudio getServiceInterface(IBinder service) {
+ return IBluetoothLeAudio.Stub.asInterface(Binder.allowBlocking(service));
+ }
+ };
+
+ /**
+ * Create a BluetoothLeAudio proxy object for interacting with the local
+ * Bluetooth LeAudio service.
+ */
+ /*package*/ BluetoothLeAudio(Context context, ServiceListener listener) {
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+ mProfileConnector.connect(context, listener);
+ mCloseGuard = new CloseGuard();
+ mCloseGuard.open("close");
+ }
+
+ /**
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public void close() {
+ mProfileConnector.disconnect();
+ }
+
+ private IBluetoothLeAudio getService() {
+ return mProfileConnector.getService();
+ }
+
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ protected void finalize() {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
+ close();
+ }
+
+ /**
+ * Initiate connection to a profile of the remote bluetooth device.
+ *
+ * <p> This API returns false in scenarios like the profile on the
+ * device is already connected or Bluetooth is not turned on.
+ * When this API returns true, it is guaranteed that
+ * connection state intent for the profile will be broadcasted with
+ * the state. Users can get the connection state of the profile
+ * from this intent.
+ *
+ *
+ * @param device Remote Bluetooth Device
+ * @return false on immediate error, true otherwise
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public boolean connect(@Nullable BluetoothDevice device) {
+ if (DBG) log("connect(" + device + ")");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled() && isValidDevice(device)) {
+ return service.connect(device);
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
+ }
+
+ /**
+ * Initiate disconnection from a profile
+ *
+ * <p> This API will return false in scenarios like the profile on the
+ * Bluetooth device is not in connected state etc. When this API returns,
+ * true, it is guaranteed that the connection state change
+ * intent will be broadcasted with the state. Users can get the
+ * disconnection state of the profile from this intent.
+ *
+ * <p> If the disconnection is initiated by a remote device, the state
+ * will transition from {@link #STATE_CONNECTED} to
+ * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
+ * host (local) device the state will transition from
+ * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
+ * state {@link #STATE_DISCONNECTED}. The transition to
+ * {@link #STATE_DISCONNECTING} can be used to distinguish between the
+ * two scenarios.
+ *
+ *
+ * @param device Remote Bluetooth Device
+ * @return false on immediate error, true otherwise
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public boolean disconnect(@Nullable BluetoothDevice device) {
+ if (DBG) log("disconnect(" + device + ")");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled() && isValidDevice(device)) {
+ return service.disconnect(device);
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public @NonNull List<BluetoothDevice> getConnectedDevices() {
+ if (VDBG) log("getConnectedDevices()");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled()) {
+ return service.getConnectedDevices();
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
+ @NonNull int[] states) {
+ if (VDBG) log("getDevicesMatchingStates()");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled()) {
+ return service.getDevicesMatchingConnectionStates(states);
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public @BtProfileState int getConnectionState(@NonNull BluetoothDevice device) {
+ if (VDBG) log("getState(" + device + ")");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled()
+ && isValidDevice(device)) {
+ return service.getConnectionState(device);
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.STATE_DISCONNECTED;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+ }
+
+ /**
+ * Select a connected device as active.
+ *
+ * The active device selection is per profile. An active device's
+ * purpose is profile-specific. For example, LeAudio audio
+ * streaming is to the active LeAudio device. If a remote device
+ * is not connected, it cannot be selected as active.
+ *
+ * <p> This API returns false in scenarios like the profile on the
+ * device is not connected or Bluetooth is not turned on.
+ * When this API returns true, it is guaranteed that the
+ * {@link #ACTION_LEAUDIO_ACTIVE_DEVICE_CHANGED} intent will be broadcasted
+ * with the active device.
+ *
+ *
+ * @param device the remote Bluetooth device. Could be null to clear
+ * the active device and stop streaming audio to a Bluetooth device.
+ * @return false on immediate error, true otherwise
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public boolean setActiveDevice(@Nullable BluetoothDevice device) {
+ if (DBG) log("setActiveDevice(" + device + ")");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled()
+ && ((device == null) || isValidDevice(device))) {
+ service.setActiveDevice(device);
+ return true;
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
+ }
+
+ /**
+ * Get the connected LeAudio devices that are active
+ *
+ * @return the list of active devices. Returns empty list on error.
+ * @hide
+ */
+ @NonNull
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public List<BluetoothDevice> getActiveDevices() {
+ if (VDBG) log("getActiveDevices()");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled()) {
+ return service.getActiveDevices();
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<>();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<>();
+ }
+ }
+
+ /**
+ * Get device group id. Devices with same group id belong to same group (i.e left and right
+ * earbud)
+ * @param device LE Audio capable device
+ * @return group id that this device currently belongs to
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getGroupId(@NonNull BluetoothDevice device) {
+ if (VDBG) log("getGroupId()");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled()) {
+ return service.getGroupId(device);
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return GROUP_ID_INVALID;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return GROUP_ID_INVALID;
+ }
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
+ @ConnectionPolicy int connectionPolicy) {
+ if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled()
+ && isValidDevice(device)) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+ return false;
+ }
+ return service.setConnectionPolicy(device, connectionPolicy);
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
+ if (VDBG) log("getConnectionPolicy(" + device + ")");
+ try {
+ final IBluetoothLeAudio service = getService();
+ if (service != null && mAdapter.isEnabled()
+ && isValidDevice(device)) {
+ return service.getConnectionPolicy(device);
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+ }
+ }
+
+
+ /**
+ * Helper for converting a state to a string.
+ *
+ * For debug use only - strings are not internationalized.
+ *
+ * @hide
+ */
+ public static String stateToString(int state) {
+ switch (state) {
+ case STATE_DISCONNECTED:
+ return "disconnected";
+ case STATE_CONNECTING:
+ return "connecting";
+ case STATE_CONNECTED:
+ return "connected";
+ case STATE_DISCONNECTING:
+ return "disconnecting";
+ default:
+ return "<unknown state " + state + ">";
+ }
+ }
+
+ private boolean isValidDevice(@Nullable BluetoothDevice device) {
+ if (device == null) return false;
+
+ if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+ return false;
+ }
+
+ private static void log(String msg) {
+ Log.d(TAG, msg);
+ }
+}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index db851c4f33b9..c31b04e81456 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -207,12 +207,19 @@ public interface BluetoothProfile {
int HEARING_AID = 21;
/**
+ * LE Audio Device
+ *
+ * @hide
+ */
+ int LE_AUDIO = 22;
+
+ /**
* Max profile ID. This value should be updated whenever a new profile is added to match
* the largest value assigned to a profile.
*
* @hide
*/
- int MAX_PROFILE_ID = 21;
+ int MAX_PROFILE_ID = 22;
/**
* Default priority for devices that we try to auto-connect to and
diff --git a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
index 3fd20f12381e..c6007f1184f5 100644
--- a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
+++ b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
@@ -513,4 +513,19 @@ public class HdmiDeviceInfo implements Parcelable {
&& mDeviceId == other.mDeviceId
&& mAdopterId == other.mAdopterId;
}
+
+ @Override
+ public int hashCode() {
+ return java.util.Objects.hash(
+ mHdmiDeviceType,
+ mPhysicalAddress,
+ mPortId,
+ mLogicalAddress,
+ mDeviceType,
+ mVendorId,
+ mDevicePowerStatus,
+ mDisplayName,
+ mDeviceId,
+ mAdopterId);
+ }
}
diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java
index c2586fa0c825..269bbf20c8b1 100644
--- a/core/java/android/net/CaptivePortal.java
+++ b/core/java/android/net/CaptivePortal.java
@@ -15,7 +15,6 @@
*/
package android.net;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
@@ -24,8 +23,6 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
/**
* A class allowing apps handling the {@link ConnectivityManager#ACTION_CAPTIVE_PORTAL_SIGN_IN}
* activity to indicate to the system different outcomes of captive portal sign in. This class is
@@ -75,17 +72,6 @@ public class CaptivePortal implements Parcelable {
private final IBinder mBinder;
/** @hide */
- @IntDef(value = {
- MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY,
- MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_DISMISSED,
- MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_UNWANTED,
- MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_WANTED_AS_IS,
- MetricsEvent.CAPTIVE_PORTAL_LOGIN_ACTIVITY_SSL_ERROR,
- })
- public @interface EventId {
- }
-
- /** @hide */
public CaptivePortal(@NonNull IBinder binder) {
mBinder = binder;
}
@@ -176,7 +162,7 @@ public class CaptivePortal implements Parcelable {
* @hide
*/
@SystemApi
- public void logEvent(@EventId int eventId, @NonNull String packageName) {
+ public void logEvent(int eventId, @NonNull String packageName) {
try {
ICaptivePortal.Stub.asInterface(mBinder).logEvent(eventId, packageName);
} catch (RemoteException e) {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4b38d6377f37..3f2c966f9ed2 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -684,7 +684,7 @@ public class ConnectivityManager {
* {@hide}
*/
@Deprecated
- @UnsupportedAppUsage
+ @SystemApi
public static final int TYPE_PROXY = 16;
/**
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index d130bc5d37e7..b951aca6d680 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -67,7 +67,7 @@ public final class PowerManager {
/* NOTE: Wake lock levels were previously defined as a bit field, except that only a few
* combinations were actually supported so the bit field was removed. This explains
* why the numbering scheme is so odd. If adding a new wake lock level, any unused
- * value (in frameworks/base/core/proto/android/os/enums.proto) can be used.
+ * value (in frameworks/proto_logging/stats/enums/os/enums.proto) can be used.
*/
/**
diff --git a/core/java/android/service/autofill/TEST_MAPPING b/core/java/android/service/autofill/TEST_MAPPING
new file mode 100644
index 000000000000..87a17ebee36d
--- /dev/null
+++ b/core/java/android/service/autofill/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "imports": [
+ {
+ "path": "frameworks/base/services/autofill/java/com/android/server/autofill"
+ }
+ ]
+}
diff --git a/core/java/android/view/autofill/TEST_MAPPING b/core/java/android/view/autofill/TEST_MAPPING
new file mode 100644
index 000000000000..87a17ebee36d
--- /dev/null
+++ b/core/java/android/view/autofill/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "imports": [
+ {
+ "path": "frameworks/base/services/autofill/java/com/android/server/autofill"
+ }
+ ]
+}
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index dde9c3089370..b91e7d39f51c 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -251,15 +251,8 @@ public final class WebViewFactory {
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getProvider()");
try {
Class<WebViewFactoryProvider> providerClass = getProviderClass();
- Method staticFactory = null;
- try {
- staticFactory = providerClass.getMethod(
+ Method staticFactory = providerClass.getMethod(
CHROMIUM_WEBVIEW_FACTORY_METHOD, WebViewDelegate.class);
- } catch (Exception e) {
- if (DEBUG) {
- Log.w(LOGTAG, "error instantiating provider with static factory method", e);
- }
- }
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactoryProvider invocation");
try {
@@ -267,12 +260,12 @@ public final class WebViewFactory {
staticFactory.invoke(null, new WebViewDelegate());
if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance);
return sProviderInstance;
- } catch (Exception e) {
- Log.e(LOGTAG, "error instantiating provider", e);
- throw new AndroidRuntimeException(e);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
}
+ } catch (Exception e) {
+ Log.e(LOGTAG, "error instantiating provider", e);
+ throw new AndroidRuntimeException(e);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2357f368c428..02a930017906 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -964,6 +964,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @hide
*/
public static void preloadFontCache() {
+ if (Typeface.ENABLE_LAZY_TYPEFACE_INITIALIZATION) {
+ return;
+ }
Paint p = new Paint();
p.setAntiAlias(true);
// Ensure that the Typeface is loaded here.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5a6905699535..60dd0eb8a780 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1815,6 +1815,16 @@
<permission android:name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi @hide Allows system APK to update Wifi/Cellular coex channels to avoid.
+ <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS"
+ android:protectionLevel="signature" />
+
+ <!-- @SystemApi @hide Allows applications to access Wifi/Cellular coex channels being avoided.
+ <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS"
+ android:protectionLevel="signature|privileged" />
+
<!-- ======================================= -->
<!-- Permissions for short range, peripheral networks -->
<!-- ======================================= -->
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 5871e2e04687..7e992989426d 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -52,6 +52,7 @@ import android.os.Parcelable;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.RemoteException;
+import android.os.SharedMemory;
import android.platform.test.annotations.Presubmit;
import android.view.DisplayAdjustments.FixedRotationAdjustments;
import android.view.DisplayCutout;
@@ -440,7 +441,8 @@ public class TransactionParcelTests {
IUiAutomationConnection iUiAutomationConnection, int i, boolean b, boolean b1,
boolean b2, boolean b3, Configuration configuration,
CompatibilityInfo compatibilityInfo, Map map, Bundle bundle1, String s1,
- AutofillOptions ao, ContentCaptureOptions co, long[] disableCompatChanges)
+ AutofillOptions ao, ContentCaptureOptions co, long[] disableCompatChanges,
+ SharedMemory serializedSystemFontMap)
throws RemoteException {
}
diff --git a/core/tests/hdmitests/Android.bp b/core/tests/hdmitests/Android.bp
index 2194d4b030ce..4755e0ea5259 100644
--- a/core/tests/hdmitests/Android.bp
+++ b/core/tests/hdmitests/Android.bp
@@ -19,6 +19,7 @@ android_test {
static_libs: [
"androidx.test.rules",
"frameworks-base-testutils",
+ "guava-android-testlib",
"truth-prebuilt",
],
libs: ["android.test.runner"],
diff --git a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiDeviceInfoTest.java b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiDeviceInfoTest.java
new file mode 100755
index 000000000000..4c0de629c464
--- /dev/null
+++ b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiDeviceInfoTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.hdmi;
+
+import androidx.test.filters.SmallTest;
+
+import com.google.common.testing.EqualsTester;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link HdmiDeviceInfo} */
+@RunWith(JUnit4.class)
+@SmallTest
+public class HdmiDeviceInfoTest {
+
+ @Test
+ public void testEquals() {
+ int logicalAddr = 0x00;
+ int phyAddr = 0x1000;
+ int portId = 1;
+ int deviceType = 0;
+ int vendorId = 0x123456;
+ String displayName = "test device";
+ int powerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY;
+ int deviceId = 3;
+ int adopterId = 2;
+
+ new EqualsTester()
+ .addEqualityGroup(new HdmiDeviceInfo())
+ .addEqualityGroup(
+ new HdmiDeviceInfo(phyAddr, portId), new HdmiDeviceInfo(phyAddr, portId))
+ .addEqualityGroup(
+ new HdmiDeviceInfo(phyAddr, portId, adopterId, deviceId),
+ new HdmiDeviceInfo(phyAddr, portId, adopterId, deviceId))
+ .addEqualityGroup(
+ new HdmiDeviceInfo(
+ logicalAddr, phyAddr, portId, deviceType, vendorId, displayName),
+ new HdmiDeviceInfo(
+ logicalAddr, phyAddr, portId, deviceType, vendorId, displayName))
+ .addEqualityGroup(
+ new HdmiDeviceInfo(
+ logicalAddr,
+ phyAddr,
+ portId,
+ deviceType,
+ vendorId,
+ displayName,
+ powerStatus),
+ new HdmiDeviceInfo(
+ logicalAddr,
+ phyAddr,
+ portId,
+ deviceType,
+ vendorId,
+ displayName,
+ powerStatus))
+ .testEquals();
+ }
+}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 36ef0a48fa20..24987daf87b5 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -81,6 +81,9 @@ public class Typeface {
private static String TAG = "Typeface";
+ /** @hide */
+ public static final boolean ENABLE_LAZY_TYPEFACE_INITIALIZATION = false;
+
private static final NativeAllocationRegistry sRegistry =
NativeAllocationRegistry.createMalloced(
Typeface.class.getClassLoader(), nativeGetReleaseFunc());
@@ -1329,7 +1332,9 @@ public class Typeface {
}
static {
- loadPreinstalledSystemFontMap();
+ if (!ENABLE_LAZY_TYPEFACE_INITIALIZATION) {
+ loadPreinstalledSystemFontMap();
+ }
}
@Override
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 f199072f7bca..d3032f83fc1c 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
@@ -136,13 +136,6 @@ class AppPair implements ShellTaskOrganizer.TaskListener {
mAppPairLayout = null;
}
- void setVisible(boolean visible) {
- if (mAppPairLayout == null) {
- return;
- }
- mAppPairLayout.setDividerVisibility(visible);
- }
-
@Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
if (mRootTaskInfo == null || taskInfo.taskId == mRootTaskInfo.taskId) {
@@ -160,32 +153,41 @@ class AppPair implements ShellTaskOrganizer.TaskListener {
if (mTaskLeash1 == null || mTaskLeash2 == null) return;
- setVisible(true);
+ mAppPairLayout.init();
final SurfaceControl dividerLeash = mAppPairLayout.getDividerLeash();
final Rect dividerBounds = mAppPairLayout.getDividerBounds();
// TODO: Is there more we need to do here?
- mSyncQueue.runInSync(t -> t
- .setPosition(mTaskLeash1, mTaskInfo1.positionInParent.x,
- mTaskInfo1.positionInParent.y)
- .setPosition(mTaskLeash2, mTaskInfo2.positionInParent.x,
- mTaskInfo2.positionInParent.y)
- .setLayer(dividerLeash, Integer.MAX_VALUE)
- .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
- .show(mRootTaskLeash)
- .show(dividerLeash)
- .show(mTaskLeash1)
- .show(mTaskLeash2));
+ mSyncQueue.runInSync(t -> {
+ t.setPosition(mTaskLeash1, mTaskInfo1.positionInParent.x,
+ mTaskInfo1.positionInParent.y)
+ .setPosition(mTaskLeash2, mTaskInfo2.positionInParent.x,
+ mTaskInfo2.positionInParent.y)
+ .setLayer(dividerLeash, Integer.MAX_VALUE)
+ .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
+ .show(mRootTaskLeash)
+ .show(mTaskLeash1)
+ .show(mTaskLeash2);
+ });
}
@Override
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
if (taskInfo.taskId == getRootTaskId()) {
+ if (mRootTaskInfo.isVisible != taskInfo.isVisible) {
+ mSyncQueue.runInSync(t -> {
+ if (taskInfo.isVisible) {
+ t.show(mRootTaskLeash);
+ } else {
+ t.hide(mRootTaskLeash);
+ }
+ });
+ }
mRootTaskInfo = taskInfo;
if (mAppPairLayout != null
&& mAppPairLayout.updateConfiguration(mRootTaskInfo.configuration)) {
- // Update bounds when there is root bounds or orientation changed.
+ // Update bounds when root bounds or its orientation changed.
final WindowContainerTransaction wct = new WindowContainerTransaction();
final SurfaceControl dividerLeash = mAppPairLayout.getDividerLeash();
final Rect dividerBounds = mAppPairLayout.getDividerBounds();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairLayout.java
index f8703f7ec0bc..8c8655e1ff1f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairLayout.java
@@ -16,7 +16,6 @@
package com.android.wm.shell.apppairs;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
@@ -45,21 +44,18 @@ import com.android.wm.shell.R;
/**
* Records and handles layout of a pair of apps.
*/
-// TODO(172704238): add tests
final class AppPairLayout {
private static final String DIVIDER_WINDOW_TITLE = "AppPairDivider";
- private final Context mContext;
- private final AppPairWindowManager mAppPairWindowManager;
- private final SurfaceControlViewHost mViewHost;
-
+ private final Display mDisplay;
private final int mDividerWindowWidth;
private final int mDividerWindowInsets;
+ private final AppPairWindowManager mAppPairWindowManager;
- private boolean mIsLandscape;
+ private Context mContext;
private Rect mRootBounds;
private DIVIDE_POLICY mDividePolicy;
- private DividerView mDividerView;
+ private SurfaceControlViewHost mViewHost;
private SurfaceControl mDividerLeash;
AppPairLayout(
@@ -68,7 +64,7 @@ final class AppPairLayout {
Configuration configuration,
SurfaceControl rootLeash) {
mContext = context.createConfigurationContext(configuration);
- mIsLandscape = isLandscape(configuration);
+ mDisplay = display;
mRootBounds = configuration.windowConfiguration.getBounds();
mDividerWindowWidth = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.docked_stack_divider_thickness);
@@ -76,26 +72,22 @@ final class AppPairLayout {
com.android.internal.R.dimen.docked_stack_divider_insets);
mAppPairWindowManager = new AppPairWindowManager(configuration, rootLeash);
- mViewHost = new SurfaceControlViewHost(mContext, display, mAppPairWindowManager);
mDividePolicy = DIVIDE_POLICY.MIDDLE;
- mDividePolicy.update(mIsLandscape, mRootBounds, mDividerWindowWidth, mDividerWindowInsets);
+ mDividePolicy.update(mRootBounds, mDividerWindowWidth, mDividerWindowInsets);
}
boolean updateConfiguration(Configuration configuration) {
mAppPairWindowManager.setConfiguration(configuration);
final Rect rootBounds = configuration.windowConfiguration.getBounds();
- final boolean isLandscape = isLandscape(configuration);
- if (mIsLandscape == isLandscape && isIdenticalBounds(mRootBounds, rootBounds)) {
+ if (isIdenticalBounds(mRootBounds, rootBounds)) {
return false;
}
- mIsLandscape = isLandscape;
+ mContext = mContext.createConfigurationContext(configuration);
mRootBounds = rootBounds;
- mDividePolicy.update(mIsLandscape, mRootBounds, mDividerWindowWidth, mDividerWindowInsets);
- mViewHost.relayout(
- mDividePolicy.mDividerBounds.width(),
- mDividePolicy.mDividerBounds.height());
- // TODO(172704238): handle divider bar rotation.
+ mDividePolicy.update(mRootBounds, mDividerWindowWidth, mDividerWindowInsets);
+ release();
+ init();
return true;
}
@@ -116,22 +108,19 @@ final class AppPairLayout {
}
void release() {
- if (mViewHost == null) return;
+ if (mViewHost == null) {
+ return;
+ }
mViewHost.release();
+ mDividerLeash = null;
+ mViewHost = null;
}
- void setDividerVisibility(boolean visible) {
- if (mDividerView == null) {
- initDivider();
- }
- if (visible) {
- mDividerView.show();
- } else {
- mDividerView.hide();
+ void init() {
+ if (mViewHost == null) {
+ mViewHost = new SurfaceControlViewHost(mContext, mDisplay, mAppPairWindowManager);
}
- }
- private void initDivider() {
final DividerView dividerView = (DividerView) LayoutInflater.from(mContext)
.inflate(R.layout.split_divider, null);
@@ -147,14 +136,9 @@ final class AppPairLayout {
lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
mViewHost.setView(dividerView, lp);
- mDividerView = dividerView;
mDividerLeash = mAppPairWindowManager.getSurfaceControl(mViewHost.getWindowToken());
}
- private static boolean isLandscape(Configuration configuration) {
- return configuration.orientation == ORIENTATION_LANDSCAPE;
- }
-
private static boolean isIdenticalBounds(Rect bounds1, Rect bounds2) {
return bounds1.left == bounds2.left && bounds1.top == bounds2.top
&& bounds1.right == bounds2.right && bounds1.bottom == bounds2.bottom;
@@ -167,8 +151,7 @@ final class AppPairLayout {
enum DIVIDE_POLICY {
MIDDLE;
- void update(boolean isLandscape, Rect rootBounds, int dividerWindowWidth,
- int dividerWindowInsets) {
+ void update(Rect rootBounds, int dividerWindowWidth, int dividerWindowInsets) {
final int dividerOffset = dividerWindowWidth / 2;
final int boundsOffset = dividerOffset - dividerWindowInsets;
@@ -179,7 +162,7 @@ final class AppPairLayout {
switch (this) {
case MIDDLE:
default:
- if (isLandscape) {
+ if (isLandscape(rootBounds)) {
mDividerBounds.left = rootBounds.width() / 2 - dividerOffset;
mDividerBounds.right = rootBounds.width() / 2 + dividerOffset;
mBounds1.left = rootBounds.width() / 2 + boundsOffset;
@@ -193,6 +176,10 @@ final class AppPairLayout {
}
}
+ private boolean isLandscape(Rect bounds) {
+ return bounds.width() > bounds.height();
+ }
+
Rect mDividerBounds;
Rect mBounds1;
Rect mBounds2;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java
index af06764145e3..ef3e3e0220e7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java
@@ -36,6 +36,4 @@ public interface AppPairs {
void dump(@NonNull PrintWriter pw, String prefix);
/** Called when the shell organizer has been registered. */
void onOrganizerRegistered();
- /** Called when the visibility of the keyguard changes. */
- void onKeyguardVisibilityChanged(boolean showing);
}
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 925a4f36d5e6..f2f09820639a 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
@@ -16,8 +16,6 @@
package com.android.wm.shell.apppairs;
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
import android.app.ActivityManager;
@@ -30,15 +28,13 @@ 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.SyncTransactionQueue;
-import com.android.wm.shell.common.TaskStackListenerCallback;
-import com.android.wm.shell.common.TaskStackListenerImpl;
import java.io.PrintWriter;
/**
* Class manages app-pairs multitasking mode and implements the main interface {@link AppPairs}.
*/
-public class AppPairsController implements AppPairs, TaskStackListenerCallback {
+public class AppPairsController implements AppPairs {
private static final String TAG = AppPairsController.class.getSimpleName();
private final ShellTaskOrganizer mTaskOrganizer;
@@ -48,14 +44,12 @@ public class AppPairsController implements AppPairs, TaskStackListenerCallback {
// Active app-pairs mapped by root task id key.
private final SparseArray<AppPair> mActiveAppPairs = new SparseArray<>();
private final DisplayController mDisplayController;
- private int mForegroundTaskId = INVALID_TASK_ID;
public AppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
- DisplayController displayController, TaskStackListenerImpl taskStackListener) {
+ DisplayController displayController) {
mTaskOrganizer = organizer;
mSyncQueue = syncQueue;
mDisplayController = displayController;
- taskStackListener.addListener(this);
}
@Override
@@ -71,27 +65,6 @@ public class AppPairsController implements AppPairs, TaskStackListenerCallback {
}
@Override
- public void onTaskMovedToFront(int taskId) {
- mForegroundTaskId = INVALID_TASK_ID;
- for (int i = mActiveAppPairs.size() - 1; i >= 0; --i) {
- final AppPair candidate = mActiveAppPairs.valueAt(i);
- final boolean containForegroundTask = candidate.contains(taskId);
- candidate.setVisible(containForegroundTask);
- if (containForegroundTask) {
- mForegroundTaskId = candidate.getRootTaskId();
- }
- }
- }
-
- @Override
- public void onKeyguardVisibilityChanged(boolean showing) {
- if (mForegroundTaskId == INVALID_TASK_ID) {
- return;
- }
- mActiveAppPairs.get(mForegroundTaskId).setVisible(!showing);
- }
-
- @Override
public boolean pair(int taskId1, int taskId2) {
final ActivityManager.RunningTaskInfo task1 = mTaskOrganizer.getRunningTaskInfo(taskId1);
final ActivityManager.RunningTaskInfo task2 = mTaskOrganizer.getRunningTaskInfo(taskId2);
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OpenAppToSplitScreenTest.kt
index 1e328a8dae40..c85561d96091 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OpenAppToSplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OpenAppToSplitScreenTest.kt
@@ -17,7 +17,7 @@
package com.android.wm.shell.flicker.splitscreen
import android.platform.test.annotations.Presubmit
-import androidx.test.filters.FlakyTest
+import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.DOCKED_STACK_DIVIDER
@@ -54,7 +54,6 @@ import org.junit.runners.Parameterized
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 161435597)
class OpenAppToSplitScreenTest(
testName: String,
flickerSpec: Flicker
@@ -67,7 +66,8 @@ class OpenAppToSplitScreenTest(
val testApp = StandardAppHelper(instrumentation,
"com.android.wm.shell.flicker.testapp", "SimpleApp")
- return FlickerTestRunnerFactory(instrumentation)
+ // b/161435597 causes the test not to work on 90 degrees
+ return FlickerTestRunnerFactory(instrumentation, listOf(Surface.ROTATION_0))
.buildTest { configuration ->
withTestName {
buildTestTag("appToSplitScreen", testApp, configuration)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateOneLaunchedAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateOneLaunchedAppTest.kt
new file mode 100644
index 000000000000..d2371bd766f5
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateOneLaunchedAppTest.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2020 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.flicker.splitscreen
+
+import androidx.test.filters.FlakyTest
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.Flicker
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.helpers.StandardAppHelper
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.isInSplitScreen
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.repetitions
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open app to split screen.
+ * To run this test: `atest WMShellFlickerTests:SplitScreenRotateOneLaunchedAppTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest
+class SplitScreenRotateOneLaunchedAppTest(
+ testName: String,
+ flickerSpec: Flicker
+) : FlickerTestRunner(testName, flickerSpec) {
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val instrumentation = InstrumentationRegistry.getInstrumentation()
+ val testApp = StandardAppHelper(instrumentation,
+ "com.android.wm.shell.flicker.testapp", "SimpleApp")
+
+ return FlickerTestRunnerFactory(instrumentation, repetitions = 3)
+ .buildTest { configuration ->
+ withTestName {
+ buildTestTag("splitScreenRotateOneApp", testApp, configuration)
+ }
+ repeat { configuration.repetitions }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ testApp.open()
+ device.launchSplitScreen()
+ device.waitForIdle()
+ }
+ eachRun {
+ this.setRotation(configuration.startRotation)
+ }
+ }
+ teardown {
+ eachRun {
+ setRotation(Surface.ROTATION_0)
+ }
+ test {
+ testApp.exit()
+ if (device.isInSplitScreen()) {
+ device.exitSplitScreen()
+ }
+ }
+ }
+ transitions {
+ this.setRotation(configuration.endRotation)
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateTwoLaunchedAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateTwoLaunchedAppTest.kt
new file mode 100644
index 000000000000..67346424acd2
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateTwoLaunchedAppTest.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2020 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.flicker.splitscreen
+
+import androidx.test.filters.FlakyTest
+import android.view.Surface
+import androidx.test.filters.RequiresDevice
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.Flicker
+import com.android.server.wm.flicker.FlickerTestRunner
+import com.android.server.wm.flicker.FlickerTestRunnerFactory
+import com.android.server.wm.flicker.helpers.StandardAppHelper
+import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.helpers.buildTestTag
+import com.android.server.wm.flicker.helpers.exitSplitScreen
+import com.android.server.wm.flicker.helpers.reopenAppFromOverview
+import com.android.server.wm.flicker.helpers.isInSplitScreen
+import com.android.server.wm.flicker.helpers.launchSplitScreen
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.repetitions
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open app to split screen.
+ * To run this test: `atest WMShellFlickerTests:SplitScreenRotateTwoLaunchedAppTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest
+class SplitScreenRotateTwoLaunchedAppTest(
+ testName: String,
+ flickerSpec: Flicker
+) : FlickerTestRunner(testName, flickerSpec) {
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val instrumentation = InstrumentationRegistry.getInstrumentation()
+ val testApp = StandardAppHelper(instrumentation,
+ "com.android.wm.shell.flicker.testapp", "SimpleApp")
+ val secondaryApp = StandardAppHelper(instrumentation,
+ "com.android.wm.shell.flicker.testapp",
+ "SplitScreenSecondaryApp")
+
+ return FlickerTestRunnerFactory(instrumentation, repetitions = 3)
+ .buildTest { configuration ->
+ withTestName {
+ buildTestTag("splitScreenRotateTwoApps", testApp, configuration)
+ }
+ repeat { configuration.repetitions }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ testApp.open()
+ device.pressHome()
+ secondaryApp.open()
+ device.pressHome()
+ device.launchSplitScreen()
+ device.reopenAppFromOverview()
+ device.waitForIdle()
+ }
+ eachRun {
+ this.setRotation(configuration.startRotation)
+ }
+ }
+ teardown {
+ eachRun {
+ setRotation(Surface.ROTATION_0)
+ }
+ test {
+ testApp.exit()
+ secondaryApp.exit()
+ if (device.isInSplitScreen()) {
+ device.exitSplitScreen()
+ }
+ }
+ }
+ transitions {
+ this.setRotation(configuration.endRotation)
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairLayoutTests.java
new file mode 100644
index 000000000000..c9d32c4b1f76
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairLayoutTests.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 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.apppairs;
+
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.view.Display;
+import android.view.SurfaceControl;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Tests for {@link AppPairLayout} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AppPairLayoutTests extends ShellTestCase {
+ @Mock SurfaceControl mSurfaceControl;
+ private Display mDisplay;
+ private Configuration mConfiguration;
+ private AppPairLayout mAppPairLayout;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mConfiguration = getConfiguration(false);
+ mDisplay = mContext.getDisplay();
+ mAppPairLayout = new AppPairLayout(mContext, mDisplay, mConfiguration, mSurfaceControl);
+ }
+
+ @After
+ @UiThreadTest
+ public void tearDown() {
+ mAppPairLayout.release();
+ }
+
+ @Test
+ @UiThreadTest
+ public void testUpdateConfiguration() {
+ assertThat(mAppPairLayout.updateConfiguration(getConfiguration(false))).isFalse();
+ assertThat(mAppPairLayout.updateConfiguration(getConfiguration(true))).isTrue();
+ }
+
+ @Test
+ @UiThreadTest
+ public void testInitRelease() {
+ mAppPairLayout.init();
+ assertThat(mAppPairLayout.getDividerLeash()).isNotNull();
+ mAppPairLayout.release();
+ assertThat(mAppPairLayout.getDividerLeash()).isNull();
+ }
+
+ private static Configuration getConfiguration(boolean isLandscape) {
+ final Configuration configuration = new Configuration();
+ configuration.unset();
+ configuration.orientation = isLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
+ configuration.windowConfiguration.setBounds(
+ new Rect(0, 0, isLandscape ? 2160 : 1080, isLandscape ? 1080 : 2160));
+ return configuration;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java
index 754f73246c86..f12648a7f709 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java
@@ -34,7 +34,6 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.TaskStackListenerImpl;
import org.junit.After;
import org.junit.Before;
@@ -52,7 +51,6 @@ public class AppPairTests extends ShellTestCase {
@Mock private SyncTransactionQueue mSyncQueue;
@Mock private ShellTaskOrganizer mTaskOrganizer;
@Mock private DisplayController mDisplayController;
- @Mock private TaskStackListenerImpl mTaskStackListener;
@Before
public void setUp() {
@@ -60,8 +58,7 @@ public class AppPairTests extends ShellTestCase {
mController = new TestAppPairsController(
mTaskOrganizer,
mSyncQueue,
- mDisplayController,
- mTaskStackListener);
+ mDisplayController);
when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
when(mDisplayController.getDisplay(anyInt())).thenReturn(
mContext.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java
index 6d441ab898ec..f8c68d2018da 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java
@@ -34,7 +34,6 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.TaskStackListenerImpl;
import org.junit.After;
import org.junit.Before;
@@ -52,7 +51,6 @@ public class AppPairsControllerTests extends ShellTestCase {
@Mock private SyncTransactionQueue mSyncQueue;
@Mock private ShellTaskOrganizer mTaskOrganizer;
@Mock private DisplayController mDisplayController;
- @Mock private TaskStackListenerImpl mTaskStackListener;
@Before
public void setUp() {
@@ -60,8 +58,7 @@ public class AppPairsControllerTests extends ShellTestCase {
mController = new TestAppPairsController(
mTaskOrganizer,
mSyncQueue,
- mDisplayController,
- mTaskStackListener);
+ mDisplayController);
mPool = mController.getPool();
when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
when(mDisplayController.getDisplay(anyInt())).thenReturn(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java
index d3dbbfe37985..8ece913de53f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java
@@ -24,7 +24,6 @@ import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.TaskStackListenerImpl;
import org.junit.After;
import org.junit.Before;
@@ -42,7 +41,6 @@ public class AppPairsPoolTests {
@Mock private SyncTransactionQueue mSyncQueue;
@Mock private ShellTaskOrganizer mTaskOrganizer;
@Mock private DisplayController mDisplayController;
- @Mock private TaskStackListenerImpl mTaskStackListener;
@Before
public void setUp() {
@@ -50,8 +48,7 @@ public class AppPairsPoolTests {
mController = new TestAppPairsController(
mTaskOrganizer,
mSyncQueue,
- mDisplayController,
- mTaskStackListener);
+ mDisplayController);
mPool = mController.getPool();
}
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 e61cc91c394b..be0963628933 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
@@ -19,14 +19,13 @@ package com.android.wm.shell.apppairs;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.TaskStackListenerImpl;
public class TestAppPairsController extends AppPairsController {
TestAppPairsPool mPool;
public TestAppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
- DisplayController displayController, TaskStackListenerImpl taskStackListener) {
- super(organizer, syncQueue, displayController, taskStackListener);
+ DisplayController displayController) {
+ super(organizer, syncQueue, displayController);
mPool = new TestAppPairsPool(this);
setPairsPool(mPool);
}
diff --git a/media/java/android/media/metrics/IPlaybackMetricsManager.aidl b/media/java/android/media/metrics/IPlaybackMetricsManager.aidl
index fcb7d608f662..47debe90c854 100644
--- a/media/java/android/media/metrics/IPlaybackMetricsManager.aidl
+++ b/media/java/android/media/metrics/IPlaybackMetricsManager.aidl
@@ -23,5 +23,6 @@ import android.media.metrics.PlaybackMetrics;
* @hide
*/
interface IPlaybackMetricsManager {
- void reportPlaybackMetrics(in PlaybackMetrics metrics, int userId);
+ void reportPlaybackMetrics(in String sessionId, in PlaybackMetrics metrics, int userId);
+ String getSessionId(int userId);
} \ No newline at end of file
diff --git a/media/java/android/media/metrics/PlaybackMetricsManager.java b/media/java/android/media/metrics/PlaybackMetricsManager.java
index 3606f53d7220..d51ff473696d 100644
--- a/media/java/android/media/metrics/PlaybackMetricsManager.java
+++ b/media/java/android/media/metrics/PlaybackMetricsManager.java
@@ -16,6 +16,7 @@
package android.media.metrics;
+import android.annotation.NonNull;
import android.os.RemoteException;
/**
@@ -38,10 +39,24 @@ public class PlaybackMetricsManager {
/**
* Reports playback metrics.
+ * @hide
+ */
+ public void reportPlaybackMetrics(@NonNull String sessionId, PlaybackMetrics metrics) {
+ try {
+ mService.reportPlaybackMetrics(sessionId, metrics, mUserId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Creates a playback session.
*/
- public void reportPlaybackMetrics(PlaybackMetrics metrics) {
+ public PlaybackSession createSession() {
try {
- mService.reportPlaybackMetrics(metrics, mUserId);
+ String id = mService.getSessionId(mUserId);
+ PlaybackSession session = new PlaybackSession(id, this);
+ return session;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/metrics/PlaybackSession.java b/media/java/android/media/metrics/PlaybackSession.java
new file mode 100644
index 000000000000..4ad89067952c
--- /dev/null
+++ b/media/java/android/media/metrics/PlaybackSession.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.metrics;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.AnnotationValidations;
+
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+public final class PlaybackSession implements AutoCloseable {
+ private final @NonNull String mId;
+ private final @NonNull PlaybackMetricsManager mManager;
+ private boolean mClosed = false;
+
+ /**
+ * Creates a new PlaybackSession.
+ *
+ * @hide
+ */
+ public PlaybackSession(@NonNull String id, @NonNull PlaybackMetricsManager manager) {
+ mId = id;
+ mManager = manager;
+ AnnotationValidations.validate(NonNull.class, null, mId);
+ AnnotationValidations.validate(NonNull.class, null, mManager);
+ }
+
+ /**
+ * Reports playback metrics.
+ */
+ public void reportPlaybackMetrics(@NonNull PlaybackMetrics metrics) {
+ mManager.reportPlaybackMetrics(mId, metrics);
+ }
+
+ public @NonNull String getId() {
+ return mId;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PlaybackSession that = (PlaybackSession) o;
+ return Objects.equals(mId, that.mId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId);
+ }
+
+ @Override
+ public void close() throws Exception {
+ mClosed = true;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
index 00f94f5c2e64..9d4669a5a37d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
@@ -18,6 +18,7 @@ package com.android.settingslib.media;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
@@ -56,8 +57,9 @@ public class BluetoothMediaDevice extends MediaDevice {
@Override
public Drawable getIcon() {
- final Drawable drawable = getIconWithoutBackground();
- if (!isFastPairDevice()) {
+ final Drawable drawable =
+ BluetoothUtils.getBtDrawableWithDescription(mContext, mCachedDevice).first;
+ if (!(drawable instanceof BitmapDrawable)) {
setColorFilter(drawable);
}
return BluetoothUtils.buildAdvancedDrawable(mContext, drawable);
@@ -65,9 +67,7 @@ public class BluetoothMediaDevice extends MediaDevice {
@Override
public Drawable getIconWithoutBackground() {
- return isFastPairDevice()
- ? BluetoothUtils.getBtDrawableWithDescription(mContext, mCachedDevice).first
- : mContext.getDrawable(R.drawable.ic_headphone);
+ return BluetoothUtils.getBtClassDrawableWithDescription(mContext, mCachedDevice).first;
}
@Override
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java
index 8973d116e438..e887c45083c0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaDeviceTest.java
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
+import android.graphics.drawable.BitmapDrawable;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -96,4 +97,17 @@ public class BluetoothMediaDeviceTest {
assertThat(mBluetoothMediaDevice.isFastPairDevice()).isFalse();
}
+
+ @Test
+ public void getIcon_isNotFastPairDevice_drawableTypeIsNotBitmapDrawable() {
+ final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+ when(mDevice.getDevice()).thenReturn(bluetoothDevice);
+
+ final String value = "False";
+ final byte[] bytes = value.getBytes();
+ when(bluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
+ .thenReturn(bytes);
+
+ assertThat(mBluetoothMediaDevice.getIcon() instanceof BitmapDrawable).isFalse();
+ }
}
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index 6c20c1e95c6d..2bf41d2472be 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -40,18 +40,4 @@
android:visibility="gone"
android:pointerIcon="crosshair"/>
<include layout="@layout/global_screenshot_static"/>
- <FrameLayout
- android:id="@+id/global_screenshot_dismiss_button"
- android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
- android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
- android:elevation="7dp"
- android:visibility="gone"
- android:contentDescription="@string/screenshot_dismiss_description">
- <ImageView
- android:id="@+id/global_screenshot_dismiss_image"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_margin="@dimen/screenshot_dismiss_button_margin"
- android:src="@drawable/screenshot_cancel"/>
- </FrameLayout>
</com.android.systemui.screenshot.ScreenshotView>
diff --git a/packages/SystemUI/res/layout/global_screenshot_static.xml b/packages/SystemUI/res/layout/global_screenshot_static.xml
index 096ec7ddd004..9f63c4334a8c 100644
--- a/packages/SystemUI/res/layout/global_screenshot_static.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_static.xml
@@ -17,7 +17,6 @@
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
@@ -62,4 +61,22 @@
</LinearLayout>
</HorizontalScrollView>
<include layout="@layout/global_screenshot_preview"/>
+ <FrameLayout
+ android:id="@+id/global_screenshot_dismiss_button"
+ android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
+ android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
+ android:elevation="7dp"
+ android:visibility="gone"
+ app:layout_constraintStart_toEndOf="@id/global_screenshot_preview"
+ app:layout_constraintEnd_toEndOf="@id/global_screenshot_preview"
+ app:layout_constraintTop_toTopOf="@id/global_screenshot_preview"
+ app:layout_constraintBottom_toTopOf="@id/global_screenshot_preview"
+ android:contentDescription="@string/screenshot_dismiss_description">
+ <ImageView
+ android:id="@+id/global_screenshot_dismiss_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="@dimen/screenshot_dismiss_button_margin"
+ android:src="@drawable/screenshot_cancel"/>
+ </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 70a57cc8bd2a..e24a513437ea 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,44 +14,39 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.systemui.classifier.FalsingManagerProxy.FALSING_SUCCESS;
+import static com.android.systemui.classifier.FalsingModule.BRIGHT_LINE_GESTURE_CLASSIFERS;
-import android.app.ActivityManager;
-import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.view.MotionEvent;
-import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
-import com.android.systemui.classifier.Classifier;
-import com.android.systemui.classifier.FalsingDataProvider;
import com.android.systemui.classifier.FalsingDataProvider.SessionListener;
-import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dagger.qualifiers.TestHarness;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.statusbar.phone.NotificationTapHelper;
-import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.sensors.ThresholdSensor;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayDeque;
-import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Queue;
+import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import javax.inject.Inject;
+import javax.inject.Named;
/**
* FalsingManager designed to make clear why a touch was rejected.
@@ -68,6 +63,7 @@ public class BrightLineFalsingManager implements FalsingManager {
private final DockManager mDockManager;
private final SingleTapClassifier mSingleTapClassifier;
private final DoubleTapClassifier mDoubleTapClassifier;
+ private final boolean mTestHarness;
private final MetricsLogger mMetricsLogger;
private int mIsFalseTouchCalls;
private static final Queue<String> RECENT_INFO_LOG =
@@ -75,7 +71,7 @@ public class BrightLineFalsingManager implements FalsingManager {
private static final Queue<DebugSwipeRecord> RECENT_SWIPES =
new ArrayDeque<>(RECENT_SWIPE_LOG_SIZE + 1);
- private final List<FalsingClassifier> mClassifiers;
+ private final Collection<FalsingClassifier> mClassifiers;
private final SessionListener mSessionListener = new SessionListener() {
@Override
@@ -93,29 +89,17 @@ public class BrightLineFalsingManager implements FalsingManager {
@Inject
public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider,
- DeviceConfigProxy deviceConfigProxy, @Main Resources resources,
- ViewConfiguration viewConfiguration, DockManager dockManager) {
+ DockManager dockManager, MetricsLogger metricsLogger,
+ @Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set<FalsingClassifier> classifiers,
+ SingleTapClassifier singleTapClassifier, DoubleTapClassifier doubleTapClassifier,
+ @TestHarness boolean testHarness) {
mDataProvider = falsingDataProvider;
mDockManager = dockManager;
-
- mMetricsLogger = new MetricsLogger();
- mClassifiers = new ArrayList<>();
- DistanceClassifier distanceClassifier =
- new DistanceClassifier(mDataProvider, deviceConfigProxy);
- ProximityClassifier proximityClassifier =
- new ProximityClassifier(distanceClassifier, mDataProvider, deviceConfigProxy);
- mClassifiers.add(new PointerCountClassifier(mDataProvider));
- mClassifiers.add(new TypeClassifier(mDataProvider));
- mClassifiers.add(new DiagonalClassifier(mDataProvider, deviceConfigProxy));
- mClassifiers.add(distanceClassifier);
- mClassifiers.add(proximityClassifier);
- mClassifiers.add(new ZigZagClassifier(mDataProvider, deviceConfigProxy));
-
- mSingleTapClassifier = new SingleTapClassifier(
- mDataProvider, viewConfiguration.getScaledTouchSlop());
- mDoubleTapClassifier = new DoubleTapClassifier(mDataProvider, mSingleTapClassifier,
- resources.getDimension(R.dimen.double_tap_slop),
- NotificationTapHelper.DOUBLE_TAP_TIMEOUT_MS);
+ mMetricsLogger = metricsLogger;
+ mClassifiers = classifiers;
+ mSingleTapClassifier = singleTapClassifier;
+ mDoubleTapClassifier = doubleTapClassifier;
+ mTestHarness = testHarness;
mDataProvider.addSessionListener(mSessionListener);
}
@@ -132,7 +116,7 @@ public class BrightLineFalsingManager implements FalsingManager {
return mPreviousResult;
}
- mPreviousResult = !ActivityManager.isRunningInUserTestHarness()
+ mPreviousResult = !mTestHarness
&& !mDataProvider.isJustUnlockedWithFace() && !mDockManager.isDocked()
&& mClassifiers.stream().anyMatch(falsingClassifier -> {
boolean result = falsingClassifier.isFalseTouch();
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DiagonalClassifier.java
index a73ccf575249..92dd8b74e959 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/DiagonalClassifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DIAGONAL_HORIZONTAL_ANGLE_RANGE;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DIAGONAL_VERTICAL_ANGLE_RANGE;
@@ -23,11 +23,12 @@ import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
import android.provider.DeviceConfig;
-import com.android.systemui.classifier.FalsingDataProvider;
import com.android.systemui.util.DeviceConfigProxy;
import java.util.Locale;
+import javax.inject.Inject;
+
/**
* False on swipes that are too close to 45 degrees.
*
@@ -47,6 +48,7 @@ class DiagonalClassifier extends FalsingClassifier {
private final float mHorizontalAngleRange;
private final float mVerticalAngleRange;
+ @Inject
DiagonalClassifier(FalsingDataProvider dataProvider, DeviceConfigProxy deviceConfigProxy) {
super(dataProvider);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
index 524d524f38b6..50d55f6f6028 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_FLING_THRESHOLD_IN;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_SWIPE_THRESHOLD_IN;
@@ -27,12 +27,13 @@ import android.provider.DeviceConfig;
import android.view.MotionEvent;
import android.view.VelocityTracker;
-import com.android.systemui.classifier.FalsingDataProvider;
import com.android.systemui.util.DeviceConfigProxy;
import java.util.List;
import java.util.Locale;
+import javax.inject.Inject;
+
/**
* Ensure that the swipe + momentum covers a minimum distance.
*/
@@ -54,6 +55,7 @@ class DistanceClassifier extends FalsingClassifier {
private boolean mDistanceDirty;
private DistanceVectors mCachedDistance;
+ @Inject
DistanceClassifier(FalsingDataProvider dataProvider, DeviceConfigProxy deviceConfigProxy) {
super(dataProvider);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DoubleTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java
index a27ea6172414..1c8f4208edba 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DoubleTapClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java
@@ -14,15 +14,19 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
-import android.view.MotionEvent;
+import static com.android.systemui.classifier.FalsingModule.DOUBLE_TAP_TIMEOUT_MS;
+import static com.android.systemui.classifier.FalsingModule.DOUBLE_TAP_TOUCH_SLOP;
-import com.android.systemui.classifier.FalsingDataProvider;
+import android.view.MotionEvent;
import java.util.List;
import java.util.Queue;
+import javax.inject.Inject;
+import javax.inject.Named;
+
/**
* Returns a false touch if the most two recent gestures are not taps or are too far apart.
*/
@@ -34,8 +38,10 @@ public class DoubleTapClassifier extends FalsingClassifier {
private StringBuilder mReason = new StringBuilder();
+ @Inject
DoubleTapClassifier(FalsingDataProvider dataProvider, SingleTapClassifier singleTapClassifier,
- float doubleTapSlop, long doubleTapTimeMs) {
+ @Named(DOUBLE_TAP_TOUCH_SLOP) float doubleTapSlop,
+ @Named(DOUBLE_TAP_TIMEOUT_MS) long doubleTapTimeMs) {
super(dataProvider);
mSingleTapClassifier = singleTapClassifier;
mDoubleTapSlop = doubleTapSlop;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
index 568dc432729f..82575c3e639e 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,12 +14,10 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import android.view.MotionEvent;
-import com.android.systemui.classifier.Classifier;
-import com.android.systemui.classifier.FalsingDataProvider;
import com.android.systemui.util.sensors.ProximitySensor;
import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index b29871c1c3d0..009b311f2363 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -21,9 +21,6 @@ import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
-import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
-import com.android.systemui.classifier.brightline.FalsingClassifier;
-import com.android.systemui.classifier.brightline.TimeLimitedMotionEventBuffer;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.util.time.SystemClock;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 74629411c13d..d4f58c324d39 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -24,7 +24,6 @@ import android.view.MotionEvent;
import androidx.annotation.NonNull;
import com.android.systemui.Dumpable;
-import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
index 937bcbaa6222..7b7f17e1568b 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
@@ -16,16 +16,69 @@
package com.android.systemui.classifier;
+import android.content.res.Resources;
+import android.view.ViewConfiguration;
+
+import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.statusbar.phone.NotificationTapHelper;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.inject.Named;
import dagger.Binds;
import dagger.Module;
+import dagger.Provides;
+import dagger.multibindings.ElementsIntoSet;
/** Dagger Module for Falsing. */
@Module
public interface FalsingModule {
+ String BRIGHT_LINE_GESTURE_CLASSIFERS = "bright_line_gesture_classifiers";
+ String SINGLE_TAP_TOUCH_SLOP = "falsing_single_tap_touch_slop";
+ String DOUBLE_TAP_TOUCH_SLOP = "falsing_double_tap_touch_slop";
+ String DOUBLE_TAP_TIMEOUT_MS = "falsing_double_tap_timeout_ms";
+
/** */
@Binds
@SysUISingleton
FalsingCollector bindsFalsingCollector(FalsingCollectorImpl impl);
+
+ /** */
+ @Provides
+ @ElementsIntoSet
+ @Named(BRIGHT_LINE_GESTURE_CLASSIFERS)
+ static Set<FalsingClassifier> providesBrightLineGestureClassifiers(
+ DistanceClassifier distanceClassifier, ProximityClassifier proximityClassifier,
+ PointerCountClassifier pointerCountClassifier, TypeClassifier typeClassifier,
+ DiagonalClassifier diagonalClassifier, ZigZagClassifier zigZagClassifier) {
+ return new HashSet<>(Arrays.asList(
+ pointerCountClassifier, typeClassifier, diagonalClassifier, distanceClassifier,
+ proximityClassifier, zigZagClassifier));
+ }
+
+ /** */
+ @Provides
+ @Named(DOUBLE_TAP_TIMEOUT_MS)
+ static long providesDoubleTapTimeoutMs() {
+ return NotificationTapHelper.DOUBLE_TAP_TIMEOUT_MS;
+ }
+
+ /** */
+ @Provides
+ @Named(DOUBLE_TAP_TOUCH_SLOP)
+ static float providesDoubleTapTouchSlop(@Main Resources resources) {
+ return resources.getDimension(R.dimen.double_tap_slop);
+ }
+
+ /** */
+ @Provides
+ @Named(SINGLE_TAP_TOUCH_SLOP)
+ static float providesSingleTapTouchSlop(ViewConfiguration viewConfiguration) {
+ return viewConfiguration.getScaledTouchSlop();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/PointerCountClassifier.java
index dd5d8a8f557b..0565165e1e8d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/PointerCountClassifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import android.view.MotionEvent;
-import com.android.systemui.classifier.FalsingDataProvider;
-
import java.util.Locale;
+import javax.inject.Inject;
+
/**
* False touch if more than one finger touches the screen.
*
@@ -37,6 +37,7 @@ class PointerCountClassifier extends FalsingClassifier {
private static final int MAX_ALLOWED_POINTERS_SWIPE_DOWN = 2;
private int mMaxPointerCount;
+ @Inject
PointerCountClassifier(FalsingDataProvider dataProvider) {
super(dataProvider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
index 3551c241e71e..6e73fc06de4c 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
@@ -22,12 +22,13 @@ import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import android.provider.DeviceConfig;
import android.view.MotionEvent;
-import com.android.systemui.classifier.FalsingDataProvider;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.sensors.ProximitySensor;
import java.util.Locale;
+import javax.inject.Inject;
+
/**
* False touch if proximity sensor is covered for more than a certain percentage of the gesture.
@@ -47,10 +48,11 @@ class ProximityClassifier extends FalsingClassifier {
private long mNearDurationNs;
private float mPercentNear;
+ @Inject
ProximityClassifier(DistanceClassifier distanceClassifier,
FalsingDataProvider dataProvider, DeviceConfigProxy deviceConfigProxy) {
super(dataProvider);
- this.mDistanceClassifier = distanceClassifier;
+ mDistanceClassifier = distanceClassifier;
mPercentCoveredThreshold = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/SingleTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java
index 8c7648149e44..6b7a1413bc74 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/SingleTapClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java
@@ -14,14 +14,17 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
-import android.view.MotionEvent;
+import static com.android.systemui.classifier.FalsingModule.SINGLE_TAP_TOUCH_SLOP;
-import com.android.systemui.classifier.FalsingDataProvider;
+import android.view.MotionEvent;
import java.util.List;
+import javax.inject.Inject;
+import javax.inject.Named;
+
/**
* Falsing classifier that accepts or rejects a single gesture as a tap.
*/
@@ -29,7 +32,9 @@ public class SingleTapClassifier extends FalsingClassifier {
private final float mTouchSlop;
private String mReason;
- SingleTapClassifier(FalsingDataProvider dataProvider, float touchSlop) {
+ @Inject
+ SingleTapClassifier(FalsingDataProvider dataProvider,
+ @Named(SINGLE_TAP_TOUCH_SLOP) float touchSlop) {
super(dataProvider);
mTouchSlop = touchSlop;
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
index 7430a1eda920..7969b4e83ac0 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import android.view.MotionEvent;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
index f62871f383b3..711a0fc0f478 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
@@ -26,12 +26,13 @@ import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.UNLOCK;
-import com.android.systemui.classifier.FalsingDataProvider;
+import javax.inject.Inject;
/**
* Ensure that the swipe direction generally matches that of the interaction type.
*/
public class TypeClassifier extends FalsingClassifier {
+ @Inject
TypeClassifier(FalsingDataProvider dataProvider) {
super(dataProvider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/ZigZagClassifier.java
index 9ca77d364bc4..383dda498b49 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/ZigZagClassifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_X_PRIMARY_DEVIANCE;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_X_SECONDARY_DEVIANCE;
@@ -25,13 +25,14 @@ import android.graphics.Point;
import android.provider.DeviceConfig;
import android.view.MotionEvent;
-import com.android.systemui.classifier.FalsingDataProvider;
import com.android.systemui.util.DeviceConfigProxy;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import javax.inject.Inject;
+
/**
* Penalizes gestures that change direction in either the x or y too much.
*/
@@ -56,6 +57,7 @@ class ZigZagClassifier extends FalsingClassifier {
private float mLastMaxXDeviance;
private float mLastMaxYDeviance;
+ @Inject
ZigZagClassifier(FalsingDataProvider dataProvider, DeviceConfigProxy deviceConfigProxy) {
super(dataProvider);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
index 53383d65e379..d683a74aedcc 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java
@@ -16,11 +16,13 @@
package com.android.systemui.dagger;
+import android.app.ActivityManager;
import android.content.Context;
import android.util.DisplayMetrics;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
+import com.android.systemui.dagger.qualifiers.TestHarness;
import com.android.systemui.util.concurrency.GlobalConcurrencyModule;
import com.android.wm.shell.animation.FlingAnimationUtils;
@@ -66,4 +68,10 @@ public class GlobalModule {
static UiEventLogger provideUiEventLogger() {
return new UiEventLoggerImpl();
}
+
+ @Provides
+ @TestHarness
+ static boolean provideIsTestHarness() {
+ return ActivityManager.isRunningInUserTestHarness();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/TestHarness.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/TestHarness.java
new file mode 100644
index 000000000000..f68ab188c93c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/TestHarness.java
@@ -0,0 +1,34 @@
+/*
+ * 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.dagger.qualifiers;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+
+/**
+ * An annotation for injecting whether or not we are running in a test environment.
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface TestHarness {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 35874cd8bb28..d7f9c6163b1d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -16,20 +16,20 @@
package com.android.systemui.screenshot;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
import static java.util.Objects.requireNonNull;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
-import android.annotation.SuppressLint;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
-import android.content.res.Configuration;
+import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.PixelFormat;
@@ -52,7 +52,8 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
-import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -60,6 +61,8 @@ import android.widget.Toast;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.UiEventLogger;
+import com.android.internal.policy.PhoneWindow;
+import com.android.settingslib.applications.InterestingConfigChanges;
import com.android.systemui.R;
import com.android.systemui.util.DeviceConfigProxy;
@@ -141,12 +144,13 @@ public class ScreenshotController {
private final WindowManager mWindowManager;
private final WindowManager.LayoutParams mWindowLayoutParams;
- private final Display mDisplay;
private final DisplayMetrics mDisplayMetrics;
private final AccessibilityManager mAccessibilityManager;
private final MediaActionSound mCameraSound;
private final ScrollCaptureClient mScrollCaptureClient;
private final DeviceConfigProxy mConfigProxy;
+ private final PhoneWindow mWindow;
+ private final View mDecorView;
private final Binder mWindowToken;
private ScreenshotView mScreenshotView;
@@ -156,9 +160,6 @@ public class ScreenshotController {
private Animator mScreenshotAnimation;
private Runnable mOnCompleteRunnable;
- private boolean mInDarkMode;
- private boolean mDirectionLTR;
- private boolean mOrientationPortrait;
private final Handler mScreenshotHandler = new Handler(Looper.getMainLooper()) {
@Override
@@ -174,6 +175,15 @@ public class ScreenshotController {
}
};
+ /** Tracks config changes that require re-creating UI */
+ private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
+ ActivityInfo.CONFIG_ORIENTATION
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
+ | ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_UI_MODE
+ | ActivityInfo.CONFIG_SCREEN_LAYOUT
+ | ActivityInfo.CONFIG_ASSETS_PATHS);
+
@Inject
ScreenshotController(
Context context,
@@ -188,25 +198,20 @@ public class ScreenshotController {
mUiEventLogger = uiEventLogger;
final DisplayManager dm = requireNonNull(context.getSystemService(DisplayManager.class));
- mDisplay = dm.getDisplay(DEFAULT_DISPLAY);
- mContext = context.createDisplayContext(mDisplay);
+ final Display display = dm.getDisplay(DEFAULT_DISPLAY);
+ final Context displayContext = context.createDisplayContext(display);
+ mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null);
mWindowManager = mContext.getSystemService(WindowManager.class);
mAccessibilityManager = AccessibilityManager.getInstance(mContext);
mConfigProxy = configProxy;
- reloadAssets();
- Configuration config = mContext.getResources().getConfiguration();
- mInDarkMode = config.isNightModeActive();
- mDirectionLTR = config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
- mOrientationPortrait = config.orientation == ORIENTATION_PORTRAIT;
mWindowToken = new Binder("ScreenshotController");
mScrollCaptureClient.setHostWindowToken(mWindowToken);
// Setup the window that we are going to use
mWindowLayoutParams = new WindowManager.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
- WindowManager.LayoutParams.TYPE_SCREENSHOT,
+ MATCH_PARENT, MATCH_PARENT, /* xpos */ 0, /* ypos */ 0, TYPE_SCREENSHOT,
WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
@@ -217,13 +222,21 @@ public class ScreenshotController {
mWindowLayoutParams.setTitle("ScreenshotAnimation");
mWindowLayoutParams.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- mWindowLayoutParams.setFitInsetsTypes(0 /* types */);
mWindowLayoutParams.token = mWindowToken;
// This is needed to let touches pass through outside the touchable areas
mWindowLayoutParams.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+ mWindow = new PhoneWindow(mContext);
+ mWindow.setWindowManager(mWindowManager, null, null);
+ mWindow.requestFeature(Window.FEATURE_NO_TITLE);
+ mWindow.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
+ mWindow.setBackgroundDrawableResource(android.R.color.transparent);
+ mDecorView = mWindow.getDecorView();
+
+ reloadAssets();
+
mDisplayMetrics = new DisplayMetrics();
- mDisplay.getRealMetrics(mDisplayMetrics);
+ display.getRealMetrics(mDisplayMetrics);
// Setup the Camera shutter sound
mCameraSound = new MediaActionSound();
@@ -233,7 +246,6 @@ public class ScreenshotController {
void takeScreenshotFullscreen(Consumer<Uri> finisher, Runnable onComplete) {
mOnCompleteRunnable = onComplete;
- mDisplay.getRealMetrics(mDisplayMetrics);
takeScreenshotInternal(
finisher,
new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
@@ -254,19 +266,18 @@ public class ScreenshotController {
return;
}
- if (aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) {
- saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, false);
- } else {
- saveScreenshot(screenshot, finisher,
- new Rect(0, 0, screenshot.getWidth(), screenshot.getHeight()), Insets.NONE,
- true);
+ boolean showFlash = false;
+ if (!aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) {
+ showFlash = true;
+ visibleInsets = Insets.NONE;
+ screenshotScreenBounds.set(0, 0, screenshot.getWidth(), screenshot.getHeight());
}
+ saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, showFlash);
}
/**
* Displays a screenshot selector
*/
- @SuppressLint("ClickableViewAccessibility")
void takeScreenshotPartial(final Consumer<Uri> finisher, Runnable onComplete) {
dismissScreenshot(true);
mOnCompleteRunnable = onComplete;
@@ -296,70 +307,27 @@ public class ScreenshotController {
}
}
- private void onConfigChanged(Configuration newConfig) {
- boolean needsUpdate = false;
- // dark mode
- if (newConfig.isNightModeActive()) {
- // Night mode is active, we're using dark theme
- if (!mInDarkMode) {
- mInDarkMode = true;
- needsUpdate = true;
- }
- } else {
- // Night mode is not active, we're using the light theme
- if (mInDarkMode) {
- mInDarkMode = false;
- needsUpdate = true;
- }
- }
-
- // RTL configuration
- switch (newConfig.getLayoutDirection()) {
- case View.LAYOUT_DIRECTION_LTR:
- if (!mDirectionLTR) {
- mDirectionLTR = true;
- needsUpdate = true;
- }
- break;
- case View.LAYOUT_DIRECTION_RTL:
- if (mDirectionLTR) {
- mDirectionLTR = false;
- needsUpdate = true;
- }
- break;
- }
-
- // portrait/landscape orientation
- switch (newConfig.orientation) {
- case ORIENTATION_PORTRAIT:
- if (!mOrientationPortrait) {
- mOrientationPortrait = true;
- needsUpdate = true;
- }
- break;
- case ORIENTATION_LANDSCAPE:
- if (mOrientationPortrait) {
- mOrientationPortrait = false;
- needsUpdate = true;
- }
- break;
- }
-
- if (needsUpdate) {
- reloadAssets();
- }
- }
-
/**
* Update assets (called when the dark theme status changes). We only need to update the dismiss
* button and the actions container background, since the buttons are re-inflated on demand.
*/
private void reloadAssets() {
- boolean wasAttached = mScreenshotView != null && mScreenshotView.isAttachedToWindow();
+ boolean wasAttached = mDecorView.isAttachedToWindow();
if (wasAttached) {
- mWindowManager.removeView(mScreenshotView);
+ mWindowManager.removeView(mDecorView);
}
+ // respect the display cutout in landscape (since we'd otherwise overlap) but not portrait
+ int orientation = mContext.getResources().getConfiguration().orientation;
+ mWindowLayoutParams.setFitInsetsTypes(
+ orientation == ORIENTATION_PORTRAIT ? 0 : WindowInsets.Type.displayCutout());
+
+ // ignore system bar insets for the purpose of window layout
+ mDecorView.setOnApplyWindowInsetsListener((v, insets) -> v.onApplyWindowInsets(
+ new WindowInsets.Builder(insets)
+ .setInsets(WindowInsets.Type.all(), Insets.NONE)
+ .build()));
+
// Inflate the screenshot layout
mScreenshotView = (ScreenshotView)
LayoutInflater.from(mContext).inflate(R.layout.global_screenshot, null);
@@ -382,9 +350,8 @@ public class ScreenshotController {
return false;
});
- if (wasAttached) {
- mWindowManager.addView(mScreenshotView, mWindowLayoutParams);
- }
+ // view is added to window manager in startAnimation
+ mWindow.setContentView(mScreenshotView, mWindowLayoutParams);
}
/**
@@ -448,7 +415,9 @@ public class ScreenshotController {
mScreenBitmap.setHasAlpha(false);
mScreenBitmap.prepareToDraw();
- onConfigChanged(mContext.getResources().getConfiguration());
+ if (mConfigChanges.applyNewConfig(mContext.getResources())) {
+ reloadAssets();
+ }
// The window is focusable by default
setWindowFocusable(true);
@@ -510,10 +479,10 @@ public class ScreenshotController {
mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
mScreenshotHandler.post(() -> {
if (!mScreenshotView.isAttachedToWindow()) {
- mWindowManager.addView(mScreenshotView, mWindowLayoutParams);
+ mWindowManager.addView(mWindow.getDecorView(), mWindowLayoutParams);
}
- mScreenshotView.prepareForAnimation(mScreenBitmap, screenRect, screenInsets);
+ mScreenshotView.prepareForAnimation(mScreenBitmap, screenInsets);
mScreenshotHandler.post(() -> {
mScreenshotView.getViewTreeObserver().addOnComputeInternalInsetsListener(
@@ -541,7 +510,7 @@ public class ScreenshotController {
private void resetScreenshotView() {
if (mScreenshotView.isAttachedToWindow()) {
- mWindowManager.removeView(mScreenshotView);
+ mWindowManager.removeView(mDecorView);
}
mScreenshotView.reset();
mOnCompleteRunnable.run();
@@ -636,8 +605,8 @@ public class ScreenshotController {
} else {
mWindowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
}
- if (mScreenshotView.isAttachedToWindow()) {
- mWindowManager.updateViewLayout(mScreenshotView, mWindowLayoutParams);
+ if (mDecorView.isAttachedToWindow()) {
+ mWindowManager.updateViewLayout(mDecorView, mWindowLayoutParams);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index b020275ae3ae..3814bd2999e9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -240,8 +240,7 @@ public class ScreenshotView extends FrameLayout implements
setOnApplyWindowInsetsListener((v, insets) -> {
if (QuickStepContract.isGesturalMode(mNavMode)) {
- Insets gestureInsets = insets.getInsets(
- WindowInsets.Type.systemGestures());
+ Insets gestureInsets = insets.getInsets(WindowInsets.Type.systemGestures());
mLeftInset = gestureInsets.left;
mRightInset = gestureInsets.right;
} else {
@@ -272,7 +271,7 @@ public class ScreenshotView extends FrameLayout implements
mScreenshotSelectorView.requestFocus();
}
- void prepareForAnimation(Bitmap bitmap, Rect screenRect, Insets screenInsets) {
+ void prepareForAnimation(Bitmap bitmap, Insets screenInsets) {
mScreenshotPreview.setImageDrawable(createScreenDrawable(mResources, bitmap, screenInsets));
// make static preview invisible (from gone) so we can query its location on screen
mScreenshotPreview.setVisibility(View.INVISIBLE);
@@ -284,6 +283,8 @@ public class ScreenshotView extends FrameLayout implements
Rect previewBounds = new Rect();
mScreenshotPreview.getBoundsOnScreen(previewBounds);
+ int[] previewLocation = new int[2];
+ mScreenshotPreview.getLocationInWindow(previewLocation);
float cornerScale =
mCornerSizeX / (mOrientationPortrait ? bounds.width() : bounds.height());
@@ -310,7 +311,8 @@ public class ScreenshotView extends FrameLayout implements
// animate from the current location, to the static preview location
final PointF startPos = new PointF(bounds.centerX(), bounds.centerY());
- final PointF finalPos = new PointF(previewBounds.centerX(), previewBounds.centerY());
+ final PointF finalPos = new PointF(previewLocation[0] + previewBounds.width() / 2f,
+ previewLocation[1] + previewBounds.height() / 2f);
ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 2c82bcb24ad0..4aaea8041abd 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -41,6 +41,8 @@ import android.os.UserManager;
import android.util.Log;
import android.view.WindowManager;
+import androidx.annotation.NonNull;
+
import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.ScreenshotHelper;
import com.android.systemui.R;
@@ -57,9 +59,8 @@ public class TakeScreenshotService extends Service {
private final UserManager mUserManager;
private final UiEventLogger mUiEventLogger;
private final ScreenshotNotificationsController mNotificationsController;
-
- private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-
+ private final Handler mHandler;
+ private final BroadcastReceiver mCloseSystemDialogs = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction()) && mScreenshot != null) {
@@ -68,72 +69,11 @@ public class TakeScreenshotService extends Service {
}
};
- private Handler mHandler = new Handler(Looper.myLooper()) {
- @Override
- public void handleMessage(Message msg) {
- final Messenger callback = msg.replyTo;
- Consumer<Uri> uriConsumer = uri -> {
- Message reply = Message.obtain(null, SCREENSHOT_MSG_URI, uri);
- try {
- callback.send(reply);
- } catch (RemoteException e) {
- }
- };
- Runnable onComplete = () -> {
- Message reply = Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE);
- try {
- callback.send(reply);
- } catch (RemoteException e) {
- }
- };
-
- // If the storage for this user is locked, we have no place to store
- // the screenshot, so skip taking it instead of showing a misleading
- // animation and error notification.
- if (!mUserManager.isUserUnlocked()) {
- Log.w(TAG, "Skipping screenshot because storage is locked!");
- mNotificationsController.notifyScreenshotError(
- R.string.screenshot_failed_to_save_user_locked_text);
- post(() -> uriConsumer.accept(null));
- post(onComplete);
- return;
- }
-
- ScreenshotHelper.ScreenshotRequest screenshotRequest =
- (ScreenshotHelper.ScreenshotRequest) msg.obj;
-
- mUiEventLogger.log(ScreenshotEvent.getScreenshotSource(screenshotRequest.getSource()));
-
- switch (msg.what) {
- case WindowManager.TAKE_SCREENSHOT_FULLSCREEN:
- mScreenshot.takeScreenshotFullscreen(uriConsumer, onComplete);
- break;
- case WindowManager.TAKE_SCREENSHOT_SELECTED_REGION:
- mScreenshot.takeScreenshotPartial(uriConsumer, onComplete);
- break;
- case WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE:
- Bitmap screenshot = BitmapUtil.bundleToHardwareBitmap(
- screenshotRequest.getBitmapBundle());
- Rect screenBounds = screenshotRequest.getBoundsInScreen();
- Insets insets = screenshotRequest.getInsets();
- int taskId = screenshotRequest.getTaskId();
- int userId = screenshotRequest.getUserId();
- ComponentName topComponent = screenshotRequest.getTopComponent();
- mScreenshot.handleImageAsScreenshot(screenshot, screenBounds, insets,
- taskId, userId, topComponent, uriConsumer, onComplete);
- break;
- default:
- Log.d(TAG, "Invalid screenshot option: " + msg.what);
- }
- }
- };
-
@Inject
- public TakeScreenshotService(
- ScreenshotController screenshotController,
- UserManager userManager,
+ public TakeScreenshotService(ScreenshotController screenshotController, UserManager userManager,
UiEventLogger uiEventLogger,
ScreenshotNotificationsController notificationsController) {
+ mHandler = new Handler(Looper.getMainLooper(), this::handleMessage);
mScreenshot = screenshotController;
mUserManager = userManager;
mUiEventLogger = uiEventLogger;
@@ -141,13 +81,9 @@ public class TakeScreenshotService extends Service {
}
@Override
- public IBinder onBind(Intent intent) {
- // register broadcast receiver
- IntentFilter filter = new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS);
- registerReceiver(mBroadcastReceiver, filter);
-
+ public IBinder onBind(@NonNull Intent intent) {
+ registerReceiver(mCloseSystemDialogs, new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS));
return new Messenger(mHandler).getBinder();
-
}
@Override
@@ -155,7 +91,73 @@ public class TakeScreenshotService extends Service {
if (mScreenshot != null) {
mScreenshot.dismissScreenshot(true);
}
- unregisterReceiver(mBroadcastReceiver);
+ unregisterReceiver(mCloseSystemDialogs);
+ return false;
+ }
+
+ /** Respond to incoming Message via Binder (Messenger) */
+ private boolean handleMessage(Message msg) {
+ final Messenger replyTo = msg.replyTo;
+ final Runnable onComplete = () -> sendComplete(replyTo);
+ final Consumer<Uri> uriConsumer = (uri) -> reportUri(replyTo, uri);
+
+ // If the storage for this user is locked, we have no place to store
+ // the screenshot, so skip taking it instead of showing a misleading
+ // animation and error notification.
+ if (!mUserManager.isUserUnlocked()) {
+ Log.w(TAG, "Skipping screenshot because storage is locked!");
+ mNotificationsController.notifyScreenshotError(
+ R.string.screenshot_failed_to_save_user_locked_text);
+ uriConsumer.accept(null);
+ onComplete.run();
+ return true;
+ }
+
+ ScreenshotHelper.ScreenshotRequest screenshotRequest =
+ (ScreenshotHelper.ScreenshotRequest) msg.obj;
+
+ mUiEventLogger.log(ScreenshotEvent.getScreenshotSource(screenshotRequest.getSource()));
+
+ switch (msg.what) {
+ case WindowManager.TAKE_SCREENSHOT_FULLSCREEN:
+ mScreenshot.takeScreenshotFullscreen(uriConsumer, onComplete);
+ break;
+ case WindowManager.TAKE_SCREENSHOT_SELECTED_REGION:
+ mScreenshot.takeScreenshotPartial(uriConsumer, onComplete);
+ break;
+ case WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE:
+ Bitmap screenshot = BitmapUtil.bundleToHardwareBitmap(
+ screenshotRequest.getBitmapBundle());
+ Rect screenBounds = screenshotRequest.getBoundsInScreen();
+ Insets insets = screenshotRequest.getInsets();
+ int taskId = screenshotRequest.getTaskId();
+ int userId = screenshotRequest.getUserId();
+ ComponentName topComponent = screenshotRequest.getTopComponent();
+ mScreenshot.handleImageAsScreenshot(screenshot, screenBounds, insets,
+ taskId, userId, topComponent, uriConsumer, onComplete);
+ break;
+ default:
+ Log.w(TAG, "Invalid screenshot option: " + msg.what);
+ return false;
+ }
return true;
+ };
+
+ private void sendComplete(Messenger target) {
+ try {
+ Log.d(TAG, "sendComplete: " + target);
+ target.send(Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE));
+ } catch (RemoteException e) {
+ Log.d(TAG, "ignored remote exception", e);
+ }
+ }
+
+ private void reportUri(Messenger target, Uri uri) {
+ try {
+ Log.d(TAG, "reportUri: " + target + " -> " + uri);
+ target.send(Message.obtain(null, SCREENSHOT_MSG_URI, uri));
+ } catch (RemoteException e) {
+ Log.d(TAG, "ignored remote exception", e);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index a252a7a12274..3765e5a26e8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -69,7 +69,6 @@ import com.android.systemui.util.wakelock.WakeLock;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.text.NumberFormat;
-import java.util.IllegalFormatConversionException;
import javax.inject.Inject;
@@ -575,24 +574,12 @@ public class KeyguardIndicationController implements StateListener,
String percentage = NumberFormat.getPercentInstance()
.format(mBatteryLevel / 100f);
if (hasChargingTime) {
- // We now have battery percentage in these strings and it's expected that all
- // locales will also have it in the future. For now, we still have to support the old
- // format until all languages get the new translations.
String chargingTimeFormatted = Formatter.formatShortElapsedTimeRoundingUpToMinutes(
mContext, mChargingTimeRemaining);
- try {
- return mContext.getResources().getString(chargingId, chargingTimeFormatted,
- percentage);
- } catch (IllegalFormatConversionException e) {
- return mContext.getResources().getString(chargingId, chargingTimeFormatted);
- }
+ return mContext.getResources().getString(chargingId, chargingTimeFormatted,
+ percentage);
} else {
- // Same as above
- try {
- return mContext.getResources().getString(chargingId, percentage);
- } catch (IllegalFormatConversionException e) {
- return mContext.getResources().getString(chargingId);
- }
+ return mContext.getResources().getString(chargingId, percentage);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 411fbc3ad64c..a879a1ef4b77 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -53,7 +53,6 @@ import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.tracing.ProtoTracer;
import com.android.systemui.tracing.nano.SystemUiTraceProto;
import com.android.wm.shell.ShellCommandHandler;
-import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.nano.WmShellTraceProto;
import com.android.wm.shell.onehanded.OneHanded;
@@ -99,13 +98,11 @@ public final class WMShell extends SystemUI
private final Optional<HideDisplayCutout> mHideDisplayCutoutOptional;
private final ProtoTracer mProtoTracer;
private final Optional<ShellCommandHandler> mShellCommandHandler;
- private final Optional<AppPairs> mAppPairsOptional;
private boolean mIsSysUiStateValid;
private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback;
private KeyguardUpdateMonitorCallback mPipKeyguardCallback;
private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback;
- private KeyguardUpdateMonitorCallback mAppPairsKeyguardCallback;
@Inject
public WMShell(Context context, CommandQueue commandQueue,
@@ -119,8 +116,7 @@ public final class WMShell extends SystemUI
Optional<OneHanded> oneHandedOptional,
Optional<HideDisplayCutout> hideDisplayCutoutOptional,
ProtoTracer protoTracer,
- Optional<ShellCommandHandler> shellCommandHandler,
- Optional<AppPairs> appPairsOptional) {
+ Optional<ShellCommandHandler> shellCommandHandler) {
super(context);
mCommandQueue = commandQueue;
mConfigurationController = configurationController;
@@ -135,7 +131,6 @@ public final class WMShell extends SystemUI
mProtoTracer = protoTracer;
mProtoTracer.add(this);
mShellCommandHandler = shellCommandHandler;
- mAppPairsOptional = appPairsOptional;
}
@Override
@@ -145,7 +140,6 @@ public final class WMShell extends SystemUI
mSplitScreenOptional.ifPresent(this::initSplitScreen);
mOneHandedOptional.ifPresent(this::initOneHanded);
mHideDisplayCutoutOptional.ifPresent(this::initHideDisplayCutout);
- mAppPairsOptional.ifPresent(this::initAppPairs);
}
@VisibleForTesting
@@ -294,16 +288,6 @@ public final class WMShell extends SystemUI
});
}
- void initAppPairs(AppPairs appPairs) {
- mAppPairsKeyguardCallback = new KeyguardUpdateMonitorCallback() {
- @Override
- public void onKeyguardVisibilityChanged(boolean showing) {
- appPairs.onKeyguardVisibilityChanged(showing);
- }
- };
- mKeyguardUpdateMonitor.registerCallback(mAppPairsKeyguardCallback);
- }
-
@Override
public void writeToProto(SystemUiTraceProto proto) {
if (proto.wmShell == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
index 4505b2a87c78..7a1c05890873 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
@@ -84,10 +84,8 @@ public class WMShellModule {
@WMSingleton
@Provides
static AppPairs provideAppPairs(ShellTaskOrganizer shellTaskOrganizer,
- SyncTransactionQueue syncQueue, DisplayController displayController,
- TaskStackListenerImpl taskStackListener) {
- return new AppPairsController(shellTaskOrganizer, syncQueue, displayController,
- taskStackListener);
+ SyncTransactionQueue syncQueue, DisplayController displayController) {
+ return new AppPairsController(shellTaskOrganizer, syncQueue, displayController);
}
@WMSingleton
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
new file mode 100644
index 000000000000..19f0a15c8936
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2020 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.classifier;
+
+import static com.android.systemui.util.mockito.KotlinMockitoHelpersKt.any;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.view.MotionEvent;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.testing.FakeMetricsLogger;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dock.DockManagerFake;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class BrightLineClassifierTest extends SysuiTestCase {
+ private BrightLineFalsingManager mBrightLineFalsingManager;
+ @Mock
+ private FalsingDataProvider mFalsingDataProvider;
+ private final DockManagerFake mDockManager = new DockManagerFake();
+ private final MetricsLogger mMetricsLogger = new FakeMetricsLogger();
+ private final Set<FalsingClassifier> mClassifiers = new HashSet<>();
+ @Mock
+ private SingleTapClassifier mSingleTapClassfier;
+ @Mock
+ private DoubleTapClassifier mDoubleTapClassifier;
+ @Mock
+ private FalsingClassifier mClassifierA;
+ @Mock
+ private FalsingClassifier mClassifierB;
+ private final List<MotionEvent> mMotionEventList = new ArrayList<>();
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mClassifiers.add(mClassifierA);
+ mClassifiers.add(mClassifierB);
+ when(mFalsingDataProvider.isDirty()).thenReturn(true);
+ when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
+ mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mDockManager,
+ mMetricsLogger, mClassifiers, mSingleTapClassfier, mDoubleTapClassifier, false);
+ }
+
+ @Test
+ public void testRegisterSessionListener() {
+ verify(mFalsingDataProvider).addSessionListener(
+ any(FalsingDataProvider.SessionListener.class));
+
+ mBrightLineFalsingManager.cleanup();
+ verify(mFalsingDataProvider).removeSessionListener(
+ any(FalsingDataProvider.SessionListener.class));
+ }
+
+ @Test
+ public void testIsFalseTouch_NoClassifiers() {
+ mClassifiers.clear();
+
+ assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse();
+ }
+
+ @Test
+ public void testIsFalseTouch_ClassffiersPass() {
+ assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse();
+ }
+
+ @Test
+ public void testIsFalseTouch_ClassifierARejects() {
+ when(mClassifierA.isFalseTouch()).thenReturn(true);
+ assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isTrue();
+ }
+
+ @Test
+ public void testIsFalseTouch_ClassifierBRejects() {
+ when(mClassifierB.isFalseTouch()).thenReturn(true);
+ assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isTrue();
+ }
+
+ @Test
+ public void testIsFalseTouch_FaceAuth() {
+ // Even when the classifiers report a false, we should allow.
+ when(mClassifierA.isFalseTouch()).thenReturn(true);
+ when(mFalsingDataProvider.isJustUnlockedWithFace()).thenReturn(true);
+
+ assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse();
+ }
+
+ @Test
+ public void testIsFalseTouch_Docked() {
+ // Even when the classifiers report a false, we should allow.
+ when(mClassifierA.isFalseTouch()).thenReturn(true);
+ mDockManager.setIsDocked(true);
+
+ assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse();
+ }
+
+ @Test
+ public void testIsFalseTap_BasicCheck() {
+ when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(false);
+
+ assertThat(mBrightLineFalsingManager.isFalseTap(false)).isTrue();
+
+ when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(true);
+
+ assertThat(mBrightLineFalsingManager.isFalseTap(false)).isFalse();
+ }
+
+ @Test
+ public void testIsFalseTap_RobustCheck_NoFaceAuth() {
+ when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(true);
+ mFalsingDataProvider.setJustUnlockedWithFace(false);
+ assertThat(mBrightLineFalsingManager.isFalseTap(true)).isTrue();
+ }
+
+ @Test
+ public void testIsFalseTap_RobustCheck_FaceAuth() {
+ when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(true);
+ when(mFalsingDataProvider.isJustUnlockedWithFace()).thenReturn(true);
+ assertThat(mBrightLineFalsingManager.isFalseTap(true)).isFalse();
+ }
+
+ @Test
+ public void testIsFalseDoubleTap() {
+ when(mDoubleTapClassifier.isFalseTouch()).thenReturn(false);
+
+ assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse();
+
+ when(mDoubleTapClassifier.isFalseTouch()).thenReturn(true);
+
+ assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isTrue();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DiagonalClassifierTest.java
index 714d6581ff00..7659db8cc9ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DiagonalClassifierTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
@@ -27,8 +27,6 @@ import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
-import com.android.systemui.classifier.ClassifierTest;
-import com.android.systemui.classifier.FalsingDataProvider;
import com.android.systemui.util.DeviceConfigProxyFake;
import org.junit.After;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
index d66c7a9d43a5..013fa369e876 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@@ -23,8 +23,6 @@ import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
-import com.android.systemui.classifier.ClassifierTest;
-import com.android.systemui.classifier.FalsingDataProvider;
import com.android.systemui.util.DeviceConfigProxyFake;
import org.junit.After;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DoubleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
index 288ab0ad6596..4c4108a0cb90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DoubleTapClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@@ -27,9 +27,6 @@ import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
-import com.android.systemui.classifier.ClassifierTest;
-import com.android.systemui.classifier.FalsingDataProvider;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/PointerCountClassifierTest.java
index b512f0d6ef32..ee289b5b922d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/PointerCountClassifierTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
@@ -26,8 +26,6 @@ import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
-import com.android.systemui.classifier.ClassifierTest;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
index c2e290f166a3..38b025f675ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.GENERIC;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
@@ -28,8 +28,6 @@ import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
-import com.android.systemui.classifier.ClassifierTest;
-import com.android.systemui.classifier.FalsingDataProvider;
import com.android.systemui.util.DeviceConfigProxyFake;
import com.android.systemui.util.sensors.ProximitySensor;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/SingleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java
index d67f2b833deb..941e12e475f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/SingleTapClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@@ -25,9 +25,6 @@ import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
-import com.android.systemui.classifier.ClassifierTest;
-import com.android.systemui.classifier.FalsingDataProvider;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBufferTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
index 1dfffb271f02..6e312594a2e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBufferTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
index 5f3b84c2f7ae..6b9bb4fedd16 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
@@ -33,9 +33,6 @@ import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
-import com.android.systemui.classifier.ClassifierTest;
-import com.android.systemui.classifier.FalsingDataProvider;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
index e49262f5099f..339dd9e9e6d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.classifier.brightline;
+package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@@ -23,7 +23,6 @@ import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
-import com.android.systemui.classifier.ClassifierTest;
import com.android.systemui.util.DeviceConfigProxyFake;
import org.junit.After;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java b/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java
index a6355880c660..37540621557f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java
@@ -22,6 +22,7 @@ package com.android.systemui.dock;
public class DockManagerFake implements DockManager {
DockEventListener mCallback;
AlignmentStateListener mAlignmentListener;
+ private boolean mDocked;
@Override
public void addListener(DockEventListener callback) {
@@ -45,7 +46,11 @@ public class DockManagerFake implements DockManager {
@Override
public boolean isDocked() {
- return false;
+ return mDocked;
+ }
+
+ public void setIsDocked(boolean docked) {
+ mDocked = docked;
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
index 822a6f2ad810..ef25b73fd748 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -34,7 +34,6 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.tracing.ProtoTracer;
import com.android.wm.shell.ShellCommandHandler;
-import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedGestureHandler;
@@ -69,7 +68,6 @@ public class WMShellTest extends SysuiTestCase {
@Mock HideDisplayCutout mHideDisplayCutout;
@Mock ProtoTracer mProtoTracer;
@Mock ShellCommandHandler mShellCommandHandler;
- @Mock AppPairs mAppPairs;
@Before
public void setUp() {
@@ -79,7 +77,7 @@ public class WMShellTest extends SysuiTestCase {
mKeyguardUpdateMonitor, mNavigationModeController,
mScreenLifecycle, mSysUiState, Optional.of(mPip), Optional.of(mSplitScreen),
Optional.of(mOneHanded), Optional.of(mHideDisplayCutout), mProtoTracer,
- Optional.of(mShellCommandHandler), Optional.of(mAppPairs));
+ Optional.of(mShellCommandHandler));
when(mPip.getPipTouchHandler()).thenReturn(mPipTouchHandler);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index be7643ecbd4e..61de53a2a483 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -558,12 +558,13 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
if (mAms.getMagnificationMode(displayId)
== Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
magnificationGestureHandler = new WindowMagnificationGestureHandler(displayContext,
- mAms.getWindowMagnificationMgr(), mAms::onMagnificationScaleChanged,
- detectControlGestures, triggerable, displayId);
+ mAms.getWindowMagnificationMgr(), mAms.getMagnificationController(),
+ detectControlGestures, triggerable,
+ displayId);
} else {
magnificationGestureHandler = new FullScreenMagnificationGestureHandler(displayContext,
- mAms.getFullScreenMagnificationController(),
- mAms::onMagnificationScaleChanged, detectControlGestures, triggerable,
+ mAms.getFullScreenMagnificationController(), mAms.getMagnificationController(),
+ detectControlGestures, triggerable,
new WindowMagnificationPromptController(displayContext, mUserId), displayId);
}
return magnificationGestureHandler;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 4c85490a8086..be2f8f16a412 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -119,7 +119,6 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
import com.android.server.accessibility.magnification.MagnificationController;
-import com.android.server.accessibility.magnification.MagnificationGestureHandler;
import com.android.server.accessibility.magnification.WindowMagnificationManager;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -153,7 +152,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
AccessibilityUserState.ServiceInfoChangeListener,
AccessibilityWindowManager.AccessibilityEventSender,
AccessibilitySecurityPolicy.AccessibilityUserManager,
- MagnificationGestureHandler.ScaleChangedListener,
SystemActionPerformer.SystemActionsChangedListener {
private static final boolean DEBUG = false;
@@ -1066,17 +1064,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
- @Override
- public void onMagnificationScaleChanged(int displayId, int mode) {
- synchronized (mLock) {
- final int capabilities =
- getCurrentUserStateLocked().getMagnificationCapabilitiesLocked();
- if (capabilities == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) {
- getWindowMagnificationMgr().showMagnificationButton(displayId, mode);
- }
- }
- }
-
/**
* Called by AccessibilityInputFilter when it creates or destroys the motionEventInjector.
* Not using a getter because the AccessibilityInputFilter isn't thread-safe
@@ -3000,6 +2987,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
+ /**
+ * Getter of {@link MagnificationController}.
+ *
+ * @return MagnificationController
+ */
+ MagnificationController getMagnificationController() {
+ synchronized (mLock) {
+ return mMagnificationController;
+ }
+ }
+
@Override
public void associateEmbeddedHierarchy(@NonNull IBinder host, @NonNull IBinder embedded) {
synchronized (mLock) {
@@ -3584,6 +3582,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, userState.mUserId);
if (capabilities != userState.getMagnificationCapabilitiesLocked()) {
userState.setMagnificationCapabilitiesLocked(capabilities);
+ mMagnificationController.setMagnificationCapabilities(capabilities);
return true;
}
return false;
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index efb9d87a0bfd..7483ff3ef3f4 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -62,9 +62,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accessibility.gestures.GestureUtils;
-import java.util.ArrayDeque;
-import java.util.Queue;
-
/**
* This class handles full screen magnification in response to touch events.
*
@@ -115,13 +112,10 @@ import java.util.Queue;
*/
@SuppressWarnings("WeakerAccess")
public class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler {
- private static final String LOG_TAG = "FullScreenMagnificationGestureHandler";
- private static final boolean DEBUG_ALL = false;
private static final boolean DEBUG_STATE_TRANSITIONS = false | DEBUG_ALL;
private static final boolean DEBUG_DETECTING = false | DEBUG_ALL;
private static final boolean DEBUG_PANNING_SCALING = false | DEBUG_ALL;
- private static final boolean DEBUG_EVENT_STREAM = false | DEBUG_ALL;
// The MIN_SCALE is different from MagnificationController.MIN_SCALE due
// to AccessibilityService.MagnificationController#setScale() has
@@ -139,41 +133,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
private final ScreenStateReceiver mScreenStateReceiver;
private final WindowMagnificationPromptController mPromptController;
- /**
- * {@code true} if this detector should detect and respond to triple-tap
- * gestures for engaging and disengaging magnification,
- * {@code false} if it should ignore such gestures
- */
- final boolean mDetectTripleTap;
-
- /**
- * Whether {@link DetectingState#mShortcutTriggered shortcut} is enabled
- */
- final boolean mDetectShortcutTrigger;
-
@VisibleForTesting State mCurrentState;
@VisibleForTesting State mPreviousState;
private PointerCoords[] mTempPointerCoords;
private PointerProperties[] mTempPointerProperties;
- private final int mDisplayId;
-
- private final Queue<MotionEvent> mDebugInputEventHistory;
- private final Queue<MotionEvent> mDebugOutputEventHistory;
-
- /**
- * @param context Context for resolving various magnification-related resources
- * @param fullScreenMagnificationController the {@link FullScreenMagnificationController}
- *
- * @param detectTripleTap {@code true} if this detector should detect and respond to triple-tap
- * gestures for engaging and disengaging magnification,
- * {@code false} if it should ignore such gestures
- * @param detectShortcutTrigger {@code true} if this detector should be "triggerable" by some
- * external shortcut invoking {@link #notifyShortcutTriggered},
- * {@code false} if it should ignore such triggers.
- * @param displayId The logical display id.
- */
public FullScreenMagnificationGestureHandler(Context context,
FullScreenMagnificationController fullScreenMagnificationController,
ScaleChangedListener listener,
@@ -181,23 +146,20 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
boolean detectShortcutTrigger,
@NonNull WindowMagnificationPromptController promptController,
int displayId) {
- super(listener);
+ super(displayId, detectTripleTap, detectShortcutTrigger, listener);
if (DEBUG_ALL) {
- Log.i(LOG_TAG,
+ Log.i(mLogTag,
"FullScreenMagnificationGestureHandler(detectTripleTap = " + detectTripleTap
+ ", detectShortcutTrigger = " + detectShortcutTrigger + ")");
}
mFullScreenMagnificationController = fullScreenMagnificationController;
mPromptController = promptController;
- mDisplayId = displayId;
mDelegatingState = new DelegatingState();
mDetectingState = new DetectingState(context);
mViewportDraggingState = new ViewportDraggingState();
mPanningScalingState = new PanningScalingState(context);
- mDetectTripleTap = detectTripleTap;
- mDetectShortcutTrigger = detectShortcutTrigger;
if (mDetectShortcutTrigger) {
mScreenStateReceiver = new ScreenStateReceiver(context, this);
mScreenStateReceiver.register();
@@ -205,36 +167,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
mScreenStateReceiver = null;
}
- mDebugInputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;
- mDebugOutputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;
-
transitionTo(mDetectingState);
}
@Override
- public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
- if (DEBUG_EVENT_STREAM) {
- storeEventInto(mDebugInputEventHistory, event);
- try {
- onMotionEventInternal(event, rawEvent, policyFlags);
- } catch (Exception e) {
- throw new RuntimeException(
- "Exception following input events: " + mDebugInputEventHistory, e);
- }
- } else {
- onMotionEventInternal(event, rawEvent, policyFlags);
- }
- }
-
- private void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
- if (DEBUG_ALL) Slog.i(LOG_TAG, "onMotionEvent(" + event + ")");
-
- if ((!mDetectTripleTap && !mDetectShortcutTrigger)
- || !event.isFromSource(SOURCE_TOUCHSCREEN)) {
- dispatchTransformedEvent(event, rawEvent, policyFlags);
- return;
- }
-
+ void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
handleEventWith(mCurrentState, event, rawEvent, policyFlags);
}
@@ -259,7 +196,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
@Override
public void onDestroy() {
if (DEBUG_STATE_TRANSITIONS) {
- Slog.i(LOG_TAG, "onDestroy(); delayed = "
+ Slog.i(mLogTag, "onDestroy(); delayed = "
+ MotionEventInfo.toString(mDetectingState.mDelayedEventQueue));
}
@@ -299,31 +236,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
mPanningScalingState.clear();
}
- private void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
- int policyFlags) {
- if (DEBUG_EVENT_STREAM) {
- storeEventInto(mDebugOutputEventHistory, event);
- try {
- super.onMotionEvent(event, rawEvent, policyFlags);
- } catch (Exception e) {
- throw new RuntimeException(
- "Exception downstream following input events: " + mDebugInputEventHistory
- + "\nTransformed into output events: " + mDebugOutputEventHistory,
- e);
- }
- } else {
- super.onMotionEvent(event, rawEvent, policyFlags);
- }
- }
-
- private static void storeEventInto(Queue<MotionEvent> queue, MotionEvent event) {
- queue.add(MotionEvent.obtain(event));
- // Prune old events
- while (!queue.isEmpty() && (event.getEventTime() - queue.peek().getEventTime() > 5000)) {
- queue.remove().recycle();
- }
- }
-
private PointerCoords[] getTempPointerCoordsWithMinSize(int size) {
final int oldSize = (mTempPointerCoords != null) ? mTempPointerCoords.length : 0;
if (oldSize < size) {
@@ -358,7 +270,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
private void transitionTo(State state) {
if (DEBUG_STATE_TRANSITIONS) {
- Slog.i(LOG_TAG,
+ Slog.i(mLogTag,
(State.nameOf(mCurrentState) + " -> " + State.nameOf(state)
+ " at " + asList(copyOfRange(new RuntimeException().getStackTrace(), 1, 5)))
.replace(getClass().getName(), ""));
@@ -440,7 +352,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
return true;
}
if (DEBUG_PANNING_SCALING) {
- Slog.i(LOG_TAG, "Panned content by scrollX: " + distanceX
+ Slog.i(mLogTag, "Panned content by scrollX: " + distanceX
+ " scrollY: " + distanceY);
}
mFullScreenMagnificationController.offsetMagnifiedRegion(mDisplayId, distanceX,
@@ -480,7 +392,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
final float pivotX = detector.getFocusX();
final float pivotY = detector.getFocusY();
- if (DEBUG_PANNING_SCALING) Slog.i(LOG_TAG, "Scaled content to: " + scale + "x");
+ if (DEBUG_PANNING_SCALING) Slog.i(mLogTag, "Scaled content to: " + scale + "x");
mFullScreenMagnificationController.setScale(mDisplayId, scale, pivotX, pivotY, false,
AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
mListener.onMagnificationScaleChanged(mDisplayId, getMode());
@@ -945,7 +857,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
private void onTripleTap(MotionEvent up) {
if (DEBUG_DETECTING) {
- Slog.i(LOG_TAG, "onTripleTap(); delayed: "
+ Slog.i(mLogTag, "onTripleTap(); delayed: "
+ MotionEventInfo.toString(mDelayedEventQueue));
}
clear();
@@ -965,7 +877,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
void transitionToViewportDraggingStateAndClear(MotionEvent down) {
- if (DEBUG_DETECTING) Slog.i(LOG_TAG, "onTripleTapAndHold()");
+ if (DEBUG_DETECTING) Slog.i(mLogTag, "onTripleTapAndHold()");
clear();
mViewportDraggingState.mZoomedInBeforeDrag =
@@ -997,7 +909,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
if (mShortcutTriggered == state) {
return;
}
- if (DEBUG_DETECTING) Slog.i(LOG_TAG, "setShortcutTriggered(" + state + ")");
+ if (DEBUG_DETECTING) Slog.i(mLogTag, "setShortcutTriggered(" + state + ")");
mShortcutTriggered = state;
mFullScreenMagnificationController.setForceShowMagnifiableBounds(mDisplayId, state);
@@ -1030,7 +942,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
private void zoomOn(float centerX, float centerY) {
- if (DEBUG_DETECTING) Slog.i(LOG_TAG, "zoomOn(" + centerX + ", " + centerY + ")");
+ if (DEBUG_DETECTING) Slog.i(mLogTag, "zoomOn(" + centerX + ", " + centerY + ")");
final float scale = MathUtils.constrain(
mFullScreenMagnificationController.getPersistedScale(),
@@ -1042,7 +954,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
private void zoomOff() {
- if (DEBUG_DETECTING) Slog.i(LOG_TAG, "zoomOff()");
+ if (DEBUG_DETECTING) Slog.i(mLogTag, "zoomOff()");
mFullScreenMagnificationController.reset(mDisplayId, /* animate */ true);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index 6f81b5cfe3e6..df88ceb95d9e 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -37,7 +37,8 @@ import com.android.server.accessibility.AccessibilityManagerService;
* Handles all magnification controllers initialization, generic interactions
* and magnification mode transition.
*/
-public class MagnificationController implements WindowMagnificationManager.Callback {
+public class MagnificationController implements WindowMagnificationManager.Callback,
+ MagnificationGestureHandler.ScaleChangedListener {
private static final boolean DEBUG = false;
private static final String TAG = "MagnificationController";
@@ -50,6 +51,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
private FullScreenMagnificationController mFullScreenMagnificationController;
private WindowMagnificationManager mWindowMagnificationMgr;
+ private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
/**
* A callback to inform the magnification transition result.
@@ -82,10 +84,18 @@ public class MagnificationController implements WindowMagnificationManager.Callb
public void onPerformScaleAction(int displayId, float scale) {
getWindowMagnificationMgr().setScale(displayId, scale);
getWindowMagnificationMgr().persistScale(displayId);
- mAms.onMagnificationScaleChanged(displayId,
+ onMagnificationScaleChanged(displayId,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
}
+ @Override
+ public void onMagnificationScaleChanged(int displayId, int mode) {
+ if (mMagnificationCapabilities != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) {
+ return;
+ }
+ getWindowMagnificationMgr().showMagnificationButton(displayId, mode);
+ }
+
/**
* Transitions to the target Magnification mode with current center of the magnification mode
* if it is available.
@@ -182,6 +192,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
}
+ public void setMagnificationCapabilities(int capabilities) {
+ mMagnificationCapabilities = capabilities;
+ }
+
private DisableMagnificationCallback getDisableMagnificationEndRunnableLocked(
int displayId) {
return mMagnificationEndRunnableSparseArray.get(displayId);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
index d6f53d2c225c..386d0bbf35ec 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
@@ -16,32 +16,127 @@
package com.android.server.accessibility.magnification;
+import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
+
+import android.annotation.NonNull;
+import android.util.Log;
+import android.util.Slog;
+import android.view.MotionEvent;
+
import com.android.server.accessibility.BaseEventStreamTransformation;
+import java.util.ArrayDeque;
+import java.util.Queue;
+
/**
* A base class that detects gestures and defines common methods for magnification.
*/
public abstract class MagnificationGestureHandler extends BaseEventStreamTransformation {
- protected final ScaleChangedListener mListener;
+ protected final String mLogTag = this.getClass().getSimpleName();
+ protected static final boolean DEBUG_ALL = Log.isLoggable("MagnificationGestureHandler",
+ Log.DEBUG);
+ protected static final boolean DEBUG_EVENT_STREAM = false | DEBUG_ALL;
+ private final Queue<MotionEvent> mDebugInputEventHistory;
+ private final Queue<MotionEvent> mDebugOutputEventHistory;
- protected MagnificationGestureHandler(ScaleChangedListener listener) {
- mListener = listener;
- }
+ /**
+ * The logical display id.
+ */
+ protected final int mDisplayId;
/**
- * Interface for listening to the magnification scaling gesture.
+ * {@code true} if this detector should be "triggerable" by some
+ * external shortcut invoking {@link #notifyShortcutTriggered},
+ * {@code false} if it should ignore such triggers.
*/
+ protected final boolean mDetectShortcutTrigger;
+
+ /**
+ * {@code true} if this detector should detect and respond to triple-tap
+ * gestures for engaging and disengaging magnification,
+ * {@code false} if it should ignore such gestures
+ */
+ protected final boolean mDetectTripleTap;
+
+ /** Interface for listening to the magnification scaling gesture. */
public interface ScaleChangedListener {
/**
* Called when the magnification scale is changed by users.
*
* @param displayId The logical display id
- * @param mode The magnification mode
+ * @param mode The magnification mode
*/
void onMagnificationScaleChanged(int displayId, int mode);
}
+ protected final ScaleChangedListener mListener;
+
+ protected MagnificationGestureHandler(int displayId, boolean detectTripleTap,
+ boolean detectShortcutTrigger,
+ @NonNull ScaleChangedListener listener) {
+ mDisplayId = displayId;
+ mDetectTripleTap = detectTripleTap;
+ mDetectShortcutTrigger = detectShortcutTrigger;
+ mListener = listener;
+
+ mDebugInputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;
+ mDebugOutputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;
+ }
+
+ @Override
+ public final void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ if (DEBUG_ALL) {
+ Slog.i(mLogTag, "onMotionEvent(" + event + ")");
+ }
+ if (DEBUG_EVENT_STREAM) {
+ storeEventInto(mDebugInputEventHistory, event);
+ }
+ if (shouldDispatchTransformedEvent(event)) {
+ dispatchTransformedEvent(event, rawEvent, policyFlags);
+ } else {
+ onMotionEventInternal(event, rawEvent, policyFlags);
+ }
+ }
+
+ private boolean shouldDispatchTransformedEvent(MotionEvent event) {
+ if ((!mDetectTripleTap && !mDetectShortcutTrigger) || !event.isFromSource(
+ SOURCE_TOUCHSCREEN)) {
+ return true;
+ }
+ return false;
+ }
+
+ final void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
+ int policyFlags) {
+ if (DEBUG_EVENT_STREAM) {
+ storeEventInto(mDebugOutputEventHistory, event);
+ try {
+ super.onMotionEvent(event, rawEvent, policyFlags);
+ return;
+ } catch (Exception e) {
+ throw new RuntimeException(
+ "Exception downstream following input events: " + mDebugInputEventHistory
+ + "\nTransformed into output events: " + mDebugOutputEventHistory,
+ e);
+ }
+ }
+ super.onMotionEvent(event, rawEvent, policyFlags);
+ }
+
+ private static void storeEventInto(Queue<MotionEvent> queue, MotionEvent event) {
+ queue.add(MotionEvent.obtain(event));
+ // Prune old events
+ while (!queue.isEmpty() && (event.getEventTime() - queue.peek().getEventTime() > 5000)) {
+ queue.remove().recycle();
+ }
+ }
+
+ /**
+ * Called when this MagnificationGestureHandler handles the motion event.
+ */
+ abstract void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags);
+
/**
* Called when the shortcut target is magnification.
*/
@@ -51,7 +146,6 @@ public abstract class MagnificationGestureHandler extends BaseEventStreamTransfo
* Indicates the magnification mode.
*
* @return the magnification mode of the handler
- *
* @see android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
* @see android.provider.Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
*/
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
index 7d6067c8e1da..7f26b2755900 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
@@ -27,7 +27,6 @@ import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Point;
import android.provider.Settings;
-import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
import android.view.Display;
@@ -38,9 +37,7 @@ import com.android.server.accessibility.EventStreamTransformation;
import com.android.server.accessibility.gestures.MultiTap;
import com.android.server.accessibility.gestures.MultiTapAndHold;
-import java.util.ArrayDeque;
import java.util.List;
-import java.util.Queue;
/**
* This class handles window magnification in response to touch events and shortcut.
@@ -64,12 +61,9 @@ import java.util.Queue;
*/
@SuppressWarnings("WeakerAccess")
public class WindowMagnificationGestureHandler extends MagnificationGestureHandler {
- private static final String LOG_TAG = "WindowMagnificationGestureHandler";
- private static final boolean DEBUG_ALL = Log.isLoggable(LOG_TAG, Log.DEBUG);
private static final boolean DEBUG_STATE_TRANSITIONS = false | DEBUG_ALL;
private static final boolean DEBUG_DETECTING = false | DEBUG_ALL;
- private static final boolean DEBUG_EVENT_STREAM = false | DEBUG_ALL;
//Ensure the range has consistency with FullScreenMagnificationGestureHandler.
private static final float MIN_SCALE = 2.0f;
@@ -88,38 +82,26 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
@VisibleForTesting
State mPreviousState;
- final boolean mDetectShortcutTrigger;
-
private MotionEventDispatcherDelegate mMotionEventDispatcherDelegate;
- private final int mDisplayId;
private final Context mContext;
private final Point mTempPoint = new Point();
- private final Queue<MotionEvent> mDebugOutputEventHistory;
-
- /**
- * @param context Context for resolving various magnification-related resources
- * @param windowMagnificationMgr The {@link WindowMagnificationManager}
- * @param displayId The logical display id.
- */
public WindowMagnificationGestureHandler(Context context,
WindowMagnificationManager windowMagnificationMgr,
- ScaleChangedListener listener, boolean detectTripleTap,
- boolean detectShortcutTrigger, int displayId) {
- super(listener);
+ ScaleChangedListener listener,
+ boolean detectTripleTap, boolean detectShortcutTrigger, int displayId) {
+ super(displayId, detectTripleTap, detectShortcutTrigger, listener);
if (DEBUG_ALL) {
- Slog.i(LOG_TAG,
+ Slog.i(mLogTag,
"WindowMagnificationGestureHandler() , displayId = " + displayId + ")");
}
mContext = context;
mWindowMagnificationMgr = windowMagnificationMgr;
- mDetectShortcutTrigger = detectShortcutTrigger;
- mDisplayId = displayId;
mMotionEventDispatcherDelegate = new MotionEventDispatcherDelegate(context,
- (event, rawEvent, policyFlags) -> super.onMotionEvent(
- event, rawEvent, policyFlags));
+ (event, rawEvent, policyFlags) -> dispatchTransformedEvent(event, rawEvent,
+ policyFlags));
mDelegatingState = new DelegatingState(mMotionEventDispatcherDelegate);
- mDetectingState = new DetectingState(context, detectTripleTap);
+ mDetectingState = new DetectingState(context, mDetectTripleTap);
mObservePanningScalingState = new PanningScalingGestureState(
new PanningScalingHandler(context, MAX_SCALE, MIN_SCALE, true,
new PanningScalingHandler.MagnificationDelegate() {
@@ -142,24 +124,14 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
}
}));
- mDebugOutputEventHistory = DEBUG_EVENT_STREAM ? new ArrayDeque<>() : null;
-
transitionTo(mDetectingState);
}
@Override
- public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
- if (DEBUG_ALL) {
- Slog.i(LOG_TAG, "onMotionEvent(" + event + ")");
- }
- if (!event.isFromSource(SOURCE_TOUCHSCREEN)) {
- dispatchTransformedEvent(event, rawEvent, policyFlags);
- return;
- } else {
- // To keep InputEventConsistencyVerifiers within GestureDetectors happy.
- mObservePanningScalingState.mPanningScalingHandler.onTouchEvent(event);
- mCurrentState.onMotionEvent(event, rawEvent, policyFlags);
- }
+ void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ // To keep InputEventConsistencyVerifiers within GestureDetectors happy.
+ mObservePanningScalingState.mPanningScalingHandler.onTouchEvent(event);
+ mCurrentState.onMotionEvent(event, rawEvent, policyFlags);
}
@Override
@@ -173,7 +145,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
@Override
public void onDestroy() {
if (DEBUG_ALL) {
- Slog.i(LOG_TAG, "onDestroy(); delayed = "
+ Slog.i(mLogTag, "onDestroy(); delayed = "
+ mDetectingState.toString());
}
mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, true);
@@ -183,7 +155,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
@Override
public void notifyShortcutTriggered() {
if (DEBUG_ALL) {
- Slog.i(LOG_TAG, "notifyShortcutTriggered():");
+ Slog.i(mLogTag, "notifyShortcutTriggered():");
}
if (!mDetectShortcutTrigger) {
return;
@@ -205,7 +177,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
private void enableWindowMagnifier(float centerX, float centerY) {
if (DEBUG_ALL) {
- Slog.i(LOG_TAG, "enableWindowMagnifier :" + centerX + ", " + centerY);
+ Slog.i(mLogTag, "enableWindowMagnifier :" + centerX + ", " + centerY);
}
final float scale = MathUtils.constrain(
@@ -216,7 +188,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
private void disableWindowMagnifier() {
if (DEBUG_ALL) {
- Slog.i(LOG_TAG, "disableWindowMagnifier()");
+ Slog.i(mLogTag, "disableWindowMagnifier()");
}
mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, false);
}
@@ -231,7 +203,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
private void onTripleTap(MotionEvent up) {
if (DEBUG_DETECTING) {
- Slog.i(LOG_TAG, "onTripleTap()");
+ Slog.i(mLogTag, "onTripleTap()");
}
toggleMagnification(up.getX(), up.getY());
}
@@ -240,30 +212,6 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
transitionTo(mDetectingState);
}
- private void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
- int policyFlags) {
- if (DEBUG_EVENT_STREAM) {
- storeEventInto(mDebugOutputEventHistory, event);
- try {
- super.onMotionEvent(event, rawEvent, policyFlags);
- } catch (Exception e) {
- throw new RuntimeException(
- "Exception downstream following input events: " + mDebugOutputEventHistory,
- e);
- }
- } else {
- super.onMotionEvent(event, rawEvent, policyFlags);
- }
- }
-
- private static void storeEventInto(Queue<MotionEvent> queue, MotionEvent event) {
- queue.add(MotionEvent.obtain(event));
- // Prune old events.
- while (!queue.isEmpty() && (event.getEventTime() - queue.peek().getEventTime() > 5000)) {
- queue.remove().recycle();
- }
- }
-
/**
* An interface to intercept the {@link MotionEvent} for gesture detection. The intercepted
* events should be delivered to next {@link EventStreamTransformation} with {
@@ -293,7 +241,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
private void transitionTo(State state) {
if (DEBUG_STATE_TRANSITIONS) {
- Slog.i(LOG_TAG, "state transition: " + (State.nameOf(mCurrentState) + " -> "
+ Slog.i(mLogTag, "state transition: " + (State.nameOf(mCurrentState) + " -> "
+ State.nameOf(state) + " at "
+ asList(copyOfRange(new RuntimeException().getStackTrace(), 1, 5)))
.replace(getClass().getName(), ""));
@@ -451,10 +399,10 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
List<MotionEventInfo> delayedEventQueue,
MotionEvent motionEvent) {
if (DEBUG_DETECTING) {
- Slog.d(LOG_TAG, "onGestureDetected : gesture = "
+ Slog.d(mLogTag, "onGestureDetected : gesture = "
+ MagnificationGestureMatcher.gestureIdToString(
gestureId));
- Slog.d(LOG_TAG,
+ Slog.d(mLogTag,
"onGestureDetected : delayedEventQueue = " + delayedEventQueue);
}
if (gestureId == MagnificationGestureMatcher.GESTURE_TWO_FINGER_DOWN
@@ -474,7 +422,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
List<MotionEventInfo> delayedEventQueue,
MotionEvent motionEvent) {
if (DEBUG_DETECTING) {
- Slog.d(LOG_TAG,
+ Slog.d(mLogTag,
"onGestureCancelled : delayedEventQueue = " + delayedEventQueue);
}
mMotionEventDispatcherDelegate.sendDelayedMotionEvents(delayedEventQueue,
diff --git a/services/autofill/java/com/android/server/autofill/TEST_MAPPING b/services/autofill/java/com/android/server/autofill/TEST_MAPPING
new file mode 100644
index 000000000000..cf058add0262
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsAutoFillServiceTestCases",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 614863d6b8f5..17e3456e565b 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -145,6 +145,7 @@ java_library_static {
"SurfaceFlingerProperties",
"com.android.sysprop.watchdog",
],
+ javac_shard_size: 50,
}
java_genrule {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index e8ee18c6f4d4..f0677a23765c 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -41,6 +41,7 @@ import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
@@ -6354,18 +6355,71 @@ public class ConnectivityService extends IConnectivityManager.Stub
nai.declaredMetered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED);
}
- /** Propagates to |nc| the capabilities declared by the underlying networks of |nai|. */
- private void mixInUnderlyingCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
- Network[] underlyingNetworks = nai.declaredUnderlyingNetworks;
- Network defaultNetwork = getNetwork(getDefaultNetwork());
+ /** Modifies |caps| based on the capabilities of the specified underlying networks. */
+ @VisibleForTesting
+ void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks,
+ @NonNull NetworkCapabilities caps, boolean declaredMetered) {
+ final Network defaultNetwork = getNetwork(getDefaultNetwork());
if (underlyingNetworks == null && defaultNetwork != null) {
// null underlying networks means to track the default.
underlyingNetworks = new Network[] { defaultNetwork };
}
+ int[] transportTypes = new int[] { NetworkCapabilities.TRANSPORT_VPN };
+ int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
+ int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
+ boolean metered = declaredMetered; // metered if any underlying is metered, or agentMetered
+ boolean roaming = false; // roaming if any underlying is roaming
+ boolean congested = false; // congested if any underlying is congested
+ boolean suspended = true; // suspended if all underlying are suspended
+
+ boolean hadUnderlyingNetworks = false;
+ if (null != underlyingNetworks) {
+ for (Network underlyingNetwork : underlyingNetworks) {
+ final NetworkAgentInfo underlying =
+ getNetworkAgentInfoForNetwork(underlyingNetwork);
+ if (underlying == null) continue;
+
+ final NetworkCapabilities underlyingCaps = underlying.networkCapabilities;
+ hadUnderlyingNetworks = true;
+ for (int underlyingType : underlyingCaps.getTransportTypes()) {
+ transportTypes = ArrayUtils.appendInt(transportTypes, underlyingType);
+ }
- // TODO(b/124469351): Get capabilities directly from ConnectivityService instead.
- final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
- Vpn.applyUnderlyingCapabilities(cm, underlyingNetworks, nc, nai.declaredMetered);
+ // Merge capabilities of this underlying network. For bandwidth, assume the
+ // worst case.
+ downKbps = NetworkCapabilities.minBandwidth(downKbps,
+ underlyingCaps.getLinkDownstreamBandwidthKbps());
+ upKbps = NetworkCapabilities.minBandwidth(upKbps,
+ underlyingCaps.getLinkUpstreamBandwidthKbps());
+ // If this underlying network is metered, the VPN is metered (it may cost money
+ // to send packets on this network).
+ metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
+ // If this underlying network is roaming, the VPN is roaming (the billing structure
+ // is different than the usual, local one).
+ roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING);
+ // If this underlying network is congested, the VPN is congested (the current
+ // condition of the network affects the performance of this network).
+ congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED);
+ // If this network is not suspended, the VPN is not suspended (the VPN
+ // is able to transfer some data).
+ suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ }
+ }
+ if (!hadUnderlyingNetworks) {
+ // No idea what the underlying networks are; assume reasonable defaults
+ metered = true;
+ roaming = false;
+ congested = false;
+ suspended = false;
+ }
+
+ caps.setTransportTypes(transportTypes);
+ caps.setLinkDownstreamBandwidthKbps(downKbps);
+ caps.setLinkUpstreamBandwidthKbps(upKbps);
+ caps.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
+ caps.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming);
+ caps.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested);
+ caps.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended);
}
/**
@@ -6422,7 +6476,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
if (nai.supportsUnderlyingNetworks()) {
- mixInUnderlyingCapabilities(nai, newNc);
+ applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, newNc, nai.declaredMetered);
}
return newNc;
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index d6bd5a1d7c4c..a45466d98563 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -29,9 +29,9 @@ import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkAgent;
+import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkProvider;
import android.net.RouteInfo;
import android.net.StringNetworkSpecifier;
import android.net.TestNetworkInterface;
@@ -62,7 +62,8 @@ import java.util.concurrent.atomic.AtomicInteger;
/** @hide */
class TestNetworkService extends ITestNetworkManager.Stub {
@NonNull private static final String TAG = TestNetworkService.class.getSimpleName();
- @NonNull private static final String TEST_NETWORK_TYPE = "TEST_NETWORK";
+ @NonNull private static final String TEST_NETWORK_LOGTAG = "TestNetworkAgent";
+ @NonNull private static final String TEST_NETWORK_PROVIDER_NAME = TAG;
@NonNull private static final AtomicInteger sTestTunIndex = new AtomicInteger();
@NonNull private final Context mContext;
@@ -72,6 +73,9 @@ class TestNetworkService extends ITestNetworkManager.Stub {
@NonNull private final HandlerThread mHandlerThread;
@NonNull private final Handler mHandler;
+ @NonNull private final ConnectivityManager mCm;
+ @NonNull private final NetworkProvider mNetworkProvider;
+
// Native method stubs
private static native int jniCreateTunTap(boolean isTun, @NonNull String iface);
@@ -85,6 +89,10 @@ class TestNetworkService extends ITestNetworkManager.Stub {
mContext = Objects.requireNonNull(context, "missing Context");
mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
mNetd = Objects.requireNonNull(NetdService.getInstance(), "could not get netd instance");
+ mCm = mContext.getSystemService(ConnectivityManager.class);
+ mNetworkProvider = new NetworkProvider(mContext, mHandler.getLooper(),
+ TEST_NETWORK_PROVIDER_NAME);
+ mCm.registerNetworkProvider(mNetworkProvider);
}
/**
@@ -150,9 +158,6 @@ class TestNetworkService extends ITestNetworkManager.Stub {
private static final int NETWORK_SCORE = 1; // Use a low, non-zero score.
private final int mUid;
- @NonNull private final NetworkInfo mNi;
- @NonNull private final NetworkCapabilities mNc;
- @NonNull private final LinkProperties mLp;
@GuardedBy("mBinderLock")
@NonNull
@@ -161,20 +166,18 @@ class TestNetworkService extends ITestNetworkManager.Stub {
@NonNull private final Object mBinderLock = new Object();
private TestNetworkAgent(
- @NonNull Looper looper,
@NonNull Context context,
- @NonNull NetworkInfo ni,
+ @NonNull Looper looper,
+ @NonNull NetworkAgentConfig config,
@NonNull NetworkCapabilities nc,
@NonNull LinkProperties lp,
int uid,
- @NonNull IBinder binder)
+ @NonNull IBinder binder,
+ @NonNull NetworkProvider np)
throws RemoteException {
- super(looper, context, TEST_NETWORK_TYPE, ni, nc, lp, NETWORK_SCORE);
+ super(context, looper, TEST_NETWORK_LOGTAG, nc, lp, NETWORK_SCORE, config, np);
mUid = uid;
- mNi = ni;
- mNc = nc;
- mLp = lp;
synchronized (mBinderLock) {
mBinder = binder; // Binder null-checks in create()
@@ -203,9 +206,7 @@ class TestNetworkService extends ITestNetworkManager.Stub {
}
private void teardown() {
- mNi.setDetailedState(DetailedState.DISCONNECTED, null, null);
- mNi.setIsAvailable(false);
- sendNetworkInfo(mNi);
+ unregister();
// Synchronize on mBinderLock to ensure that unlinkToDeath is never called more than
// once (otherwise it could throw an exception)
@@ -238,11 +239,6 @@ class TestNetworkService extends ITestNetworkManager.Stub {
Objects.requireNonNull(context, "missing Context");
// iface and binder validity checked by caller
- // Build network info with special testing type
- NetworkInfo ni = new NetworkInfo(ConnectivityManager.TYPE_TEST, 0, TEST_NETWORK_TYPE, "");
- ni.setDetailedState(DetailedState.CONNECTED, null, null);
- ni.setIsAvailable(true);
-
// Build narrow set of NetworkCapabilities, useful only for testing
NetworkCapabilities nc = new NetworkCapabilities();
nc.clearAll(); // Remove default capabilities.
@@ -290,7 +286,12 @@ class TestNetworkService extends ITestNetworkManager.Stub {
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null, iface));
}
- return new TestNetworkAgent(looper, context, ni, nc, lp, callingUid, binder);
+ final TestNetworkAgent agent = new TestNetworkAgent(context, looper,
+ new NetworkAgentConfig.Builder().build(), nc, lp, callingUid, binder,
+ mNetworkProvider);
+ agent.register();
+ agent.markConnected();
+ return agent;
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index df1081e43262..da6e7ff84525 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -252,6 +252,7 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
+import android.os.SharedMemory;
import android.os.ShellCallback;
import android.os.StrictMode;
import android.os.SystemClock;
@@ -348,6 +349,7 @@ import com.android.server.appop.AppOpsService;
import com.android.server.compat.PlatformCompat;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
import com.android.server.firewall.IntentFirewall;
+import com.android.server.graphics.fonts.FontManagerInternal;
import com.android.server.job.JobSchedulerInternal;
import com.android.server.pm.Installer;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
@@ -4358,6 +4360,11 @@ public class ActivityManagerService extends IActivityManager.Stub
app.info.packageName);
}
}
+ SharedMemory serializedSystemFontMap = null;
+ final FontManagerInternal fm = LocalServices.getService(FontManagerInternal.class);
+ if (fm != null) {
+ serializedSystemFontMap = fm.getSerializedSystemFontMap();
+ }
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
bindApplicationTimeMillis = SystemClock.elapsedRealtime();
@@ -4383,7 +4390,7 @@ public class ActivityManagerService extends IActivityManager.Stub
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
- app.mDisabledCompatChanges);
+ app.mDisabledCompatChanges, serializedSystemFontMap);
} else {
thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
null, null, null, testMode,
@@ -4393,7 +4400,7 @@ public class ActivityManagerService extends IActivityManager.Stub
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
- app.mDisabledCompatChanges);
+ app.mDisabledCompatChanges, serializedSystemFontMap);
}
if (profilerInfo != null) {
profilerInfo.closeFd();
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 234dcc9d74a5..3445275b76dd 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -18,10 +18,7 @@ package com.android.server.connectivity;
import static android.Manifest.permission.BIND_VPN_SERVICE;
import static android.net.ConnectivityManager.NETID_UNSET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE;
@@ -111,7 +108,6 @@ import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnInfo;
import com.android.internal.net.VpnProfile;
-import com.android.internal.util.ArrayUtils;
import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
import com.android.server.net.BaseNetworkObserver;
@@ -463,99 +459,6 @@ public class Vpn {
}
/**
- * Updates {@link #mNetworkCapabilities} based on current underlying networks and returns a
- * defensive copy.
- *
- * <p>Does not propagate updated capabilities to apps.
- *
- * @param defaultNetwork underlying network for VPNs following platform's default
- */
- public synchronized NetworkCapabilities updateCapabilities(@Nullable Network defaultNetwork) {
- if (mConfig == null) {
- // VPN is not running.
- return null;
- }
-
- Network[] underlyingNetworks = mConfig.underlyingNetworks;
- if (underlyingNetworks == null && defaultNetwork != null) {
- // null underlying networks means to track the default.
- underlyingNetworks = new Network[] { defaultNetwork };
- }
- // Only apps targeting Q and above can explicitly declare themselves as metered.
- final boolean isAlwaysMetered = mIsPackageTargetingAtLeastQ && mConfig.isMetered;
-
- applyUnderlyingCapabilities(
- mConnectivityManager,
- underlyingNetworks,
- mNetworkCapabilities,
- isAlwaysMetered);
-
- return new NetworkCapabilities(mNetworkCapabilities);
- }
-
- @VisibleForTesting
- public static void applyUnderlyingCapabilities(
- @NonNull final ConnectivityManager cm,
- @Nullable final Network[] underlyingNetworks,
- @NonNull final NetworkCapabilities caps,
- final boolean isAlwaysMetered) {
- int[] transportTypes = new int[] { NetworkCapabilities.TRANSPORT_VPN };
- int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
- int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
- boolean metered = isAlwaysMetered; // metered if any underlying is metered, or alwaysMetered
- boolean roaming = false; // roaming if any underlying is roaming
- boolean congested = false; // congested if any underlying is congested
- boolean suspended = true; // suspended if all underlying are suspended
-
- boolean hadUnderlyingNetworks = false;
- if (null != underlyingNetworks) {
- for (Network underlying : underlyingNetworks) {
- // TODO(b/124469351): Get capabilities directly from ConnectivityService instead.
- final NetworkCapabilities underlyingCaps = cm.getNetworkCapabilities(underlying);
- if (underlyingCaps == null) continue;
- hadUnderlyingNetworks = true;
- for (int underlyingType : underlyingCaps.getTransportTypes()) {
- transportTypes = ArrayUtils.appendInt(transportTypes, underlyingType);
- }
-
- // Merge capabilities of this underlying network. For bandwidth, assume the
- // worst case.
- downKbps = NetworkCapabilities.minBandwidth(downKbps,
- underlyingCaps.getLinkDownstreamBandwidthKbps());
- upKbps = NetworkCapabilities.minBandwidth(upKbps,
- underlyingCaps.getLinkUpstreamBandwidthKbps());
- // If this underlying network is metered, the VPN is metered (it may cost money
- // to send packets on this network).
- metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
- // If this underlying network is roaming, the VPN is roaming (the billing structure
- // is different than the usual, local one).
- roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING);
- // If this underlying network is congested, the VPN is congested (the current
- // condition of the network affects the performance of this network).
- congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED);
- // If this network is not suspended, the VPN is not suspended (the VPN
- // is able to transfer some data).
- suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
- }
- }
- if (!hadUnderlyingNetworks) {
- // No idea what the underlying networks are; assume the safer defaults
- metered = true;
- roaming = false;
- congested = false;
- suspended = false;
- }
-
- caps.setTransportTypes(transportTypes);
- caps.setLinkDownstreamBandwidthKbps(downKbps);
- caps.setLinkUpstreamBandwidthKbps(upKbps);
- caps.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
- caps.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming);
- caps.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested);
- caps.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended);
- }
-
- /**
* Chooses whether to force all connections to go though VPN.
*
* Used to enable/disable legacy VPN lockdown.
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerInternal.java b/services/core/java/com/android/server/graphics/fonts/FontManagerInternal.java
new file mode 100644
index 000000000000..e4b7b03a8e07
--- /dev/null
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerInternal.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.graphics.fonts;
+
+import android.annotation.Nullable;
+import android.os.SharedMemory;
+
+/** Local interface for {@link FontManagerService}. */
+public interface FontManagerInternal {
+
+ /** Returns a SharedMemory in which the system font map is serialized. */
+ @Nullable SharedMemory getSerializedSystemFontMap();
+}
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
new file mode 100644
index 000000000000..22921ad1ecc2
--- /dev/null
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.graphics.fonts;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.SharedMemory;
+import android.system.ErrnoException;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+
+import java.io.IOException;
+
+/** A service for managing system fonts. */
+// TODO(b/173619554): Add API to update fonts.
+public final class FontManagerService {
+
+ private static final String TAG = "FontManagerService";
+
+ /** Class to manage FontManagerService's lifecycle. */
+ public static final class Lifecycle extends SystemService {
+ private final FontManagerService mService;
+
+ public Lifecycle(@NonNull Context context) {
+ super(context);
+ mService = new FontManagerService();
+ }
+
+ @Override
+ public void onStart() {
+ LocalServices.addService(FontManagerInternal.class,
+ new FontManagerInternal() {
+ @Override
+ @Nullable
+ public SharedMemory getSerializedSystemFontMap() {
+ return mService.getSerializedSystemFontMap();
+ }
+ });
+ }
+ }
+
+ @GuardedBy("this")
+ @Nullable
+ private SharedMemory mSerializedSystemFontMap = null;
+
+ @Nullable
+ private SharedMemory getSerializedSystemFontMap() {
+ synchronized (FontManagerService.this) {
+ if (mSerializedSystemFontMap == null) {
+ mSerializedSystemFontMap = createSerializedSystemFontMapLocked();
+ }
+ return mSerializedSystemFontMap;
+ }
+ }
+
+ @Nullable
+ private SharedMemory createSerializedSystemFontMapLocked() {
+ // TODO(b/173619554): use updated fonts.
+ try {
+ return Typeface.serializeFontMap(Typeface.getSystemFontMap());
+ } catch (IOException | ErrnoException e) {
+ Slog.e(TAG, "Failed to serialize SystemServer system font map", e);
+ }
+ return null;
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/CecMessageBuffer.java b/services/core/java/com/android/server/hdmi/CecMessageBuffer.java
new file mode 100644
index 000000000000..8f971fd7db07
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/CecMessageBuffer.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Buffer for processing the incoming CEC messages while allocating logical addresses.
+ */
+final class CecMessageBuffer {
+ private List<HdmiCecMessage> mBuffer = new ArrayList<>();
+ private HdmiControlService mHdmiControlService;
+
+ CecMessageBuffer(HdmiControlService hdmiControlService) {
+ mHdmiControlService = hdmiControlService;
+ }
+
+ /**
+ * Adds a message to the buffer.
+ * Only certain types of messages need to be buffered.
+ * @param message The message to add to the buffer
+ * @return Whether the message was added to the buffer
+ */
+ public boolean bufferMessage(HdmiCecMessage message) {
+ switch (message.getOpcode()) {
+ case Constants.MESSAGE_ACTIVE_SOURCE:
+ bufferActiveSource(message);
+ return true;
+ case Constants.MESSAGE_IMAGE_VIEW_ON:
+ case Constants.MESSAGE_TEXT_VIEW_ON:
+ bufferImageOrTextViewOn(message);
+ return true;
+ case Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST:
+ bufferSystemAudioModeRequest(message);
+ return true;
+ // Add here if new message that needs to buffer
+ default:
+ // Do not need to buffer messages other than above
+ return false;
+ }
+ }
+
+ /**
+ * Process all messages in the buffer.
+ */
+ public void processMessages() {
+ for (final HdmiCecMessage message : mBuffer) {
+ mHdmiControlService.runOnServiceThread(new Runnable() {
+ @Override
+ public void run() {
+ mHdmiControlService.handleCecCommand(message);
+ }
+ });
+ }
+ mBuffer.clear();
+ }
+
+ private void bufferActiveSource(HdmiCecMessage message) {
+ if (!replaceMessageIfBuffered(message, Constants.MESSAGE_ACTIVE_SOURCE)) {
+ mBuffer.add(message);
+ }
+ }
+
+ private void bufferImageOrTextViewOn(HdmiCecMessage message) {
+ if (!replaceMessageIfBuffered(message, Constants.MESSAGE_IMAGE_VIEW_ON)
+ && !replaceMessageIfBuffered(message, Constants.MESSAGE_TEXT_VIEW_ON)) {
+ mBuffer.add(message);
+ }
+ }
+
+ private void bufferSystemAudioModeRequest(HdmiCecMessage message) {
+ if (!replaceMessageIfBuffered(message, Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST)) {
+ mBuffer.add(message);
+ }
+ }
+
+ // Returns true if the message is replaced
+ private boolean replaceMessageIfBuffered(HdmiCecMessage message, int opcode) {
+ for (int i = 0; i < mBuffer.size(); i++) {
+ HdmiCecMessage bufferedMessage = mBuffer.get(i);
+ if (bufferedMessage.getOpcode() == opcode) {
+ mBuffer.set(i, message);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
index 2374ece1dd65..a261fa1f2741 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
@@ -22,19 +22,12 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
-import android.database.ContentObserver;
import android.hardware.hdmi.HdmiControlManager;
-import android.net.Uri;
import android.os.Environment;
-import android.os.Handler;
-import android.os.Looper;
import android.os.SystemProperties;
-import android.os.UserHandle;
import android.provider.Settings.Global;
-import android.util.ArrayMap;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -95,23 +88,6 @@ public class HdmiCecConfig {
@Nullable private final CecSettings mProductConfig;
@Nullable private final CecSettings mVendorOverride;
- private final ArrayMap<Setting, Set<SettingChangeListener>>
- mSettingChangeListeners = new ArrayMap<>();
-
- private SettingsObserver mSettingsObserver;
-
- /**
- * Listener used to get notifications when value of a setting changes.
- */
- public interface SettingChangeListener {
- /**
- * Called when value of a setting changes.
- *
- * @param setting name of a CEC setting that changed
- */
- void onChange(@NonNull @CecSettingName String setting);
- }
-
/**
* Setting storage input/output helper class.
*/
@@ -183,18 +159,6 @@ public class HdmiCecConfig {
}
}
- private class SettingsObserver extends ContentObserver {
- SettingsObserver(Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- String setting = uri.getLastPathSegment();
- HdmiCecConfig.this.notifyGlobalSettingChanged(setting);
- }
- }
-
@VisibleForTesting
HdmiCecConfig(@NonNull Context context,
@NonNull StorageAdapter storageAdapter,
@@ -347,7 +311,6 @@ public class HdmiCecConfig {
} else if (storage == STORAGE_SHARED_PREFS) {
Slog.d(TAG, "Setting '" + storageKey + "' shared pref.");
mStorageAdapter.storeSharedPref(storageKey, value);
- notifySettingChanged(setting);
}
}
@@ -355,103 +318,6 @@ public class HdmiCecConfig {
return Integer.decode(value.getIntValue());
}
- private void notifyGlobalSettingChanged(String setting) {
- switch (setting) {
- case Global.HDMI_CONTROL_ENABLED:
- notifySettingChanged(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED);
- break;
- case Global.HDMI_CEC_VERSION:
- notifySettingChanged(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION);
- break;
- case Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP:
- notifySettingChanged(HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
- break;
- }
- }
-
- private void notifySettingChanged(@NonNull @CecSettingName String name) {
- Setting setting = getSetting(name);
- if (setting == null) {
- throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
- }
- notifySettingChanged(setting);
- }
-
- private void notifySettingChanged(@NonNull Setting setting) {
- Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
- if (listeners == null) {
- return; // No listeners registered, do nothing.
- }
- for (SettingChangeListener listener: listeners) {
- listener.onChange(setting.getName());
- }
- }
-
- /**
- * This method registers Global Setting change observer.
- * Needs to be called once after initialization of HdmiCecConfig.
- */
- public void registerGlobalSettingsObserver(Looper looper) {
- Handler handler = new Handler(looper);
- mSettingsObserver = new SettingsObserver(handler);
- ContentResolver resolver = mContext.getContentResolver();
- String[] settings = new String[] {
- Global.HDMI_CONTROL_ENABLED,
- Global.HDMI_CEC_VERSION,
- Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
- };
- for (String setting: settings) {
- resolver.registerContentObserver(Global.getUriFor(setting), false,
- mSettingsObserver, UserHandle.USER_ALL);
- }
- }
-
- /**
- * This method unregisters Global Setting change observer.
- */
- public void unregisterGlobalSettingsObserver() {
- ContentResolver resolver = mContext.getContentResolver();
- resolver.unregisterContentObserver(mSettingsObserver);
- }
-
- /**
- * Register change listener for a given setting name.
- */
- public void registerChangeListener(@NonNull @CecSettingName String name,
- SettingChangeListener listener) {
- Setting setting = getSetting(name);
- if (setting == null) {
- throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
- }
- @Storage int storage = getStorage(setting);
- if (storage != STORAGE_GLOBAL_SETTINGS && storage != STORAGE_SHARED_PREFS) {
- throw new IllegalArgumentException("Change listeners for setting '" + name
- + "' not supported.");
- }
- if (!mSettingChangeListeners.containsKey(setting)) {
- mSettingChangeListeners.put(setting, new HashSet<>());
- }
- mSettingChangeListeners.get(setting).add(listener);
- }
-
- /**
- * Remove change listener for a given setting name.
- */
- public void removeChangeListener(@NonNull @CecSettingName String name,
- SettingChangeListener listener) {
- Setting setting = getSetting(name);
- if (setting == null) {
- throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
- }
- if (mSettingChangeListeners.containsKey(setting)) {
- Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
- listeners.remove(listener);
- if (listeners.isEmpty()) {
- mSettingChangeListeners.remove(setting);
- }
- }
- }
-
/**
* Returns a list of all settings based on the XML metadata.
*/
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index fd825d6f6288..56b73ba04d89 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -405,74 +405,7 @@ public class HdmiControlService extends SystemService {
// Use getAtomWriter() instead of accessing directly, to allow dependency injection for testing.
private HdmiCecAtomWriter mAtomWriter = new HdmiCecAtomWriter();
- // Buffer for processing the incoming cec messages while allocating logical addresses.
- private final class CecMessageBuffer {
- private List<HdmiCecMessage> mBuffer = new ArrayList<>();
-
- public boolean bufferMessage(HdmiCecMessage message) {
- switch (message.getOpcode()) {
- case Constants.MESSAGE_ACTIVE_SOURCE:
- bufferActiveSource(message);
- return true;
- case Constants.MESSAGE_IMAGE_VIEW_ON:
- case Constants.MESSAGE_TEXT_VIEW_ON:
- bufferImageOrTextViewOn(message);
- return true;
- case Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST:
- bufferSystemAudioModeRequest(message);
- return true;
- // Add here if new message that needs to buffer
- default:
- // Do not need to buffer messages other than above
- return false;
- }
- }
-
- public void processMessages() {
- for (final HdmiCecMessage message : mBuffer) {
- runOnServiceThread(new Runnable() {
- @Override
- public void run() {
- handleCecCommand(message);
- }
- });
- }
- mBuffer.clear();
- }
-
- private void bufferActiveSource(HdmiCecMessage message) {
- if (!replaceMessageIfBuffered(message, Constants.MESSAGE_ACTIVE_SOURCE)) {
- mBuffer.add(message);
- }
- }
-
- private void bufferImageOrTextViewOn(HdmiCecMessage message) {
- if (!replaceMessageIfBuffered(message, Constants.MESSAGE_IMAGE_VIEW_ON) &&
- !replaceMessageIfBuffered(message, Constants.MESSAGE_TEXT_VIEW_ON)) {
- mBuffer.add(message);
- }
- }
-
- private void bufferSystemAudioModeRequest(HdmiCecMessage message) {
- if (!replaceMessageIfBuffered(message, Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST)) {
- mBuffer.add(message);
- }
- }
-
- // Returns true if the message is replaced
- private boolean replaceMessageIfBuffered(HdmiCecMessage message, int opcode) {
- for (int i = 0; i < mBuffer.size(); i++) {
- HdmiCecMessage bufferedMessage = mBuffer.get(i);
- if (bufferedMessage.getOpcode() == opcode) {
- mBuffer.set(i, message);
- return true;
- }
- }
- return false;
- }
- }
-
- private final CecMessageBuffer mCecMessageBuffer = new CecMessageBuffer();
+ private CecMessageBuffer mCecMessageBuffer = new CecMessageBuffer(this);
private final SelectRequestBuffer mSelectRequestBuffer = new SelectRequestBuffer();
@@ -563,7 +496,6 @@ public class HdmiControlService extends SystemService {
if (mMessageValidator == null) {
mMessageValidator = new HdmiCecMessageValidator(this);
}
- mHdmiCecConfig.registerGlobalSettingsObserver(mIoLooper);
}
private void bootCompleted() {
@@ -988,6 +920,11 @@ public class HdmiControlService extends SystemService {
mMessageValidator = messageValidator;
}
+ @VisibleForTesting
+ void setCecMessageBuffer(CecMessageBuffer cecMessageBuffer) {
+ this.mCecMessageBuffer = cecMessageBuffer;
+ }
+
/**
* Returns {@link Looper} of main thread. Use this {@link Looper} instance
* for tasks that are running on main service thread.
diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
index 0dbc8392b610..63618eef250a 100644
--- a/services/core/java/com/android/server/media/MediaKeyDispatcher.java
+++ b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
+import android.content.Context;
import android.media.session.ISessionManager;
import android.media.session.MediaSession;
import android.os.Binder;
@@ -60,7 +61,7 @@ public abstract class MediaKeyDispatcher {
private Map<Integer, Integer> mOverriddenKeyEvents;
- public MediaKeyDispatcher() {
+ public MediaKeyDispatcher(Context context) {
// Constructor used for reflection
mOverriddenKeyEvents = new HashMap<>();
mOverriddenKeyEvents.put(KeyEvent.KEYCODE_MEDIA_PLAY, 0);
diff --git a/services/core/java/com/android/server/media/MediaServerUtils.java b/services/core/java/com/android/server/media/MediaServerUtils.java
index 5fa2b1ceaae9..a4f11b2470f1 100644
--- a/services/core/java/com/android/server/media/MediaServerUtils.java
+++ b/services/core/java/com/android/server/media/MediaServerUtils.java
@@ -18,6 +18,9 @@ package com.android.server.media;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
import android.os.Binder;
import java.io.PrintWriter;
@@ -29,7 +32,7 @@ class MediaServerUtils {
/**
* Verify that caller holds {@link android.Manifest.permission#DUMP}.
*/
- public static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
+ static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump " + tag + " from from pid="
@@ -40,4 +43,18 @@ class MediaServerUtils {
return true;
}
}
+
+ /**
+ * Whether the given stream is currently active or not.
+ */
+ static boolean isStreamActive(AudioManager audioManager, int stream) {
+ for (AudioPlaybackConfiguration configuration
+ : audioManager.getActivePlaybackConfigurations()) {
+ AudioAttributes attributes = configuration.getAudioAttributes();
+ if (attributes != null && attributes.getVolumeControlStream() == stream) {
+ return configuration.isActive();
+ }
+ }
+ return false;
+ }
}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index f9973529a120..ea6e7d7d0bf6 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -23,7 +23,6 @@ import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.AudioManager;
-import android.media.AudioSystem;
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
@@ -513,7 +512,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
public void run() {
try {
if (useSuggested) {
- if (AudioSystem.isStreamActive(stream, 0)) {
+ if (MediaServerUtils.isStreamActive(mAudioManager, stream)) {
mAudioManager.adjustSuggestedStreamVolumeForUid(stream,
direction, flags, opPackageName, uid, pid,
mContext.getApplicationInfo().targetSdkVersion);
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index c23bfc442bd9..11dbef21b34f 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -43,7 +43,6 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.media.AudioManager;
import android.media.AudioPlaybackConfiguration;
-import android.media.AudioSystem;
import android.media.IRemoteVolumeControllerCallback;
import android.media.Session2Token;
import android.media.session.IActiveSessionsListener;
@@ -94,7 +93,6 @@ import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* System implementation of MediaSessionManager
@@ -149,7 +147,6 @@ public class MediaSessionService extends SystemService implements Monitor {
private SessionPolicyProvider mCustomSessionPolicyProvider;
private MediaKeyDispatcher mCustomMediaKeyDispatcher;
- private Map<Integer, Integer> mOverriddenKeyEventsMap;
public MediaSessionService(Context context) {
super(context);
@@ -780,7 +777,6 @@ public class MediaSessionService extends SystemService implements Monitor {
private void instantiateCustomDispatcher(String nameFromTesting) {
synchronized (mLock) {
mCustomMediaKeyDispatcher = null;
- mOverriddenKeyEventsMap = null;
String customDispatcherClassName = (nameFromTesting == null)
? mContext.getResources().getString(R.string.config_customMediaKeyDispatcher)
@@ -788,9 +784,10 @@ public class MediaSessionService extends SystemService implements Monitor {
try {
if (!TextUtils.isEmpty(customDispatcherClassName)) {
Class customDispatcherClass = Class.forName(customDispatcherClassName);
- Constructor constructor = customDispatcherClass.getDeclaredConstructor();
- mCustomMediaKeyDispatcher = (MediaKeyDispatcher) constructor.newInstance();
- mOverriddenKeyEventsMap = mCustomMediaKeyDispatcher.getOverriddenKeyEvents();
+ Constructor constructor =
+ customDispatcherClass.getDeclaredConstructor(Context.class);
+ mCustomMediaKeyDispatcher =
+ (MediaKeyDispatcher) constructor.newInstance(mContext);
}
} catch (ClassNotFoundException | InstantiationException | InvocationTargetException
| IllegalAccessException | NoSuchMethodException e) {
@@ -810,9 +807,10 @@ public class MediaSessionService extends SystemService implements Monitor {
try {
if (!TextUtils.isEmpty(customProviderClassName)) {
Class customProviderClass = Class.forName(customProviderClassName);
- Constructor constructor = customProviderClass.getDeclaredConstructor();
+ Constructor constructor =
+ customProviderClass.getDeclaredConstructor(Context.class);
mCustomSessionPolicyProvider =
- (SessionPolicyProvider) constructor.newInstance();
+ (SessionPolicyProvider) constructor.newInstance(mContext);
}
} catch (ClassNotFoundException | InstantiationException | InvocationTargetException
| IllegalAccessException | NoSuchMethodException e) {
@@ -2019,7 +2017,7 @@ public class MediaSessionService extends SystemService implements Monitor {
boolean preferSuggestedStream = false;
if (isValidLocalStreamType(suggestedStream)
- && AudioSystem.isStreamActive(suggestedStream, 0)) {
+ && MediaServerUtils.isStreamActive(mAudioManager, suggestedStream)) {
preferSuggestedStream = true;
}
if (session == null || preferSuggestedStream) {
@@ -2028,7 +2026,8 @@ public class MediaSessionService extends SystemService implements Monitor {
+ ". flags=" + flags + ", preferSuggestedStream="
+ preferSuggestedStream + ", session=" + session);
}
- if (musicOnly && !AudioSystem.isStreamActive(AudioManager.STREAM_MUSIC, 0)) {
+ if (musicOnly && !MediaServerUtils.isStreamActive(mAudioManager,
+ AudioManager.STREAM_MUSIC)) {
if (DEBUG_KEY_EVENT) {
Log.d(TAG, "Nothing is playing on the music stream. Skipping volume event,"
+ " flags=" + flags);
@@ -2382,9 +2381,12 @@ public class MediaSessionService extends SystemService implements Monitor {
return;
}
- int overriddenKeyEvents = (mCustomMediaKeyDispatcher == null) ? 0
- : mCustomMediaKeyDispatcher.getOverriddenKeyEvents()
- .get(keyEvent.getKeyCode());
+ int overriddenKeyEvents = 0;
+ if (mCustomMediaKeyDispatcher != null
+ && mCustomMediaKeyDispatcher.getOverriddenKeyEvents() != null) {
+ overriddenKeyEvents = mCustomMediaKeyDispatcher.getOverriddenKeyEvents()
+ .get(keyEvent.getKeyCode());
+ }
cancelTrackingIfNeeded(packageName, pid, uid, asSystemService, keyEvent,
needWakeLock, opPackageName, stream, musicOnly, overriddenKeyEvents);
if (!needTracking(keyEvent, overriddenKeyEvents)) {
diff --git a/services/core/java/com/android/server/media/SessionPolicyProvider.java b/services/core/java/com/android/server/media/SessionPolicyProvider.java
index 5f02a075344e..332c85adec01 100644
--- a/services/core/java/com/android/server/media/SessionPolicyProvider.java
+++ b/services/core/java/com/android/server/media/SessionPolicyProvider.java
@@ -18,6 +18,7 @@ package com.android.server.media;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.content.Context;
import android.media.session.MediaSession;
import java.lang.annotation.Retention;
@@ -54,7 +55,7 @@ public abstract class SessionPolicyProvider {
*/
static final int SESSION_POLICY_IGNORE_BUTTON_SESSION = 1 << 1;
- public SessionPolicyProvider() {
+ public SessionPolicyProvider(Context context) {
// Constructor used for reflection
}
diff --git a/services/core/java/com/android/server/media/metrics/PlaybackMetricsManagerService.java b/services/core/java/com/android/server/media/metrics/PlaybackMetricsManagerService.java
index adb98695161a..9c68349af7d5 100644
--- a/services/core/java/com/android/server/media/metrics/PlaybackMetricsManagerService.java
+++ b/services/core/java/com/android/server/media/metrics/PlaybackMetricsManagerService.java
@@ -19,13 +19,17 @@ package com.android.server.media.metrics;
import android.content.Context;
import android.media.metrics.IPlaybackMetricsManager;
import android.media.metrics.PlaybackMetrics;
+import android.util.Base64;
import com.android.server.SystemService;
+import java.security.SecureRandom;
+
/**
* System service manages playback metrics.
*/
public final class PlaybackMetricsManagerService extends SystemService {
+ private final SecureRandom mSecureRandom;
/**
* Initializes the playback metrics manager service.
@@ -34,6 +38,7 @@ public final class PlaybackMetricsManagerService extends SystemService {
*/
public PlaybackMetricsManagerService(Context context) {
super(context);
+ mSecureRandom = new SecureRandom();
}
@Override
@@ -44,8 +49,16 @@ public final class PlaybackMetricsManagerService extends SystemService {
private final class BinderService extends IPlaybackMetricsManager.Stub {
@Override
- public void reportPlaybackMetrics(PlaybackMetrics metrics, int userId) {
+ public void reportPlaybackMetrics(String sessionId, PlaybackMetrics metrics, int userId) {
// TODO: log it to statsd
}
+
+ @Override
+ public String getSessionId(int userId) {
+ byte[] byteId = new byte[16]; // 128 bits
+ mSecureRandom.nextBytes(byteId);
+ String id = Base64.encodeToString(byteId, Base64.DEFAULT);
+ return id;
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e95b1a2b9d7a..85659edd1321 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1741,6 +1741,14 @@ public class PackageManagerService extends IPackageManager.Stub
private final PackageUsage mPackageUsage = new PackageUsage();
private final CompilerStats mCompilerStats = new CompilerStats();
+ /**
+ * Invalidate the package info cache, which includes updating the cached computer.
+ * @hide
+ */
+ public static void invalidatePackageInfoCache() {
+ PackageManager.invalidatePackageInfoCache();
+ }
+
class PackageHandler extends Handler {
PackageHandler(Looper looper) {
@@ -2683,14 +2691,14 @@ public class PackageManagerService extends IPackageManager.Stub
// We normally invalidate when we write settings, but in cases where we delay and
// coalesce settings writes, this strategy would have us invalidate the cache too late.
// Invalidating on schedule addresses this problem.
- PackageManager.invalidatePackageInfoCache();
+ invalidatePackageInfoCache();
if (!mHandler.hasMessages(WRITE_SETTINGS)) {
mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
}
}
void scheduleWritePackageListLocked(int userId) {
- PackageManager.invalidatePackageInfoCache();
+ invalidatePackageInfoCache();
if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
msg.arg1 = userId;
@@ -2704,7 +2712,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
void scheduleWritePackageRestrictionsLocked(int userId) {
- PackageManager.invalidatePackageInfoCache();
+ invalidatePackageInfoCache();
final int[] userIds = (userId == UserHandle.USER_ALL)
? mUserManager.getUserIds() : new int[]{userId};
for (int nextUserId : userIds) {
@@ -6939,8 +6947,7 @@ public class PackageManagerService extends IPackageManager.Stub
private boolean isPersistentPreferredActivitySetByDpm(Intent intent, int userId,
String resolvedType, int flags) {
- PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
- .get(userId);
+ PersistentPreferredIntentResolver ppir = mSettings.getPersistentPreferredActivities(userId);
//TODO(b/158003772): Remove double query
List<PersistentPreferredActivity> pprefs = ppir != null
? ppir.queryIntent(intent, resolvedType,
@@ -6959,8 +6966,7 @@ public class PackageManagerService extends IPackageManager.Stub
private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
int flags, List<ResolveInfo> query, boolean debug, int userId) {
final int N = query.size();
- PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
- .get(userId);
+ PersistentPreferredIntentResolver ppir = mSettings.getPersistentPreferredActivities(userId);
// Get the list of persistent preferred activities that handle the intent
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
List<PersistentPreferredActivity> pprefs = ppir != null
@@ -7060,7 +7066,7 @@ public class PackageManagerService extends IPackageManager.Stub
return pri;
}
- PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
+ PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
// Get the list of preferred activities that handle the intent
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
List<PreferredActivity> prefs = pir != null
@@ -7287,7 +7293,7 @@ public class PackageManagerService extends IPackageManager.Stub
private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
String resolvedType, int userId) {
- CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
+ CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolvers(userId);
if (resolver != null) {
return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
}
@@ -9889,7 +9895,7 @@ public class PackageManagerService extends IPackageManager.Stub
android.Manifest.permission.INTERACT_ACROSS_PROFILES,
PermissionChecker.PID_UNKNOWN,
callingUid,
- mPmInternal.getPackage(callingUid).getPackageName())
+ getPackage(callingUid).getPackageName())
== PermissionChecker.PERMISSION_GRANTED) {
return;
}
@@ -20447,7 +20453,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
synchronized (mLock) {
- final PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
+ final PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
if (pir != null) {
// Get all of the existing entries that exactly match this filter.
final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
@@ -20544,35 +20550,7 @@ public class PackageManagerService extends IPackageManager.Stub
@GuardedBy("mLock")
private void clearPackagePreferredActivitiesLPw(String packageName,
@NonNull SparseBooleanArray outUserChanged, int userId) {
- ArrayList<PreferredActivity> removed = null;
- for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
- final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
- PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
- if (userId != UserHandle.USER_ALL && userId != thisUserId) {
- continue;
- }
- Iterator<PreferredActivity> it = pir.filterIterator();
- while (it.hasNext()) {
- PreferredActivity pa = it.next();
- // Mark entry for removal only if it matches the package name
- // and the entry is of type "always".
- if (packageName == null ||
- (pa.mPref.mComponent.getPackageName().equals(packageName)
- && pa.mPref.mAlways)) {
- if (removed == null) {
- removed = new ArrayList<>();
- }
- removed.add(pa);
- }
- }
- if (removed != null) {
- for (int j=0; j<removed.size(); j++) {
- PreferredActivity pa = removed.get(j);
- pir.removeFilter(pa);
- }
- outUserChanged.put(thisUserId, true);
- }
- }
+ mSettings.clearPackagePreferredActivities(packageName, outUserChanged, userId);
}
/** This method takes a specific user id as well as UserHandle.USER_ALL. */
@@ -20689,7 +20667,7 @@ public class PackageManagerService extends IPackageManager.Stub
final int userId = UserHandle.getCallingUserId();
// reader
synchronized (mLock) {
- PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
+ PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
if (pir != null) {
final Iterator<PreferredActivity> it = pir.filterIterator();
while (it.hasNext()) {
@@ -20744,35 +20722,9 @@ public class PackageManagerService extends IPackageManager.Stub
throw new SecurityException(
"clearPackagePersistentPreferredActivities can only be run by the system");
}
- ArrayList<PersistentPreferredActivity> removed = null;
boolean changed = false;
synchronized (mLock) {
- for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
- final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
- PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
- .valueAt(i);
- if (userId != thisUserId) {
- continue;
- }
- Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
- while (it.hasNext()) {
- PersistentPreferredActivity ppa = it.next();
- // Mark entry for removal only if it matches the package name.
- if (ppa.mComponent.getPackageName().equals(packageName)) {
- if (removed == null) {
- removed = new ArrayList<>();
- }
- removed.add(ppa);
- }
- }
- if (removed != null) {
- for (int j=0; j<removed.size(); j++) {
- PersistentPreferredActivity ppa = removed.get(j);
- ppir.removeFilter(ppa);
- }
- changed = true;
- }
- }
+ changed = mSettings.clearPackagePersistentPreferredActivities(packageName, userId);
}
if (changed) {
updateDefaultHomeNotLocked(userId);
@@ -22152,33 +22104,9 @@ public class PackageManagerService extends IPackageManager.Stub
}
synchronized (mLock) {
- // Verify that all of the preferred activity components actually
- // exist. It is possible for applications to be updated and at
- // that point remove a previously declared activity component that
- // had been set as a preferred activity. We try to clean this up
- // the next time we encounter that preferred activity, but it is
- // possible for the user flow to never be able to return to that
- // situation so here we do a validity check to make sure we haven't
- // left any junk around.
- ArrayList<PreferredActivity> removed = new ArrayList<>();
- for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
- PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
- removed.clear();
- for (PreferredActivity pa : pir.filterSet()) {
- if (!mComponentResolver.isActivityDefined(pa.mPref.mComponent)) {
- removed.add(pa);
- }
- }
- if (removed.size() > 0) {
- for (int r=0; r<removed.size(); r++) {
- PreferredActivity pa = removed.get(r);
- Slog.w(TAG, "Removing dangling preferred activity: "
- + pa.mPref.mComponent);
- pir.removeFilter(pa);
- }
- mSettings.writePackageRestrictionsLPr(
- mSettings.mPreferredActivities.keyAt(i));
- }
+ ArrayList<Integer> changed = mSettings.systemReady(mComponentResolver);
+ for (int i = 0; i < changed.size(); i++) {
+ mSettings.writePackageRestrictionsLPr(changed.get(i));
}
}
@@ -22689,17 +22617,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
- for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
- PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
- int user = mSettings.mPreferredActivities.keyAt(i);
- if (pir.dump(pw,
- dumpState.getTitlePrinted()
- ? "\nPreferred Activities User " + user + ":"
- : "Preferred Activities User " + user + ":", " ",
- packageName, true, false)) {
- dumpState.setTitlePrinted(true);
- }
- }
+ mSettings.dumpPreferred(pw, dumpState, packageName);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
@@ -24798,6 +24716,26 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
+ private AndroidPackage getPackage(String packageName) {
+ synchronized (mLock) {
+ packageName = resolveInternalPackageNameLPr(
+ packageName, PackageManager.VERSION_CODE_HIGHEST);
+ return mPackages.get(packageName);
+ }
+ }
+
+ private AndroidPackage getPackage(int uid) {
+ synchronized (mLock) {
+ final String[] packageNames = getPackagesForUidInternal(uid, Process.SYSTEM_UID);
+ AndroidPackage pkg = null;
+ final int numPackages = packageNames == null ? 0 : packageNames.length;
+ for (int i = 0; pkg == null && i < numPackages; i++) {
+ pkg = mPackages.get(packageNames[i]);
+ }
+ return pkg;
+ }
+ }
+
private class PackageManagerInternalImpl extends PackageManagerInternal {
@Override
public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
@@ -24908,24 +24846,12 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public AndroidPackage getPackage(String packageName) {
- synchronized (mLock) {
- packageName = resolveInternalPackageNameLPr(
- packageName, PackageManager.VERSION_CODE_HIGHEST);
- return mPackages.get(packageName);
- }
+ return PackageManagerService.this.getPackage(packageName);
}
@Override
public AndroidPackage getPackage(int uid) {
- synchronized (mLock) {
- final String[] packageNames = getPackagesForUidInternal(uid, Process.SYSTEM_UID);
- AndroidPackage pkg = null;
- final int numPackages = packageNames == null ? 0 : packageNames.length;
- for (int i = 0; pkg == null && i < numPackages; i++) {
- pkg = mPackages.get(packageNames[i]);
- }
- return pkg;
- }
+ return PackageManagerService.this.getPackage(uid);
}
@Nullable
@@ -25532,7 +25458,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- PackageManager.invalidatePackageInfoCache();
+ invalidatePackageInfoCache();
return true;
}
diff --git a/services/core/java/com/android/server/pm/PreferredComponent.java b/services/core/java/com/android/server/pm/PreferredComponent.java
index 804faa1b7f0f..ff6b73b36f62 100644
--- a/services/core/java/com/android/server/pm/PreferredComponent.java
+++ b/services/core/java/com/android/server/pm/PreferredComponent.java
@@ -252,6 +252,37 @@ public class PreferredComponent {
return numMatch == NS;
}
+ public boolean sameSet(PreferredComponent pc) {
+ if (mSetPackages == null || pc == null || pc.mSetPackages == null
+ || !sameComponent(pc.mComponent)) {
+ return false;
+ }
+ final int otherPackageCount = pc.mSetPackages.length;
+ final int packageCount = mSetPackages.length;
+ if (otherPackageCount != packageCount) {
+ return false;
+ }
+ for (int i = 0; i < packageCount; i++) {
+ if (!mSetPackages[i].equals(pc.mSetPackages[i])
+ || !mSetClasses[i].equals(pc.mSetClasses[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Returns true if the preferred component represents the provided ComponentName. */
+ private boolean sameComponent(ComponentName comp) {
+ if (mComponent == null || comp == null) {
+ return false;
+ }
+ if (mComponent.getPackageName().equals(comp.getPackageName())
+ && mComponent.getClassName().equals(comp.getClassName())) {
+ return true;
+ }
+ return false;
+ }
+
public boolean isSuperset(List<ResolveInfo> query, boolean excludeSetupWizardPackage) {
if (mSetPackages == null) {
return query == null;
diff --git a/services/core/java/com/android/server/pm/PreferredIntentResolver.java b/services/core/java/com/android/server/pm/PreferredIntentResolver.java
index a261e29b05a7..ff3df130a3cc 100644
--- a/services/core/java/com/android/server/pm/PreferredIntentResolver.java
+++ b/services/core/java/com/android/server/pm/PreferredIntentResolver.java
@@ -22,6 +22,7 @@ import android.content.IntentFilter;
import java.io.PrintWriter;
import com.android.server.IntentResolver;
+import java.util.ArrayList;
public class PreferredIntentResolver
extends IntentResolver<PreferredActivity, PreferredActivity> {
@@ -45,4 +46,24 @@ public class PreferredIntentResolver
protected IntentFilter getIntentFilter(@NonNull PreferredActivity input) {
return input;
}
+
+ public boolean shouldAddPreferredActivity(PreferredActivity pa) {
+ ArrayList<PreferredActivity> pal = findFilters(pa);
+ if (pal == null || pal.isEmpty()) {
+ return true;
+ }
+ if (!pa.mPref.mAlways) {
+ return false;
+ }
+ final int activityCount = pal.size();
+ for (int i = 0; i < activityCount; i++) {
+ PreferredActivity cur = pal.get(i);
+ if (cur.mPref.mAlways
+ && cur.mPref.mMatch == (pa.mPref.mMatch & IntentFilter.MATCH_CATEGORY_MASK)
+ && cur.mPref.sameSet(pa.mPref)) {
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 966090cb96a7..f47b4b46fdd4 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -369,16 +369,16 @@ public final class Settings {
// The user's preferred activities associated with particular intent
// filters.
- final SparseArray<PreferredIntentResolver> mPreferredActivities =
+ private final SparseArray<PreferredIntentResolver> mPreferredActivities =
new SparseArray<PreferredIntentResolver>();
// The persistent preferred activities of the user's profile/device owner
// associated with particular intent filters.
- final SparseArray<PersistentPreferredIntentResolver> mPersistentPreferredActivities =
+ private final SparseArray<PersistentPreferredIntentResolver> mPersistentPreferredActivities =
new SparseArray<PersistentPreferredIntentResolver>();
// For every user, it is used to find to which other users the intent can be forwarded.
- final SparseArray<CrossProfileIntentResolver> mCrossProfileIntentResolvers =
+ private final SparseArray<CrossProfileIntentResolver> mCrossProfileIntentResolvers =
new SparseArray<CrossProfileIntentResolver>();
final ArrayMap<String, SharedUserSetting> mSharedUsers = new ArrayMap<>();
@@ -467,7 +467,7 @@ public final class Settings {
}
private static void invalidatePackageCache() {
- PackageManager.invalidatePackageInfoCache();
+ PackageManagerService.invalidatePackageInfoCache();
ChangeIdStateCache.invalidate();
}
@@ -1312,8 +1312,7 @@ public final class Settings {
PreferredActivity pa = new PreferredActivity(parser);
if (pa.mPref.getParseError() == null) {
final PreferredIntentResolver resolver = editPreferredActivitiesLPw(userId);
- ArrayList<PreferredActivity> pal = resolver.findFilters(pa);
- if (pal == null || pal.size() == 0 || pa.mPref.mAlways) {
+ if (resolver.shouldAddPreferredActivity(pa)) {
resolver.addFilter(pa);
}
} else {
@@ -5543,4 +5542,130 @@ public final class Settings {
}
}
}
+
+ /**
+ * Accessor for preferred activities
+ */
+ PersistentPreferredIntentResolver getPersistentPreferredActivities(int userId) {
+ return mPersistentPreferredActivities.get(userId);
+ }
+
+ PreferredIntentResolver getPreferredActivities(int userId) {
+ return mPreferredActivities.get(userId);
+ }
+
+ CrossProfileIntentResolver getCrossProfileIntentResolvers(int userId) {
+ return mCrossProfileIntentResolvers.get(userId);
+ }
+
+ /** This method takes a specific user id as well as UserHandle.USER_ALL. */
+ void clearPackagePreferredActivities(String packageName,
+ @NonNull SparseBooleanArray outUserChanged, int userId) {
+ ArrayList<PreferredActivity> removed = null;
+ for (int i = 0; i < mPreferredActivities.size(); i++) {
+ final int thisUserId = mPreferredActivities.keyAt(i);
+ PreferredIntentResolver pir = mPreferredActivities.valueAt(i);
+ if (userId != UserHandle.USER_ALL && userId != thisUserId) {
+ continue;
+ }
+ Iterator<PreferredActivity> it = pir.filterIterator();
+ while (it.hasNext()) {
+ PreferredActivity pa = it.next();
+ // Mark entry for removal only if it matches the package name
+ // and the entry is of type "always".
+ if (packageName == null
+ || (pa.mPref.mComponent.getPackageName().equals(packageName)
+ && pa.mPref.mAlways)) {
+ if (removed == null) {
+ removed = new ArrayList<>();
+ }
+ removed.add(pa);
+ }
+ }
+ if (removed != null) {
+ for (int j = 0; j < removed.size(); j++) {
+ PreferredActivity pa = removed.get(j);
+ pir.removeFilter(pa);
+ }
+ outUserChanged.put(thisUserId, true);
+ }
+ }
+ }
+
+ boolean clearPackagePersistentPreferredActivities(String packageName, int userId) {
+ ArrayList<PersistentPreferredActivity> removed = null;
+ boolean changed = false;
+ for (int i = 0; i < mPersistentPreferredActivities.size(); i++) {
+ final int thisUserId = mPersistentPreferredActivities.keyAt(i);
+ PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.valueAt(i);
+ if (userId != thisUserId) {
+ continue;
+ }
+ Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
+ while (it.hasNext()) {
+ PersistentPreferredActivity ppa = it.next();
+ // Mark entry for removal only if it matches the package name.
+ if (ppa.mComponent.getPackageName().equals(packageName)) {
+ if (removed == null) {
+ removed = new ArrayList<>();
+ }
+ removed.add(ppa);
+ }
+ }
+ if (removed != null) {
+ for (int j = 0; j < removed.size(); j++) {
+ PersistentPreferredActivity ppa = removed.get(j);
+ ppir.removeFilter(ppa);
+ }
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ ArrayList<Integer> systemReady(ComponentResolver resolver) {
+ // Verify that all of the preferred activity components actually
+ // exist. It is possible for applications to be updated and at
+ // that point remove a previously declared activity component that
+ // had been set as a preferred activity. We try to clean this up
+ // the next time we encounter that preferred activity, but it is
+ // possible for the user flow to never be able to return to that
+ // situation so here we do a validity check to make sure we haven't
+ // left any junk around.
+ ArrayList<Integer> changed = new ArrayList<>();
+ ArrayList<PreferredActivity> removed = new ArrayList<>();
+ for (int i = 0; i < mPreferredActivities.size(); i++) {
+ PreferredIntentResolver pir = mPreferredActivities.valueAt(i);
+ removed.clear();
+ for (PreferredActivity pa : pir.filterSet()) {
+ if (!resolver.isActivityDefined(pa.mPref.mComponent)) {
+ removed.add(pa);
+ }
+ }
+ if (removed.size() > 0) {
+ for (int r = 0; r < removed.size(); r++) {
+ PreferredActivity pa = removed.get(r);
+ Slog.w(TAG, "Removing dangling preferred activity: "
+ + pa.mPref.mComponent);
+ pir.removeFilter(pa);
+ }
+ changed.add(mPreferredActivities.keyAt(i));
+ }
+ }
+ return changed;
+ }
+
+ void dumpPreferred(PrintWriter pw, DumpState dumpState, String packageName) {
+ for (int i = 0; i < mPreferredActivities.size(); i++) {
+ PreferredIntentResolver pir = mPreferredActivities.valueAt(i);
+ int user = mPreferredActivities.keyAt(i);
+ if (pir.dump(pw,
+ dumpState.getTitlePrinted()
+ ? "\nPreferred Activities User " + user + ":"
+ : "Preferred Activities User " + user + ":", " ",
+ packageName, true, false)) {
+ dumpState.setTitlePrinted(true);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/powerstats/PowerStatsDataStorage.java b/services/core/java/com/android/server/powerstats/PowerStatsDataStorage.java
index 98293570507c..c9595c2eec2b 100644
--- a/services/core/java/com/android/server/powerstats/PowerStatsDataStorage.java
+++ b/services/core/java/com/android/server/powerstats/PowerStatsDataStorage.java
@@ -177,8 +177,28 @@ public class PowerStatsDataStorage {
// filename, so any files that don't match the current version number can be deleted.
File[] files = mDataStorageDir.listFiles();
for (int i = 0; i < files.length; i++) {
- if (!files[i].getName().matches(dataStorageFilename + "(.*)")) {
- files[i].delete();
+ // Meter and model files are stored in the same directory.
+ //
+ // The format of filenames on disk is:
+ // log.powerstats.meter.version.timestamp
+ // log.powerstats.model.version.timestamp
+ //
+ // The format of dataStorageFilenames is:
+ // log.powerstats.meter.version
+ // log.powerstats.model.version
+ //
+ // A PowerStatsDataStorage object is created for meter and model data. Strip off
+ // the version and check that the current file we're checking starts with the stem
+ // (log.powerstats.meter or log.powerstats.model). If the stem matches and the
+ // version number is different, delete the old file.
+ int versionDot = dataStorageFilename.lastIndexOf('.');
+ String beforeVersionDot = dataStorageFilename.substring(0, versionDot);
+ // Check that the stems match.
+ if (files[i].getName().startsWith(beforeVersionDot)) {
+ // Check that the version number matches. If not, delete the old file.
+ if (!files[i].getName().startsWith(dataStorageFilename)) {
+ files[i].delete();
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index b4ca7c5f6ff1..6a50b793de0f 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -425,20 +425,20 @@ class ActivityMetricsLogger {
mLastLogTimeSecs = now;
mWindowState = WINDOW_STATE_INVALID;
- Task stack = mSupervisor.mRootWindowContainer.getTopDisplayFocusedStack();
- if (stack == null) {
+ Task rootTask = mSupervisor.mRootWindowContainer.getTopDisplayFocusedRootTask();
+ if (rootTask == null) {
return;
}
- if (stack.isActivityTypeAssistant()) {
+ if (rootTask.isActivityTypeAssistant()) {
mWindowState = WINDOW_STATE_ASSISTANT;
return;
}
- @WindowingMode int windowingMode = stack.getWindowingMode();
+ @WindowingMode int windowingMode = rootTask.getWindowingMode();
if (windowingMode == WINDOWING_MODE_PINNED) {
- stack = mSupervisor.mRootWindowContainer.findStackBehind(stack);
- windowingMode = stack.getWindowingMode();
+ rootTask = mSupervisor.mRootWindowContainer.findRootTaskBehind(rootTask);
+ windowingMode = rootTask.getWindowingMode();
}
switch (windowingMode) {
case WINDOWING_MODE_FULLSCREEN:
@@ -456,7 +456,7 @@ class ActivityMetricsLogger {
break;
default:
if (windowingMode != WINDOWING_MODE_UNDEFINED) {
- throw new IllegalStateException("Unknown windowing mode for stack=" + stack
+ throw new IllegalStateException("Unknown windowing mode for task=" + rootTask
+ " windowingMode=" + windowingMode);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 75273ecb7534..1b8cc082f598 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1491,13 +1491,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
- ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
+ private ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage,
@Nullable String _launchedFromFeature, Intent _intent, String _resolvedType,
ActivityInfo aInfo, Configuration _configuration, ActivityRecord _resultTo,
String _resultWho, int _reqCode, boolean _componentSpecified,
boolean _rootVoiceInteraction, ActivityTaskSupervisor supervisor,
- ActivityOptions options, ActivityRecord sourceRecord) {
+ ActivityOptions options, ActivityRecord sourceRecord, PersistableBundle persistentState,
+ TaskDescription _taskDescription, long _createTime) {
super(_service.mWindowManager, new Token(_intent).asBinder(), TYPE_APPLICATION, true,
null /* displayContent */, false /* ownerCanManageAppTokens */);
@@ -1652,6 +1653,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mHandoverLaunchDisplayId = options.getLaunchDisplayId();
mLaunchCookie = options.getLaunchCookie();
}
+
+ mPersistentState = persistentState;
+ taskDescription = _taskDescription;
+ if (_createTime > 0) {
+ createTime = _createTime;
+ }
}
/**
@@ -2550,15 +2557,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return FINISH_RESULT_CANCELLED;
}
- final Task stack = getRootTask();
- final boolean mayAdjustTop = (isState(RESUMED) || stack.mResumedActivity == null)
- && stack.isFocusedStackOnDisplay()
+ final Task rootTask = getRootTask();
+ final boolean mayAdjustTop = (isState(RESUMED) || rootTask.mResumedActivity == null)
+ && rootTask.isFocusedStackOnDisplay()
// Do not adjust focus task because the task will be reused to launch new activity.
&& !task.isClearingToReuseTask();
final boolean shouldAdjustGlobalFocus = mayAdjustTop
// It must be checked before {@link #makeFinishingLocked} is called, because a stack
// is not visible if it only contains finishing activities.
- && mRootWindowContainer.isTopDisplayFocusedStack(stack);
+ && mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask);
mAtmService.deferWindowLayout();
try {
@@ -2623,12 +2630,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Tell window manager to prepare for this one to be removed.
setVisibility(false);
- if (stack.mPausingActivity == null) {
+ if (rootTask.mPausingActivity == null) {
ProtoLog.v(WM_DEBUG_STATES, "Finish needs to pause: %s", this);
if (DEBUG_USER_LEAVING) {
Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false");
}
- stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
+ rootTask.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
null /* resuming */, "finish");
}
@@ -2827,7 +2834,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
if (activityRemoved) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
ProtoLog.d(WM_DEBUG_CONTAINERS, "destroyIfPossible: r=%s destroy returned "
@@ -2849,7 +2856,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mTaskSupervisor.mFinishingActivities.add(this);
}
resumeKeyDispatchingLocked();
- return mRootWindowContainer.resumeFocusedStacksTopActivities();
+ return mRootWindowContainer.resumeFocusedTasksTopActivities();
}
/**
@@ -3014,7 +3021,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
removeFromHistory(reason);
}
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
/**
@@ -5206,7 +5213,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
} else {
if (deferRelaunchUntilPaused) {
destroyImmediately("stop-config");
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
} else {
mRootWindowContainer.updatePreviousProcess(this);
}
@@ -5703,7 +5710,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// First find the real culprit... if this activity has stopped, then the key dispatching
// timeout should not be caused by this.
if (stopped) {
- final Task stack = mRootWindowContainer.getTopDisplayFocusedStack();
+ final Task stack = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (stack == null) {
return this;
}
@@ -6091,7 +6098,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Override
public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
t.setLayer(leash, getAnimationLayer());
- getDisplayContent().assignStackOrdering();
+ getDisplayContent().assignRootTaskOrdering();
}
@Override
@@ -7544,18 +7551,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
" resolvedType=" + resolvedType);
}
- final ActivityRecord r = new ActivityRecord(service, null /* caller */,
- 0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, launchedFromFeature,
- intent, resolvedType, aInfo, service.getConfiguration(), null /* resultTo */,
- null /* resultWho */, 0 /* reqCode */, componentSpecified,
- false /* rootVoiceInteraction */, taskSupervisor, null /* options */,
- null /* sourceRecord */);
-
- r.mPersistentState = persistentState;
- r.taskDescription = taskDescription;
- r.createTime = createTime;
-
- return r;
+ return new ActivityRecord.Builder(service)
+ .setLaunchedFromUid(launchedFromUid)
+ .setLaunchedFromPackage(launchedFromPackage)
+ .setLaunchedFromFeature(launchedFromFeature)
+ .setIntent(intent)
+ .setResolvedType(resolvedType)
+ .setActivityInfo(aInfo)
+ .setComponentSpecified(componentSpecified)
+ .setPersistentState(persistentState)
+ .setTaskDescription(taskDescription)
+ .setCreateTime(createTime)
+ .build();
}
private static boolean isInVrUiMode(Configuration config) {
@@ -7983,4 +7990,138 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
return false;
}
+
+ static class Builder {
+ private final ActivityTaskManagerService mAtmService;
+ private WindowProcessController mCallerApp;
+ private int mLaunchedFromPid;
+ private int mLaunchedFromUid;
+ private String mLaunchedFromPackage;
+ private String mLaunchedFromFeature;
+ private Intent mIntent;
+ private String mResolvedType;
+ private ActivityInfo mActivityInfo;
+ private Configuration mConfiguration;
+ private ActivityRecord mResultTo;
+ private String mResultWho;
+ private int mRequestCode;
+ private boolean mComponentSpecified;
+ private boolean mRootVoiceInteraction;
+ private ActivityOptions mOptions;
+ private ActivityRecord mSourceRecord;
+ private PersistableBundle mPersistentState;
+ private TaskDescription mTaskDescription;
+ private long mCreateTime;
+
+ Builder(ActivityTaskManagerService service) {
+ mAtmService = service;
+ }
+
+ Builder setCaller(@NonNull WindowProcessController caller) {
+ mCallerApp = caller;
+ return this;
+ }
+
+ Builder setLaunchedFromPid(int pid) {
+ mLaunchedFromPid = pid;
+ return this;
+ }
+
+ Builder setLaunchedFromUid(int uid) {
+ mLaunchedFromUid = uid;
+ return this;
+ }
+
+ Builder setLaunchedFromPackage(String fromPackage) {
+ mLaunchedFromPackage = fromPackage;
+ return this;
+ }
+
+ Builder setLaunchedFromFeature(String fromFeature) {
+ mLaunchedFromFeature = fromFeature;
+ return this;
+ }
+
+ Builder setIntent(Intent intent) {
+ mIntent = intent;
+ return this;
+ }
+
+ Builder setResolvedType(String resolvedType) {
+ mResolvedType = resolvedType;
+ return this;
+ }
+
+ Builder setActivityInfo(ActivityInfo activityInfo) {
+ mActivityInfo = activityInfo;
+ return this;
+ }
+
+ Builder setResultTo(ActivityRecord resultTo) {
+ mResultTo = resultTo;
+ return this;
+ }
+
+ Builder setResultWho(String resultWho) {
+ mResultWho = resultWho;
+ return this;
+ }
+
+ Builder setRequestCode(int reqCode) {
+ mRequestCode = reqCode;
+ return this;
+ }
+
+ Builder setComponentSpecified(boolean componentSpecified) {
+ mComponentSpecified = componentSpecified;
+ return this;
+ }
+
+ Builder setRootVoiceInteraction(boolean rootVoiceInteraction) {
+ mRootVoiceInteraction = rootVoiceInteraction;
+ return this;
+ }
+
+ Builder setActivityOptions(ActivityOptions options) {
+ mOptions = options;
+ return this;
+ }
+
+ Builder setConfiguration(Configuration config) {
+ mConfiguration = config;
+ return this;
+ }
+
+ Builder setSourceRecord(ActivityRecord source) {
+ mSourceRecord = source;
+ return this;
+ }
+
+ private Builder setPersistentState(PersistableBundle persistentState) {
+ mPersistentState = persistentState;
+ return this;
+ }
+
+ private Builder setTaskDescription(TaskDescription taskDescription) {
+ mTaskDescription = taskDescription;
+ return this;
+ }
+
+ private Builder setCreateTime(long createTime) {
+ mCreateTime = createTime;
+ return this;
+ }
+
+ ActivityRecord build() {
+ if (mConfiguration == null) {
+ mConfiguration = mAtmService.getConfiguration();
+ }
+ return new ActivityRecord(mAtmService, mCallerApp, mLaunchedFromPid,
+ mLaunchedFromUid, mLaunchedFromPackage, mLaunchedFromFeature, mIntent,
+ mResolvedType, mActivityInfo, mConfiguration, mResultTo, mResultWho,
+ mRequestCode, mComponentSpecified, mRootVoiceInteraction,
+ mAtmService.mTaskSupervisor, mOptions, mSourceRecord, mPersistentState,
+ mTaskDescription, mCreateTime);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index b88b54ef08f5..1ff3a3fb1d35 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -664,7 +664,7 @@ class ActivityStarter {
synchronized (mService.mGlobalLock) {
final boolean globalConfigWillChange = mRequest.globalConfig != null
&& mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
- final Task stack = mRootWindowContainer.getTopDisplayFocusedStack();
+ final Task stack = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (stack != null) {
stack.mConfigWillChange = globalConfigWillChange;
}
@@ -900,7 +900,7 @@ class ActivityStarter {
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
if (resultTo != null) {
- sourceRecord = mRootWindowContainer.isInAnyStack(resultTo);
+ sourceRecord = mRootWindowContainer.isInAnyTask(resultTo);
if (DEBUG_RESULTS) {
Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
}
@@ -1135,7 +1135,7 @@ class ActivityStarter {
if (DEBUG_PERMISSIONS_REVIEW) {
final Task focusedStack =
- mRootWindowContainer.getTopDisplayFocusedStack();
+ mRootWindowContainer.getTopDisplayFocusedRootTask();
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
true, false) + "} from uid " + callingUid + " on display "
+ (focusedStack == null ? DEFAULT_DISPLAY
@@ -1161,12 +1161,25 @@ class ActivityStarter {
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
}
+ final ActivityRecord r = new ActivityRecord.Builder(mService)
+ .setCaller(callerApp)
+ .setLaunchedFromPid(callingPid)
+ .setLaunchedFromUid(callingUid)
+ .setLaunchedFromPackage(callingPackage)
+ .setLaunchedFromFeature(callingFeatureId)
+ .setIntent(intent)
+ .setResolvedType(resolvedType)
+ .setActivityInfo(aInfo)
+ .setConfiguration(mService.getGlobalConfiguration())
+ .setResultTo(resultRecord)
+ .setResultWho(resultWho)
+ .setRequestCode(requestCode)
+ .setComponentSpecified(request.componentSpecified)
+ .setRootVoiceInteraction(voiceSession != null)
+ .setActivityOptions(checkedOptions)
+ .setSourceRecord(sourceRecord)
+ .build();
- final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
- callingPackage, callingFeatureId, intent, resolvedType, aInfo,
- mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
- request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
- sourceRecord);
mLastStartActivityRecord = r;
if (r.appTimeTracker == null && sourceRecord != null) {
@@ -1175,7 +1188,7 @@ class ActivityStarter {
r.appTimeTracker = sourceRecord.appTimeTracker;
}
- final Task stack = mRootWindowContainer.getTopDisplayFocusedStack();
+ final Task stack = mRootWindowContainer.getTopDisplayFocusedRootTask();
// If we are starting an activity that is not from the same uid as the currently resumed
// one, check whether app switches are allowed.
@@ -1718,7 +1731,7 @@ class ActivityStarter {
// If the activity being launched is the same as the one currently at the top, then
// we need to check if it should only be launched once.
- final Task topStack = mRootWindowContainer.getTopDisplayFocusedStack();
+ final Task topStack = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (topStack != null) {
startResult = deliverToCurrentTopIfNeeded(topStack, intentGrants);
if (startResult != START_SUCCESS) {
@@ -1806,14 +1819,14 @@ class ActivityStarter {
// task stack to be focusable, then ensure that we now update the focused stack
// accordingly.
if (mTargetStack.isTopActivityFocusable()
- && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
+ && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetStack)) {
mTargetStack.moveToFront("startActivityInner");
}
- mRootWindowContainer.resumeFocusedStacksTopActivities(
+ mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
}
- mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
+ mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetStack);
// Update the recent tasks list immediately when the activity starts
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
@@ -1849,7 +1862,7 @@ class ActivityStarter {
private void computeLaunchParams(ActivityRecord r, ActivityRecord sourceRecord,
Task targetTask) {
final Task sourceStack = mSourceStack != null ? mSourceStack
- : mRootWindowContainer.getTopDisplayFocusedStack();
+ : mRootWindowContainer.getTopDisplayFocusedRootTask();
if (sourceStack != null && sourceStack.inSplitScreenWindowingMode()
&& (mOptions == null
|| mOptions.getLaunchWindowingMode() == WINDOWING_MODE_UNDEFINED)) {
@@ -2048,7 +2061,7 @@ class ActivityStarter {
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
ActivityOptions.abort(mOptions);
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
@@ -2347,7 +2360,7 @@ class ActivityStarter {
if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
ActivityRecord checkedCaller = sourceRecord;
if (checkedCaller == null) {
- Task topFocusedStack = mRootWindowContainer.getTopDisplayFocusedStack();
+ Task topFocusedStack = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (topFocusedStack != null) {
checkedCaller = topFocusedStack.topRunningNonDelayedActivityLocked(mNotTop);
}
@@ -2567,7 +2580,7 @@ class ActivityStarter {
// to the front if the caller is not itself in the front.
final boolean differentTopTask;
if (mTargetStack.getDisplayArea() == mPreferredTaskDisplayArea) {
- final Task focusStack = mTargetStack.mDisplayContent.getFocusedStack();
+ final Task focusStack = mTargetStack.mDisplayContent.getFocusedRootTask();
final ActivityRecord curTop = (focusStack == null)
? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
final Task topTask = curTop != null ? curTop.getTask() : null;
@@ -2634,11 +2647,11 @@ class ActivityStarter {
if (next != null) {
next.setCurrentLaunchCanTurnScreenOn(true);
}
- mRootWindowContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions);
+ mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetStack, null, mOptions);
} else {
ActivityOptions.abort(mOptions);
}
- mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
+ mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetStack);
}
private void setNewTask(Task taskToAffiliate) {
@@ -2713,7 +2726,7 @@ class ActivityStarter {
final boolean onTop =
(aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
- return mRootWindowContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams,
+ return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, onTop, mLaunchParams,
mRequest.realCallingPid, mRequest.realCallingUid);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 8ba76be65cb6..3710120a7934 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1156,7 +1156,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
synchronized (mGlobalLock) {
// If this is coming from the currently resumed activity, it is
// effectively saying that app switches are allowed at this point.
- final Task stack = getTopDisplayFocusedStack();
+ final Task stack = getTopDisplayFocusedRootTask();
if (stack != null && stack.mResumedActivity != null
&& stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
mAppSwitchesAllowedTime = 0;
@@ -1470,7 +1470,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
sourceToken = resultTo;
}
- sourceRecord = mRootWindowContainer.isInAnyStack(sourceToken);
+ sourceRecord = mRootWindowContainer.isInAnyTask(sourceToken);
if (sourceRecord == null) {
throw new SecurityException("Called with bad activity token: " + sourceToken);
}
@@ -2039,7 +2039,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public boolean isTopActivityImmersive() {
enforceNotIsolatedCaller("isTopActivityImmersive");
synchronized (mGlobalLock) {
- final Task topFocusedStack = getTopDisplayFocusedStack();
+ final Task topFocusedStack = getTopDisplayFocusedRootTask();
if (topFocusedStack == null) {
return false;
}
@@ -2074,7 +2074,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public int getFrontActivityScreenCompatMode() {
enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
synchronized (mGlobalLock) {
- final Task stack = getTopDisplayFocusedStack();
+ final Task stack = getTopDisplayFocusedRootTask();
final ActivityRecord r = stack != null ? stack.topRunningActivity() : null;
if (r == null) {
return ActivityManager.COMPAT_MODE_UNKNOWN;
@@ -2089,7 +2089,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
"setFrontActivityScreenCompatMode");
ApplicationInfo ai;
synchronized (mGlobalLock) {
- final Task stack = getTopDisplayFocusedStack();
+ final Task stack = getTopDisplayFocusedRootTask();
final ActivityRecord r = stack != null ? stack.topRunningActivity() : null;
if (r == null) {
Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
@@ -2165,7 +2165,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public void notifyActivityDrawn(IBinder token) {
if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
synchronized (mGlobalLock) {
- ActivityRecord r = mRootWindowContainer.isInAnyStack(token);
+ ActivityRecord r = mRootWindowContainer.isInAnyTask(token);
if (r != null) {
r.getRootTask().notifyActivityDrawnLocked(r);
}
@@ -2201,7 +2201,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- Task focusedStack = getTopDisplayFocusedStack();
+ Task focusedStack = getTopDisplayFocusedRootTask();
if (focusedStack != null) {
return mRootWindowContainer.getRootTaskInfo(focusedStack.mTaskId);
}
@@ -2219,14 +2219,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final long callingId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- final Task task = mRootWindowContainer.getStack(taskId);
+ final Task task = mRootWindowContainer.getRootTask(taskId);
if (task == null) {
Slog.w(TAG, "setFocusedRootTask: No task with id=" + taskId);
return;
}
final ActivityRecord r = task.topRunningActivity();
if (r != null && r.moveFocusableActivityToTop("setFocusedRootTask")) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
}
} finally {
@@ -2248,7 +2248,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
final ActivityRecord r = task.topRunningActivityLocked();
if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
}
} finally {
@@ -2508,7 +2508,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
synchronized (mGlobalLock) {
final long origId = Binder.clearCallingIdentity();
try {
- final Task topFocusedStack = getTopDisplayFocusedStack();
+ final Task topFocusedStack = getTopDisplayFocusedRootTask();
if (topFocusedStack != null) {
topFocusedStack.unhandledBackLocked();
}
@@ -2820,7 +2820,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
ProtoLog.d(WM_DEBUG_TASKS, "moveTaskToRootTask: moving task=%d to "
+ "rootTaskId=%d toTop=%b", taskId, rootTaskId, toTop);
- final Task rootTask = mRootWindowContainer.getStack(rootTaskId);
+ final Task rootTask = mRootWindowContainer.getRootTask(rootTaskId);
if (rootTask == null) {
throw new IllegalStateException(
"moveTaskToRootTask: No rootTask for rootTaskId=" + rootTaskId);
@@ -3088,8 +3088,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return;
}
- final Task stack = mRootWindowContainer.getTopDisplayFocusedStack();
- if (stack == null || task != stack.getTopMostTask()) {
+ final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
+ if (rootTask == null || task != rootTask.getTopMostTask()) {
throw new IllegalArgumentException("Invalid task, not in foreground");
}
@@ -3370,7 +3370,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
final Task stack = r.getRootTask();
- final Task task = stack.getDisplayArea().createStack(stack.getWindowingMode(),
+ final Task task = stack.getDisplayArea().createRootTask(stack.getWindowingMode(),
stack.getActivityType(), !ON_TOP, ainfo, intent,
false /* createdByOrganizer */);
@@ -3533,7 +3533,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
try {
ProtoLog.d(WM_DEBUG_TASKS, "moveRootTaskToDisplay: moving taskId=%d to "
+ "displayId=%d", taskId, displayId);
- mRootWindowContainer.moveStackToDisplay(taskId, displayId, ON_TOP);
+ mRootWindowContainer.moveRootTaskToDisplay(taskId, displayId, ON_TOP);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -3741,7 +3741,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
"enqueueAssistContext()");
synchronized (mGlobalLock) {
- final Task stack = getTopDisplayFocusedStack();
+ final Task stack = getTopDisplayFocusedRootTask();
ActivityRecord activity = stack != null ? stack.getTopNonFinishingActivity() : null;
if (activity == null) {
Slog.w(TAG, "getAssistContextExtras failed: no top activity");
@@ -3870,7 +3870,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public boolean isAssistDataAllowedOnCurrentActivity() {
int userId;
synchronized (mGlobalLock) {
- final Task focusedStack = getTopDisplayFocusedStack();
+ final Task focusedStack = getTopDisplayFocusedRootTask();
if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
return false;
}
@@ -3890,7 +3890,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
try {
synchronized (mGlobalLock) {
ActivityRecord caller = ActivityRecord.forTokenLocked(token);
- ActivityRecord top = getTopDisplayFocusedStack().getTopNonFinishingActivity();
+ ActivityRecord top = getTopDisplayFocusedRootTask().getTopNonFinishingActivity();
if (top != caller) {
Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
+ " is not current top " + top);
@@ -4069,7 +4069,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final long ident = Binder.clearCallingIdentity();
try {
- return mRootWindowContainer.moveTopStackActivityToPinnedRootTask(rootTaskId);
+ return mRootWindowContainer.moveTopRootTaskActivityToPinnedRootTask(rootTaskId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4113,7 +4113,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
r.setPictureInPictureParams(params);
final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
- mRootWindowContainer.moveActivityToPinnedStack(
+ mRootWindowContainer.moveActivityToPinnedRootTask(
r, "enterPictureInPictureMode");
final Task stack = r.getRootTask();
stack.setPictureInPictureAspectRatio(aspectRatio);
@@ -4345,7 +4345,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
synchronized (mGlobalLock) {
- ActivityRecord activity = getTopDisplayFocusedStack().getTopNonFinishingActivity();
+ ActivityRecord activity = getTopDisplayFocusedRootTask().getTopNonFinishingActivity();
if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
throw new SecurityException("Only focused activity can call startVoiceInteraction");
}
@@ -4749,7 +4749,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
Slog.i(TAG, "Moving " + r.shortComponentName + " from display " + r.getDisplayId()
+ " to main display for VR");
- mRootWindowContainer.moveStackToDisplay(
+ mRootWindowContainer.moveRootTaskToDisplay(
r.getRootTaskId(), DEFAULT_DISPLAY, true /* toTop */);
}
mH.post(() -> {
@@ -4813,8 +4813,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
}
- Task getTopDisplayFocusedStack() {
- return mRootWindowContainer.getTopDisplayFocusedStack();
+ Task getTopDisplayFocusedRootTask() {
+ return mRootWindowContainer.getTopDisplayFocusedRootTask();
}
/** Pokes the task persister. */
@@ -5827,7 +5827,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
/** Applies latest configuration and/or visibility updates if needed. */
boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
boolean kept = true;
- final Task mainStack = mRootWindowContainer.getTopDisplayFocusedStack();
+ final Task mainStack = mRootWindowContainer.getTopDisplayFocusedRootTask();
// mainStack is null during startup.
if (mainStack != null) {
if (changes != 0 && starting == null) {
@@ -6082,8 +6082,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
static final int REPORT_TIME_TRACKER_MSG = 1;
- static final int FIRST_ACTIVITY_STACK_MSG = 100;
- static final int FIRST_SUPERVISOR_STACK_MSG = 200;
+ static final int FIRST_ACTIVITY_TASK_MSG = 100;
+ static final int FIRST_SUPERVISOR_TASK_MSG = 200;
H(Looper looper) {
super(looper);
@@ -6292,7 +6292,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
"setFocusedActivity: No activity record matching token=" + token);
}
if (r.moveFocusableActivityToTop("setFocusedActivity")) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
}
}
@@ -6796,7 +6796,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
if (!restarting && hasVisibleActivities) {
deferWindowLayout();
try {
- if (!mRootWindowContainer.resumeFocusedStacksTopActivities()) {
+ if (!mRootWindowContainer.resumeFocusedTasksTopActivities()) {
// If there was nothing to resume, and we are not already restarting
// this process, but there is a visible activity that is hosted by the
// process...then make sure all visible activities are running, taking
@@ -6849,7 +6849,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
if (mRootWindowContainer.finishDisabledPackageActivities(
packageName, disabledClasses, true /* doit */, false /* evenPersistent */,
userId, false /* onlyRemoveNoProcess */) && booted) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
mTaskSupervisor.scheduleIdle();
}
@@ -6879,7 +6879,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public void resumeTopActivities(boolean scheduleIdle) {
synchronized (mGlobalLock) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
if (scheduleIdle) {
mTaskSupervisor.scheduleIdle();
}
@@ -7056,7 +7056,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
mRootWindowContainer.dumpDisplayConfigs(pw, " ");
}
if (dumpAll) {
- final Task topFocusedStack = getTopDisplayFocusedStack();
+ final Task topFocusedStack = getTopDisplayFocusedRootTask();
if (dumpPackage == null && topFocusedStack != null) {
pw.println(" mConfigWillChange: " + topFocusedStack.mConfigWillChange);
}
@@ -7139,7 +7139,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
synchronized (mGlobalLock) {
if (dumpPackage == null) {
getGlobalConfiguration().dumpDebug(proto, GLOBAL_CONFIGURATION);
- final Task topFocusedStack = getTopDisplayFocusedStack();
+ final Task topFocusedStack = getTopDisplayFocusedRootTask();
if (topFocusedStack != null) {
proto.write(CONFIG_WILL_CHANGE, topFocusedStack.mConfigWillChange);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index d0c26af82d99..73d99724c65f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -63,7 +63,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
-import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_SUPERVISOR_STACK_MSG;
+import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_SUPERVISOR_TASK_MSG;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_ALLOWLISTED;
import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE;
@@ -176,18 +176,18 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
/** How long we wait until giving up on the activity telling us it released the top state. */
private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT = 500;
- private static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
- private static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
- private static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
- private static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
- private static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
- private static final int PROCESS_STOPPING_AND_FINISHING_MSG = FIRST_SUPERVISOR_STACK_MSG + 5;
- private static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
- private static final int RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
- private static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14;
- private static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15;
- private static final int START_HOME_MSG = FIRST_SUPERVISOR_STACK_MSG + 16;
- private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 17;
+ private static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG;
+ private static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_TASK_MSG + 1;
+ private static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_TASK_MSG + 2;
+ private static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 3;
+ private static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 4;
+ private static final int PROCESS_STOPPING_AND_FINISHING_MSG = FIRST_SUPERVISOR_TASK_MSG + 5;
+ private static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_TASK_MSG + 12;
+ private static final int RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 13;
+ private static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_TASK_MSG + 14;
+ private static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_TASK_MSG + 15;
+ private static final int START_HOME_MSG = FIRST_SUPERVISOR_TASK_MSG + 16;
+ private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG = FIRST_SUPERVISOR_TASK_MSG + 17;
// Used to indicate that windows of activities should be preserved during the resize.
static final boolean PRESERVE_WINDOWS = true;
@@ -202,8 +202,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// Used to indicate that a task is removed it should also be removed from recents.
static final boolean REMOVE_FROM_RECENTS = true;
- /** True if the docked stack is currently being resized. */
- private boolean mDockedStackResizing;
+ /** True if the docked root task is currently being resized. */
+ private boolean mDockedRootTaskResizing;
// Activity actions an app cannot start if it uses a permission which is not granted.
private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION =
@@ -307,7 +307,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
/** The target stack bounds for the picture-in-picture mode changed that we need to report to
* the application */
- private Rect mPipModeChangedTargetStackBounds;
+ private Rect mPipModeChangedTargetRootTaskBounds;
/** Used on user changes */
final ArrayList<UserState> mStartingUsers = new ArrayList<>();
@@ -386,17 +386,17 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
final ActivityRecord r;
final ActivityRecord sourceRecord;
final int startFlags;
- final Task stack;
+ final Task rootTask;
final WindowProcessController callerApp;
final NeededUriGrants intentGrants;
PendingActivityLaunch(ActivityRecord r, ActivityRecord sourceRecord,
- int startFlags, Task stack, WindowProcessController callerApp,
+ int startFlags, Task rootTask, WindowProcessController callerApp,
NeededUriGrants intentGrants) {
this.r = r;
this.sourceRecord = sourceRecord;
this.startFlags = startFlags;
- this.stack = stack;
+ this.rootTask = rootTask;
this.callerApp = callerApp;
this.intentGrants = intentGrants;
}
@@ -501,11 +501,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
getKeyguardController().setWindowManager(wm);
}
- void moveRecentsStackToFront(String reason) {
- final Task recentsStack = mRootWindowContainer.getDefaultTaskDisplayArea()
- .getStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
- if (recentsStack != null) {
- recentsStack.moveToFront(reason);
+ void moveRecentsRootTaskToFront(String reason) {
+ final Task recentsRootTask = mRootWindowContainer.getDefaultTaskDisplayArea()
+ .getRootTask(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
+ if (recentsRootTask != null) {
+ recentsRootTask.moveToFront(reason);
}
}
@@ -944,7 +944,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// launching the initial activity (that is, home), so that it can have
// a chance to initialize itself while in the background, making the
// switch back to it faster and look better.
- if (mRootWindowContainer.isTopDisplayFocusedStack(rootTask)) {
+ if (mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask)) {
mService.getActivityStartController().startSetupActivity();
}
@@ -1376,10 +1376,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
task.setBounds(bounds);
Task stack =
- mRootWindowContainer.getLaunchStack(null, options, task, ON_TOP);
+ mRootWindowContainer.getLaunchRootTask(null, options, task, ON_TOP);
if (stack != currentStack) {
- moveHomeStackToFrontIfNeeded(flags, stack.getDisplayArea(), reason);
+ moveHomeRootTaskToFrontIfNeeded(flags, stack.getDisplayArea(), reason);
task.reparent(stack, ON_TOP, REPARENT_KEEP_ROOT_TASK_AT_FRONT, !ANIMATE,
DEFER_RESUME, reason);
currentStack = stack;
@@ -1398,7 +1398,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
if (!reparented) {
- moveHomeStackToFrontIfNeeded(flags, currentStack.getDisplayArea(), reason);
+ moveHomeRootTaskToFrontIfNeeded(flags, currentStack.getDisplayArea(), reason);
}
final ActivityRecord r = task.getTopNonFinishingActivity();
@@ -1412,16 +1412,16 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
mRootWindowContainer.getDefaultTaskDisplayArea(), currentStack, forceNonResizeable);
}
- private void moveHomeStackToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea,
+ private void moveHomeRootTaskToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea,
String reason) {
- final Task focusedStack = taskDisplayArea.getFocusedStack();
+ final Task focusedRootTask = taskDisplayArea.getFocusedRootTask();
if ((taskDisplayArea.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
&& (flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0)
- || (focusedStack != null && focusedStack.isActivityTypeRecents())) {
+ || (focusedRootTask != null && focusedRootTask.isActivityTypeRecents())) {
// We move home stack to front when we are on a fullscreen display area and caller has
// requested the home activity to move with it. Or the previous stack is recents.
- taskDisplayArea.moveHomeStackToFront(reason);
+ taskDisplayArea.moveHomeRootTaskToFront(reason);
}
}
@@ -1441,15 +1441,15 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
void setSplitScreenResizing(boolean resizing) {
- if (resizing == mDockedStackResizing) {
+ if (resizing == mDockedRootTaskResizing) {
return;
}
- mDockedStackResizing = resizing;
+ mDockedRootTaskResizing = resizing;
mWindowManager.setDockedStackResizing(resizing);
}
- private void removePinnedStackInSurfaceTransaction(Task stack) {
+ private void removePinnedRootTaskInSurfaceTransaction(Task rootTask) {
/**
* Workaround: Force-stop all the activities in the pinned stack before we reparent them
* to the fullscreen stack. This is to guarantee that when we are removing a stack,
@@ -1459,9 +1459,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
* marked invisible as well and added to the stopping list. After which we process the
* stopping list by handling the idle.
*/
- stack.cancelAnimation();
- stack.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */);
- stack.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
+ rootTask.cancelAnimation();
+ rootTask.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */);
+ rootTask.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
activityIdleInternal(null /* idleActivity */, false /* fromTimeout */,
true /* processPausingActivities */, null /* configuration */);
@@ -1471,17 +1471,17 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
mService.deferWindowLayout();
try {
- stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
- if (stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
- stack.setBounds(null);
+ rootTask.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ if (rootTask.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
+ rootTask.setBounds(null);
}
- toDisplay.getDefaultTaskDisplayArea().positionTaskBehindHome(stack);
+ toDisplay.getDefaultTaskDisplayArea().positionTaskBehindHome(rootTask);
// Follow on the workaround: activities are kept force hidden till the new windowing
// mode is set.
- stack.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, false /* set */);
+ rootTask.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, false /* set */);
mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
} finally {
mService.continueWindowLayout();
}
@@ -1489,7 +1489,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
private void removeRootTaskInSurfaceTransaction(Task rootTask) {
if (rootTask.getWindowingMode() == WINDOWING_MODE_PINNED) {
- removePinnedStackInSurfaceTransaction(rootTask);
+ removePinnedRootTaskInSurfaceTransaction(rootTask);
} else {
final PooledConsumer c = PooledLambda.obtainConsumer(
ActivityTaskSupervisor::processRemoveTask, this, PooledLambda.__(Task.class));
@@ -1627,7 +1627,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
*/
boolean restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop) {
final Task stack =
- mRootWindowContainer.getLaunchStack(null, aOptions, task, onTop);
+ mRootWindowContainer.getLaunchRootTask(null, aOptions, task, onTop);
final WindowContainer parent = task.getParent();
if (parent == stack || task == stack) {
@@ -1668,7 +1668,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
* the various checks on tasks that are going to be reparented from one stack to another.
*/
// TODO: Look into changing users to this method to DisplayContent.resolveWindowingMode()
- Task getReparentTargetStack(Task task, Task stack, boolean toTop) {
+ Task getReparentTargetRootTask(Task task, Task stack, boolean toTop) {
final Task prevStack = task.getRootTask();
final int rootTaskId = stack.mTaskId;
final boolean inMultiWindowMode = stack.inMultiWindowMode();
@@ -1709,7 +1709,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
if (prevStack != null) {
return prevStack;
}
- stack = stack.getDisplayArea().createStack(
+ stack = stack.getDisplayArea().createRootTask(
WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), toTop);
}
return stack;
@@ -1739,7 +1739,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
boolean timedout = false;
final long endTime = System.currentTimeMillis() + timeout;
while (true) {
- if (!mRootWindowContainer.putStacksToSleep(
+ if (!mRootWindowContainer.putTasksToSleep(
true /* allowDelay */, true /* shuttingDown */)) {
long timeRemaining = endTime - System.currentTimeMillis();
if (timeRemaining > 0) {
@@ -1776,7 +1776,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
return;
}
- if (!mRootWindowContainer.putStacksToSleep(
+ if (!mRootWindowContainer.putTasksToSleep(
allowDelay, false /* shuttingDown */)) {
return;
}
@@ -1931,7 +1931,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
mService.getLockTaskController().dump(pw, prefix);
pw.print(prefix);
pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
- pw.println(prefix + "mUserStackInFront=" + mRootWindowContainer.mUserStackInFront);
+ pw.println(prefix + "mUserRootTaskInFront=" + mRootWindowContainer.mUserRootTaskInFront);
pw.println(prefix + "mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
if (!mWaitingForActivityVisible.isEmpty()) {
pw.println(prefix + "mWaitingForActivityVisible=");
@@ -2058,7 +2058,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
*/
void updateTopResumedActivityIfNeeded() {
final ActivityRecord prevTopActivity = mTopResumedActivity;
- final Task topStack = mRootWindowContainer.getTopDisplayFocusedStack();
+ final Task topStack = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (topStack == null || topStack.mResumedActivity == prevTopActivity) {
if (mService.isSleepingLocked()) {
// There won't be a next resumed activity. The top process should still be updated
@@ -2242,7 +2242,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
}
- void logStackState() {
+ void logRootTaskState() {
mActivityMetricsLogger.logWindowState();
}
@@ -2281,7 +2281,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
task.forAllActivities(c);
c.recycle();
- mPipModeChangedTargetStackBounds = targetStackBounds;
+ mPipModeChangedTargetRootTaskBounds = targetStackBounds;
if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
@@ -2436,7 +2436,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
case REPORT_PIP_MODE_CHANGED_MSG: {
for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
final ActivityRecord r = mPipModeChangedActivities.remove(i);
- r.updatePictureInPictureMode(mPipModeChangedTargetStackBounds,
+ r.updatePictureInPictureMode(mPipModeChangedTargetRootTaskBounds,
false /* forceUpdate */);
}
} break;
@@ -2452,7 +2452,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
activityIdleFromMessage((ActivityRecord) msg.obj, false /* fromTimeout */);
} break;
case RESUME_TOP_ACTIVITY_MSG: {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
} break;
case SLEEP_TIMEOUT_MSG: {
if (mService.isSleepingOrShuttingDownLocked()) {
@@ -2542,7 +2542,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// from whatever is started from the recents activity, so move the home stack
// forward.
// TODO (b/115289124): Multi-display supports for recents.
- mRootWindowContainer.getDefaultTaskDisplayArea().moveHomeStackToFront(
+ mRootWindowContainer.getDefaultTaskDisplayArea().moveHomeRootTaskToFront(
"startActivityFromRecents");
}
@@ -2570,6 +2570,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
mService.getActivityStartController().postStartActivityProcessingForLastStarter(
task.getTopNonFinishingActivity(), ActivityManager.START_TASK_TO_FRONT,
task.getRootTask());
+
+ // As it doesn't go to ActivityStarter.executeRequest() path, we need to resume
+ // app switching here also.
+ mService.resumeAppSwitches();
+
return ActivityManager.START_TASK_TO_FRONT;
}
callingPackage = task.mCallingPackage;
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index 4b349542e347..c22bd20da042 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -17,10 +17,10 @@
package com.android.server.wm;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
-import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import android.app.ActivityManager;
import android.app.AppGlobals;
@@ -313,7 +313,7 @@ public final class CompatModePackages {
scheduleWrite();
- final Task stack = mService.getTopDisplayFocusedStack();
+ final Task stack = mService.getTopDisplayFocusedRootTask();
ActivityRecord starting = stack.restartPackage(packageName);
// Tell all processes that loaded this package about the change.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5df50500f3e2..1d2cd0a0a350 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1320,7 +1320,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
false /* deferResume */, null /* result */);
activityRecord.frozenBeforeDestroy = true;
if (!kept) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
} else {
// We have a new configuration to push so we need to update ATMS for now.
@@ -2243,26 +2243,26 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* activity type. Null is no compatible stack on the display.
*/
@Nullable
- Task getStack(int windowingMode, int activityType) {
+ Task getRootTask(int windowingMode, int activityType) {
return getItemFromTaskDisplayAreas(taskDisplayArea ->
- taskDisplayArea.getStack(windowingMode, activityType));
+ taskDisplayArea.getRootTask(windowingMode, activityType));
}
@Nullable
- Task getStack(int rootTaskId) {
+ Task getRootTask(int rootTaskId) {
return getItemFromTaskDisplayAreas(taskDisplayArea ->
- taskDisplayArea.getStack(rootTaskId));
+ taskDisplayArea.getRootTask(rootTaskId));
}
- protected int getStackCount() {
+ protected int getRootTaskCount() {
return reduceOnAllTaskDisplayAreas((taskDisplayArea, count) ->
- count + taskDisplayArea.getStackCount(), 0 /* initValue */);
+ count + taskDisplayArea.getRootTaskCount(), 0 /* initValue */);
}
@VisibleForTesting
@Nullable
- Task getTopStack() {
- return getItemFromTaskDisplayAreas(TaskDisplayArea::getTopStack);
+ Task getTopRootTask() {
+ return getItemFromTaskDisplayAreas(TaskDisplayArea::getTopRootTask);
}
/**
@@ -2926,7 +2926,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mClosingApps.valueAt(i).writeIdentifierToProto(proto, CLOSING_APPS);
}
- final Task focusedStack = getFocusedStack();
+ final Task focusedStack = getFocusedRootTask();
if (focusedStack != null) {
proto.write(FOCUSED_ROOT_TASK_ID, focusedStack.getRootTaskId());
final ActivityRecord focusedActivity = focusedStack.getDisplayArea()
@@ -2970,7 +2970,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
super.dump(pw, prefix, dumpAll);
pw.print(prefix);
- pw.println("Display: mDisplayId=" + mDisplayId + " stacks=" + getStackCount());
+ pw.println("Display: mDisplayId=" + mDisplayId + " stacks=" + getRootTaskCount());
final String subPrefix = " " + prefix;
pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
@@ -3068,13 +3068,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
pw.println(prefix + "splitScreenPrimaryStack=" + splitScreenPrimaryStack.getName());
}
// TODO: Support recents on non-default task containers
- final Task recentsStack = getDefaultTaskDisplayArea().getStack(
+ final Task recentsStack = getDefaultTaskDisplayArea().getRootTask(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
if (recentsStack != null) {
pw.println(prefix + "recentsStack=" + recentsStack.getName());
}
final Task dreamStack =
- getStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_DREAM);
+ getRootTask(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_DREAM);
if (dreamStack != null) {
pw.println(prefix + "dreamStack=" + dreamStack.getName());
}
@@ -4516,9 +4516,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
}
- void assignStackOrdering() {
+ void assignRootTaskOrdering() {
forAllTaskDisplayAreas(taskDisplayArea -> {
- taskDisplayArea.assignStackOrdering(getPendingTransaction());
+ taskDisplayArea.assignRootTaskOrdering(getPendingTransaction());
});
}
@@ -5083,7 +5083,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mWmService.requestTraversal();
}
- static boolean alwaysCreateStack(int windowingMode, int activityType) {
+ static boolean alwaysCreateRootTask(int windowingMode, int activityType) {
// Always create a stack for fullscreen, freeform, and split-screen-secondary windowing
// modes so that we can manage visual ordering and return types correctly.
return activityType == ACTIVITY_TYPE_STANDARD
@@ -5097,13 +5097,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
static boolean canReuseExistingTask(int windowingMode, int activityType) {
// Existing Tasks can be reused if a new stack will be created anyway, or for the Dream -
// because there can only ever be one DreamActivity.
- return alwaysCreateStack(windowingMode, activityType)
+ return alwaysCreateRootTask(windowingMode, activityType)
|| activityType == ACTIVITY_TYPE_DREAM;
}
@Nullable
- Task getFocusedStack() {
- return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedStack);
+ Task getFocusedRootTask() {
+ return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedRootTask);
}
/**
@@ -5340,19 +5340,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// Check if all task display areas have only the empty home stacks left.
boolean hasNonEmptyHomeStack = forAllTaskDisplayAreas(taskDisplayArea -> {
- if (taskDisplayArea.getStackCount() != 1) {
+ if (taskDisplayArea.getRootTaskCount() != 1) {
return true;
}
- final Task stack = taskDisplayArea.getStackAt(0);
+ final Task stack = taskDisplayArea.getRootTaskAt(0);
return !stack.isActivityTypeHome() || stack.hasChild();
});
if (!hasNonEmptyHomeStack) {
// Release this display if only empty home stack(s) are left. This display will be
// released along with the stack(s) removal.
forAllTaskDisplayAreas(taskDisplayArea -> {
- taskDisplayArea.getStackAt(0).removeIfPossible();
+ taskDisplayArea.getRootTaskAt(0).removeIfPossible();
});
- } else if (getTopStack() == null) {
+ } else if (getTopRootTask() == null) {
removeIfPossible();
mRootWindowContainer.mTaskSupervisor
.getKeyguardController().onDisplayRemoved(mDisplayId);
@@ -5379,7 +5379,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
boolean shouldSleep() {
- return (getStackCount() == 0 || !mAllSleepTokens.isEmpty())
+ return (getRootTaskCount() == 0 || !mAllSleepTokens.isEmpty())
&& (mAtmService.mRunningVoice == null);
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 826b7259a9ff..2ddd00101769 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2046,7 +2046,7 @@ public class DisplayPolicy {
// requests to hide the status bar. Not sure if there is another way that to be the
// case though.
if (!topIsFullscreen || mDisplayContent.getDefaultTaskDisplayArea()
- .isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
+ .isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
topAppHidesStatusBar = false;
}
}
@@ -2830,9 +2830,9 @@ public class DisplayPolicy {
private int updateSystemBarsLw(WindowState win, int disableFlags) {
final boolean dockedStackVisible = mDisplayContent.getDefaultTaskDisplayArea()
- .isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ .isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
final boolean freeformStackVisible = mDisplayContent.getDefaultTaskDisplayArea()
- .isStackVisible(WINDOWING_MODE_FREEFORM);
+ .isRootTaskVisible(WINDOWING_MODE_FREEFORM);
final boolean resizing = mDisplayContent.getDockedDividerController().isResizing();
// We need to force system bars when the docked stack is visible, when the freeform stack
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index d308766b9fe5..ee150c31184c 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -392,9 +392,9 @@ class InsetsPolicy {
private boolean forceShowsSystemBarsForWindowingMode() {
final boolean isDockedStackVisible = mDisplayContent.getDefaultTaskDisplayArea()
- .isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ .isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
final boolean isFreeformStackVisible = mDisplayContent.getDefaultTaskDisplayArea()
- .isStackVisible(WINDOWING_MODE_FREEFORM);
+ .isRootTaskVisible(WINDOWING_MODE_FREEFORM);
final boolean isResizing = mDisplayContent.getDockedDividerController().isResizing();
// We need to force system bars when the docked stack is visible, when the freeform stack
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index ebd91a093326..e45310a99fbd 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -211,7 +211,7 @@ class KeyguardController {
updateKeyguardSleepToken();
// Some stack visibility might change (e.g. docked stack)
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
mRootWindowContainer.addStartingWindowsForVisibleActivities();
mWindowManager.executeAppTransition();
@@ -595,8 +595,8 @@ class KeyguardController {
@Nullable
private Task getRootTaskForControllingOccluding(DisplayContent display) {
return display.getItemFromTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task task = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task task = taskDisplayArea.getRootTaskAt(sNdx);
if (task != null && task.isFocusableAndVisible()
&& !task.inPinnedWindowingMode()) {
return task;
diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java
index b6b172eeae5b..8745e95dba4d 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsController.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsController.java
@@ -143,7 +143,7 @@ class LaunchParamsController {
try {
if (mTmpParams.mPreferredTaskDisplayArea != null
&& task.getDisplayArea() != mTmpParams.mPreferredTaskDisplayArea) {
- mService.mRootWindowContainer.moveStackToTaskDisplayArea(task.getRootTaskId(),
+ mService.mRootWindowContainer.moveRootTaskToTaskDisplayArea(task.getRootTaskId(),
mTmpParams.mPreferredTaskDisplayArea, true /* onTop */);
}
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index ee3978746488..4b3a43432fc5 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -504,7 +504,7 @@ public class LockTaskController {
return;
}
task.performClearTaskLocked();
- mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities();
}
/**
@@ -640,7 +640,7 @@ public class LockTaskController {
if (andResume) {
mSupervisor.findTaskToMoveToFront(task, 0, null, reason,
lockTaskModeState != LOCK_TASK_MODE_NONE);
- mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities();
final Task rootTask = task.getRootTask();
if (rootTask != null) {
rootTask.mDisplayContent.executeAppTransition();
@@ -717,7 +717,7 @@ public class LockTaskController {
}
if (taskChanged) {
- mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities();
}
}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index ba6b27ac3252..5598937da63d 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -36,13 +36,13 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.Process.SYSTEM_UID;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
-import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS_TRIM_TASKS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -220,7 +220,7 @@ class RecentTasks {
final RootWindowContainer rac = mService.mRootWindowContainer;
final DisplayContent dc = rac.getDisplayContent(displayId).mDisplayContent;
if (dc.pointWithinAppWindow(x, y)) {
- final Task stack = mService.getTopDisplayFocusedStack();
+ final Task stack = mService.getTopDisplayFocusedRootTask();
final Task topTask = stack != null ? stack.getTopMostTask() : null;
resetFreezeTaskListReordering(topTask);
}
@@ -328,7 +328,7 @@ class RecentTasks {
@VisibleForTesting
void resetFreezeTaskListReorderingOnTimeout() {
synchronized (mService.mGlobalLock) {
- final Task focusedStack = mService.getTopDisplayFocusedStack();
+ final Task focusedStack = mService.getTopDisplayFocusedRootTask();
final Task topTask = focusedStack != null ? focusedStack.getTopMostTask() : null;
resetFreezeTaskListReordering(topTask);
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 823dc51e939f..067c772dad93 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -29,7 +29,7 @@ import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP;
-import static com.android.server.wm.TaskDisplayArea.getStackAbove;
+import static com.android.server.wm.TaskDisplayArea.getRootTaskAbove;
import android.annotation.Nullable;
import android.app.ActivityOptions;
@@ -45,13 +45,13 @@ import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallbacks;
+import com.android.server.wm.TaskDisplayArea.OnRootTaskOrderChangedListener;
/**
* Manages the recents animation, including the reordering of the stacks for the transition and
* cleanup. See {@link com.android.server.wm.RecentsAnimationController}.
*/
-class RecentsAnimation implements RecentsAnimationCallbacks,
- TaskDisplayArea.OnStackOrderChangedListener {
+class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChangedListener {
private static final String TAG = RecentsAnimation.class.getSimpleName();
private final ActivityTaskManagerService mService;
@@ -106,7 +106,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
void preloadRecentsActivity() {
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Preload recents with %s",
mTargetIntent);
- Task targetStack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED,
+ Task targetStack = mDefaultTaskDisplayArea.getRootTask(WINDOWING_MODE_UNDEFINED,
mTargetActivityType);
ActivityRecord targetActivity = getTargetActivity(targetStack);
if (targetActivity != null) {
@@ -127,7 +127,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
// Create the activity record. Because the activity is invisible, this doesn't really
// start the client.
startRecentsActivityInBackground("preloadRecents");
- targetStack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED,
+ targetStack = mDefaultTaskDisplayArea.getRootTask(WINDOWING_MODE_UNDEFINED,
mTargetActivityType);
targetActivity = getTargetActivity(targetStack);
if (targetActivity == null) {
@@ -165,12 +165,12 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "RecentsAnimation#startRecentsActivity");
// If the activity is associated with the recents stack, then try and get that first
- Task targetStack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED,
+ Task targetStack = mDefaultTaskDisplayArea.getRootTask(WINDOWING_MODE_UNDEFINED,
mTargetActivityType);
ActivityRecord targetActivity = getTargetActivity(targetStack);
final boolean hasExistingActivity = targetActivity != null;
if (hasExistingActivity) {
- mRestoreTargetBehindStack = getStackAbove(targetStack);
+ mRestoreTargetBehindStack = getRootTaskAbove(targetStack);
if (mRestoreTargetBehindStack == null) {
notifyAnimationCancelBeforeStart(recentsAnimationRunner);
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
@@ -197,9 +197,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
try {
if (hasExistingActivity) {
// Move the recents activity into place for the animation if it is not top most
- mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(targetStack);
+ mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(targetStack);
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Moved stack=%s behind stack=%s",
- targetStack, getStackAbove(targetStack));
+ targetStack, getRootTaskAbove(targetStack));
// If there are multiple tasks in the target stack (ie. the home stack, with 3p
// and default launchers coexisting), then move the task to the top as a part of
@@ -213,12 +213,12 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
startRecentsActivityInBackground("startRecentsActivity_noTargetActivity");
// Move the recents activity into place for the animation
- targetStack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED,
+ targetStack = mDefaultTaskDisplayArea.getRootTask(WINDOWING_MODE_UNDEFINED,
mTargetActivityType);
targetActivity = getTargetActivity(targetStack);
- mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(targetStack);
+ mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(targetStack);
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Moved stack=%s behind stack=%s",
- targetStack, getStackAbove(targetStack));
+ targetStack, getRootTaskAbove(targetStack));
mWindowManager.prepareAppTransitionNone();
mWindowManager.executeAppTransition();
@@ -257,7 +257,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
START_TASK_TO_FRONT, targetActivity, options);
// Register for stack order changes
- mDefaultTaskDisplayArea.registerStackOrderChangedListener(this);
+ mDefaultTaskDisplayArea.registerRootTaskOrderChangedListener(this);
} catch (Exception e) {
Slog.e(TAG, "Failed to start recents activity", e);
throw e;
@@ -275,7 +275,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
mWindowManager.getRecentsAnimationController(), reorderMode);
// Unregister for stack order changes
- mDefaultTaskDisplayArea.unregisterStackOrderChangedListener(this);
+ mDefaultTaskDisplayArea.unregisterRootTaskOrderChangedListener(this);
final RecentsAnimationController controller =
mWindowManager.getRecentsAnimationController();
@@ -303,7 +303,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
try {
mWindowManager.cleanupRecentsAnimation(reorderMode);
- final Task targetStack = mDefaultTaskDisplayArea.getStack(
+ final Task targetStack = mDefaultTaskDisplayArea.getRootTask(
WINDOWING_MODE_UNDEFINED, mTargetActivityType);
// Prefer to use the original target activity instead of top activity because
// we may have moved another task to top (starting 3p launcher).
@@ -348,10 +348,10 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
} else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){
// Restore the target stack to its previous position
final TaskDisplayArea taskDisplayArea = targetActivity.getDisplayArea();
- taskDisplayArea.moveStackBehindStack(targetStack,
+ taskDisplayArea.moveRootTaskBehindRootTask(targetStack,
mRestoreTargetBehindStack);
if (WM_DEBUG_RECENTS_ANIMATIONS.isLogToAny()) {
- final Task aboveTargetStack = getStackAbove(targetStack);
+ final Task aboveTargetStack = getRootTaskAbove(targetStack);
if (mRestoreTargetBehindStack != null
&& aboveTargetStack != mRestoreTargetBehindStack) {
ProtoLog.w(WM_DEBUG_RECENTS_ANIMATIONS,
@@ -378,7 +378,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
mWindowManager.prepareAppTransitionNone();
mService.mRootWindowContainer.ensureActivitiesVisible(null, 0, false);
- mService.mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mService.mRootWindowContainer.resumeFocusedTasksTopActivities();
// No reason to wait for the pausing activity in this case, as the hiding of
// surfaces needs to be done immediately.
@@ -412,9 +412,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
}
@Override
- public void onStackOrderChanged(Task stack) {
- ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "onStackOrderChanged(): stack=%s", stack);
- if (mDefaultTaskDisplayArea.getIndexOf(stack) == -1 || !stack.shouldBeVisible(null)) {
+ public void onRootTaskOrderChanged(Task rootTask) {
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "onStackOrderChanged(): stack=%s", rootTask);
+ if (mDefaultTaskDisplayArea.getIndexOf(rootTask) == -1 || !rootTask.shouldBeVisible(null)) {
// The stack is not visible, so ignore this change
return;
}
@@ -428,8 +428,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
// cases:
// 1) The next launching task is not being animated by the recents animation
// 2) The next task is home activity. (i.e. pressing home key to back home in recents).
- if ((!controller.isAnimatingTask(stack.getTopMostTask())
- || controller.isTargetApp(stack.getTopNonFinishingActivity()))
+ if ((!controller.isAnimatingTask(rootTask.getTopMostTask())
+ || controller.isTargetApp(rootTask.getTopNonFinishingActivity()))
&& controller.shouldDeferCancelUntilNextTransition()) {
// Always prepare an app transition since we rely on the transition callbacks to cleanup
mWindowManager.prepareAppTransitionNone();
@@ -468,8 +468,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
* @return The top stack that is not always-on-top.
*/
private Task getTopNonAlwaysOnTopStack() {
- for (int i = mDefaultTaskDisplayArea.getStackCount() - 1; i >= 0; i--) {
- final Task s = mDefaultTaskDisplayArea.getStackAt(i);
+ for (int i = mDefaultTaskDisplayArea.getRootTaskCount() - 1; i >= 0; i--) {
+ final Task s = mDefaultTaskDisplayArea.getRootTaskAt(i);
if (s.getWindowConfiguration().isAlwaysOnTop()) {
continue;
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index abee032d042a..5da668c8c361 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -398,7 +398,7 @@ public class RecentsAnimationController implements DeathRecipient {
final ArrayList<Task> visibleTasks = mDisplayContent.getDefaultTaskDisplayArea()
.getVisibleTasks();
final Task targetStack = mDisplayContent.getDefaultTaskDisplayArea()
- .getStack(WINDOWING_MODE_UNDEFINED, targetActivityType);
+ .getRootTask(WINDOWING_MODE_UNDEFINED, targetActivityType);
if (targetStack != null) {
final PooledConsumer c = PooledLambda.obtainConsumer((t, outList) ->
{ if (!outList.contains(t)) outList.add(t); }, PooledLambda.__(Task.class),
diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
index 7bd5d03f1bc1..17cb8905f260 100644
--- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
+++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
@@ -237,7 +237,7 @@ class ResetTargetTaskHelper {
while (!mPendingReparentActivities.isEmpty()) {
final ActivityRecord r = mPendingReparentActivities.remove(0);
- final boolean alwaysCreateTask = DisplayContent.alwaysCreateStack(windowingMode,
+ final boolean alwaysCreateTask = DisplayContent.alwaysCreateRootTask(windowingMode,
activityType);
final Task task = alwaysCreateTask
? taskDisplayArea.getBottomMostTask() : mTargetStack.getBottomMostTask();
@@ -251,7 +251,7 @@ class ResetTargetTaskHelper {
}
if (targetTask == null) {
if (alwaysCreateTask) {
- targetTask = taskDisplayArea.getOrCreateStack(windowingMode,
+ targetTask = taskDisplayArea.getOrCreateRootTask(windowingMode,
activityType, false /* onTop */);
} else {
targetTask = mTargetStack.reuseOrCreateTask(r.info, null /*intent*/,
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index cbeaecf7f58c..497087a967f3 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -256,8 +256,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
/** The current user */
int mCurrentUser;
- /** Stack id of the front stack when user switched, indexed by userId. */
- SparseIntArray mUserStackInFront = new SparseIntArray(2);
+ /** Root task id of the front root task when user switched, indexed by userId. */
+ SparseIntArray mUserRootTaskInFront = new SparseIntArray(2);
/**
* A list of tokens that cause the top activity to be put to sleep.
@@ -296,7 +296,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
c.recycle();
} finally {
mTaskSupervisor.endDeferResume();
- resumeFocusedStacksTopActivities();
+ resumeFocusedTasksTopActivities();
}
}
}
@@ -1484,7 +1484,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
boolean fromHomeKey) {
// Fallback to top focused display or default display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
- final Task stack = getTopDisplayFocusedStack();
+ final Task stack = getTopDisplayFocusedRootTask();
displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY;
}
@@ -1510,7 +1510,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
boolean allowInstrumenting, boolean fromHomeKey) {
// Fallback to top focused display area if the provided one is invalid.
if (taskDisplayArea == null) {
- final Task stack = getTopDisplayFocusedStack();
+ final Task stack = getTopDisplayFocusedRootTask();
taskDisplayArea = stack != null ? stack.getDisplayArea()
: getDefaultTaskDisplayArea();
}
@@ -1677,7 +1677,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// Only resume home activity if isn't finishing.
if (r != null && !r.finishing) {
r.moveFocusableActivityToTop(myReason);
- return resumeFocusedStacksTopActivities(r.getRootTask(), prev, null);
+ return resumeFocusedTasksTopActivities(r.getRootTask(), prev, null);
}
return startHomeOnTaskDisplayArea(mCurrentUser, myReason, taskDisplayArea,
false /* allowInstrumenting */, false /* fromHomeKey */);
@@ -1831,12 +1831,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
*/
List<IBinder> getTopVisibleActivities() {
final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
- final Task topFocusedStack = getTopDisplayFocusedStack();
+ final Task topFocusedStack = getTopDisplayFocusedRootTask();
// Traverse all displays.
forAllTaskDisplayAreas(taskDisplayArea -> {
// Traverse all stacks on a display area.
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
// Get top activity from a visible stack and add it to the list.
if (stack.shouldBeVisible(null /* starting */)) {
final ActivityRecord top = stack.getTopNonFinishingActivity();
@@ -1854,9 +1854,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
@Nullable
- Task getTopDisplayFocusedStack() {
+ Task getTopDisplayFocusedRootTask() {
for (int i = getChildCount() - 1; i >= 0; --i) {
- final Task focusedStack = getChildAt(i).getFocusedStack();
+ final Task focusedStack = getChildAt(i).getFocusedRootTask();
if (focusedStack != null) {
return focusedStack;
}
@@ -1866,7 +1866,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
@Nullable
ActivityRecord getTopResumedActivity() {
- final Task focusedStack = getTopDisplayFocusedStack();
+ final Task focusedStack = getTopDisplayFocusedRootTask();
if (focusedStack == null) {
return null;
}
@@ -1879,8 +1879,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedActivity);
}
- boolean isTopDisplayFocusedStack(Task stack) {
- return stack != null && stack == getTopDisplayFocusedStack();
+ boolean isTopDisplayFocusedRootTask(Task task) {
+ return task != null && task == getTopDisplayFocusedRootTask();
}
void updatePreviousProcess(ActivityRecord r) {
@@ -1891,9 +1891,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// previous app if this activity is being hosted by the process that is actually still the
// foreground.
WindowProcessController fgApp = reduceOnAllTaskDisplayAreas((taskDisplayArea, app) -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
- if (isTopDisplayFocusedStack(stack)) {
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
+ if (isTopDisplayFocusedRootTask(stack)) {
final ActivityRecord resumedActivity = stack.getResumedActivity();
if (resumedActivity != null) {
app = resumedActivity.app;
@@ -1926,8 +1926,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return;
}
- for (int taskNdx = displayArea.getStackCount() - 1; taskNdx >= 0; --taskNdx) {
- final Task rootTask = displayArea.getStackAt(taskNdx);
+ for (int taskNdx = displayArea.getRootTaskCount() - 1; taskNdx >= 0; --taskNdx) {
+ final Task rootTask = displayArea.getRootTaskAt(taskNdx);
if (rootTask.getVisibility(null /*starting*/) == TASK_VISIBILITY_INVISIBLE) {
break;
}
@@ -2009,7 +2009,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
boolean switchUser(int userId, UserState uss) {
- final Task topFocusedStack = getTopDisplayFocusedStack();
+ final Task topFocusedStack = getTopDisplayFocusedRootTask();
final int focusStackId = topFocusedStack != null
? topFocusedStack.getRootTaskId() : INVALID_TASK_ID;
// We dismiss the docked stack whenever we switch users.
@@ -2021,19 +2021,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// appropriate.
removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED);
- mUserStackInFront.put(mCurrentUser, focusStackId);
+ mUserRootTaskInFront.put(mCurrentUser, focusStackId);
mCurrentUser = userId;
mTaskSupervisor.mStartingUsers.add(uss);
forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
stack.switchUser(userId);
}
});
- final int restoreStackId = mUserStackInFront.get(userId);
- Task stack = getStack(restoreStackId);
+ final int restoreStackId = mUserRootTaskInFront.get(userId);
+ Task stack = getRootTask(restoreStackId);
if (stack == null) {
stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
}
@@ -2048,20 +2048,20 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
void removeUser(int userId) {
- mUserStackInFront.delete(userId);
+ mUserRootTaskInFront.delete(userId);
}
/**
- * Update the last used stack id for non-current user (current user's last
- * used stack is the focused stack)
+ * Update the last used root task id for non-current user (current user's last
+ * used root task is the focused root task)
*/
- void updateUserStack(int userId, Task stack) {
+ void updateUserRootTask(int userId, Task rootTask) {
if (userId != mCurrentUser) {
- if (stack == null) {
- stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
+ if (rootTask == null) {
+ rootTask = getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
}
- mUserStackInFront.put(userId, stack.getRootTaskId());
+ mUserRootTaskInFront.put(userId, rootTask.getRootTaskId());
}
}
@@ -2072,8 +2072,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
* @param taskDisplayArea The task display area to move stack to.
* @param onTop Indicates whether container should be place on top or on bottom.
*/
- void moveStackToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea, boolean onTop) {
- final Task stack = getStack(stackId);
+ void moveRootTaskToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea,
+ boolean onTop) {
+ final Task stack = getRootTask(stackId);
if (stack == null) {
throw new IllegalArgumentException("moveStackToTaskDisplayArea: Unknown stackId="
+ stackId);
@@ -2101,22 +2102,23 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
/**
* Move stack with all its existing content to specified display.
*
- * @param stackId Id of stack to move.
+ * @param rootTaskId Id of stack to move.
* @param displayId Id of display to move stack to.
* @param onTop Indicates whether container should be place on top or on bottom.
*/
- void moveStackToDisplay(int stackId, int displayId, boolean onTop) {
+ void moveRootTaskToDisplay(int rootTaskId, int displayId, boolean onTop) {
final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
if (displayContent == null) {
throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId="
+ displayId);
}
- moveStackToTaskDisplayArea(stackId, displayContent.getDefaultTaskDisplayArea(), onTop);
+ moveRootTaskToTaskDisplayArea(rootTaskId, displayContent.getDefaultTaskDisplayArea(),
+ onTop);
}
- boolean moveTopStackActivityToPinnedRootTask(int rootTaskId) {
- final Task rootTask = getStack(rootTaskId);
+ boolean moveTopRootTaskActivityToPinnedRootTask(int rootTaskId) {
+ final Task rootTask = getRootTask(rootTaskId);
if (rootTask == null) {
throw new IllegalArgumentException(
"moveTopStackActivityToPinnedRootTask: Unknown rootTaskId=" + rootTaskId);
@@ -2135,11 +2137,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return false;
}
- moveActivityToPinnedStack(r, "moveTopStackActivityToPinnedRootTask");
+ moveActivityToPinnedRootTask(r, "moveTopStackActivityToPinnedRootTask");
return true;
}
- void moveActivityToPinnedStack(ActivityRecord r, String reason) {
+ void moveActivityToPinnedRootTask(ActivityRecord r, String reason) {
mService.deferWindowLayout();
final TaskDisplayArea taskDisplayArea = r.getDisplayArea();
@@ -2159,25 +2161,26 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
r.getDisplayContent().prepareAppTransition(TRANSIT_NONE);
final boolean singleActivity = task.getChildCount() == 1;
- final Task stack;
+ final Task rootTask;
if (singleActivity) {
- stack = task;
+ rootTask = task;
} else {
// In the case of multiple activities, we will create a new task for it and then
// move the PIP activity into the task.
- stack = taskDisplayArea.createStack(WINDOWING_MODE_UNDEFINED, r.getActivityType(),
- ON_TOP, r.info, r.intent, false /* createdByOrganizer */);
+ rootTask = taskDisplayArea.createRootTask(WINDOWING_MODE_UNDEFINED,
+ r.getActivityType(), ON_TOP, r.info, r.intent,
+ false /* createdByOrganizer */);
// It's possible the task entering PIP is in freeform, so save the last
// non-fullscreen bounds. Then when this new PIP task exits PIP, it can restore
// to its previous freeform bounds.
- stack.setLastNonFullscreenBounds(task.mLastNonFullscreenBounds);
- stack.setBounds(task.getBounds());
+ rootTask.setLastNonFullscreenBounds(task.mLastNonFullscreenBounds);
+ rootTask.setBounds(task.getBounds());
// There are multiple activities in the task and moving the top activity should
// reveal/leave the other activities in their original task.
// On the other hand, ActivityRecord#onParentChanged takes care of setting the
// up-to-dated pinned stack information on this newly created stack.
- r.reparent(stack, MAX_VALUE, reason);
+ r.reparent(rootTask, MAX_VALUE, reason);
// In the case of this activity entering PIP due to it being moved to the back,
// the old activity would have a TRANSIT_TASK_TO_BACK transition that needs to be
@@ -2196,17 +2199,17 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// The intermediate windowing mode to be set on the ActivityRecord later.
// This needs to happen before the re-parenting, otherwise we will always set the
// ActivityRecord to be fullscreen.
- final int intermediateWindowingMode = stack.getWindowingMode();
- if (stack.getParent() != taskDisplayArea) {
+ final int intermediateWindowingMode = rootTask.getWindowingMode();
+ if (rootTask.getParent() != taskDisplayArea) {
// stack is nested, but pinned tasks need to be direct children of their
// display area, so reparent.
- stack.reparent(taskDisplayArea, true /* onTop */);
+ rootTask.reparent(taskDisplayArea, true /* onTop */);
}
// Defer the windowing mode change until after the transition to prevent the activity
// from doing work and changing the activity visuals while animating
// TODO(task-org): Figure-out more structured way to do this long term.
r.setWindowingMode(intermediateWindowingMode);
- stack.setWindowingMode(WINDOWING_MODE_PINNED);
+ rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
// Reset the state that indicates it can enter PiP while pausing after we've moved it
// to the pinned stack
@@ -2216,7 +2219,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
ensureActivitiesVisible(null, 0, false /* preserveWindows */);
- resumeFocusedStacksTopActivities();
+ resumeFocusedTasksTopActivities();
notifyActivityPipModeChanged(r);
}
@@ -2288,13 +2291,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
* @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
*/
int finishTopCrashedActivities(WindowProcessController app, String reason) {
- Task focusedStack = getTopDisplayFocusedStack();
+ Task focusedStack = getTopDisplayFocusedRootTask();
Task finishedTask = reduceOnAllTaskDisplayAreas((taskDisplayArea, task) -> {
// It is possible that request to finish activity might also remove its task and
// stack, so we need to be careful with indexes in the loop and check child count
// every time.
- for (int stackNdx = 0; stackNdx < taskDisplayArea.getStackCount(); ++stackNdx) {
- final Task stack = taskDisplayArea.getStackAt(stackNdx);
+ for (int stackNdx = 0; stackNdx < taskDisplayArea.getRootTaskCount(); ++stackNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(stackNdx);
final Task t = stack.finishTopCrashedActivityLocked(app, reason);
if (stack == focusedStack || task == null) {
task = t;
@@ -2305,21 +2308,21 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
}
- boolean resumeFocusedStacksTopActivities() {
- return resumeFocusedStacksTopActivities(null, null, null);
+ boolean resumeFocusedTasksTopActivities() {
+ return resumeFocusedTasksTopActivities(null, null, null);
}
- boolean resumeFocusedStacksTopActivities(
- Task targetStack, ActivityRecord target, ActivityOptions targetOptions) {
+ boolean resumeFocusedTasksTopActivities(
+ Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions) {
if (!mTaskSupervisor.readyToResume()) {
return false;
}
boolean result = false;
- if (targetStack != null && (targetStack.isTopStackInDisplayArea()
- || getTopDisplayFocusedStack() == targetStack)) {
- result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
+ if (targetRootTask != null && (targetRootTask.isTopStackInDisplayArea()
+ || getTopDisplayFocusedRootTask() == targetRootTask)) {
+ result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions);
}
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
@@ -2327,13 +2330,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
final boolean curResult = result;
boolean resumedOnDisplay = display.reduceOnAllTaskDisplayAreas(
(taskDisplayArea, resumed) -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
- final ActivityRecord topRunningActivity = stack.topRunningActivity();
- if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task rootTask = taskDisplayArea.getRootTaskAt(sNdx);
+ final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
+ if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) {
continue;
}
- if (stack == targetStack) {
+ if (rootTask == targetRootTask) {
// Simply update the result for targetStack because the targetStack
// had already resumed in above. We don't want to resume it again,
// especially in some cases, it would cause a second launch failure
@@ -2341,12 +2344,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
resumed |= curResult;
continue;
}
- if (taskDisplayArea.isTopStack(stack)
+ if (taskDisplayArea.isTopRootTask(rootTask)
&& topRunningActivity.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront
// operation, but only consider the top task and stack on that
// display.
- stack.executeAppTransition(targetOptions);
+ rootTask.executeAppTransition(targetOptions);
} else {
resumed |= topRunningActivity.makeActiveIfNeeded(target);
}
@@ -2359,10 +2362,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// crashed) it's possible that nothing was resumed on a display. Requesting resume
// of top activity in focused stack explicitly will make sure that at least home
// activity is started and resumed, and no recursion occurs.
- final Task focusedStack = display.getFocusedStack();
- if (focusedStack != null) {
- result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
- } else if (targetStack == null) {
+ final Task focusedRoot = display.getFocusedRootTask();
+ if (focusedRoot != null) {
+ result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
+ } else if (targetRootTask == null) {
result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
display.getDefaultTaskDisplayArea());
}
@@ -2388,8 +2391,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// Set the sleeping state of the stacks on the display.
display.forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
if (displayShouldSleep) {
stack.goToSleepIfPossible(false /* shuttingDown */);
} else {
@@ -2416,34 +2419,34 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
}
- protected Task getStack(int stackId) {
+ protected Task getRootTask(int rooTaskId) {
for (int i = getChildCount() - 1; i >= 0; --i) {
- final Task stack = getChildAt(i).getStack(stackId);
- if (stack != null) {
- return stack;
+ final Task rootTask = getChildAt(i).getRootTask(rooTaskId);
+ if (rootTask != null) {
+ return rootTask;
}
}
return null;
}
- /** @see DisplayContent#getStack(int, int) */
- Task getStack(int windowingMode, int activityType) {
+ /** @see DisplayContent#getRootTask(int, int) */
+ Task getRootTask(int windowingMode, int activityType) {
for (int i = getChildCount() - 1; i >= 0; --i) {
- final Task stack = getChildAt(i).getStack(windowingMode, activityType);
- if (stack != null) {
- return stack;
+ final Task rootTask = getChildAt(i).getRootTask(windowingMode, activityType);
+ if (rootTask != null) {
+ return rootTask;
}
}
return null;
}
- private Task getStack(int windowingMode, int activityType,
+ private Task getRootTask(int windowingMode, int activityType,
int displayId) {
DisplayContent display = getDisplayContent(displayId);
if (display == null) {
return null;
}
- return display.getStack(windowingMode, activityType);
+ return display.getRootTask(windowingMode, activityType);
}
private RootTaskInfo getRootTaskInfo(Task task) {
@@ -2488,7 +2491,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
RootTaskInfo getRootTaskInfo(int taskId) {
- Task task = getStack(taskId);
+ Task task = getRootTask(taskId);
if (task != null) {
return getRootTaskInfo(task);
}
@@ -2496,12 +2499,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
RootTaskInfo getRootTaskInfo(int windowingMode, int activityType) {
- final Task stack = getStack(windowingMode, activityType);
+ final Task stack = getRootTask(windowingMode, activityType);
return (stack != null) ? getRootTaskInfo(stack) : null;
}
RootTaskInfo getRootTaskInfo(int windowingMode, int activityType, int displayId) {
- final Task stack = getStack(windowingMode, activityType, displayId);
+ final Task stack = getRootTask(windowingMode, activityType, displayId);
return (stack != null) ? getRootTaskInfo(stack) : null;
}
@@ -2510,8 +2513,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
ArrayList<RootTaskInfo> list = new ArrayList<>();
if (displayId == INVALID_DISPLAY) {
forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
list.add(getRootTaskInfo(stack));
}
});
@@ -2522,8 +2525,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return list;
}
display.forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
list.add(getRootTaskInfo(stack));
}
});
@@ -2595,16 +2598,16 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs);
}
- Task findStackBehind(Task stack) {
- final TaskDisplayArea taskDisplayArea = stack.getDisplayArea();
+ Task findRootTaskBehind(Task rootTask) {
+ final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea();
if (taskDisplayArea != null) {
- for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; i--) {
- if (taskDisplayArea.getStackAt(i) == stack && i > 0) {
- return taskDisplayArea.getStackAt(i - 1);
+ for (int i = taskDisplayArea.getRootTaskCount() - 1; i >= 0; i--) {
+ if (taskDisplayArea.getRootTaskAt(i) == rootTask && i > 0) {
+ return taskDisplayArea.getRootTaskAt(i - 1);
}
}
}
- throw new IllegalStateException("Failed to find a stack behind stack=" + stack
+ throw new IllegalStateException("Failed to find a root task behind root task =" + rootTask
+ " in=" + taskDisplayArea);
}
@@ -2740,22 +2743,22 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
r.destroyImmediately(mDestroyAllActivitiesReason);
}
- // Tries to put all activity stacks to sleep. Returns true if all stacks were
+ // Tries to put all activity tasks to sleep. Returns true if all tasks were
// successfully put to sleep.
- boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) {
+ boolean putTasksToSleep(boolean allowDelay, boolean shuttingDown) {
return reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
// Stacks and activities could be removed while putting activities to sleep if
// the app process was gone. This prevents us getting exception by accessing an
// invalid stack index.
- if (sNdx >= taskDisplayArea.getStackCount()) {
+ if (sNdx >= taskDisplayArea.getRootTaskCount()) {
continue;
}
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ final Task task = taskDisplayArea.getRootTaskAt(sNdx);
if (allowDelay) {
- result &= stack.goToSleepIfPossible(shuttingDown);
+ result &= task.goToSleepIfPossible(shuttingDown);
} else {
- stack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
+ task.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
!PRESERVE_WINDOWS);
}
}
@@ -2824,9 +2827,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return false;
}
- Task getLaunchStack(@Nullable ActivityRecord r,
+ Task getLaunchRootTask(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) {
- return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
+ return getLaunchRootTask(r, options, candidateTask, onTop, null /* launchParams */,
-1 /* no realCallingPid */, -1 /* no realCallingUid */);
}
@@ -2841,7 +2844,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
* @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
* @return The stack to use for the launch or INVALID_STACK_ID.
*/
- Task getLaunchStack(@Nullable ActivityRecord r,
+ Task getLaunchRootTask(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop,
@Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
int realCallingUid) {
@@ -2894,7 +2897,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
realCallingPid, realCallingUid, r.info);
if (canLaunchOnDisplayFromStartRequest || canLaunchOnDisplay(r, tdaDisplayId)) {
if (r != null) {
- final Task result = getValidLaunchStackInTaskDisplayArea(
+ final Task result = getValidLaunchRootTaskInTaskDisplayArea(
taskDisplayArea, r, candidateTask, options, launchParams);
if (result != null) {
return result;
@@ -2902,7 +2905,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
// Falling back to default task container
taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea();
- stack = taskDisplayArea.getOrCreateStack(r, options, candidateTask, activityType,
+ stack = taskDisplayArea.getOrCreateRootTask(r, options, candidateTask, activityType,
onTop);
if (stack != null) {
return stack;
@@ -2956,7 +2959,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
}
- return container.getOrCreateStack(r, options, candidateTask, activityType, onTop);
+ return container.getOrCreateRootTask(r, options, candidateTask, activityType, onTop);
}
/** @return true if activity record is null or can be launched on provided display. */
@@ -2977,7 +2980,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
* @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
*/
@VisibleForTesting
- Task getValidLaunchStackInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea,
+ Task getValidLaunchRootTaskInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea,
@NonNull ActivityRecord r, @Nullable Task candidateTask,
@Nullable ActivityOptions options,
@Nullable LaunchParamsController.LaunchParams launchParams) {
@@ -3016,9 +3019,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
r.getActivityType());
// Return the topmost valid stack on the display.
- for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; --i) {
- final Task stack = taskDisplayArea.getStackAt(i);
- if (isValidLaunchStack(stack, r, windowingMode)) {
+ for (int i = taskDisplayArea.getRootTaskCount() - 1; i >= 0; --i) {
+ final Task stack = taskDisplayArea.getRootTaskAt(i);
+ if (isValidLaunchRootTask(stack, r, windowingMode)) {
return stack;
}
}
@@ -3030,15 +3033,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
final int activityType =
options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
? options.getLaunchActivityType() : r.getActivityType();
- return taskDisplayArea.createStack(windowingMode, activityType, true /*onTop*/);
+ return taskDisplayArea.createRootTask(windowingMode, activityType, true /*onTop*/);
}
return null;
}
// TODO: Can probably be consolidated into getLaunchStack()...
- private boolean isValidLaunchStack(Task stack, ActivityRecord r, int windowingMode) {
- switch (stack.getActivityType()) {
+ private boolean isValidLaunchRootTask(Task task, ActivityRecord r, int windowingMode) {
+ switch (task.getActivityType()) {
case ACTIVITY_TYPE_HOME:
return r.isActivityTypeHome();
case ACTIVITY_TYPE_RECENTS:
@@ -3048,13 +3051,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
case ACTIVITY_TYPE_DREAM:
return r.isActivityTypeDream();
}
- if (stack.mCreatedByOrganizer) {
+ if (task.mCreatedByOrganizer) {
// Don't launch directly into task created by organizer...but why can't we?
return false;
}
// There is a 1-to-1 relationship between stack and task when not in
// primary split-windowing mode.
- if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
+ if (task.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
&& r.supportsSplitScreenWindowingMode()
&& (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
|| windowingMode == WINDOWING_MODE_UNDEFINED)) {
@@ -3091,8 +3094,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
* candidate.
* @return Next focusable {@link Task}, {@code null} if not found.
*/
- Task getNextFocusableStack(@NonNull Task currentFocus,
- boolean ignoreCurrent) {
+ Task getNextFocusableRootTask(@NonNull Task currentFocus, boolean ignoreCurrent) {
// First look for next focusable stack on the same display
TaskDisplayArea preferredDisplayArea = currentFocus.getDisplayArea();
if (preferredDisplayArea == null) {
@@ -3101,7 +3103,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
preferredDisplayArea = getDisplayContent(currentFocus.mPrevDisplayId)
.getDefaultTaskDisplayArea();
}
- final Task preferredFocusableStack = preferredDisplayArea.getNextFocusableStack(
+ final Task preferredFocusableStack = preferredDisplayArea.getNextFocusableRootTask(
currentFocus, ignoreCurrent);
if (preferredFocusableStack != null) {
return preferredFocusableStack;
@@ -3121,7 +3123,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
continue;
}
final Task nextFocusableStack = display.getDefaultTaskDisplayArea()
- .getNextFocusableStack(currentFocus, ignoreCurrent);
+ .getNextFocusableRootTask(currentFocus, ignoreCurrent);
if (nextFocusableStack != null) {
return nextFocusableStack;
}
@@ -3257,9 +3259,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
void finishVoiceTask(IVoiceInteractionSession session) {
forAllTaskDisplayAreas(taskDisplayArea -> {
- final int numStacks = taskDisplayArea.getStackCount();
+ final int numStacks = taskDisplayArea.getRootTaskCount();
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
- final Task stack = taskDisplayArea.getStackAt(stackNdx);
+ final Task stack = taskDisplayArea.getRootTaskAt(stackNdx);
stack.finishVoiceTask(session);
}
});
@@ -3302,7 +3304,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// If the focused stack is not null or not empty, there should have some activities
// resuming or resumed. Make sure these activities are idle.
- final Task stack = display.getFocusedStack();
+ final Task stack = display.getFocusedRootTask();
if (stack == null || !stack.hasActivity()) {
continue;
}
@@ -3322,8 +3324,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
boolean[] foundResumed = {false};
final boolean foundInvisibleResumedActivity = forAllTaskDisplayAreas(
taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
final ActivityRecord r = stack.getResumedActivity();
if (r != null) {
if (!r.nowVisible) {
@@ -3344,8 +3346,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
boolean[] pausing = {true};
final boolean hasActivityNotCompleted = forAllTaskDisplayAreas(
taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
final ActivityRecord r = stack.mPausingActivity;
if (r != null && !r.isState(PAUSED, STOPPED, STOPPING, FINISHING)) {
ProtoLog.d(WM_DEBUG_STATES, "allPausedActivitiesComplete: "
@@ -3410,10 +3412,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
void cancelInitializingActivities() {
forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
// We don't want to clear starting window for activities that aren't occluded
// as we need to display their starting window until they are done initializing.
- taskDisplayArea.getStackAt(sNdx).forAllOccludedActivities(
+ taskDisplayArea.getRootTaskAt(sNdx).forAllOccludedActivities(
ActivityRecord::cancelInitializing);
}
});
@@ -3453,7 +3455,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// Resolve the stack the task should be placed in now based on options
// and reparent if needed.
final Task launchStack =
- getLaunchStack(null, aOptions, task, onTop);
+ getLaunchRootTask(null, aOptions, task, onTop);
if (launchStack != null && task.getRootTask() != launchStack) {
final int reparentMode = onTop
? REPARENT_MOVE_ROOT_TASK_TO_FRONT : REPARENT_LEAVE_ROOT_TASK_IN_PLACE;
@@ -3498,7 +3500,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
return task;
}
- ActivityRecord isInAnyStack(IBinder token) {
+ ActivityRecord isInAnyTask(IBinder token) {
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
return (r != null && r.isDescendantOf(this)) ? r : null;
}
@@ -3568,7 +3570,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly,
boolean dumpFocusedStackOnly) {
if (dumpFocusedStackOnly) {
- final Task topFocusedStack = getTopDisplayFocusedStack();
+ final Task topFocusedStack = getTopDisplayFocusedRootTask();
if (topFocusedStack != null) {
return topFocusedStack.getDumpActivitiesLocked(name);
} else {
@@ -3577,8 +3579,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
} else {
ArrayList<ActivityRecord> activities = new ArrayList<>();
forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) {
activities.addAll(stack.getDumpActivitiesLocked(name));
}
@@ -3592,7 +3594,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
super.dump(pw, prefix, dumpAll);
pw.print(prefix);
- pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
+ pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedRootTask());
for (int i = getChildCount() - 1; i >= 0; --i) {
final DisplayContent display = getChildAt(i);
display.dump(pw, prefix, dumpAll);
@@ -3632,8 +3634,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
pw.print(displayContent.mDisplayId);
pw.println(" (activities from top to bottom):");
displayContent.forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
if (needSep[0]) {
pw.println();
}
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 7b5b0ad870dd..6ef5d4da63cb 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -67,7 +67,7 @@ class RunningTasks {
mProfileIds = profileIds;
mAllowed = allowed;
mFilterOnlyVisibleRecents = filterOnlyVisibleRecents;
- mTopDisplayFocusStack = root.getTopDisplayFocusedStack();
+ mTopDisplayFocusStack = root.getTopDisplayFocusedRootTask();
mRecentTasks = root.mService.getRecentTasks();
final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index fb441fa94893..4b65ce0f7088 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -101,7 +101,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG;
+import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_TASK_MSG;
import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
@@ -599,7 +599,7 @@ class Task extends WindowContainer<WindowContainer> {
private final AnimatingActivityRegistry mAnimatingActivityRegistry =
new AnimatingActivityRegistry();
- private static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 1;
+ private static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_TASK_MSG + 1;
private final Handler mHandler;
@@ -652,7 +652,7 @@ class Task extends WindowContainer<WindowContainer> {
if (mUpdateConfig) {
// Ensure the resumed state of the focus activity if we updated the configuration of
// any activity.
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
}
@@ -975,7 +975,7 @@ class Task extends WindowContainer<WindowContainer> {
}
mResizeMode = resizeMode;
mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
updateTaskDescription();
}
@@ -1030,7 +1030,7 @@ class Task extends WindowContainer<WindowContainer> {
// activities stay the same.
mRootWindowContainer.ensureActivitiesVisible(r, 0, preserveWindow);
if (!kept) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
}
}
@@ -1098,7 +1098,7 @@ class Task extends WindowContainer<WindowContainer> {
final RootWindowContainer root = mRootWindowContainer;
final WindowManagerService windowManager = mAtmService.mWindowManager;
final Task sourceStack = getRootTask();
- final Task toStack = supervisor.getReparentTargetStack(this, preferredStack,
+ final Task toStack = supervisor.getReparentTargetRootTask(this, preferredStack,
position == MAX_VALUE);
if (toStack == sourceStack) {
return false;
@@ -1136,7 +1136,7 @@ class Task extends WindowContainer<WindowContainer> {
boolean kept = true;
try {
final ActivityRecord r = topRunningActivityLocked();
- final boolean wasFocused = r != null && root.isTopDisplayFocusedStack(sourceStack)
+ final boolean wasFocused = r != null && root.isTopDisplayFocusedRootTask(sourceStack)
&& (topRunningActivityLocked() == r);
final boolean wasResumed = r != null && sourceStack.getResumedActivity() == r;
final boolean wasPaused = r != null && sourceStack.mPausingActivity == r;
@@ -1176,7 +1176,7 @@ class Task extends WindowContainer<WindowContainer> {
&& moveStackMode == REPARENT_KEEP_ROOT_TASK_AT_FRONT) {
// Move recents to front so it is not behind home stack when going into docked
// mode
- mTaskSupervisor.moveRecentsStackToFront(reason);
+ mTaskSupervisor.moveRecentsRootTaskToFront(reason);
}
} finally {
mAtmService.continueWindowLayout();
@@ -1193,7 +1193,7 @@ class Task extends WindowContainer<WindowContainer> {
// The task might have already been running and its visibility needs to be synchronized
// with the visibility of the stack / windows.
root.ensureActivitiesVisible(null, 0, !mightReplaceWindow);
- root.resumeFocusedStacksTopActivities();
+ root.resumeFocusedTasksTopActivities();
}
// TODO: Handle incorrect request to move before the actual move, not after.
@@ -1696,7 +1696,7 @@ class Task extends WindowContainer<WindowContainer> {
// A rootable task that is now being added to be the child of an organized task. Making
// sure the stack references is keep updated.
if (mTaskOrganizer != null && mCreatedByOrganizer && child.asTask() != null) {
- getDisplayArea().addStackReferenceIfNeeded((Task) child);
+ getDisplayArea().addRootTaskReferenceIfNeeded((Task) child);
}
// Make sure the list of display UID allowlists is updated
@@ -1746,7 +1746,7 @@ class Task extends WindowContainer<WindowContainer> {
// A rootable child task that is now being removed from an organized task. Making sure
// the stack references is keep updated.
if (mCreatedByOrganizer && r.asTask() != null) {
- getDisplayArea().removeStackReferenceIfNeeded((Task) r);
+ getDisplayArea().removeRootTaskReferenceIfNeeded((Task) r);
}
if (!mChildren.contains(r)) {
Slog.e(TAG, "removeChild: r=" + r + " not found in t=" + this);
@@ -2303,7 +2303,7 @@ class Task extends WindowContainer<WindowContainer> {
}
if (prevWindowingMode != getWindowingMode()) {
- taskDisplayArea.onStackWindowingModeChanged(this);
+ taskDisplayArea.onRootTaskWindowingModeChanged(this);
}
if (mDisplayContent == null) {
@@ -2330,7 +2330,7 @@ class Task extends WindowContainer<WindowContainer> {
}
if (windowingModeChanged) {
- taskDisplayArea.onStackWindowingModeChanged(this);
+ taskDisplayArea.onRootTaskWindowingModeChanged(this);
}
if (hasNewOverrideBounds) {
if (inSplitScreenWindowingMode()) {
@@ -3097,7 +3097,7 @@ class Task extends WindowContainer<WindowContainer> {
boolean moveDisplayToTop) {
Task focusableTask = getNextFocusableTask(allowFocusSelf);
if (focusableTask == null) {
- focusableTask = mRootWindowContainer.getNextFocusableStack(this, !allowFocusSelf);
+ focusableTask = mRootWindowContainer.getNextFocusableRootTask(this, !allowFocusSelf);
}
if (focusableTask == null) {
return null;
@@ -5133,7 +5133,7 @@ class Task extends WindowContainer<WindowContainer> {
// The change in force-hidden state will change visibility without triggering a stack
// order change, so we should reset the preferred top focusable stack to ensure it's not
// used if a new activity is started from this task.
- getDisplayArea().resetPreferredTopFocusableStackIfBelow(this);
+ getDisplayArea().resetPreferredTopFocusableRootTaskIfBelow(this);
}
return true;
}
@@ -5276,14 +5276,14 @@ class Task extends WindowContainer<WindowContainer> {
}
mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
/** Resume next focusable stack after reparenting to another display. */
void postReparent() {
adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */,
true /* moveDisplayToTop */);
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
// Update visibility of activities before notifying WM. This way it won't try to resize
// windows that are no longer visible.
mRootWindowContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
@@ -5320,7 +5320,7 @@ class Task extends WindowContainer<WindowContainer> {
// cutting between them.
// TODO(b/70677280): This is a workaround until we can fix as part of b/70677280.
final Task topFullScreenStack =
- taskDisplayArea.getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ taskDisplayArea.getTopRootTaskInWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (topFullScreenStack != null) {
final Task primarySplitScreenStack =
taskDisplayArea.getRootSplitScreenPrimaryTask();
@@ -5335,10 +5335,10 @@ class Task extends WindowContainer<WindowContainer> {
if (!isActivityTypeHome() && returnsToHomeStack()) {
// Make sure the home stack is behind this stack since that is where we should return to
// when this stack is no longer visible.
- taskDisplayArea.moveHomeStackToFront(reason + " returnToHome");
+ taskDisplayArea.moveHomeRootTaskToFront(reason + " returnToHome");
}
- final Task lastFocusedTask = isRootTask() ? taskDisplayArea.getFocusedStack() : null;
+ final Task lastFocusedTask = isRootTask() ? taskDisplayArea.getFocusedRootTask() : null;
if (task == null) {
task = this;
}
@@ -5366,7 +5366,7 @@ class Task extends WindowContainer<WindowContainer> {
if (parentTask != null) {
parentTask.moveToBack(reason, this);
} else {
- final Task lastFocusedTask = displayArea.getFocusedStack();
+ final Task lastFocusedTask = displayArea.getFocusedRootTask();
displayArea.positionChildAt(POSITION_BOTTOM, this, false /*includingParents*/);
displayArea.updateLastFocusedRootTask(lastFocusedTask, reason);
}
@@ -5515,7 +5515,7 @@ class Task extends WindowContainer<WindowContainer> {
if (prev == null) {
if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed");
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
return false;
}
@@ -5622,7 +5622,7 @@ class Task extends WindowContainer<WindowContainer> {
// pause, so just treat it as being paused now.
ProtoLog.v(WM_DEBUG_STATES, "Activity not running, resuming next.");
if (resuming == null) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
return false;
}
@@ -5675,9 +5675,9 @@ class Task extends WindowContainer<WindowContainer> {
}
if (resumeNext) {
- final Task topStack = mRootWindowContainer.getTopDisplayFocusedStack();
+ final Task topStack = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) {
- mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
+ mRootWindowContainer.resumeFocusedTasksTopActivities(topStack, prev, null);
} else {
checkReadyForSleep();
final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null;
@@ -5686,7 +5686,7 @@ class Task extends WindowContainer<WindowContainer> {
// something. Also if the top activity on the stack is not the just paused
// activity, we need to go ahead and resume it to ensure we complete an
// in-flight app switch.
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
}
}
@@ -5709,7 +5709,7 @@ class Task extends WindowContainer<WindowContainer> {
boolean isTopStackInDisplayArea() {
final TaskDisplayArea taskDisplayArea = getDisplayArea();
- return taskDisplayArea != null && taskDisplayArea.isTopStack(this);
+ return taskDisplayArea != null && taskDisplayArea.isTopRootTask(this);
}
/**
@@ -5717,7 +5717,7 @@ class Task extends WindowContainer<WindowContainer> {
* otherwise.
*/
boolean isFocusedStackOnDisplay() {
- return mDisplayContent != null && this == mDisplayContent.getFocusedStack();
+ return mDisplayContent != null && this == mDisplayContent.getFocusedRootTask();
}
/**
@@ -5795,7 +5795,7 @@ class Task extends WindowContainer<WindowContainer> {
*/
boolean isTopSplitScreenStack() {
return inSplitScreenWindowingMode()
- && this == getDisplayArea().getTopStackInWindowingMode(getWindowingMode());
+ && this == getDisplayArea().getTopRootTaskInWindowingMode(getWindowingMode());
}
void checkTranslucentActivityWaiting(ActivityRecord top) {
@@ -5879,7 +5879,7 @@ class Task extends WindowContainer<WindowContainer> {
*
* NOTE: It is not safe to call this method directly as it can cause an activity in a
* non-focused stack to be resumed.
- * Use {@link RootWindowContainer#resumeFocusedStacksTopActivities} to resume the
+ * Use {@link RootWindowContainer#resumeFocusedTasksTopActivities} to resume the
* right activity for the current system state.
*/
@GuardedBy("mService")
@@ -6033,7 +6033,7 @@ class Task extends WindowContainer<WindowContainer> {
mTaskSupervisor.setLaunchSource(next.info.applicationInfo.uid);
ActivityRecord lastResumed = null;
- final Task lastFocusedStack = taskDisplayArea.getLastFocusedStack();
+ final Task lastFocusedStack = taskDisplayArea.getLastFocusedRootTask();
if (lastFocusedStack != null && lastFocusedStack != this) {
// So, why aren't we using prev here??? See the param comment on the method. prev
// doesn't represent the last resumed activity. However, the last focus stack does if
@@ -6048,7 +6048,7 @@ class Task extends WindowContainer<WindowContainer> {
}
}
- boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
+ boolean pausing = taskDisplayArea.pauseBackTasks(userLeaving, next);
if (mResumedActivity != null) {
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Pausing %s", mResumedActivity);
pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next,
@@ -6069,7 +6069,7 @@ class Task extends WindowContainer<WindowContainer> {
// Since the start-process is asynchronous, if we already know the process of next
// activity isn't running, we can start the process earlier to save the time to wait
// for the current activity to be paused.
- final boolean isTop = this == taskDisplayArea.getFocusedStack();
+ final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? "pre-top-activity" : "pre-activity");
}
@@ -6359,7 +6359,7 @@ class Task extends WindowContainer<WindowContainer> {
// Try to move focus to the next visible stack with a running activity if this
// stack is not covering the entire screen or is on a secondary display with no home
// stack.
- return mRootWindowContainer.resumeFocusedStacksTopActivities(nextFocusedStack,
+ return mRootWindowContainer.resumeFocusedTasksTopActivities(nextFocusedStack,
prev, null /* targetOptions */);
}
}
@@ -6839,7 +6839,7 @@ class Task extends WindowContainer<WindowContainer> {
AppTimeTracker timeTracker, boolean deferResume, String reason) {
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
- final Task topStack = getDisplayArea().getTopStack();
+ final Task topStack = getDisplayArea().getTopRootTask();
final ActivityRecord topActivity = topStack != null
? topStack.getTopNonFinishingActivity() : null;
@@ -6902,7 +6902,7 @@ class Task extends WindowContainer<WindowContainer> {
}
if (!deferResume) {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
} finally {
mDisplayContent.continueUpdateImeTarget();
@@ -6975,7 +6975,7 @@ class Task extends WindowContainer<WindowContainer> {
// resumed in this case, so we need to execute it explicitly.
mDisplayContent.executeAppTransition();
} else {
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
return true;
}
@@ -7280,7 +7280,7 @@ class Task extends WindowContainer<WindowContainer> {
final boolean wasResumed = topRunningActivity == task.getRootTask().mResumedActivity;
boolean toTop = position >= getChildCount();
- boolean includingParents = toTop || getDisplayArea().getNextFocusableStack(this,
+ boolean includingParents = toTop || getDisplayArea().getNextFocusableRootTask(this,
true /* ignoreCurrent */) == null;
if (WindowManagerDebugConfig.DEBUG_ROOT_TASK) {
Slog.i(TAG_WM, "positionChildAt: positioning task=" + task + " at " + position);
@@ -7309,7 +7309,7 @@ class Task extends WindowContainer<WindowContainer> {
// The task might have already been running and its visibility needs to be synchronized with
// the visibility of the stack / windows.
ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
}
public void setAlwaysOnTop(boolean alwaysOnTop) {
@@ -7431,7 +7431,7 @@ class Task extends WindowContainer<WindowContainer> {
// If there are other focusable stacks on the display, the z-order of the display should not
// be changed just because a task was placed at the bottom. E.g. if it is moving the topmost
// task to bottom, the next focusable stack on the same display should be focused.
- final Task nextFocusableStack = getDisplayArea().getNextFocusableStack(
+ final Task nextFocusableStack = getDisplayArea().getNextFocusableRootTask(
child.getRootTask(), true /* ignoreCurrent */);
positionChildAtBottom(child, nextFocusableStack == null /* includingParents */);
}
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 4682ba836426..b4d069c0edc1 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -193,7 +193,7 @@ class TaskChangeNotificationController {
switch (msg.what) {
case LOG_STACK_STATE_MSG: {
synchronized (mServiceLock) {
- mTaskSupervisor.logStackState();
+ mTaskSupervisor.logRootTaskState();
}
break;
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 81b8200aa2b4..4498a8c82583 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -38,7 +38,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
import static com.android.server.wm.ActivityTaskManagerService.TAG_ROOT_TASK;
-import static com.android.server.wm.DisplayContent.alwaysCreateStack;
+import static com.android.server.wm.DisplayContent.alwaysCreateRootTask;
import static com.android.server.wm.Task.ActivityState.RESUMED;
import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK;
@@ -107,9 +107,9 @@ final class TaskDisplayArea extends DisplayArea<Task> {
// TODO(b/159029784): Remove when getStack() behavior is cleaned-up
private Task mRootRecentsTask;
- private final ArrayList<Task> mTmpAlwaysOnTopStacks = new ArrayList<>();
- private final ArrayList<Task> mTmpNormalStacks = new ArrayList<>();
- private final ArrayList<Task> mTmpHomeStacks = new ArrayList<>();
+ private final ArrayList<Task> mTmpAlwaysOnTopRootTasks = new ArrayList<>();
+ private final ArrayList<Task> mTmpNormalRootTasks = new ArrayList<>();
+ private final ArrayList<Task> mTmpHomeRootTasks = new ArrayList<>();
private final IntArray mTmpNeedsZBoostIndexes = new IntArray();
private int mTmpLayerForSplitScreenDividerAnchor;
private int mTmpLayerForAnimationLayer;
@@ -128,23 +128,25 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* have the topmost index, it is used as a preferred candidate to prevent being unable to resume
* target stack properly when there are other focusable always-on-top stacks.
*/
- Task mPreferredTopFocusableStack;
+ Task mPreferredTopFocusableRootTask;
private final RootWindowContainer.FindTaskResult
mTmpFindTaskResult = new RootWindowContainer.FindTaskResult();
/**
- * If this is the same as {@link #getFocusedStack} then the activity on the top of the focused
- * stack has been resumed. If stacks are changing position this will hold the old stack until
- * the new stack becomes resumed after which it will be set to current focused stack.
+ * If this is the same as {@link #getFocusedRootTask} then the activity on the top of the
+ * focused root task has been resumed. If root tasks are changing position this will hold the
+ * old root task until the new root task becomes resumed after which it will be set to
+ * current focused root task.
*/
- Task mLastFocusedStack;
+ Task mLastFocusedRootTask;
/**
* All of the stacks on this display. Order matters, topmost stack is in front of all other
* stacks, bottommost behind. Accessed directly by ActivityManager package classes. Any calls
- * changing the list should also call {@link #onStackOrderChanged()}.
+ * changing the list should also call {@link #onRootTaskOrderChanged(Task)}.
*/
- private ArrayList<OnStackOrderChangedListener> mStackOrderChangedCallbacks = new ArrayList<>();
+ private ArrayList<OnRootTaskOrderChangedListener> mRootTaskOrderChangedCallbacks =
+ new ArrayList<>();
/**
* The task display area is removed from the system and we are just waiting for all activities
@@ -181,7 +183,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* Returns the topmost stack on the display that is compatible with the input windowing mode
* and activity type. Null is no compatible stack on the display.
*/
- Task getStack(int windowingMode, int activityType) {
+ Task getRootTask(int windowingMode, int activityType) {
if (activityType == ACTIVITY_TYPE_HOME) {
return mRootHomeTask;
} else if (activityType == ACTIVITY_TYPE_RECENTS) {
@@ -208,7 +210,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
@VisibleForTesting
- Task getTopStack() {
+ Task getTopRootTask() {
final int count = getChildCount();
return count > 0 ? getChildAt(count - 1) : null;
}
@@ -255,68 +257,68 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return visibleTasks;
}
- void onStackWindowingModeChanged(Task stack) {
- removeStackReferenceIfNeeded(stack);
- addStackReferenceIfNeeded(stack);
- if (stack == mRootPinnedTask && getTopStack() != stack) {
+ void onRootTaskWindowingModeChanged(Task rootTask) {
+ removeRootTaskReferenceIfNeeded(rootTask);
+ addRootTaskReferenceIfNeeded(rootTask);
+ if (rootTask == mRootPinnedTask && getTopRootTask() != rootTask) {
// Looks like this stack changed windowing mode to pinned. Move it to the top.
- positionChildAt(POSITION_TOP, stack, false /* includingParents */);
+ positionChildAt(POSITION_TOP, rootTask, false /* includingParents */);
}
}
- void addStackReferenceIfNeeded(Task stack) {
- if (stack.isActivityTypeHome()) {
+ void addRootTaskReferenceIfNeeded(Task rootTask) {
+ if (rootTask.isActivityTypeHome()) {
if (mRootHomeTask != null) {
- if (!stack.isDescendantOf(mRootHomeTask)) {
+ if (!rootTask.isDescendantOf(mRootHomeTask)) {
throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
+ mRootHomeTask + " already exist on display=" + this
- + " stack=" + stack);
+ + " stack=" + rootTask);
}
} else {
- mRootHomeTask = stack;
+ mRootHomeTask = rootTask;
}
- } else if (stack.isActivityTypeRecents()) {
+ } else if (rootTask.isActivityTypeRecents()) {
if (mRootRecentsTask != null) {
- if (!stack.isDescendantOf(mRootRecentsTask)) {
+ if (!rootTask.isDescendantOf(mRootRecentsTask)) {
throw new IllegalArgumentException("addStackReferenceIfNeeded: recents stack="
+ mRootRecentsTask + " already exist on display=" + this
- + " stack=" + stack);
+ + " stack=" + rootTask);
}
} else {
- mRootRecentsTask = stack;
+ mRootRecentsTask = rootTask;
}
}
- if (!stack.isRootTask()) {
+ if (!rootTask.isRootTask()) {
return;
}
- final int windowingMode = stack.getWindowingMode();
+ final int windowingMode = rootTask.getWindowingMode();
if (windowingMode == WINDOWING_MODE_PINNED) {
if (mRootPinnedTask != null) {
throw new IllegalArgumentException(
"addStackReferenceIfNeeded: pinned stack=" + mRootPinnedTask
- + " already exist on display=" + this + " stack=" + stack);
+ + " already exist on display=" + this + " stack=" + rootTask);
}
- mRootPinnedTask = stack;
+ mRootPinnedTask = rootTask;
} else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
if (mRootSplitScreenPrimaryTask != null) {
throw new IllegalArgumentException(
"addStackReferenceIfNeeded: split screen primary stack="
+ mRootSplitScreenPrimaryTask
- + " already exist on display=" + this + " stack=" + stack);
+ + " already exist on display=" + this + " stack=" + rootTask);
}
- mRootSplitScreenPrimaryTask = stack;
+ mRootSplitScreenPrimaryTask = rootTask;
}
}
- void removeStackReferenceIfNeeded(Task stack) {
- if (stack == mRootHomeTask) {
+ void removeRootTaskReferenceIfNeeded(Task rootTask) {
+ if (rootTask == mRootHomeTask) {
mRootHomeTask = null;
- } else if (stack == mRootRecentsTask) {
+ } else if (rootTask == mRootRecentsTask) {
mRootRecentsTask = null;
- } else if (stack == mRootPinnedTask) {
+ } else if (rootTask == mRootPinnedTask) {
mRootPinnedTask = null;
- } else if (stack == mRootSplitScreenPrimaryTask) {
+ } else if (rootTask == mRootSplitScreenPrimaryTask) {
mRootSplitScreenPrimaryTask = null;
}
}
@@ -325,20 +327,20 @@ final class TaskDisplayArea extends DisplayArea<Task> {
void addChild(Task task, int position) {
if (DEBUG_ROOT_TASK) Slog.d(TAG_WM, "Set task=" + task + " on taskDisplayArea=" + this);
- addStackReferenceIfNeeded(task);
- position = findPositionForStack(position, task, true /* adding */);
+ addRootTaskReferenceIfNeeded(task);
+ position = findPositionForRootTask(position, task, true /* adding */);
super.addChild(task, position);
mAtmService.updateSleepIfNeededLocked();
- onStackOrderChanged(task);
+ onRootTaskOrderChanged(task);
}
@Override
protected void removeChild(Task stack) {
super.removeChild(stack);
- onStackRemoved(stack);
+ onRootTaskRemoved(stack);
mAtmService.updateSleepIfNeededLocked();
- removeStackReferenceIfNeeded(stack);
+ removeRootTaskReferenceIfNeeded(stack);
}
@Override
@@ -367,7 +369,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
if (!mDisplayContent.isTrusted() && !getParent().isOnTop()) {
includingParents = false;
}
- final int targetPosition = findPositionForStack(position, child, false /* adding */);
+ final int targetPosition = findPositionForRootTask(position, child, false /* adding */);
super.positionChildAt(targetPosition, child, false /* includingParents */);
if (includingParents && getParent() != null && (moveToTop || moveToBottom)) {
@@ -385,16 +387,16 @@ final class TaskDisplayArea extends DisplayArea<Task> {
// preferred stack is set only when moving an existing stack to top instead of adding a new
// stack that may be too early (e.g. in the middle of launching or reparenting).
if (moveToTop && child.isFocusableAndVisible()) {
- mPreferredTopFocusableStack = child;
- } else if (mPreferredTopFocusableStack == child) {
- mPreferredTopFocusableStack = null;
+ mPreferredTopFocusableRootTask = child;
+ } else if (mPreferredTopFocusableRootTask == child) {
+ mPreferredTopFocusableRootTask = null;
}
// Update the top resumed activity because the preferred top focusable task may be changed.
mAtmService.mTaskSupervisor.updateTopResumedActivityIfNeeded();
if (mChildren.indexOf(child) != oldPosition) {
- onStackOrderChanged(child);
+ onRootTaskOrderChanged(child);
}
}
@@ -469,21 +471,21 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return 0;
}
- private int findMinPositionForStack(Task stack) {
+ private int findMinPositionForRootTask(Task rootTask) {
int minPosition = POSITION_BOTTOM;
for (int i = 0; i < mChildren.size(); ++i) {
- if (getPriority(getStackAt(i)) < getPriority(stack)) {
+ if (getPriority(getRootTaskAt(i)) < getPriority(rootTask)) {
minPosition = i;
} else {
break;
}
}
- if (stack.isAlwaysOnTop()) {
+ if (rootTask.isAlwaysOnTop()) {
// Since a stack could be repositioned while still being one of the children, we check
// if this always-on-top stack already exists and if so, set the minPosition to its
// previous position.
- final int currentIndex = getIndexOf(stack);
+ final int currentIndex = getIndexOf(rootTask);
if (currentIndex > minPosition) {
minPosition = currentIndex;
}
@@ -491,13 +493,13 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return minPosition;
}
- private int findMaxPositionForStack(Task stack) {
+ private int findMaxPositionForRootTask(Task rootTask) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
- final Task curr = getStackAt(i);
+ final Task curr = getRootTaskAt(i);
// Since a stack could be repositioned while still being one of the children, we check
// if 'curr' is the same stack and skip it if so
- final boolean sameStack = curr == stack;
- if (getPriority(curr) <= getPriority(stack) && !sameStack) {
+ final boolean sameRootTask = curr == rootTask;
+ if (getPriority(curr) <= getPriority(rootTask) && !sameRootTask) {
return i;
}
}
@@ -519,16 +521,16 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* (including the Dream); otherwise, it is a normal non-always-on-top stack
*
* @param requestedPosition Position requested by caller.
- * @param stack Stack to be added or positioned.
+ * @param rootTask Root task to be added or positioned.
* @param adding Flag indicates whether we're adding a new stack or positioning an
* existing.
* @return The proper position for the stack.
*/
- private int findPositionForStack(int requestedPosition, Task stack, boolean adding) {
+ private int findPositionForRootTask(int requestedPosition, Task rootTask, boolean adding) {
// The max possible position we can insert the stack at.
- int maxPosition = findMaxPositionForStack(stack);
+ int maxPosition = findMaxPositionForRootTask(rootTask);
// The min possible position we can insert the stack at.
- int minPosition = findMinPositionForStack(stack);
+ int minPosition = findMinPositionForRootTask(rootTask);
// Cap the requested position to something reasonable for the previous position check
// below.
@@ -542,7 +544,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
targetPosition = Math.min(targetPosition, maxPosition);
targetPosition = Math.max(targetPosition, minPosition);
- int prevPosition = mChildren.indexOf(stack);
+ int prevPosition = mChildren.indexOf(rootTask);
// The positions we calculated above (maxPosition, minPosition) do not take into
// consideration the following edge cases.
// 1) We need to adjust the position depending on the value "adding".
@@ -645,7 +647,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return SCREEN_ORIENTATION_UNSET;
}
- if (isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
+ if (isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
// Apps and their containers are not allowed to specify an orientation while using
// root tasks...except for the home stack if it is not resizable and currently
// visible (top of) its root task.
@@ -672,7 +674,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
} else {
// Apps and their containers are not allowed to specify an orientation of full screen
// tasks created by organizer. The organizer handles the orientation instead.
- final Task task = getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ final Task task = getTopRootTaskInWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (task != null && task.isVisible() && task.mCreatedByOrganizer) {
return SCREEN_ORIENTATION_UNSPECIFIED;
}
@@ -697,7 +699,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
@Override
void assignChildLayers(SurfaceControl.Transaction t) {
- assignStackOrdering(t);
+ assignRootTaskOrdering(t);
for (int i = 0; i < mChildren.size(); i++) {
final Task s = mChildren.get(i);
@@ -705,37 +707,37 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
}
- void assignStackOrdering(SurfaceControl.Transaction t) {
+ void assignRootTaskOrdering(SurfaceControl.Transaction t) {
if (getParent() == null) {
return;
}
- mTmpAlwaysOnTopStacks.clear();
- mTmpHomeStacks.clear();
- mTmpNormalStacks.clear();
+ mTmpAlwaysOnTopRootTasks.clear();
+ mTmpHomeRootTasks.clear();
+ mTmpNormalRootTasks.clear();
for (int i = 0; i < mChildren.size(); ++i) {
final Task s = mChildren.get(i);
if (s.isAlwaysOnTop()) {
- mTmpAlwaysOnTopStacks.add(s);
+ mTmpAlwaysOnTopRootTasks.add(s);
} else if (s.isActivityTypeHome()) {
- mTmpHomeStacks.add(s);
+ mTmpHomeRootTasks.add(s);
} else {
- mTmpNormalStacks.add(s);
+ mTmpNormalRootTasks.add(s);
}
}
int layer = 0;
// Place home stacks to the bottom.
- layer = adjustRootTaskLayer(t, mTmpHomeStacks, layer, false /* normalStacks */);
+ layer = adjustRootTaskLayer(t, mTmpHomeRootTasks, layer, false /* normalStacks */);
// The home animation layer is between the home stacks and the normal stacks.
final int layerForHomeAnimationLayer = layer++;
mTmpLayerForSplitScreenDividerAnchor = layer++;
mTmpLayerForAnimationLayer = layer++;
- layer = adjustRootTaskLayer(t, mTmpNormalStacks, layer, true /* normalStacks */);
+ layer = adjustRootTaskLayer(t, mTmpNormalRootTasks, layer, true /* normalStacks */);
// The boosted animation layer is between the normal stacks and the always on top
// stacks.
final int layerForBoostedAnimationLayer = layer++;
- adjustRootTaskLayer(t, mTmpAlwaysOnTopStacks, layer, false /* normalStacks */);
+ adjustRootTaskLayer(t, mTmpAlwaysOnTopRootTasks, layer, false /* normalStacks */);
t.setLayer(mHomeAppAnimationLayer, layerForHomeAnimationLayer);
t.setLayer(mAppAnimationLayer, mTmpLayerForAnimationLayer);
@@ -743,7 +745,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer);
}
- private int adjustNormalStackLayer(Task s, int layer) {
+ private int adjustNormalRootTaskLayer(Task s, int layer) {
if (s.inSplitScreenWindowingMode()) {
// The split screen divider anchor is located above the split screen window.
mTmpLayerForSplitScreenDividerAnchor = layer++;
@@ -773,7 +775,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
if (!stack.needsZBoost()) {
stack.assignLayer(t, startLayer++);
if (normalStacks) {
- startLayer = adjustNormalStackLayer(stack, startLayer);
+ startLayer = adjustNormalRootTaskLayer(stack, startLayer);
}
} else {
mTmpNeedsZBoostIndexes.add(i);
@@ -785,7 +787,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
final Task stack = stacks.get(mTmpNeedsZBoostIndexes.get(i));
stack.assignLayer(t, startLayer++);
if (normalStacks) {
- startLayer = adjustNormalStackLayer(stack, startLayer);
+ startLayer = adjustNormalRootTaskLayer(stack, startLayer);
}
}
return startLayer;
@@ -849,22 +851,22 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
}
- void onStackRemoved(Task stack) {
+ void onRootTaskRemoved(Task rootTask) {
if (ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK) {
- Slog.v(TAG_ROOT_TASK, "removeStack: detaching " + stack + " from displayId="
+ Slog.v(TAG_ROOT_TASK, "removeStack: detaching " + rootTask + " from displayId="
+ mDisplayContent.mDisplayId);
}
- if (mPreferredTopFocusableStack == stack) {
- mPreferredTopFocusableStack = null;
+ if (mPreferredTopFocusableRootTask == rootTask) {
+ mPreferredTopFocusableRootTask = null;
}
mDisplayContent.releaseSelfIfNeeded();
- onStackOrderChanged(stack);
+ onRootTaskOrderChanged(rootTask);
}
- void resetPreferredTopFocusableStackIfBelow(Task task) {
- if (mPreferredTopFocusableStack != null
- && mPreferredTopFocusableStack.compareTo(task) < 0) {
- mPreferredTopFocusableStack = null;
+ void resetPreferredTopFocusableRootTaskIfBelow(Task task) {
+ if (mPreferredTopFocusableRootTask != null
+ && mPreferredTopFocusableRootTask.compareTo(task) < 0) {
+ mPreferredTopFocusableRootTask = null;
}
}
@@ -894,9 +896,9 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
}
- Task getStack(int rootTaskId) {
- for (int i = getStackCount() - 1; i >= 0; --i) {
- final Task stack = getStackAt(i);
+ Task getRootTask(int rootTaskId) {
+ for (int i = getRootTaskCount() - 1; i >= 0; --i) {
+ final Task stack = getRootTaskAt(i);
if (stack.getRootTaskId() == rootTaskId) {
return stack;
}
@@ -908,10 +910,10 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* Returns an existing stack compatible with the windowing mode and activity type or creates one
* if a compatible stack doesn't exist.
*
- * @see #getOrCreateStack(int, int, boolean, Intent, Task)
+ * @see #getOrCreateRootTask(int, int, boolean, Intent, Task)
*/
- Task getOrCreateStack(int windowingMode, int activityType, boolean onTop) {
- return getOrCreateStack(windowingMode, activityType, onTop, null /* intent */,
+ Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop) {
+ return getOrCreateRootTask(windowingMode, activityType, onTop, null /* intent */,
null /* candidateTask */);
}
@@ -921,17 +923,17 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* For one level task, the candidate task would be reused to also be the root task or create
* a new root task if no candidate task.
*
- * @see #getStack(int, int)
- * @see #createStack(int, int, boolean)
+ * @see #getRootTask(int, int)
+ * @see #createRootTask(int, int, boolean)
*/
- Task getOrCreateStack(int windowingMode, int activityType, boolean onTop,
+ Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop,
Intent intent, Task candidateTask) {
// Need to pass in a determined windowing mode to see if a new stack should be created,
// so use its parent's windowing mode if it is undefined.
- if (!alwaysCreateStack(
+ if (!alwaysCreateRootTask(
windowingMode != WINDOWING_MODE_UNDEFINED ? windowingMode : getWindowingMode(),
activityType)) {
- Task stack = getStack(windowingMode, activityType);
+ Task stack = getRootTask(windowingMode, activityType);
if (stack != null) {
return stack;
}
@@ -959,7 +961,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
return stack;
}
- return createStack(windowingMode, activityType, onTop, null /*info*/, intent,
+ return createRootTask(windowingMode, activityType, onTop, null /*info*/, intent,
false /* createdByOrganizer */);
}
@@ -967,9 +969,9 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* Returns an existing stack compatible with the input params or creates one
* if a compatible stack doesn't exist.
*
- * @see #getOrCreateStack(int, int, boolean)
+ * @see #getOrCreateRootTask(int, int, boolean)
*/
- Task getOrCreateStack(@Nullable ActivityRecord r,
+ Task getOrCreateRootTask(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable Task candidateTask, int activityType,
boolean onTop) {
// First preference is the windowing mode in the activity options if set.
@@ -979,24 +981,24 @@ final class TaskDisplayArea extends DisplayArea<Task> {
// UNDEFINED windowing mode is a valid result and means that the new stack will inherit
// it's display's windowing mode.
windowingMode = validateWindowingMode(windowingMode, r, candidateTask, activityType);
- return getOrCreateStack(windowingMode, activityType, onTop, null /* intent */,
+ return getOrCreateRootTask(windowingMode, activityType, onTop, null /* intent */,
candidateTask);
}
@VisibleForTesting
- int getNextStackId() {
+ int getNextRootTaskId() {
return mAtmService.mTaskSupervisor.getNextTaskIdForUser();
}
- Task createStack(int windowingMode, int activityType, boolean onTop) {
- return createStack(windowingMode, activityType, onTop, null /* info */, null /* intent */,
- false /* createdByOrganizer */);
+ Task createRootTask(int windowingMode, int activityType, boolean onTop) {
+ return createRootTask(windowingMode, activityType, onTop, null /* info */,
+ null /* intent */, false /* createdByOrganizer */);
}
- Task createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info,
+ Task createRootTask(int windowingMode, int activityType, boolean onTop, ActivityInfo info,
Intent intent, boolean createdByOrganizer) {
- return createStack(windowingMode, activityType, onTop, null /* info */, null /* intent */,
- false /* createdByOrganizer */ , false /* deferTaskAppear */,
+ return createRootTask(windowingMode, activityType, onTop, null /* info */,
+ null /* intent */, false /* createdByOrganizer */, false /* deferTaskAppear */,
null /* launchCookie */);
}
@@ -1022,7 +1024,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* creating.
* @return The newly created stack.
*/
- Task createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info,
+ Task createRootTask(int windowingMode, int activityType, boolean onTop, ActivityInfo info,
Intent intent, boolean createdByOrganizer, boolean deferTaskAppear,
IBinder launchCookie) {
if (activityType == ACTIVITY_TYPE_UNDEFINED && !createdByOrganizer) {
@@ -1034,7 +1036,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
if (activityType != ACTIVITY_TYPE_STANDARD && activityType != ACTIVITY_TYPE_UNDEFINED) {
// For now there can be only one stack of a particular non-standard activity type on a
// display. So, get that ignoring whatever windowing mode it is currently in.
- Task stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
+ Task stack = getRootTask(WINDOWING_MODE_UNDEFINED, activityType);
if (stack != null) {
throw new IllegalArgumentException("Stack=" + stack + " of activityType="
+ activityType + " already on display=" + this + ". Can't have multiple.");
@@ -1054,8 +1056,8 @@ final class TaskDisplayArea extends DisplayArea<Task> {
getRootPinnedTask().dismissPip();
}
- final int stackId = getNextStackId();
- return createStackUnchecked(windowingMode, activityType, stackId, onTop, info, intent,
+ final int stackId = getNextRootTaskId();
+ return createRootTaskUnchecked(windowingMode, activityType, stackId, onTop, info, intent,
createdByOrganizer, deferTaskAppear, launchCookie);
}
@@ -1065,15 +1067,15 @@ final class TaskDisplayArea extends DisplayArea<Task> {
// Only split-screen windowing modes can do this currently...
return null;
}
- for (int i = getStackCount() - 1; i >= 0; --i) {
- final Task t = getStackAt(i);
+ for (int i = getRootTaskCount() - 1; i >= 0; --i) {
+ final Task t = getRootTaskAt(i);
if (!t.mCreatedByOrganizer || t.getRequestedOverrideWindowingMode() != windowingMode) {
continue;
}
// If not already set, pick a launch root which is not the one we are launching into.
if (mLaunchRootTask == null) {
- for (int j = 0, n = getStackCount(); j < n; ++j) {
- final Task tt = getStackAt(j);
+ for (int j = 0, n = getRootTaskCount(); j < n; ++j) {
+ final Task tt = getRootTaskAt(j);
if (tt.mCreatedByOrganizer && tt != t) {
mLaunchRootTask = tt;
break;
@@ -1086,7 +1088,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
@VisibleForTesting
- Task createStackUnchecked(int windowingMode, int activityType, int stackId, boolean onTop,
+ Task createRootTaskUnchecked(int windowingMode, int activityType, int stackId, boolean onTop,
ActivityInfo info, Intent intent, boolean createdByOrganizer, boolean deferTaskAppear,
IBinder launchCookie) {
if (windowingMode == WINDOWING_MODE_PINNED && activityType != ACTIVITY_TYPE_STANDARD) {
@@ -1123,13 +1125,13 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* Get the preferred focusable stack in priority. If the preferred stack does not exist, find a
* focusable and visible stack from the top of stacks in this display.
*/
- Task getFocusedStack() {
- if (mPreferredTopFocusableStack != null) {
- return mPreferredTopFocusableStack;
+ Task getFocusedRootTask() {
+ if (mPreferredTopFocusableRootTask != null) {
+ return mPreferredTopFocusableRootTask;
}
- for (int i = getStackCount() - 1; i >= 0; --i) {
- final Task stack = getStackAt(i);
+ for (int i = getRootTaskCount() - 1; i >= 0; --i) {
+ final Task stack = getRootTaskAt(i);
if (stack.isFocusableAndVisible()) {
return stack;
}
@@ -1138,22 +1140,22 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return null;
}
- Task getNextFocusableStack(Task currentFocus, boolean ignoreCurrent) {
+ Task getNextFocusableRootTask(Task currentFocus, boolean ignoreCurrent) {
final int currentWindowingMode = currentFocus != null
? currentFocus.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
Task candidate = null;
- for (int i = getStackCount() - 1; i >= 0; --i) {
- final Task stack = getStackAt(i);
- if (ignoreCurrent && stack == currentFocus) {
+ for (int i = getRootTaskCount() - 1; i >= 0; --i) {
+ final Task rootTask = getRootTaskAt(i);
+ if (ignoreCurrent && rootTask == currentFocus) {
continue;
}
- if (!stack.isFocusableAndVisible()) {
+ if (!rootTask.isFocusableAndVisible()) {
continue;
}
if (currentWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
- && candidate == null && stack.inSplitScreenPrimaryWindowingMode()) {
+ && candidate == null && rootTask.inSplitScreenPrimaryWindowingMode()) {
// If the currently focused stack is in split-screen secondary we save off the
// top primary split-screen stack as a candidate for focus because we might
// prefer focus to move to an other stack to avoid primary split-screen stack
@@ -1161,20 +1163,20 @@ final class TaskDisplayArea extends DisplayArea<Task> {
// than the next split-screen stack. Assistant stack, I am looking at you...
// We only move the focus to the primary-split screen stack if there isn't a
// better alternative.
- candidate = stack;
+ candidate = rootTask;
continue;
}
- if (candidate != null && stack.inSplitScreenSecondaryWindowingMode()) {
+ if (candidate != null && rootTask.inSplitScreenSecondaryWindowingMode()) {
// Use the candidate stack since we are now at the secondary split-screen.
return candidate;
}
- return stack;
+ return rootTask;
}
return candidate;
}
ActivityRecord getFocusedActivity() {
- final Task focusedStack = getFocusedStack();
+ final Task focusedStack = getFocusedRootTask();
if (focusedStack == null) {
return null;
}
@@ -1194,8 +1196,8 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return resumedActivity;
}
- Task getLastFocusedStack() {
- return mLastFocusedStack;
+ Task getLastFocusedRootTask() {
+ return mLastFocusedRootTask;
}
void updateLastFocusedRootTask(Task prevFocusedTask, String updateLastFocusedTaskReason) {
@@ -1203,7 +1205,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return;
}
- final Task currentFocusedTask = getFocusedStack();
+ final Task currentFocusedTask = getFocusedRootTask();
if (currentFocusedTask == prevFocusedTask) {
return;
}
@@ -1214,27 +1216,27 @@ final class TaskDisplayArea extends DisplayArea<Task> {
currentFocusedTask.mLastPausedActivity = null;
}
- mLastFocusedStack = prevFocusedTask;
+ mLastFocusedRootTask = prevFocusedTask;
EventLogTags.writeWmFocusedStack(mRootWindowContainer.mCurrentUser,
mDisplayContent.mDisplayId,
currentFocusedTask == null ? -1 : currentFocusedTask.getRootTaskId(),
- mLastFocusedStack == null ? -1 : mLastFocusedStack.getRootTaskId(),
+ mLastFocusedRootTask == null ? -1 : mLastFocusedRootTask.getRootTaskId(),
updateLastFocusedTaskReason);
}
boolean allResumedActivitiesComplete() {
- for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityRecord r = getStackAt(stackNdx).getResumedActivity();
+ for (int stackNdx = getRootTaskCount() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityRecord r = getRootTaskAt(stackNdx).getResumedActivity();
if (r != null && !r.isState(RESUMED)) {
return false;
}
}
- final Task currentFocusedStack = getFocusedStack();
+ final Task currentFocusedStack = getFocusedRootTask();
if (ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK) {
Slog.d(TAG_ROOT_TASK, "allResumedActivitiesComplete: mLastFocusedStack changing from="
- + mLastFocusedStack + " to=" + currentFocusedStack);
+ + mLastFocusedRootTask + " to=" + currentFocusedStack);
}
- mLastFocusedStack = currentFocusedStack;
+ mLastFocusedRootTask = currentFocusedStack;
return true;
}
@@ -1249,10 +1251,10 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* @param resuming The resuming activity.
* @return {@code true} if any activity was paused as a result of this call.
*/
- boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming) {
+ boolean pauseBackTasks(boolean userLeaving, ActivityRecord resuming) {
boolean someActivityPaused = false;
- for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
- final Task stack = getStackAt(stackNdx);
+ for (int stackNdx = getRootTaskCount() - 1; stackNdx >= 0; --stackNdx) {
+ final Task stack = getRootTaskAt(stackNdx);
final ActivityRecord resumedActivity = stack.getResumedActivity();
if (resumedActivity != null
&& (stack.getVisibility(resuming) != TASK_VISIBILITY_VISIBLE
@@ -1272,8 +1274,8 @@ final class TaskDisplayArea extends DisplayArea<Task> {
void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplayArea,
RootWindowContainer.FindTaskResult result) {
mTmpFindTaskResult.clear();
- for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
- final Task stack = getStackAt(stackNdx);
+ for (int stackNdx = getRootTaskCount() - 1; stackNdx >= 0; --stackNdx) {
+ final Task stack = getRootTaskAt(stackNdx);
if (!r.hasCompatibleActivityType(stack) && stack.isLeafTask()) {
ProtoLog.d(WM_DEBUG_TASKS, "Skipping stack: (mismatch activity/stack) "
+ "%s", stack);
@@ -1367,7 +1369,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
// The focused task could be a non-resizeable fullscreen root task that is on top of the
// other split-screen tasks, therefore had to dismiss split-screen, make sure the current
// focused root task can still be on top after dismissal
- final Task rootTask = getFocusedStack();
+ final Task rootTask = getFocusedRootTask();
final Task toTop =
rootTask != null && !rootTask.inSplitScreenWindowingMode() ? rootTask : null;
onSplitScreenModeDismissed(toTop);
@@ -1380,9 +1382,9 @@ final class TaskDisplayArea extends DisplayArea<Task> {
moveSplitScreenTasksToFullScreen();
} finally {
final Task topFullscreenStack = toTop != null
- ? toTop : getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ ? toTop : getTopRootTaskInWindowingMode(WINDOWING_MODE_FULLSCREEN);
final Task homeStack = getOrCreateRootHomeTask();
- if (homeStack != null && ((topFullscreenStack != null && !isTopStack(homeStack))
+ if (homeStack != null && ((topFullscreenStack != null && !isTopRootTask(homeStack))
|| toTop != null)) {
// Whenever split-screen is dismissed we want the home stack directly behind the
// current top fullscreen stack so it shows up when the top stack is finished.
@@ -1556,8 +1558,8 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return windowingMode;
}
- boolean isTopStack(Task stack) {
- return stack == getTopStack();
+ boolean isTopRootTask(Task stack) {
+ return stack == getTopRootTask();
}
ActivityRecord topRunningActivity() {
@@ -1575,15 +1577,15 @@ final class TaskDisplayArea extends DisplayArea<Task> {
*/
ActivityRecord topRunningActivity(boolean considerKeyguardState) {
ActivityRecord topRunning = null;
- final Task focusedStack = getFocusedStack();
+ final Task focusedStack = getFocusedRootTask();
if (focusedStack != null) {
topRunning = focusedStack.topRunningActivity();
}
// Look in other focusable stacks.
if (topRunning == null) {
- for (int i = getStackCount() - 1; i >= 0; --i) {
- final Task stack = getStackAt(i);
+ for (int i = getRootTaskCount() - 1; i >= 0; --i) {
+ final Task stack = getRootTaskAt(i);
// Only consider focusable stacks other than the current focused one.
if (stack == focusedStack || !stack.isTopActivityFocusable()) {
continue;
@@ -1607,13 +1609,11 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return topRunning;
}
- // TODO (b/157876447): switch to Task related name
- protected int getStackCount() {
+ protected int getRootTaskCount() {
return mChildren.size();
}
- // TODO (b/157876447): switch to Task related name
- protected Task getStackAt(int index) {
+ protected Task getRootTaskAt(int index) {
return mChildren.get(index);
}
@@ -1633,7 +1633,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
Task getOrCreateRootHomeTask(boolean onTop) {
Task homeTask = getRootHomeTask();
if (homeTask == null && mDisplayContent.supportsSystemDecorations()) {
- homeTask = createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, onTop);
+ homeTask = createRootTask(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, onTop);
}
return homeTask;
}
@@ -1647,14 +1647,14 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* Returns the topmost stack on the display that is compatible with the input windowing mode.
* Null is no compatible stack on the display.
*/
- Task getTopStackInWindowingMode(int windowingMode) {
- return getStack(windowingMode, ACTIVITY_TYPE_UNDEFINED);
+ Task getTopRootTaskInWindowingMode(int windowingMode) {
+ return getRootTask(windowingMode, ACTIVITY_TYPE_UNDEFINED);
}
- void moveHomeStackToFront(String reason) {
- final Task homeStack = getOrCreateRootHomeTask();
- if (homeStack != null) {
- homeStack.moveToFront(reason);
+ void moveHomeRootTaskToFront(String reason) {
+ final Task homeRootTask = getOrCreateRootHomeTask();
+ if (homeRootTask != null) {
+ homeRootTask.moveToFront(reason);
}
}
@@ -1665,7 +1665,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
void moveHomeActivityToTop(String reason) {
final ActivityRecord top = getHomeActivity();
if (top == null) {
- moveHomeStackToFront(reason);
+ moveHomeRootTaskToFront(reason);
return;
}
top.moveFocusableActivityToTop(reason);
@@ -1697,25 +1697,27 @@ final class TaskDisplayArea extends DisplayArea<Task> {
/**
* Adjusts the {@param stack} behind the last visible stack in the display if necessary.
- * Generally used in conjunction with {@link #moveStackBehindStack}.
+ * Generally used in conjunction with {@link #moveRootTaskBehindRootTask}.
*/
// TODO(b/151575894): Remove special stack movement methods.
- void moveStackBehindBottomMostVisibleStack(Task stack) {
- if (stack.shouldBeVisible(null)) {
+ void moveRootTaskBehindBottomMostVisibleRootTask(Task rootTask) {
+ if (rootTask.shouldBeVisible(null)) {
// Skip if the stack is already visible
return;
}
// Move the stack to the bottom to not affect the following visibility checks
- stack.getParent().positionChildAt(POSITION_BOTTOM, stack, false /* includingParents */);
+ rootTask.getParent().positionChildAt(POSITION_BOTTOM, rootTask,
+ false /* includingParents */);
// Find the next position where the stack should be placed
- final boolean isRootTask = stack.isRootTask();
- final int numStacks = isRootTask ? getStackCount() : stack.getParent().getChildCount();
- for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
- final Task s = isRootTask ? getStackAt(stackNdx)
- : (Task) stack.getParent().getChildAt(stackNdx);
- if (s == stack) {
+ final boolean isRootTask = rootTask.isRootTask();
+ final int numRootTasks =
+ isRootTask ? getRootTaskCount() : rootTask.getParent().getChildCount();
+ for (int rootTaskNdx = 0; rootTaskNdx < numRootTasks; rootTaskNdx++) {
+ final Task s = isRootTask ? getRootTaskAt(rootTaskNdx)
+ : (Task) rootTask.getParent().getChildAt(rootTaskNdx);
+ if (s == rootTask) {
continue;
}
final int winMode = s.getWindowingMode();
@@ -1723,8 +1725,9 @@ final class TaskDisplayArea extends DisplayArea<Task> {
|| winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
if (s.shouldBeVisible(null) && isValidWindowingMode) {
// Move the provided stack to behind this stack
- final int position = Math.max(0, stackNdx - 1);
- stack.getParent().positionChildAt(position, stack, false /*includingParents */);
+ final int position = Math.max(0, rootTaskNdx - 1);
+ rootTask.getParent().positionChildAt(position, rootTask,
+ false /*includingParents */);
break;
}
}
@@ -1733,15 +1736,16 @@ final class TaskDisplayArea extends DisplayArea<Task> {
/**
* Moves the {@param stack} behind the given {@param behindStack} if possible. If
* {@param behindStack} is not currently in the display, then then the stack is moved to the
- * back. Generally used in conjunction with {@link #moveStackBehindBottomMostVisibleStack}.
+ * back. Generally used in conjunction with
+ * {@link #moveRootTaskBehindBottomMostVisibleRootTask}.
*/
- void moveStackBehindStack(Task stack, Task behindStack) {
- if (behindStack == null || behindStack == stack) {
+ void moveRootTaskBehindRootTask(Task rootTask, Task behindRootTask) {
+ if (behindRootTask == null || behindRootTask == rootTask) {
return;
}
- final WindowContainer parent = stack.getParent();
- if (parent == null || parent != behindStack.getParent()) {
+ final WindowContainer parent = rootTask.getParent();
+ if (parent == null || parent != behindRootTask.getParent()) {
return;
}
@@ -1749,12 +1753,12 @@ final class TaskDisplayArea extends DisplayArea<Task> {
// list, so we need to adjust the insertion index to account for the removed index
// TODO: Remove this logic when WindowContainer.positionChildAt() is updated to adjust the
// position internally
- final int stackIndex = parent.mChildren.indexOf(stack);
- final int behindStackIndex = parent.mChildren.indexOf(behindStack);
+ final int stackIndex = parent.mChildren.indexOf(rootTask);
+ final int behindStackIndex = parent.mChildren.indexOf(behindRootTask);
final int insertIndex = stackIndex <= behindStackIndex
? behindStackIndex - 1 : behindStackIndex;
final int position = Math.max(0, insertIndex);
- parent.positionChildAt(position, stack, false /* includingParents */);
+ parent.positionChildAt(position, rootTask, false /* includingParents */);
}
boolean hasPinnedTask() {
@@ -1765,20 +1769,20 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* @return the stack currently above the {@param stack}. Can be null if the {@param stack} is
* already top-most.
*/
- static Task getStackAbove(Task stack) {
- final WindowContainer wc = stack.getParent();
- final int index = wc.mChildren.indexOf(stack) + 1;
+ static Task getRootTaskAbove(Task rootTask) {
+ final WindowContainer wc = rootTask.getParent();
+ final int index = wc.mChildren.indexOf(rootTask) + 1;
return (index < wc.mChildren.size()) ? (Task) wc.mChildren.get(index) : null;
}
/** Returns true if the stack in the windowing mode is visible. */
- boolean isStackVisible(int windowingMode) {
- final Task stack = getTopStackInWindowingMode(windowingMode);
- return stack != null && stack.isVisible();
+ boolean isRootTaskVisible(int windowingMode) {
+ final Task rootTask = getTopRootTaskInWindowingMode(windowingMode);
+ return rootTask != null && rootTask.isVisible();
}
- void removeStack(Task stack) {
- removeChild(stack);
+ void removeRootTask(Task rootTask) {
+ removeChild(rootTask);
}
int getDisplayId() {
@@ -1794,27 +1798,27 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* only used by the {@link RecentsAnimation} to determine whether to interrupt and cancel the
* current animation when the system state changes.
*/
- void registerStackOrderChangedListener(OnStackOrderChangedListener listener) {
- if (!mStackOrderChangedCallbacks.contains(listener)) {
- mStackOrderChangedCallbacks.add(listener);
+ void registerRootTaskOrderChangedListener(OnRootTaskOrderChangedListener listener) {
+ if (!mRootTaskOrderChangedCallbacks.contains(listener)) {
+ mRootTaskOrderChangedCallbacks.add(listener);
}
}
/**
* Removes a previously registered stack order change listener.
*/
- void unregisterStackOrderChangedListener(OnStackOrderChangedListener listener) {
- mStackOrderChangedCallbacks.remove(listener);
+ void unregisterRootTaskOrderChangedListener(OnRootTaskOrderChangedListener listener) {
+ mRootTaskOrderChangedCallbacks.remove(listener);
}
/**
- * Notifies of a stack order change
+ * Notifies of a root task order change
*
- * @param stack The stack which triggered the order change
+ * @param rootTask The root task which triggered the order change
*/
- void onStackOrderChanged(Task stack) {
- for (int i = mStackOrderChangedCallbacks.size() - 1; i >= 0; i--) {
- mStackOrderChangedCallbacks.get(i).onStackOrderChanged(stack);
+ void onRootTaskOrderChanged(Task rootTask) {
+ for (int i = mRootTaskOrderChangedCallbacks.size() - 1; i >= 0; i--) {
+ mRootTaskOrderChangedCallbacks.get(i).onRootTaskOrderChanged(rootTask);
}
}
@@ -1826,16 +1830,16 @@ final class TaskDisplayArea extends DisplayArea<Task> {
/**
* Callback for when the order of the stacks in the display changes.
*/
- interface OnStackOrderChangedListener {
- void onStackOrderChanged(Task stack);
+ interface OnRootTaskOrderChangedListener {
+ void onRootTaskOrderChanged(Task rootTask);
}
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients, boolean userLeaving) {
mAtmService.mTaskSupervisor.beginActivityVisibilityUpdate();
try {
- for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
- final Task stack = getStackAt(stackNdx);
+ for (int stackNdx = getRootTaskCount() - 1; stackNdx >= 0; --stackNdx) {
+ final Task stack = getRootTaskAt(stackNdx);
stack.ensureActivitiesVisible(starting, configChanges, preserveWindows,
notifyClients, userLeaving);
}
@@ -1857,7 +1861,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
* @return last reparented stack, or {@code null} if the stacks had to be destroyed.
*/
Task remove() {
- mPreferredTopFocusableStack = null;
+ mPreferredTopFocusableRootTask = null;
// TODO(b/153090332): Allow setting content removal mode per task display area
final boolean destroyContentOnRemoval = mDisplayContent.shouldDestroyContentOnRemove();
final TaskDisplayArea toDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
@@ -1869,13 +1873,13 @@ final class TaskDisplayArea extends DisplayArea<Task> {
// related WindowContainer will also be removed. So, we set display area as removed after
// reparenting stack finished.
// Keep the order from bottom to top.
- int numStacks = getStackCount();
+ int numStacks = getRootTaskCount();
final boolean splitScreenActivated = toDisplayArea.isSplitScreenModeActivated();
final Task rootStack = splitScreenActivated ? toDisplayArea
- .getTopStackInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) : null;
+ .getTopRootTaskInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) : null;
for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) {
- final Task stack = getStackAt(stackNdx);
+ final Task stack = getRootTaskAt(stackNdx);
// Always finish non-standard type stacks and stacks created by a organizer.
// TODO: For stacks created by organizer, consider reparenting children tasks if the use
// case arises in the future.
@@ -1895,8 +1899,8 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
// Stacks may be removed from this display. Ensure each stack will be processed
// and the loop will end.
- stackNdx -= numStacks - getStackCount();
- numStacks = getStackCount();
+ stackNdx -= numStacks - getRootTaskCount();
+ numStacks = getRootTaskCount();
}
if (lastReparentedStack != null && splitScreenActivated) {
if (!lastReparentedStack.supportsSplitScreenWindowingMode()) {
@@ -1935,18 +1939,19 @@ final class TaskDisplayArea extends DisplayArea<Task> {
pw.println(prefix + "TaskDisplayArea " + getName());
final String doublePrefix = prefix + " ";
super.dump(pw, doublePrefix, dumpAll);
- if (mPreferredTopFocusableStack != null) {
- pw.println(doublePrefix + "mPreferredTopFocusableStack=" + mPreferredTopFocusableStack);
+ if (mPreferredTopFocusableRootTask != null) {
+ pw.println(doublePrefix + "mPreferredTopFocusableRootTask="
+ + mPreferredTopFocusableRootTask);
}
- if (mLastFocusedStack != null) {
- pw.println(doublePrefix + "mLastFocusedStack=" + mLastFocusedStack);
+ if (mLastFocusedRootTask != null) {
+ pw.println(doublePrefix + "mLastFocusedRootTask=" + mLastFocusedRootTask);
}
final String triplePrefix = doublePrefix + " ";
pw.println(doublePrefix + "Application tokens in top down Z order:");
- for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final Task stack = getChildAt(stackNdx);
- pw.println(doublePrefix + "* " + stack);
- stack.dump(pw, triplePrefix, dumpAll);
+ for (int rootTaskNdx = getChildCount() - 1; rootTaskNdx >= 0; --rootTaskNdx) {
+ final Task rootTask = getChildAt(rootTaskNdx);
+ pw.println(doublePrefix + "* " + rootTask);
+ rootTask.dump(pw, triplePrefix, dumpAll);
}
}
}
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 8b2fa52afd22..9d36b84431f3 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -796,9 +796,9 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
@NonNull Rect inOutBounds) {
final List<Rect> taskBoundsToCheck = new ArrayList<>();
display.forAllTaskDisplayAreas(taskDisplayArea -> {
- int numStacks = taskDisplayArea.getStackCount();
+ int numStacks = taskDisplayArea.getRootTaskCount();
for (int sNdx = 0; sNdx < numStacks; ++sNdx) {
- final Task task = taskDisplayArea.getStackAt(sNdx);
+ final Task task = taskDisplayArea.getRootTaskAt(sNdx);
if (!task.inFreeformWindowingMode()) {
continue;
}
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 009a7ef9e4f2..e635219bc6e5 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -478,7 +478,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
// We want to defer the task appear signal until the task is fully created and attached to
// to the hierarchy so that the complete starting configuration is in the task info we send
// over to the organizer.
- final Task task = display.getDefaultTaskDisplayArea().createStack(windowingMode,
+ final Task task = display.getDefaultTaskDisplayArea().createRootTask(windowingMode,
ACTIVITY_TYPE_UNDEFINED, false /* onTop */, null /* info */, new Intent(),
true /* createdByOrganizer */, true /* deferTaskAppear */, launchCookie);
task.setDeferTaskAppear(false /* deferTaskAppear */);
@@ -688,8 +688,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
}
ArrayList<RunningTaskInfo> out = new ArrayList<>();
dc.forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task task = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task task = taskDisplayArea.getRootTaskAt(sNdx);
if (activityTypes != null
&& !ArrayUtils.contains(activityTypes, task.getActivityType())) {
continue;
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 7d61c1973a2a..7809cbc2a167 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -502,7 +502,8 @@ class WallpaperController {
private void findWallpaperTarget() {
mFindResults.reset();
- if (mDisplayContent.getDefaultTaskDisplayArea().isStackVisible(WINDOWING_MODE_FREEFORM)) {
+ if (mDisplayContent.getDefaultTaskDisplayArea()
+ .isRootTaskVisible(WINDOWING_MODE_FREEFORM)) {
// In freeform mode we set the wallpaper as its own target, so we don't need an
// additional window to make it visible.
mFindResults.setUseTopWallpaperAsTarget(true);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 25049ae6d8b5..f8b5914d3e53 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2922,7 +2922,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
void getStackBounds(int windowingMode, int activityType, Rect bounds) {
- final Task stack = mRoot.getStack(windowingMode, activityType);
+ final Task stack = mRoot.getRootTask(windowingMode, activityType);
if (stack != null) {
stack.getBounds(bounds);
return;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index 05b1e4253bc0..ce61d50df1d9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -101,9 +101,4 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
public boolean canProfileOwnerResetPasswordWhenLocked(int userId) {
return false;
}
-
- public boolean hasKeyPair(String callerPackage, String alias) {
- // STOPSHIP: implement delegation code in ArcDevicePolicyManagerWrapperService & nuke this.
- return false;
- }
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 69297f9b67dd..02894b16c079 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -233,6 +233,7 @@ import android.provider.ContactsInternal;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Telephony;
+import android.security.AppUriAuthenticationPolicy;
import android.security.IKeyChainAliasCallback;
import android.security.IKeyChainService;
import android.security.KeyChain;
@@ -266,7 +267,6 @@ import android.view.inputmethod.InputMethodInfo;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.compat.IPlatformCompat;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
@@ -554,7 +554,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
private final LockSettingsInternal mLockSettingsInternal;
private final DeviceAdminServiceController mDeviceAdminServiceController;
private final OverlayPackagesProvider mOverlayPackagesProvider;
- private final IPlatformCompat mIPlatformCompat;
private final DevicePolicyCacheImpl mPolicyCache = new DevicePolicyCacheImpl();
private final DeviceStateCacheImpl mStateCache = new DeviceStateCacheImpl();
@@ -1154,13 +1153,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return LocalServices.getService(PersistentDataBlockManagerInternal.class);
}
- LockSettingsInternal getLockSettingsInternal() {
- return LocalServices.getService(LockSettingsInternal.class);
+ AppOpsManager getAppOpsManager() {
+ return mContext.getSystemService(AppOpsManager.class);
}
- IPlatformCompat getIPlatformCompat() {
- return IPlatformCompat.Stub.asInterface(
- ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+ LockSettingsInternal getLockSettingsInternal() {
+ return LocalServices.getService(LockSettingsInternal.class);
}
boolean hasUserSetupCompleted(DevicePolicyData userData) {
@@ -1433,7 +1431,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
mUsageStatsManagerInternal = Objects.requireNonNull(
injector.getUsageStatsManagerInternal());
mIPackageManager = Objects.requireNonNull(injector.getIPackageManager());
- mIPlatformCompat = Objects.requireNonNull(injector.getIPlatformCompat());
mIPermissionManager = Objects.requireNonNull(injector.getIPermissionManager());
mTelephonyManager = Objects.requireNonNull(injector.getTelephonyManager());
@@ -3377,13 +3374,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
private boolean passwordQualityInvocationOrderCheckEnabled(String packageName, int userId) {
- try {
- return mIPlatformCompat.isChangeEnabledByPackageName(ADMIN_APP_PASSWORD_COMPLEXITY,
- packageName, userId);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Failed to get a response from PLATFORM_COMPAT_SERVICE", e);
- }
- return getTargetSdk(packageName, userId) > Build.VERSION_CODES.Q;
+ return mInjector.isChangeEnabled(ADMIN_APP_PASSWORD_COMPLEXITY, packageName, userId);
}
/**
@@ -5031,7 +5022,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
Preconditions.checkCallAuthorization((caller.hasAdminComponent()
&& (isProfileOwner(caller) || isDeviceOwner(caller)))
- || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_CERT_INSTALL)));
+ || (caller.hasPackage() && (isCallerDelegate(caller, DELEGATION_CERT_INSTALL)
+ || isCredentialManagementApp(caller, alias, isUserSelectable))));
final long id = mInjector.binderClearCallingIdentity();
try {
@@ -5071,7 +5063,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
Preconditions.checkCallAuthorization((caller.hasAdminComponent()
&& (isProfileOwner(caller) || isDeviceOwner(caller)))
- || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_CERT_INSTALL)));
+ || (caller.hasPackage() && (isCallerDelegate(caller, DELEGATION_CERT_INSTALL)
+ || isCredentialManagementApp(caller, alias))));
final long id = Binder.clearCallingIdentity();
try {
@@ -5275,7 +5268,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
} else {
Preconditions.checkCallAuthorization((caller.hasAdminComponent()
&& (isProfileOwner(caller) || isDeviceOwner(caller)))
- || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_CERT_INSTALL)));
+ || (caller.hasPackage() && (isCallerDelegate(caller, DELEGATION_CERT_INSTALL)
+ || isCredentialManagementApp(caller, alias))));
}
// As the caller will be granted access to the key, ensure no UID was specified, as
@@ -5371,7 +5365,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
Preconditions.checkCallAuthorization((caller.hasAdminComponent()
&& (isProfileOwner(caller) || isDeviceOwner(caller)))
- || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_CERT_INSTALL)));
+ || (caller.hasPackage() && (isCallerDelegate(caller, DELEGATION_CERT_INSTALL)
+ || isCredentialManagementApp(caller, alias))));
final long id = mInjector.binderClearCallingIdentity();
try (final KeyChainConnection keyChainConnection =
@@ -5806,6 +5801,70 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
+ /**
+ * Check whether a caller application is the credential management app, which can access
+ * privileged APIs.
+ * <p>
+ * This is done by checking that the calling package is authorized to perform the app operation
+ * {@link android.app.AppOpsManager#OP_MANAGE_CREDENTIALS}. The alias provided must be contained
+ * in the aliases specified in the credential management app's authentication policy. The
+ * key pair to install must not be user selectable.
+ *
+ * @param caller the calling identity
+ * @return {@code true} if the calling process is the credential management app.
+ */
+ private boolean isCredentialManagementApp(CallerIdentity caller, String alias,
+ boolean isUserSelectable) {
+ // Should not be user selectable
+ if (isUserSelectable) {
+ Log.e(LOG_TAG, "The credential management app is not allowed to install a "
+ + "user selectable key pair");
+ return false;
+ }
+ return isCredentialManagementApp(caller, alias);
+ }
+
+ /**
+ * Check whether a caller application is the credential mangement app, which can access
+ * privileged APIs.
+ * <p>
+ * This is done by checking that the calling package is authorized to perform the app operation
+ * {@link android.app.AppOpsManager#OP_MANAGE_CREDENTIALS}. The alias provided must be contained
+ * in the aliases specified in the credential management app's authentication policy.
+ *
+ * @param caller the calling identity
+ * @return {@code true} if the calling process is the credential management app.
+ */
+ private boolean isCredentialManagementApp(CallerIdentity caller, String alias) {
+ // Should include alias in authentication policy
+ try (KeyChainConnection connection = KeyChain.bindAsUser(mContext,
+ caller.getUserHandle())) {
+ if (!containsAlias(connection.getService().getCredentialManagementAppPolicy(), alias)) {
+ return false;
+ }
+ } catch (RemoteException | InterruptedException e) {
+ return false;
+ }
+
+ AppOpsManager appOpsManager = mInjector.getAppOpsManager();
+ return appOpsManager != null
+ ? appOpsManager.noteOpNoThrow(AppOpsManager.OP_MANAGE_CREDENTIALS, caller.getUid(),
+ caller.getPackageName(), null, null) == AppOpsManager.MODE_ALLOWED
+ : false;
+ }
+
+ private static boolean containsAlias(AppUriAuthenticationPolicy policy, String alias) {
+ for (Map.Entry<String, Map<Uri, String>> appsToUris :
+ policy.getAppAndUriMappings().entrySet()) {
+ for (Map.Entry<Uri, String> urisToAliases : appsToUris.getValue().entrySet()) {
+ if (urisToAliases.getValue().equals(alias)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
@Override
public void setCertInstallerPackage(ComponentName who, String installerPackage)
throws SecurityException {
@@ -7415,6 +7474,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
admin.getPackageName(), userId, "set-device-owner");
Slog.i(LOG_TAG, "Device owner set: " + admin + " on user " + userId);
+
+ if (mInjector.userManagerIsHeadlessSystemUserMode()) {
+ Slog.i(LOG_TAG, "manageUser: " + admin + " on user " + userId);
+
+ manageUser(admin, admin, caller.getUserId(), null);
+ }
return true;
}
}
@@ -9468,29 +9533,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final long id = mInjector.binderClearCallingIdentity();
try {
- final String adminPkg = admin.getPackageName();
- try {
- // Install the profile owner if not present.
- if (!mIPackageManager.isPackageAvailable(adminPkg, userHandle)) {
- mIPackageManager.installExistingPackageAsUser(adminPkg, userHandle,
- PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
- PackageManager.INSTALL_REASON_POLICY, null);
- }
- } catch (RemoteException e) {
- // Does not happen, same process
- }
-
- // Set admin.
- setActiveAdmin(profileOwner, true, userHandle);
- final String ownerName = getProfileOwnerName(Process.myUserHandle().getIdentifier());
- setProfileOwner(profileOwner, ownerName, userHandle);
-
- synchronized (getLockObject()) {
- DevicePolicyData policyData = getUserData(userHandle);
- policyData.mInitBundle = adminExtras;
- policyData.mAdminBroadcastPending = true;
- saveSettingsLocked(userHandle);
- }
+ manageUser(admin, profileOwner, userHandle, adminExtras);
if ((flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0) {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
@@ -9511,6 +9554,46 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
+ private void manageUser(ComponentName admin, ComponentName profileOwner,
+ @UserIdInt int userId, PersistableBundle adminExtras) {
+ // Check for permission
+ final CallerIdentity caller = getCallerIdentity();
+ Preconditions.checkCallAuthorization(canManageUsers(caller));
+ Preconditions.checkCallAuthorization(
+ hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ mInjector.binderWithCleanCallingIdentity(() ->
+ manageUserNoCheck(admin, profileOwner, userId, adminExtras));
+ }
+
+ private void manageUserNoCheck(ComponentName admin, ComponentName profileOwner,
+ int user, PersistableBundle adminExtras) {
+
+ final String adminPkg = admin.getPackageName();
+ try {
+ // Install the profile owner if not present.
+ if (!mIPackageManager.isPackageAvailable(adminPkg, user)) {
+ mIPackageManager.installExistingPackageAsUser(adminPkg, user,
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_POLICY, null);
+ }
+ } catch (RemoteException e) {
+ // Does not happen, same process
+ }
+
+ // Set admin.
+ setActiveAdmin(profileOwner, true, user);
+ final String ownerName = getProfileOwnerName(Process.myUserHandle().getIdentifier());
+ setProfileOwner(profileOwner, ownerName, user);
+
+ synchronized (getLockObject()) {
+ DevicePolicyData policyData = getUserData(user);
+ policyData.mInitBundle = adminExtras;
+ policyData.mAdminBroadcastPending = true;
+
+ saveSettingsLocked(user);
+ }
+ }
+
@Override
public boolean removeUser(ComponentName who, UserHandle userHandle) {
Objects.requireNonNull(who, "ComponentName is null");
@@ -10951,16 +11034,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
private boolean isSetSecureSettingLocationModeCheckEnabled(String packageName, int userId) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
- return mIPlatformCompat.isChangeEnabledByPackageName(USE_SET_LOCATION_ENABLED,
- packageName, userId);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Failed to get a response from PLATFORM_COMPAT_SERVICE", e);
- return getTargetSdk(packageName, userId) > Build.VERSION_CODES.Q;
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ return mInjector.isChangeEnabled(USE_SET_LOCATION_ENABLED, packageName, userId);
}
@Override
@@ -12188,8 +12262,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
return CODE_USER_SETUP_COMPLETED;
}
- } else {
- // STOPSHIP Do proper check in split user mode
}
return CODE_OK;
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 10b3265cd081..6525e1126478 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -47,6 +47,7 @@ import android.content.res.Resources.Theme;
import android.database.sqlite.SQLiteCompatibilityWalFlags;
import android.database.sqlite.SQLiteGlobal;
import android.graphics.GraphicsStatsService;
+import android.graphics.Typeface;
import android.hardware.display.DisplayManagerInternal;
import android.net.ConnectivityManager;
import android.net.ConnectivityModuleConnector;
@@ -120,6 +121,7 @@ import com.android.server.display.color.ColorDisplayService;
import com.android.server.dreams.DreamManagerService;
import com.android.server.emergency.EmergencyAffordanceService;
import com.android.server.gpu.GpuService;
+import com.android.server.graphics.fonts.FontManagerService;
import com.android.server.hdmi.HdmiControlService;
import com.android.server.incident.IncidentCompanionService;
import com.android.server.input.InputManagerService;
@@ -673,6 +675,11 @@ public final class SystemServer implements Dumpable {
SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
mDumper.addDumpable(tp);
+ // Load preinstalled system fonts for system server, so that WindowManagerService, etc
+ // can start using Typeface. Note that fonts are required not only for text rendering,
+ // but also for some text operations (e.g. TextUtils.makeSafeForPresentation()).
+ Typeface.loadPreinstalledSystemFontMap();
+
// Attach JVMTI agent if this is a debuggable build and the system property is set.
if (Build.IS_DEBUGGABLE) {
// Property is of the form "library_path=parameters".
@@ -1604,6 +1611,10 @@ public final class SystemServer implements Dumpable {
}
t.traceEnd();
+ t.traceBegin("StartFontManagerService");
+ mSystemServiceManager.startService(FontManagerService.Lifecycle.class);
+ t.traceEnd();
+
t.traceBegin("StartTextServicesManager");
mSystemServiceManager.startService(TextServicesManagerService.Lifecycle.class);
t.traceEnd();
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index b9c2e56a4d90..3f3d5e5106c5 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -17,7 +17,6 @@
package com.android.server.accessibility;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -42,7 +41,6 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import android.view.Display;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import androidx.test.InstrumentationRegistry;
@@ -208,34 +206,6 @@ public class AccessibilityManagerServiceTest extends AndroidTestCase {
}
@SmallTest
- public void testOnMagnificationScaleChanged_MagnificationCapabilitiesAll_showButton() {
- // Request showing magnification button if the magnification capability is all mode.
- mA11yms.mUserStates.get(
- mA11yms.getCurrentUserIdLocked()).setMagnificationCapabilitiesLocked(
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
-
- mA11yms.onMagnificationScaleChanged(Display.DEFAULT_DISPLAY,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-
- verify(mMockWindowMagnificationMgr).showMagnificationButton(Display.DEFAULT_DISPLAY,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
- }
-
- @SmallTest
- public void testOnMagnificationScaleChanged_MagnificationCapabilitiesNotAll_NoAction() {
- // Do nothing if the magnification capability is not all mode.
- mA11yms.mUserStates.get(
- mA11yms.getCurrentUserIdLocked()).setMagnificationCapabilitiesLocked(
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-
- mA11yms.onMagnificationScaleChanged(Display.DEFAULT_DISPLAY,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-
- verify(mMockWindowMagnificationMgr, never()).showMagnificationButton(anyInt(),
- anyInt());
- }
-
- @SmallTest
public void testOnMagnificationTransitionFailed_capabilitiesIsAll_fallBackToPreviousMode() {
final AccessibilityUserState userState = mA11yms.mUserStates.get(
mA11yms.getCurrentUserIdLocked());
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index e43a002806ee..c038a0f33904 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -54,7 +54,6 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accessibility.EventStreamTransformation;
import com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationRequestObserver;
-import com.android.server.accessibility.magnification.MagnificationGestureHandler.ScaleChangedListener;
import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
import com.android.server.wm.WindowManagerInternal;
@@ -125,7 +124,7 @@ public class FullScreenMagnificationGestureHandlerTest {
private Context mContext;
FullScreenMagnificationController mFullScreenMagnificationController;
@Mock
- ScaleChangedListener mMockScaleChangedListener;
+ MagnificationGestureHandler.ScaleChangedListener mMockScaleChangedListener;
@Mock
MagnificationRequestObserver mMagnificationRequestObserver;
@Mock
@@ -181,8 +180,8 @@ public class FullScreenMagnificationGestureHandlerTest {
boolean detectShortcutTrigger) {
FullScreenMagnificationGestureHandler h = new FullScreenMagnificationGestureHandler(
mContext, mFullScreenMagnificationController, mMockScaleChangedListener,
- detectTripleTap, detectShortcutTrigger, mWindowMagnificationPromptController,
- DISPLAY_0);
+ detectTripleTap, detectShortcutTrigger,
+ mWindowMagnificationPromptController, DISPLAY_0);
mHandler = new TestHandler(h.mDetectingState, mClock) {
@Override
protected String messageToString(Message m) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index aed590b8b7e0..cba618bf94b8 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -29,6 +29,7 @@ import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -106,8 +107,8 @@ public class MagnificationControllerTest {
mock(WindowMagnificationManager.Callback.class)));
mMockConnection = new MockWindowMagnificationConnection(true);
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mMagnificationController = new MagnificationController(mService, new Object(), mContext,
- mScreenMagnificationController, mWindowMagnificationManager);
+ mMagnificationController = spy(new MagnificationController(mService, new Object(), mContext,
+ mScreenMagnificationController, mWindowMagnificationManager));
}
@After
@@ -277,8 +278,32 @@ public class MagnificationControllerTest {
verify(mWindowMagnificationManager).setScale(eq(TEST_DISPLAY), eq(newScale));
verify(mWindowMagnificationManager).persistScale(eq(TEST_DISPLAY));
- verify(mService).onMagnificationScaleChanged(eq(TEST_DISPLAY),
- eq(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
+ verify(mMagnificationController).onMagnificationScaleChanged(eq(TEST_DISPLAY),
+ eq(MODE_WINDOW));
+ }
+
+ @Test
+ public void onMagnificationScaleChanged_capabilitiesAllMode_showMagnificationButton()
+ throws RemoteException {
+ mMagnificationController.setMagnificationCapabilities(
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
+
+ mMagnificationController.onMagnificationScaleChanged(TEST_DISPLAY, MODE_WINDOW);
+
+ verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+ eq(MODE_WINDOW));
+ }
+
+ @Test
+ public void onMagnificationScaleChanged_capabilitiesNotAllMode_notShowMagnificationButton()
+ throws RemoteException {
+ mMagnificationController.setMagnificationCapabilities(
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+
+ mMagnificationController.onMagnificationScaleChanged(TEST_DISPLAY, MODE_WINDOW);
+
+ verify(mWindowMagnificationManager, never()).showMagnificationButton(eq(TEST_DISPLAY),
+ eq(MODE_WINDOW));
}
private void setMagnificationEnabled(int mode) throws RemoteException {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
index 41b6e987f819..9f930da4ee29 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
@@ -32,7 +32,6 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.accessibility.EventStreamTransformation;
-import com.android.server.accessibility.magnification.MagnificationGestureHandler.ScaleChangedListener;
import com.android.server.accessibility.utils.TouchEventGenerator;
import org.junit.After;
@@ -74,7 +73,8 @@ public class WindowMagnificationGestureHandlerTest {
mock(WindowMagnificationManager.Callback.class));
mMockConnection = new MockWindowMagnificationConnection();
mWindowMagnificationGestureHandler = new WindowMagnificationGestureHandler(
- mContext, mWindowMagnificationManager, mock(ScaleChangedListener.class),
+ mContext, mWindowMagnificationManager, mock(
+ MagnificationGestureHandler.ScaleChangedListener.class),
/** detectTripleTap= */true, /** detectShortcutTrigger= */true, DISPLAY_0);
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationGestureHandler.setNext(strictMock(EventStreamTransformation.class));
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
index de9a5e4f0fe7..d10e075c5136 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
@@ -18,17 +18,13 @@ package com.android.server.hdmi;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;
-import android.annotation.NonNull;
import android.content.Context;
import android.hardware.hdmi.HdmiControlManager;
-import android.os.Looper;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings.Global;
@@ -42,21 +38,15 @@ import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
@SmallTest
@Presubmit
@RunWith(JUnit4.class)
public final class HdmiCecConfigTest {
private static final String TAG = "HdmiCecConfigTest";
- private static final int TIMEOUT_CONTENT_CHANGE_SEC = 4;
-
private Context mContext;
@Mock private HdmiCecConfig.StorageAdapter mStorageAdapter;
- @Mock private HdmiCecConfig.SettingChangeListener mSettingChangeListener;
@Before
public void setUp() throws Exception {
@@ -1029,105 +1019,4 @@ public final class HdmiCecConfigTest {
HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
Integer.toString(HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED));
}
-
- @Test
- public void registerChangeListener_SharedPref_BasicSanity() {
- HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
- mContext, mStorageAdapter,
- "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
- + "<cec-settings>"
- + " <setting name=\"system_audio_mode_muting\""
- + " value-type=\"int\""
- + " user-configurable=\"true\">"
- + " <allowed-values>"
- + " <value int-value=\"0\" />"
- + " <value int-value=\"1\" />"
- + " </allowed-values>"
- + " <default-value int-value=\"1\" />"
- + " </setting>"
- + "</cec-settings>", null);
- hdmiCecConfig.registerChangeListener(
- HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
- mSettingChangeListener);
- hdmiCecConfig.setIntValue(
- HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
- HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED);
- verify(mSettingChangeListener).onChange(
- HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING);
- }
-
- @Test
- public void removeChangeListener_SharedPref_BasicSanity() {
- HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
- mContext, mStorageAdapter,
- "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
- + "<cec-settings>"
- + " <setting name=\"system_audio_mode_muting\""
- + " value-type=\"int\""
- + " user-configurable=\"true\">"
- + " <allowed-values>"
- + " <value int-value=\"0\" />"
- + " <value int-value=\"1\" />"
- + " </allowed-values>"
- + " <default-value int-value=\"1\" />"
- + " </setting>"
- + "</cec-settings>", null);
- hdmiCecConfig.registerChangeListener(
- HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
- mSettingChangeListener);
- hdmiCecConfig.removeChangeListener(
- HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
- mSettingChangeListener);
- hdmiCecConfig.setIntValue(
- HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
- HdmiControlManager.SYSTEM_AUDIO_MODE_MUTING_DISABLED);
- verify(mSettingChangeListener, never()).onChange(
- HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING);
- }
-
- /**
- * Externally modified Global Settings still need to be supported. This test verifies that
- * setting change notification is being forwarded to listeners registered via HdmiCecConfig.
- */
- @Test
- public void globalSettingObserver_BasicSanity() throws Exception {
- CountDownLatch notifyLatch = new CountDownLatch(1);
- // Get current value of the setting in the system.
- String val = Global.getString(mContext.getContentResolver(), Global.HDMI_CONTROL_ENABLED);
- HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
- mContext, mStorageAdapter,
- "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
- + "<cec-settings>"
- + " <setting name=\"hdmi_cec_enabled\""
- + " value-type=\"int\""
- + " user-configurable=\"true\">"
- + " <allowed-values>"
- + " <value int-value=\"0\" />"
- + " <value int-value=\"1\" />"
- + " </allowed-values>"
- + " <default-value int-value=\"1\" />"
- + " </setting>"
- + "</cec-settings>", null);
- hdmiCecConfig.registerGlobalSettingsObserver(Looper.getMainLooper());
- HdmiCecConfig.SettingChangeListener latchUpdateListener =
- new HdmiCecConfig.SettingChangeListener() {
- @Override
- public void onChange(@NonNull @HdmiControlManager.CecSettingName String setting) {
- notifyLatch.countDown();
- assertThat(setting).isEqualTo(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED);
- }
- };
- hdmiCecConfig.registerChangeListener(
- HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
- latchUpdateListener);
- // Flip the value of the setting.
- Global.putString(mContext.getContentResolver(), Global.HDMI_CONTROL_ENABLED,
- ((val == null || val.equals("1")) ? "0" : "1"));
- if (!notifyLatch.await(TIMEOUT_CONTENT_CHANGE_SEC, TimeUnit.SECONDS)) {
- fail("Timed out waiting for the notify callback");
- }
- hdmiCecConfig.unregisterGlobalSettingsObserver();
- // Restore the previous value of the setting in the system.
- Global.putString(mContext.getContentResolver(), Global.HDMI_CONTROL_ENABLED, val);
- }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index 9a6eb1cf2623..99bd0d7198c0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -68,16 +68,16 @@ public class ActivityDisplayTests extends WindowTestsBase {
mRootWindowContainer.getDefaultDisplay().getDefaultTaskDisplayArea();
final Task stack =
new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
- final Task prevFocusedStack = taskDisplayAreas.getFocusedStack();
+ final Task prevFocusedStack = taskDisplayAreas.getFocusedRootTask();
stack.moveToFront("moveStackToFront");
// After moving the stack to front, the previous focused should be the last focused.
assertTrue(stack.isFocusedStackOnDisplay());
- assertEquals(prevFocusedStack, taskDisplayAreas.getLastFocusedStack());
+ assertEquals(prevFocusedStack, taskDisplayAreas.getLastFocusedRootTask());
stack.moveToBack("moveStackToBack", null /* task */);
// After moving the stack to back, the stack should be the last focused.
- assertEquals(stack, taskDisplayAreas.getLastFocusedStack());
+ assertEquals(stack, taskDisplayAreas.getLastFocusedRootTask());
}
/**
@@ -88,7 +88,7 @@ public class ActivityDisplayTests extends WindowTestsBase {
public void testFullscreenStackCanBeFocusedWhenFocusablePinnedStackExists() {
// Create a pinned stack and move to front.
final Task pinnedStack = mRootWindowContainer.getDefaultTaskDisplayArea()
- .createStack(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
+ .createRootTask(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task pinnedTask = new TaskBuilder(mAtm.mTaskSupervisor)
.setParentTask(pinnedStack).build();
new ActivityBuilder(mAtm).setActivityFlags(FLAG_ALWAYS_FOCUSABLE)
@@ -108,7 +108,7 @@ public class ActivityDisplayTests extends WindowTestsBase {
}
/**
- * Test {@link TaskDisplayArea#mPreferredTopFocusableStack} will be cleared when
+ * Test {@link TaskDisplayArea#mPreferredTopFocusableRootTask} will be cleared when
* the stack is removed or moved to back, and the focused stack will be according to z-order.
*/
@Test
@@ -128,7 +128,7 @@ public class ActivityDisplayTests extends WindowTestsBase {
assertTrue(stack1.isFocusedStackOnDisplay());
// Stack2 should be focused after removing stack1.
- stack1.getDisplayArea().removeStack(stack1);
+ stack1.getDisplayArea().removeRootTask(stack1);
assertTrue(stack2.isFocusedStackOnDisplay());
}
@@ -155,12 +155,12 @@ public class ActivityDisplayTests extends WindowTestsBase {
display.remove();
// The removed display should have no focused stack and its home stack should never resume.
- assertNull(display.getFocusedStack());
+ assertNull(display.getFocusedRootTask());
verify(homeStack, never()).resumeTopActivityUncheckedLocked(any(), any());
}
private Task createFullscreenStackWithSimpleActivityAt(DisplayContent display) {
- final Task fullscreenStack = display.getDefaultTaskDisplayArea().createStack(
+ final Task fullscreenStack = display.getDefaultTaskDisplayArea().createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task fullscreenTask = new TaskBuilder(mAtm.mTaskSupervisor)
.setParentTask(fullscreenStack).build();
@@ -191,7 +191,7 @@ public class ActivityDisplayTests extends WindowTestsBase {
// Move stack with activity to top.
stack.moveToFront("testStackToFront");
- assertEquals(stack, display.getFocusedStack());
+ assertEquals(stack, display.getFocusedRootTask());
assertEquals(activity, display.topRunningActivity());
assertNull(display.topRunningActivity(true /* considerKeyguardState */));
@@ -207,7 +207,7 @@ public class ActivityDisplayTests extends WindowTestsBase {
// Move empty stack to front. The running activity in focusable stack which below the
// empty stack should be returned.
emptyStack.moveToFront("emptyStackToFront");
- assertEquals(stack, display.getFocusedStack());
+ assertEquals(stack, display.getFocusedRootTask());
assertTopRunningActivity(showWhenLockedActivity, display);
}
@@ -222,7 +222,7 @@ public class ActivityDisplayTests extends WindowTestsBase {
@Test
public void testAlwaysOnTopStackLocation() {
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- final Task alwaysOnTopStack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM,
+ final Task alwaysOnTopStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FREEFORM,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(alwaysOnTopStack).build();
@@ -232,31 +232,31 @@ public class ActivityDisplayTests extends WindowTestsBase {
assertTrue(alwaysOnTopStack.isAlwaysOnTop());
// Ensure always on top state is synced to the children of the stack.
assertTrue(alwaysOnTopStack.getTopNonFinishingActivity().isAlwaysOnTop());
- assertEquals(alwaysOnTopStack, taskDisplayArea.getTopStack());
+ assertEquals(alwaysOnTopStack, taskDisplayArea.getTopRootTask());
- final Task pinnedStack = taskDisplayArea.createStack(
+ final Task pinnedStack = taskDisplayArea.createRootTask(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
assertEquals(pinnedStack, taskDisplayArea.getRootPinnedTask());
- assertEquals(pinnedStack, taskDisplayArea.getTopStack());
+ assertEquals(pinnedStack, taskDisplayArea.getTopRootTask());
- final Task anotherAlwaysOnTopStack = taskDisplayArea.createStack(
+ final Task anotherAlwaysOnTopStack = taskDisplayArea.createRootTask(
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
anotherAlwaysOnTopStack.setAlwaysOnTop(true);
taskDisplayArea.positionChildAt(POSITION_TOP, anotherAlwaysOnTopStack,
false /* includingParents */);
assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
- int topPosition = taskDisplayArea.getStackCount() - 1;
+ int topPosition = taskDisplayArea.getRootTaskCount() - 1;
// Ensure the new alwaysOnTop stack is put below the pinned stack, but on top of the
// existing alwaysOnTop stack.
- assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 1));
+ assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getRootTaskAt(topPosition - 1));
- final Task nonAlwaysOnTopStack = taskDisplayArea.createStack(
+ final Task nonAlwaysOnTopStack = taskDisplayArea.createRootTask(
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
assertEquals(taskDisplayArea, nonAlwaysOnTopStack.getDisplayArea());
- topPosition = taskDisplayArea.getStackCount() - 1;
+ topPosition = taskDisplayArea.getRootTaskCount() - 1;
// Ensure the non-alwaysOnTop stack is put below the three alwaysOnTop stacks, but above the
// existing other non-alwaysOnTop stacks.
- assertEquals(nonAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 3));
+ assertEquals(nonAlwaysOnTopStack, taskDisplayArea.getRootTaskAt(topPosition - 3));
anotherAlwaysOnTopStack.setAlwaysOnTop(false);
taskDisplayArea.positionChildAt(POSITION_TOP, anotherAlwaysOnTopStack,
@@ -264,37 +264,37 @@ public class ActivityDisplayTests extends WindowTestsBase {
assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
// Ensure, when always on top is turned off for a stack, the stack is put just below all
// other always on top stacks.
- assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 2));
+ assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getRootTaskAt(topPosition - 2));
anotherAlwaysOnTopStack.setAlwaysOnTop(true);
// Ensure always on top state changes properly when windowing mode changes.
anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
- assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 2));
+ assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getRootTaskAt(topPosition - 2));
anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FREEFORM);
assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
- assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 1));
+ assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getRootTaskAt(topPosition - 1));
- final Task dreamStack = taskDisplayArea.createStack(
+ final Task dreamStack = taskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, true /* onTop */);
assertEquals(taskDisplayArea, dreamStack.getDisplayArea());
assertTrue(dreamStack.isAlwaysOnTop());
- topPosition = taskDisplayArea.getStackCount() - 1;
+ topPosition = taskDisplayArea.getRootTaskCount() - 1;
// Ensure dream shows above all activities, including PiP
- assertEquals(dreamStack, taskDisplayArea.getTopStack());
- assertEquals(pinnedStack, taskDisplayArea.getStackAt(topPosition - 1));
+ assertEquals(dreamStack, taskDisplayArea.getTopRootTask());
+ assertEquals(pinnedStack, taskDisplayArea.getRootTaskAt(topPosition - 1));
- final Task assistStack = taskDisplayArea.createStack(
+ final Task assistStack = taskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
assertEquals(taskDisplayArea, assistStack.getDisplayArea());
assertFalse(assistStack.isAlwaysOnTop());
- topPosition = taskDisplayArea.getStackCount() - 1;
+ topPosition = taskDisplayArea.getRootTaskCount() - 1;
// Ensure Assistant shows as a non-always-on-top activity when config_assistantOnTopOfDream
// is false and on top of everything when true.
final boolean isAssistantOnTop = mContext.getResources()
.getBoolean(com.android.internal.R.bool.config_assistantOnTopOfDream);
- assertEquals(assistStack, taskDisplayArea.getStackAt(
+ assertEquals(assistStack, taskDisplayArea.getRootTaskAt(
isAssistantOnTop ? topPosition : topPosition - 4));
}
@@ -312,13 +312,13 @@ public class ActivityDisplayTests extends WindowTestsBase {
private void removeStackTests(Runnable runnable) {
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- final Task stack1 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ final Task stack1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, ON_TOP);
- final Task stack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ final Task stack2 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, ON_TOP);
- final Task stack3 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ final Task stack3 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, ON_TOP);
- final Task stack4 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ final Task stack4 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, ON_TOP);
final Task task1 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(stack1).build();
final Task task2 = new TaskBuilder(mAtm.mTaskSupervisor).setParentTask(stack2).build();
@@ -333,7 +333,7 @@ public class ActivityDisplayTests extends WindowTestsBase {
// Removing stacks from the display while removing stacks.
doAnswer(invocation -> {
- taskDisplayArea.removeStack(stack2);
+ taskDisplayArea.removeRootTask(stack2);
return true;
}).when(mSupervisor).removeTask(eq(task2), anyBoolean(), anyBoolean(), any());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 2304efcaef65..2f34f708a562 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -155,7 +155,7 @@ public class ActivityRecordTests extends WindowTestsBase {
final Task rootTask = activity.getRootTask();
rootTask.removeChild(task, null /*reason*/);
// parentTask should be gone on task removal.
- assertNull(mAtm.mRootWindowContainer.getStack(rootTask.mTaskId));
+ assertNull(mAtm.mRootWindowContainer.getRootTask(rootTask.mTaskId));
}
@Test
@@ -384,6 +384,7 @@ public class ActivityRecordTests extends WindowTestsBase {
.build();
final Task task = activity.getTask();
activity.setState(DESTROYED, "Testing");
+ clearInvocations(mAtm.getLifecycleManager());
final Configuration newConfig = new Configuration(task.getConfiguration());
newConfig.orientation = newConfig.orientation == ORIENTATION_PORTRAIT
@@ -408,6 +409,7 @@ public class ActivityRecordTests extends WindowTestsBase {
activity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(),
activity.getConfiguration()));
+ clearInvocations(mAtm.getLifecycleManager());
final Configuration newConfig = new Configuration(activity.getConfiguration());
final int shortSide = Math.min(newConfig.screenWidthDp, newConfig.screenHeightDp);
final int longSide = Math.max(newConfig.screenWidthDp, newConfig.screenHeightDp);
@@ -596,6 +598,7 @@ public class ActivityRecordTests extends WindowTestsBase {
final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
try {
+ clearInvocations(mAtm.getLifecycleManager());
doReturn(false).when(stack).isTranslucent(any());
assertTrue(task.shouldBeVisible(null /* starting */));
@@ -875,7 +878,7 @@ public class ActivityRecordTests extends WindowTestsBase {
topRootableTask.moveToFront("test");
assertTrue(topRootableTask.isTopStackInDisplayArea());
assertEquals(topRootableTask, topActivityOnNonTopDisplay.getDisplayArea()
- .mPreferredTopFocusableStack);
+ .mPreferredTopFocusableRootTask);
final ActivityRecord secondaryDisplayActivity =
createActivityOnDisplay(false /* defaultDisplay */, null /* process */);
@@ -883,7 +886,7 @@ public class ActivityRecordTests extends WindowTestsBase {
topRootableTask.moveToFront("test");
assertTrue(topRootableTask.isTopStackInDisplayArea());
assertEquals(topRootableTask,
- secondaryDisplayActivity.getDisplayArea().mPreferredTopFocusableStack);
+ secondaryDisplayActivity.getDisplayArea().mPreferredTopFocusableRootTask);
// The global top focus activity is on secondary display now.
// Finish top activity on default display and verify the next preferred top focusable stack
@@ -892,7 +895,7 @@ public class ActivityRecordTests extends WindowTestsBase {
topActivityOnNonTopDisplay.finishIfPossible(0 /* resultCode */, null /* resultData */,
null /* resultGrants */, "test", false /* oomAdj */);
assertEquals(task, task.getTopMostTask());
- assertEquals(task, activity.getDisplayArea().mPreferredTopFocusableStack);
+ assertEquals(task, activity.getDisplayArea().mPreferredTopFocusableRootTask);
}
/**
@@ -1297,7 +1300,7 @@ public class ActivityRecordTests extends WindowTestsBase {
@Test
public void testDestroyIfPossible() {
final ActivityRecord activity = createActivityWithTask();
- doReturn(false).when(mRootWindowContainer).resumeFocusedStacksTopActivities();
+ doReturn(false).when(mRootWindowContainer).resumeFocusedTasksTopActivities();
activity.destroyIfPossible("test");
assertEquals(DESTROYING, activity.getState());
@@ -1319,7 +1322,7 @@ public class ActivityRecordTests extends WindowTestsBase {
homeStack.removeChild(t, "test");
}, true /* traverseTopToBottom */);
activity.finishing = true;
- doReturn(false).when(mRootWindowContainer).resumeFocusedStacksTopActivities();
+ doReturn(false).when(mRootWindowContainer).resumeFocusedTasksTopActivities();
// Try to destroy the last activity above the home stack.
activity.destroyIfPossible("test");
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 8ccbb8fe62ad..8e3e668804ff 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -48,7 +48,7 @@ import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT;
import static com.android.server.wm.Task.TASK_VISIBILITY_INVISIBLE;
import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE;
import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
-import static com.android.server.wm.TaskDisplayArea.getStackAbove;
+import static com.android.server.wm.TaskDisplayArea.getRootTaskAbove;
import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
@@ -74,6 +74,8 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
+import com.android.server.wm.TaskDisplayArea.OnRootTaskOrderChangedListener;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -154,7 +156,7 @@ public class ActivityStackTests extends WindowTestsBase {
organizer.setMoveToSecondaryOnEnter(false);
// Create primary splitscreen stack.
- final Task primarySplitScreen = mDefaultTaskDisplayArea.createStack(
+ final Task primarySplitScreen = mDefaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Assert windowing mode.
@@ -179,7 +181,7 @@ public class ActivityStackTests extends WindowTestsBase {
public void testMoveToPrimarySplitScreenThenMoveToBack() {
TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm);
// This time, start with a fullscreen activitystack
- final Task primarySplitScreen = mDefaultTaskDisplayArea.createStack(
+ final Task primarySplitScreen = mDefaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
primarySplitScreen.reparent(organizer.mPrimary, POSITION_TOP,
@@ -205,11 +207,11 @@ public class ActivityStackTests extends WindowTestsBase {
TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm);
// Set up split-screen with primary on top and secondary containing the home task below
// another stack.
- final Task primaryTask = mDefaultTaskDisplayArea.createStack(
+ final Task primaryTask = mDefaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task homeRoot = mDefaultTaskDisplayArea.getStack(
+ final Task homeRoot = mDefaultTaskDisplayArea.getRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
- final Task secondaryTask = mDefaultTaskDisplayArea.createStack(
+ final Task secondaryTask = mDefaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
mDefaultTaskDisplayArea.positionChildAt(POSITION_TOP, organizer.mPrimary,
false /* includingParents */);
@@ -257,7 +259,7 @@ public class ActivityStackTests extends WindowTestsBase {
@Test
public void testStackInheritsDisplayWindowingMode() {
- final Task primarySplitScreen = mDefaultTaskDisplayArea.createStack(
+ final Task primarySplitScreen = mDefaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
@@ -272,7 +274,7 @@ public class ActivityStackTests extends WindowTestsBase {
@Test
public void testStackOverridesDisplayWindowingMode() {
- final Task primarySplitScreen = mDefaultTaskDisplayArea.createStack(
+ final Task primarySplitScreen = mDefaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode());
@@ -365,7 +367,7 @@ public class ActivityStackTests extends WindowTestsBase {
verify(stack2).positionChildAtBottom(any(), eq(false) /* includingParents */);
// Also move display to back because there is only one stack left.
- taskDisplayArea.removeStack(stack1);
+ taskDisplayArea.removeRootTask(stack1);
stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.getTopMostTask());
verify(stack2).positionChildAtBottom(any(), eq(true) /* includingParents */);
}
@@ -747,8 +749,8 @@ public class ActivityStackTests extends WindowTestsBase {
// Ensure that we don't move the home stack if it is already behind the top fullscreen stack
int homeStackIndex = mDefaultTaskDisplayArea.getIndexOf(homeStack);
- assertEquals(fullscreenStack, getStackAbove(homeStack));
- mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
+ assertEquals(fullscreenStack, getRootTaskAbove(homeStack));
+ mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack));
}
@@ -765,8 +767,8 @@ public class ActivityStackTests extends WindowTestsBase {
// Ensure that we don't move the home stack if it is already behind the top fullscreen stack
int homeStackIndex = mDefaultTaskDisplayArea.getIndexOf(homeStack);
- assertEquals(fullscreenStack, getStackAbove(homeStack));
- mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
+ assertEquals(fullscreenStack, getRootTaskAbove(homeStack));
+ mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack));
}
@@ -783,8 +785,8 @@ public class ActivityStackTests extends WindowTestsBase {
// Ensure we don't move the home stack if it is already on top
int homeStackIndex = mDefaultTaskDisplayArea.getIndexOf(homeStack);
- assertNull(getStackAbove(homeStack));
- mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
+ assertNull(getRootTaskAbove(homeStack));
+ mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack));
}
@@ -807,9 +809,9 @@ public class ActivityStackTests extends WindowTestsBase {
// Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
// pinned stack
- assertEquals(fullscreenStack1, getStackAbove(homeStack));
- mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
- assertEquals(fullscreenStack2, getStackAbove(homeStack));
+ assertEquals(fullscreenStack1, getRootTaskAbove(homeStack));
+ mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
+ assertEquals(fullscreenStack2, getRootTaskAbove(homeStack));
}
@Test
@@ -830,9 +832,9 @@ public class ActivityStackTests extends WindowTestsBase {
// Ensure that we move the home stack behind the bottom most non-translucent fullscreen
// stack
- assertEquals(fullscreenStack1, getStackAbove(homeStack));
- mDefaultTaskDisplayArea.moveStackBehindBottomMostVisibleStack(homeStack);
- assertEquals(fullscreenStack1, getStackAbove(homeStack));
+ assertEquals(fullscreenStack1, getRootTaskAbove(homeStack));
+ mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack);
+ assertEquals(fullscreenStack1, getRootTaskAbove(homeStack));
}
@Test
@@ -852,7 +854,7 @@ public class ActivityStackTests extends WindowTestsBase {
// Ensure we don't move the home stack behind itself
int homeStackIndex = mDefaultTaskDisplayArea.getIndexOf(homeStack);
- mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, homeStack);
+ mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, homeStack);
assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack));
}
@@ -873,14 +875,14 @@ public class ActivityStackTests extends WindowTestsBase {
final Task homeStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
- mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, fullscreenStack1);
- assertEquals(fullscreenStack1, getStackAbove(homeStack));
- mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, fullscreenStack2);
- assertEquals(fullscreenStack2, getStackAbove(homeStack));
- mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, fullscreenStack4);
- assertEquals(fullscreenStack4, getStackAbove(homeStack));
- mDefaultTaskDisplayArea.moveStackBehindStack(homeStack, fullscreenStack2);
- assertEquals(fullscreenStack2, getStackAbove(homeStack));
+ mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, fullscreenStack1);
+ assertEquals(fullscreenStack1, getRootTaskAbove(homeStack));
+ mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, fullscreenStack2);
+ assertEquals(fullscreenStack2, getRootTaskAbove(homeStack));
+ mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, fullscreenStack4);
+ assertEquals(fullscreenStack4, getRootTaskAbove(homeStack));
+ mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, fullscreenStack2);
+ assertEquals(fullscreenStack2, getRootTaskAbove(homeStack));
}
@Test
@@ -889,7 +891,7 @@ public class ActivityStackTests extends WindowTestsBase {
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
final Task pinnedStack = createStackForShouldBeVisibleTest(mDefaultTaskDisplayArea,
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- assertEquals(pinnedStack, getStackAbove(homeStack));
+ assertEquals(pinnedStack, getRootTaskAbove(homeStack));
final Task alwaysOnTopStack = createStackForShouldBeVisibleTest(
mDefaultTaskDisplayArea, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
@@ -897,13 +899,13 @@ public class ActivityStackTests extends WindowTestsBase {
alwaysOnTopStack.setAlwaysOnTop(true);
assertTrue(alwaysOnTopStack.isAlwaysOnTop());
// Ensure (non-pinned) always on top stack is put below pinned stack.
- assertEquals(pinnedStack, getStackAbove(alwaysOnTopStack));
+ assertEquals(pinnedStack, getRootTaskAbove(alwaysOnTopStack));
final Task nonAlwaysOnTopStack = createStackForShouldBeVisibleTest(
mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
// Ensure non always on top stack is put below always on top stacks.
- assertEquals(alwaysOnTopStack, getStackAbove(nonAlwaysOnTopStack));
+ assertEquals(alwaysOnTopStack, getRootTaskAbove(nonAlwaysOnTopStack));
final Task alwaysOnTopStack2 = createStackForShouldBeVisibleTest(
mDefaultTaskDisplayArea, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
@@ -911,21 +913,21 @@ public class ActivityStackTests extends WindowTestsBase {
alwaysOnTopStack2.setAlwaysOnTop(true);
assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
// Ensure newly created always on top stack is placed above other all always on top stacks.
- assertEquals(pinnedStack, getStackAbove(alwaysOnTopStack2));
+ assertEquals(pinnedStack, getRootTaskAbove(alwaysOnTopStack2));
alwaysOnTopStack2.setAlwaysOnTop(false);
// Ensure, when always on top is turned off for a stack, the stack is put just below all
// other always on top stacks.
- assertEquals(alwaysOnTopStack, getStackAbove(alwaysOnTopStack2));
+ assertEquals(alwaysOnTopStack, getRootTaskAbove(alwaysOnTopStack2));
alwaysOnTopStack2.setAlwaysOnTop(true);
// Ensure always on top state changes properly when windowing mode changes.
alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
assertFalse(alwaysOnTopStack2.isAlwaysOnTop());
- assertEquals(alwaysOnTopStack, getStackAbove(alwaysOnTopStack2));
+ assertEquals(alwaysOnTopStack, getRootTaskAbove(alwaysOnTopStack2));
alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FREEFORM);
assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
- assertEquals(pinnedStack, getStackAbove(alwaysOnTopStack2));
+ assertEquals(pinnedStack, getRootTaskAbove(alwaysOnTopStack2));
}
@Test
@@ -980,7 +982,8 @@ public class ActivityStackTests extends WindowTestsBase {
int windowingMode, int activityType, boolean onTop, boolean twoLevelTask) {
final Task task;
if (activityType == ACTIVITY_TYPE_HOME) {
- task = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
+ task = mDefaultTaskDisplayArea.getRootTask(WINDOWING_MODE_FULLSCREEN,
+ ACTIVITY_TYPE_HOME);
mDefaultTaskDisplayArea.positionChildAt(onTop ? POSITION_TOP : POSITION_BOTTOM, task,
false /* includingParents */);
} else if (twoLevelTask) {
@@ -1224,12 +1227,12 @@ public class ActivityStackTests extends WindowTestsBase {
@Test
public void testStackOrderChangedOnRemoveStack() {
final Task task = new TaskBuilder(mSupervisor).build();
- StackOrderChangedListener listener = new StackOrderChangedListener();
- mDefaultTaskDisplayArea.registerStackOrderChangedListener(listener);
+ RootTaskOrderChangedListener listener = new RootTaskOrderChangedListener();
+ mDefaultTaskDisplayArea.registerRootTaskOrderChangedListener(listener);
try {
- mDefaultTaskDisplayArea.removeStack(task);
+ mDefaultTaskDisplayArea.removeRootTask(task);
} finally {
- mDefaultTaskDisplayArea.unregisterStackOrderChangedListener(listener);
+ mDefaultTaskDisplayArea.unregisterRootTaskOrderChangedListener(listener);
}
assertTrue(listener.mChanged);
}
@@ -1237,31 +1240,31 @@ public class ActivityStackTests extends WindowTestsBase {
@Test
public void testStackOrderChangedOnAddPositionStack() {
final Task task = new TaskBuilder(mSupervisor).build();
- mDefaultTaskDisplayArea.removeStack(task);
+ mDefaultTaskDisplayArea.removeRootTask(task);
- StackOrderChangedListener listener = new StackOrderChangedListener();
- mDefaultTaskDisplayArea.registerStackOrderChangedListener(listener);
+ RootTaskOrderChangedListener listener = new RootTaskOrderChangedListener();
+ mDefaultTaskDisplayArea.registerRootTaskOrderChangedListener(listener);
try {
task.mReparenting = true;
mDefaultTaskDisplayArea.addChild(task, 0);
} finally {
- mDefaultTaskDisplayArea.unregisterStackOrderChangedListener(listener);
+ mDefaultTaskDisplayArea.unregisterRootTaskOrderChangedListener(listener);
}
assertTrue(listener.mChanged);
}
@Test
public void testStackOrderChangedOnPositionStack() {
- StackOrderChangedListener listener = new StackOrderChangedListener();
+ RootTaskOrderChangedListener listener = new RootTaskOrderChangedListener();
try {
final Task fullscreenStack1 = createStackForShouldBeVisibleTest(
mDefaultTaskDisplayArea, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
- mDefaultTaskDisplayArea.registerStackOrderChangedListener(listener);
+ mDefaultTaskDisplayArea.registerRootTaskOrderChangedListener(listener);
mDefaultTaskDisplayArea.positionChildAt(POSITION_BOTTOM, fullscreenStack1,
false /*includingParents*/);
} finally {
- mDefaultTaskDisplayArea.unregisterStackOrderChangedListener(listener);
+ mDefaultTaskDisplayArea.unregisterRootTaskOrderChangedListener(listener);
}
assertTrue(listener.mChanged);
}
@@ -1447,12 +1450,12 @@ public class ActivityStackTests extends WindowTestsBase {
assertEquals(expected, task.shouldSleepActivities());
}
- private static class StackOrderChangedListener
- implements TaskDisplayArea.OnStackOrderChangedListener {
+ private static class RootTaskOrderChangedListener
+ implements OnRootTaskOrderChangedListener {
public boolean mChanged = false;
@Override
- public void onStackOrderChanged(Task stack) {
+ public void onRootTaskOrderChanged(Task rootTask) {
mChanged = true;
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
index c799f2902547..ce96771c8c27 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
@@ -33,8 +33,8 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import com.android.server.wm.ActivityTaskSupervisor.PendingActivityLaunch;
import com.android.server.wm.ActivityStarter.Factory;
+import com.android.server.wm.ActivityTaskSupervisor.PendingActivityLaunch;
import org.junit.Before;
import org.junit.Test;
@@ -77,8 +77,8 @@ public class ActivityStartControllerTests extends WindowTestsBase {
.setCreateTask(true)
.build();
final int startFlags = random.nextInt();
- final Task stack = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea()
- .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ final Task rootTask = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
final WindowProcessController wpc = new WindowProcessController(mAtm,
mAtm.mContext.getApplicationInfo(), "name", 12345,
UserHandle.getUserId(12345), mock(Object.class),
@@ -86,7 +86,7 @@ public class ActivityStartControllerTests extends WindowTestsBase {
wpc.setThread(mock(IApplicationThread.class));
mController.addPendingActivityLaunch(
- new PendingActivityLaunch(activity, source, startFlags, stack, wpc, null));
+ new PendingActivityLaunch(activity, source, startFlags, rootTask, wpc, null));
final boolean resume = random.nextBoolean();
mController.doPendingActivityLaunches(resume);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 565bf8b615c7..ef2e88913914 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -326,7 +326,7 @@ public class ActivityStarterTests extends WindowTestsBase {
* Creates a {@link ActivityStarter} with default parameters and necessary mocks.
*
* @param launchFlags The intent flags to launch activity.
- * @param mockGetLaunchStack Whether to mock {@link RootWindowContainer#getLaunchStack} for
+ * @param mockGetLaunchStack Whether to mock {@link RootWindowContainer#getLaunchRootTask} for
* always launching to the testing stack. Set to false when allowing
* the activity can be launched to any stack that is decided by real
* implementation.
@@ -342,14 +342,14 @@ public class ActivityStarterTests extends WindowTestsBase {
if (mockGetLaunchStack) {
// Instrument the stack and task used.
final Task stack = mRootWindowContainer.getDefaultTaskDisplayArea()
- .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+ .createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
// Direct starter to use spy stack.
doReturn(stack).when(mRootWindowContainer)
- .getLaunchStack(any(), any(), any(), anyBoolean());
- doReturn(stack).when(mRootWindowContainer)
- .getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt());
+ .getLaunchRootTask(any(), any(), any(), anyBoolean());
+ doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(),
+ anyBoolean(), any(), anyInt(), anyInt());
}
// Set up mock package manager internal and make sure no unmocked methods are called
@@ -513,8 +513,8 @@ public class ActivityStarterTests extends WindowTestsBase {
private void assertNoTasks(DisplayContent display) {
display.forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
assertFalse(stack.hasChild());
}
});
@@ -806,7 +806,7 @@ public class ActivityStarterTests extends WindowTestsBase {
new TestDisplayContent.Builder(mAtm, 1000, 1500)
.setPosition(POSITION_BOTTOM).build();
final TaskDisplayArea secondaryTaskContainer = secondaryDisplay.getDefaultTaskDisplayArea();
- final Task stack = secondaryTaskContainer.createStack(
+ final Task stack = secondaryTaskContainer.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Create an activity record on the top of secondary display.
@@ -828,7 +828,7 @@ public class ActivityStarterTests extends WindowTestsBase {
assertEquals(START_DELIVERED_TO_TOP, result);
// Ensure secondary display only creates one stack.
- verify(secondaryTaskContainer, times(1)).createStack(anyInt(), anyInt(), anyBoolean());
+ verify(secondaryTaskContainer, times(1)).createRootTask(anyInt(), anyInt(), anyBoolean());
}
/**
@@ -848,11 +848,11 @@ public class ActivityStarterTests extends WindowTestsBase {
false /* includingParents */);
final TaskDisplayArea secondaryTaskContainer = secondaryDisplay.getDefaultTaskDisplayArea();
final ActivityRecord singleTaskActivity = createSingleTaskActivityOn(
- secondaryTaskContainer.createStack(WINDOWING_MODE_FULLSCREEN,
+ secondaryTaskContainer.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
// Create another activity on top of the secondary display.
- final Task topStack = secondaryTaskContainer.createStack(WINDOWING_MODE_FULLSCREEN,
+ final Task topStack = secondaryTaskContainer.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
final Task topTask = new TaskBuilder(mSupervisor).setParentTask(topStack).build();
new ActivityBuilder(mAtm).setTask(topTask).build();
@@ -870,7 +870,7 @@ public class ActivityStarterTests extends WindowTestsBase {
assertEquals(START_TASK_TO_FRONT, result);
// Ensure secondary display only creates two stacks.
- verify(secondaryTaskContainer, times(2)).createStack(anyInt(), anyInt(), anyBoolean());
+ verify(secondaryTaskContainer, times(2)).createRootTask(anyInt(), anyInt(), anyBoolean());
// The metrics logger should receive the same result and non-null options.
verify(mActivityMetricsLogger).notifyActivityLaunched(any() /* launchingState */,
eq(result), eq(singleTaskActivity), notNull() /* options */);
@@ -938,7 +938,7 @@ public class ActivityStarterTests extends WindowTestsBase {
// Create a secondary display at bottom.
final TestDisplayContent secondaryDisplay = addNewDisplayContentAt(POSITION_BOTTOM);
final TaskDisplayArea secondaryTaskContainer = secondaryDisplay.getDefaultTaskDisplayArea();
- secondaryTaskContainer.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+ secondaryTaskContainer.createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
// Put an activity on default display as the top focused activity.
@@ -1053,7 +1053,7 @@ public class ActivityStarterTests extends WindowTestsBase {
final ActivityStarter starter = prepareStarter(0 /* flags */);
starter.mStartActivity = new ActivityBuilder(mAtm).build();
final Task task = new TaskBuilder(mAtm.mTaskSupervisor)
- .setParentTask(mAtm.mRootWindowContainer.getDefaultTaskDisplayArea().createStack(
+ .setParentTask(mAtm.mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */))
.setUserId(10)
.build();
@@ -1117,13 +1117,13 @@ public class ActivityStarterTests extends WindowTestsBase {
final Task stack = spy(
mRootWindowContainer.getDefaultTaskDisplayArea()
- .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
+ .createRootTask(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
/* onTop */true));
stack.addChild(targetRecord);
doReturn(stack).when(mRootWindowContainer)
- .getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt());
+ .getLaunchRootTask(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt());
starter.mStartActivity = new ActivityBuilder(mAtm).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java
index 39bf8eb857b0..5a47493c12cd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java
@@ -94,9 +94,9 @@ public class DisplayAreaPolicyTests {
@Test
public void testTaskDisplayArea_taskPositionChanged_updatesTaskDisplayAreaPosition() {
- final Task stack1 = mTaskDisplayArea1.createStack(
+ final Task stack1 = mTaskDisplayArea1.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task stack2 = mTaskDisplayArea2.createStack(
+ final Task stack2 = mTaskDisplayArea2.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Initial order
@@ -155,11 +155,11 @@ public class DisplayAreaPolicyTests {
.addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(group2)
.setTaskDisplayAreas(Lists.newArrayList(taskDisplayArea5)))
.build(wms);
- final Task stack1 = taskDisplayArea1.createStack(
+ final Task stack1 = taskDisplayArea1.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task stack3 = taskDisplayArea3.createStack(
+ final Task stack3 = taskDisplayArea3.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task stack4 = taskDisplayArea4.createStack(
+ final Task stack4 = taskDisplayArea4.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Initial order
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 64065e96b0f2..2053bfb45884 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -839,12 +839,12 @@ public class DisplayContentTests extends WindowTestsBase {
final DisplayContent newDisplay = createNewDisplay();
final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
- final Task stack = mDisplayContent.getTopStack();
+ final Task stack = mDisplayContent.getTopRootTask();
final ActivityRecord activity = stack.topRunningActivity();
doReturn(true).when(activity).shouldBeVisibleUnchecked();
final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1");
- final Task stack1 = newDisplay.getTopStack();
+ final Task stack1 = newDisplay.getTopRootTask();
final ActivityRecord activity1 = stack1.topRunningActivity();
doReturn(true).when(activity1).shouldBeVisibleUnchecked();
appWin.setHasSurface(true);
@@ -886,7 +886,7 @@ public class DisplayContentTests extends WindowTestsBase {
doReturn(true).when(freeformStack).isVisible();
freeformStack.getTopChild().setBounds(100, 100, 300, 400);
- assertTrue(dc.getDefaultTaskDisplayArea().isStackVisible(WINDOWING_MODE_FREEFORM));
+ assertTrue(dc.getDefaultTaskDisplayArea().isRootTaskVisible(WINDOWING_MODE_FREEFORM));
freeformStack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
stack.getTopNonFinishingActivity().setOrientation(SCREEN_ORIENTATION_PORTRAIT);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
index cd428e10a437..a99e40cc19ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
@@ -294,11 +294,11 @@ public class LaunchParamsControllerTests extends WindowTestsBase {
mController.registerModifier(positioner);
- doNothing().when(mRootWindowContainer).moveStackToTaskDisplayArea(anyInt(), any(),
+ doNothing().when(mRootWindowContainer).moveRootTaskToTaskDisplayArea(anyInt(), any(),
anyBoolean());
mController.layoutTask(task, null /* windowLayout */);
- verify(mRootWindowContainer, times(1)).moveStackToTaskDisplayArea(eq(task.getRootTaskId()),
- eq(preferredTaskDisplayArea), anyBoolean());
+ verify(mRootWindowContainer, times(1)).moveRootTaskToTaskDisplayArea(
+ eq(task.getRootTaskId()), eq(preferredTaskDisplayArea), anyBoolean());
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index d701a9df7cb8..b7d8638f06a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -115,7 +115,7 @@ public class LaunchParamsPersisterTests extends WindowTestsBase {
.thenReturn(mTestDisplay);
Task stack = mTestDisplay.getDefaultTaskDisplayArea()
- .createStack(TEST_WINDOWING_MODE, ACTIVITY_TYPE_STANDARD, /* onTop */ true);
+ .createRootTask(TEST_WINDOWING_MODE, ACTIVITY_TYPE_STANDARD, /* onTop */ true);
mTestTask = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT).setParentTask(stack)
.build();
mTestTask.mUserId = TEST_USER_ID;
@@ -337,7 +337,7 @@ public class LaunchParamsPersisterTests extends WindowTestsBase {
public void testClearsRecordsOfTheUserOnUserCleanUp() {
mTarget.saveTask(mTestTask);
- Task stack = mTestDisplay.getDefaultTaskDisplayArea().createStack(
+ Task stack = mTestDisplay.getDefaultTaskDisplayArea().createRootTask(
TEST_WINDOWING_MODE, ACTIVITY_TYPE_STANDARD, /* onTop */ true);
final Task anotherTaskOfTheSameUser = new TaskBuilder(mSupervisor)
.setComponent(ALTERNATIVE_COMPONENT)
@@ -349,7 +349,7 @@ public class LaunchParamsPersisterTests extends WindowTestsBase {
anotherTaskOfTheSameUser.setHasBeenVisible(true);
mTarget.saveTask(anotherTaskOfTheSameUser);
- stack = mTestDisplay.getDefaultTaskDisplayArea().createStack(TEST_WINDOWING_MODE,
+ stack = mTestDisplay.getDefaultTaskDisplayArea().createRootTask(TEST_WINDOWING_MODE,
ACTIVITY_TYPE_STANDARD, /* onTop */ true);
final Task anotherTaskOfDifferentUser = new TaskBuilder(mSupervisor)
.setComponent(TEST_COMPONENT)
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 7812934bb52f..4892ef3b6322 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -724,7 +724,7 @@ public class RecentTasksTest extends WindowTestsBase {
mRecentTasks.setParameters(-1 /* min */, 3 /* max */, -1 /* ms */);
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- final Task alwaysOnTopTask = taskDisplayArea.createStack(WINDOWING_MODE_MULTI_WINDOW,
+ final Task alwaysOnTopTask = taskDisplayArea.createRootTask(WINDOWING_MODE_MULTI_WINDOW,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
alwaysOnTopTask.setAlwaysOnTop(true);
@@ -838,7 +838,7 @@ public class RecentTasksTest extends WindowTestsBase {
Task stack = mTasks.get(2).getRootTask();
stack.moveToFront("", mTasks.get(2));
- doReturn(stack).when(mAtm.mRootWindowContainer).getTopDisplayFocusedStack();
+ doReturn(stack).when(mAtm.mRootWindowContainer).getTopDisplayFocusedRootTask();
// Simulate the reset from the timeout
mRecentTasks.resetFreezeTaskListReorderingOnTimeout();
@@ -858,7 +858,7 @@ public class RecentTasksTest extends WindowTestsBase {
mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */);
final Task homeStack = mTaskContainer.getRootHomeTask();
- final Task aboveHomeStack = mTaskContainer.createStack(
+ final Task aboveHomeStack = mTaskContainer.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Add a number of tasks (beyond the max) but ensure that nothing is trimmed because all
@@ -875,10 +875,10 @@ public class RecentTasksTest extends WindowTestsBase {
public void testBehindHomeStackTasks_expectTaskTrimmed() {
mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */);
- final Task behindHomeStack = mTaskContainer.createStack(
+ final Task behindHomeStack = mTaskContainer.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
final Task homeStack = mTaskContainer.getRootHomeTask();
- final Task aboveHomeStack = mTaskContainer.createStack(
+ final Task aboveHomeStack = mTaskContainer.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Add a number of tasks (beyond the max) but ensure that only the task in the stack behind
@@ -897,17 +897,17 @@ public class RecentTasksTest extends WindowTestsBase {
public void testOtherDisplayTasks_expectNoTrim() {
mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */);
- final Task homeStack = mTaskContainer.getRootHomeTask();
+ final Task homeTask = mTaskContainer.getRootHomeTask();
final DisplayContent otherDisplay = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
- final Task otherDisplayStack = otherDisplay.getDefaultTaskDisplayArea()
- .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ final Task otherDisplayRootTask = otherDisplay.getDefaultTaskDisplayArea().createRootTask(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Add a number of tasks (beyond the max) on each display, ensure that the tasks are not
// removed
- mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeStack).build());
- mRecentTasks.add(createTaskBuilder(".Task1").setParentTask(otherDisplayStack).build());
- mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(otherDisplayStack).build());
- mRecentTasks.add(createTaskBuilder(".HomeTask2").setParentTask(homeStack).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeTask).build());
+ mRecentTasks.add(createTaskBuilder(".Task1").setParentTask(otherDisplayRootTask).build());
+ mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(otherDisplayRootTask).build());
+ mRecentTasks.add(createTaskBuilder(".HomeTask2").setParentTask(homeTask).build());
triggerTrimAndAssertNoTasksTrimmed();
}
@@ -1103,9 +1103,9 @@ public class RecentTasksTest extends WindowTestsBase {
private void assertNotRestoreTask(Runnable action) {
// Verify stack count doesn't change because task with fullscreen mode and standard type
// would have its own stack.
- final int originalStackCount = mTaskContainer.getStackCount();
+ final int originalStackCount = mTaskContainer.getRootTaskCount();
action.run();
- assertEquals(originalStackCount, mTaskContainer.getStackCount());
+ assertEquals(originalStackCount, mTaskContainer.getRootTaskCount());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 5ff3ff5a6e0c..63ee5d05fada 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -89,7 +89,7 @@ public class RecentsAnimationTest extends WindowTestsBase {
@Test
public void testRecentsActivityVisiblility() {
TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task recentsStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS, true /* onTop */);
ActivityRecord recentActivity = new ActivityBuilder(mAtm)
.setComponent(mRecentsComponent)
@@ -118,7 +118,7 @@ public class RecentsAnimationTest extends WindowTestsBase {
public void testPreloadRecentsActivity() {
TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
final Task homeStack =
- defaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
+ defaultTaskDisplayArea.getRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
defaultTaskDisplayArea.positionChildAt(POSITION_TOP, homeStack,
false /* includingParents */);
ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity();
@@ -150,7 +150,7 @@ public class RecentsAnimationTest extends WindowTestsBase {
mAtm.startRecentsActivity(recentsIntent, 0 /* eventTime */,
null /* recentsAnimationRunner */);
- Task recentsStack = defaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN,
+ Task recentsStack = defaultTaskDisplayArea.getRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS);
assertThat(recentsStack).isNotNull();
@@ -179,7 +179,7 @@ public class RecentsAnimationTest extends WindowTestsBase {
public void testRestartRecentsActivity() throws Exception {
// Have a recents activity that is not attached to its process (ActivityRecord.app = null).
TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- Task recentsStack = defaultTaskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task recentsStack = defaultTaskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS, true /* onTop */);
ActivityRecord recentActivity = new ActivityBuilder(mAtm).setComponent(
mRecentsComponent).setCreateTask(true).setParentTask(recentsStack).build();
@@ -251,21 +251,21 @@ public class RecentsAnimationTest extends WindowTestsBase {
@Test
public void testCancelAnimationOnVisibleStackOrderChange() {
TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- Task fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task fullscreenStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App1"))
.setCreateTask(true)
.setParentTask(fullscreenStack)
.build();
- Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task recentsStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS, true /* onTop */);
new ActivityBuilder(mAtm)
.setComponent(mRecentsComponent)
.setCreateTask(true)
.setParentTask(recentsStack)
.build();
- Task fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task fullscreenStack2 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App2"))
@@ -292,21 +292,21 @@ public class RecentsAnimationTest extends WindowTestsBase {
@Test
public void testKeepAnimationOnHiddenStackOrderChange() {
TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- Task fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task fullscreenStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App1"))
.setCreateTask(true)
.setParentTask(fullscreenStack)
.build();
- Task recentsStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task recentsStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS, true /* onTop */);
new ActivityBuilder(mAtm)
.setComponent(mRecentsComponent)
.setCreateTask(true)
.setParentTask(recentsStack)
.build();
- Task fullscreenStack2 = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task fullscreenStack2 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App2"))
@@ -329,7 +329,7 @@ public class RecentsAnimationTest extends WindowTestsBase {
public void testMultipleUserHomeActivity_findUserHomeTask() {
TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultDisplay()
.getDefaultTaskDisplayArea();
- Task homeStack = taskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED,
+ Task homeStack = taskDisplayArea.getRootTask(WINDOWING_MODE_UNDEFINED,
ACTIVITY_TYPE_HOME);
ActivityRecord otherUserHomeActivity = new ActivityBuilder(mAtm)
.setParentTask(homeStack)
@@ -338,7 +338,7 @@ public class RecentsAnimationTest extends WindowTestsBase {
.build();
otherUserHomeActivity.getTask().mUserId = TEST_USER_ID;
- Task fullscreenStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task fullscreenStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
new ActivityBuilder(mAtm)
.setComponent(new ComponentName(mContext.getPackageName(), "App1"))
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 7ca364cf096f..f79e4cc9fa10 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -94,7 +94,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- mFullscreenStack = mRootWindowContainer.getDefaultTaskDisplayArea().createStack(
+ mFullscreenStack = mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
doNothing().when(mAtm).updateSleepIfNeededLocked();
}
@@ -128,7 +128,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
ensureStackPlacement(mFullscreenStack, firstActivity, secondActivity);
// Move first activity to pinned stack.
- mRootWindowContainer.moveActivityToPinnedStack(firstActivity, "initialMove");
+ mRootWindowContainer.moveActivityToPinnedRootTask(firstActivity, "initialMove");
final TaskDisplayArea taskDisplayArea = mFullscreenStack.getDisplayArea();
Task pinnedStack = taskDisplayArea.getRootPinnedTask();
@@ -137,11 +137,11 @@ public class RootActivityContainerTests extends WindowTestsBase {
ensureStackPlacement(mFullscreenStack, secondActivity);
// Move second activity to pinned stack.
- mRootWindowContainer.moveActivityToPinnedStack(secondActivity, "secondMove");
+ mRootWindowContainer.moveActivityToPinnedRootTask(secondActivity, "secondMove");
// Need to get stacks again as a new instance might have been created.
pinnedStack = taskDisplayArea.getRootPinnedTask();
- mFullscreenStack = taskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN,
+ mFullscreenStack = taskDisplayArea.getRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD);
// Ensure stacks have swapped tasks.
ensureStackPlacement(pinnedStack, secondActivity);
@@ -166,7 +166,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
// Move first activity to pinned stack.
- mRootWindowContainer.moveActivityToPinnedStack(secondActivity, "initialMove");
+ mRootWindowContainer.moveActivityToPinnedRootTask(secondActivity, "initialMove");
assertTrue(firstActivity.mRequestForceTransition);
}
@@ -237,9 +237,9 @@ public class RootActivityContainerTests extends WindowTestsBase {
doReturn(keyguardShowing).when(keyguard).isKeyguardOrAodShowing(anyInt());
doReturn(isFocusedStack).when(stack).isFocusedStackOnDisplay();
- doReturn(isFocusedStack ? stack : null).when(display).getFocusedStack();
+ doReturn(isFocusedStack ? stack : null).when(display).getFocusedRootTask();
TaskDisplayArea defaultTaskDisplayArea = display.getDefaultTaskDisplayArea();
- doReturn(isFocusedStack ? stack : null).when(defaultTaskDisplayArea).getFocusedStack();
+ doReturn(isFocusedStack ? stack : null).when(defaultTaskDisplayArea).getFocusedRootTask();
mRootWindowContainer.applySleepTokens(true);
verify(stack, times(expectWakeFromSleep ? 1 : 0)).awakeFromSleepingLocked();
verify(stack, times(expectResumeTopActivity ? 1 : 0)).resumeTopActivityUncheckedLocked(
@@ -282,19 +282,19 @@ public class RootActivityContainerTests extends WindowTestsBase {
public void testRemovingStackOnAppCrash() {
final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
.getDefaultTaskDisplayArea();
- final int originalStackCount = defaultTaskDisplayArea.getStackCount();
- final Task stack = defaultTaskDisplayArea.createStack(
+ final int originalStackCount = defaultTaskDisplayArea.getRootTaskCount();
+ final Task stack = defaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(stack).build();
- assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getStackCount());
+ assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getRootTaskCount());
// Let's pretend that the app has crashed.
firstActivity.app.setThread(null);
mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
// Verify that the stack was removed.
- assertEquals(originalStackCount, defaultTaskDisplayArea.getStackCount());
+ assertEquals(originalStackCount, defaultTaskDisplayArea.getRootTaskCount());
}
/**
@@ -305,34 +305,34 @@ public class RootActivityContainerTests extends WindowTestsBase {
public void testRemovingStackOnAppCrash_multipleDisplayAreas() {
final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
.getDefaultTaskDisplayArea();
- final int originalStackCount = defaultTaskDisplayArea.getStackCount();
- final Task stack = defaultTaskDisplayArea.createStack(
+ final int originalStackCount = defaultTaskDisplayArea.getRootTaskCount();
+ final Task stack = defaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord firstActivity = new ActivityBuilder(mAtm).setTask(stack).build();
- assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getStackCount());
+ assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getRootTaskCount());
final DisplayContent dc = defaultTaskDisplayArea.getDisplayContent();
final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
dc, mRootWindowContainer.mWmService, "TestTaskDisplayArea", FEATURE_VENDOR_FIRST);
- final Task secondStack = secondTaskDisplayArea.createStack(
+ final Task secondStack = secondTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
new ActivityBuilder(mAtm).setTask(secondStack).setUseProcess(firstActivity.app).build();
- assertEquals(1, secondTaskDisplayArea.getStackCount());
+ assertEquals(1, secondTaskDisplayArea.getRootTaskCount());
// Let's pretend that the app has crashed.
firstActivity.app.setThread(null);
mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
// Verify that the stacks were removed.
- assertEquals(originalStackCount, defaultTaskDisplayArea.getStackCount());
- assertEquals(0, secondTaskDisplayArea.getStackCount());
+ assertEquals(originalStackCount, defaultTaskDisplayArea.getRootTaskCount());
+ assertEquals(0, secondTaskDisplayArea.getRootTaskCount());
}
@Test
public void testFocusability() {
final TaskDisplayArea defaultTaskDisplayArea = mRootWindowContainer
.getDefaultTaskDisplayArea();
- final Task stack = defaultTaskDisplayArea.createStack(
+ final Task stack = defaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
@@ -345,7 +345,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
assertFalse(stack.isTopActivityFocusable());
assertFalse(activity.isFocusable());
- final Task pinnedStack = defaultTaskDisplayArea.createStack(
+ final Task pinnedStack = defaultTaskDisplayArea.createRootTask(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
final ActivityRecord pinnedActivity = new ActivityBuilder(mAtm)
.setTask(pinnedStack).build();
@@ -371,7 +371,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
public void testSplitScreenPrimaryChosenWhenTopActivityLaunchedToSecondary() {
// Create primary split-screen stack with a task and an activity.
final Task primaryStack = mRootWindowContainer.getDefaultTaskDisplayArea()
- .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
+ .createRootTask(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
final Task task = new TaskBuilder(mSupervisor).setParentTask(primaryStack).build();
final ActivityRecord r = new ActivityBuilder(mAtm).setTask(task).build();
@@ -381,7 +381,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
final Task result =
- mRootWindowContainer.getLaunchStack(r, options, task, true /* onTop */);
+ mRootWindowContainer.getLaunchRootTask(r, options, task, true /* onTop */);
// Assert that the primary stack is returned.
assertEquals(primaryStack, result);
@@ -410,7 +410,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
false);
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- verify(taskDisplayArea).moveHomeStackToFront(contains(reason));
+ verify(taskDisplayArea).moveHomeRootTaskToFront(contains(reason));
}
/**
@@ -421,7 +421,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
public void testFindTaskToMoveToFrontWhenRecentsOnOtherDisplay() {
// Create stack/task on default display.
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- final Task targetStack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ final Task targetStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */);
final Task targetTask = new TaskBuilder(mSupervisor).setParentTask(targetStack).build();
@@ -429,7 +429,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
final TestDisplayContent secondDisplay = addNewDisplayContentAt(
DisplayContent.POSITION_TOP);
final Task stack = secondDisplay.getDefaultTaskDisplayArea()
- .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */);
+ .createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */);
final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
new ActivityBuilder(mAtm).setTask(task).build();
@@ -437,7 +437,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
false);
- verify(taskDisplayArea, never()).moveHomeStackToFront(contains(reason));
+ verify(taskDisplayArea, never()).moveHomeRootTaskToFront(contains(reason));
}
/**
@@ -448,7 +448,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
public void testResumeActivityWhenNonTopmostStackIsTopFocused() {
// Create a stack at bottom.
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ final Task targetStack = spy(taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
final Task task = new TaskBuilder(mSupervisor).setParentTask(targetStack).build();
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
@@ -457,10 +457,10 @@ public class RootActivityContainerTests extends WindowTestsBase {
// Assume the stack is not at the topmost position (e.g. behind always-on-top stacks) but it
// is the current top focused stack.
assertFalse(targetStack.isTopStackInDisplayArea());
- doReturn(targetStack).when(mRootWindowContainer).getTopDisplayFocusedStack();
+ doReturn(targetStack).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
// Use the stack as target to resume.
- mRootWindowContainer.resumeFocusedStacksTopActivities(
+ mRootWindowContainer.resumeFocusedTasksTopActivities(
targetStack, activity, null /* targetOptions */);
// Verify the target stack should resume its activity.
@@ -477,14 +477,14 @@ public class RootActivityContainerTests extends WindowTestsBase {
mFullscreenStack.removeIfPossible();
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
taskDisplayArea.getRootHomeTask().removeIfPossible();
- taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+ taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
mAtm.setBooted(true);
// Trigger resume on all displays
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
// Verify that home activity was started on the default display
verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(taskDisplayArea));
@@ -499,14 +499,14 @@ public class RootActivityContainerTests extends WindowTestsBase {
mFullscreenStack.removeIfPossible();
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
taskDisplayArea.getRootHomeTask().removeIfPossible();
- taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+ taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
// Create an activity on secondary display.
final TestDisplayContent secondDisplay = addNewDisplayContentAt(
DisplayContent.POSITION_TOP);
- final Task stack = secondDisplay.getDefaultTaskDisplayArea()
- .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
+ final Task rootTask = secondDisplay.getDefaultTaskDisplayArea().createRootTask(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ final Task task = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
new ActivityBuilder(mAtm).setTask(task).build();
doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
@@ -514,7 +514,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
mAtm.setBooted(true);
// Trigger resume on all displays
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
// Verify that home activity was started on the default display
verify(mRootWindowContainer).resumeHomeActivity(any(), any(), eq(taskDisplayArea));
@@ -528,7 +528,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
public void testResumeActivityLingeringTransition() {
// Create a stack at top.
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ final Task targetStack = spy(taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
final Task task = new TaskBuilder(mSupervisor).setParentTask(targetStack).build();
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
@@ -538,7 +538,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
assertTrue(targetStack.isTopStackInDisplayArea());
// Use the stack as target to resume.
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
// Verify the lingering app transition is being executed because it's already resumed
verify(targetStack, times(1)).executeAppTransition(any());
@@ -548,7 +548,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
public void testResumeActivityLingeringTransition_notExecuted() {
// Create a stack at bottom.
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- final Task targetStack = spy(taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ final Task targetStack = spy(taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, false /* onTop */));
final Task task = new TaskBuilder(mSupervisor).setParentTask(targetStack).build();
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
@@ -557,10 +557,10 @@ public class RootActivityContainerTests extends WindowTestsBase {
// Assume the stack is at the topmost position
assertFalse(targetStack.isTopStackInDisplayArea());
- doReturn(targetStack).when(mRootWindowContainer).getTopDisplayFocusedStack();
+ doReturn(targetStack).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
// Use the stack as target to resume.
- mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mRootWindowContainer.resumeFocusedTasksTopActivities();
// Verify the lingering app transition is being executed because it's already resumed
verify(targetStack, never()).executeAppTransition(any());
@@ -586,9 +586,9 @@ public class RootActivityContainerTests extends WindowTestsBase {
mRootWindowContainer.startHomeOnAllDisplays(0, "testStartHome");
- assertTrue(mRootWindowContainer.getDefaultDisplay().getTopStack().isActivityTypeHome());
- assertNotNull(secondDisplay.getTopStack());
- assertTrue(secondDisplay.getTopStack().isActivityTypeHome());
+ assertTrue(mRootWindowContainer.getDefaultDisplay().getTopRootTask().isActivityTypeHome());
+ assertNotNull(secondDisplay.getTopRootTask());
+ assertTrue(secondDisplay.getTopRootTask().isActivityTypeHome());
}
/**
@@ -840,7 +840,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
}
/**
- * Test that {@link RootWindowContainer#getLaunchStack} with the real caller id will get the
+ * Test that {@link RootWindowContainer#getLaunchRootTask} with the real caller id will get the
* expected stack when requesting the activity launch on the secondary display.
*/
@Test
@@ -861,7 +861,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId,
300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info);
- final Task result = mRootWindowContainer.getLaunchStack(r, options,
+ final Task result = mRootWindowContainer.getLaunchRootTask(r, options,
null /* task */, true /* onTop */, null, 300 /* test realCallerPid */,
300 /* test realCallerUid */);
@@ -881,7 +881,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
// Make sure the root task is valid and can be reused on default display.
- final Task stack = mRootWindowContainer.getValidLaunchStackInTaskDisplayArea(
+ final Task stack = mRootWindowContainer.getValidLaunchRootTaskInTaskDisplayArea(
mRootWindowContainer.getDefaultTaskDisplayArea(), activity, task,
null /* options */, null /* launchParams */);
assertEquals(task, stack);
@@ -889,7 +889,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
@Test
public void testSwitchUser_missingHomeRootTask() {
- doReturn(mFullscreenStack).when(mRootWindowContainer).getTopDisplayFocusedStack();
+ doReturn(mFullscreenStack).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
Task homeStack = taskDisplayArea.getRootHomeTask();
@@ -904,7 +904,7 @@ public class RootActivityContainerTests extends WindowTestsBase {
mRootWindowContainer.switchUser(otherUser, null);
assertNotNull(taskDisplayArea.getRootHomeTask());
- assertEquals(taskDisplayArea.getTopStack(), taskDisplayArea.getRootHomeTask());
+ assertEquals(taskDisplayArea.getTopRootTask(), taskDisplayArea.getRootHomeTask());
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 42193c8fce78..9af2b96f3f78 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -92,7 +92,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
public void testAllPausedActivitiesComplete() {
DisplayContent displayContent = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
TaskDisplayArea taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
- Task stack = taskDisplayArea.getStackAt(0);
+ Task stack = taskDisplayArea.getRootTaskAt(0);
ActivityRecord activity = createActivityRecord(displayContent);
stack.mPausingActivity = activity;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index 95e344d5c184..6821d47d5b1a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -71,7 +71,7 @@ public class RunningTasksTest extends WindowTestsBase {
final int numTasks = 10;
int activeTime = 0;
for (int i = 0; i < numTasks; i++) {
- createTask(display.getDefaultTaskDisplayArea().getStackAt(i % numStacks),
+ createTask(display.getDefaultTaskDisplayArea().getRootTaskAt(i % numStacks),
".Task" + i, i, activeTime++, null);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 2db736e63391..536ef48065a5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -326,7 +326,7 @@ public class SystemServicesTestRule implements TestRule {
// Set the default focused TDA.
display.setLastFocusedTaskDisplayArea(taskDisplayArea);
spyOn(taskDisplayArea);
- final Task homeStack = taskDisplayArea.getStack(
+ final Task homeStack = taskDisplayArea.getRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
spyOn(homeStack);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index 28ba710797c9..d80f81642474 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -181,33 +181,33 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
final Task newStack = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, mDisplayContent);
final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea();
- doReturn(newStack).when(taskDisplayArea).createStack(anyInt(), anyInt(), anyBoolean(),
+ doReturn(newStack).when(taskDisplayArea).createRootTask(anyInt(), anyInt(), anyBoolean(),
any(), any(), anyBoolean());
final int type = ACTIVITY_TYPE_STANDARD;
- assertGetOrCreateStack(WINDOWING_MODE_FULLSCREEN, type, candidateTask,
+ assertGetOrCreateRootTask(WINDOWING_MODE_FULLSCREEN, type, candidateTask,
true /* reuseCandidate */);
- assertGetOrCreateStack(WINDOWING_MODE_UNDEFINED, type, candidateTask,
+ assertGetOrCreateRootTask(WINDOWING_MODE_UNDEFINED, type, candidateTask,
true /* reuseCandidate */);
- assertGetOrCreateStack(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, type, candidateTask,
+ assertGetOrCreateRootTask(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, type, candidateTask,
true /* reuseCandidate */);
- assertGetOrCreateStack(WINDOWING_MODE_FREEFORM, type, candidateTask,
+ assertGetOrCreateRootTask(WINDOWING_MODE_FREEFORM, type, candidateTask,
true /* reuseCandidate */);
- assertGetOrCreateStack(WINDOWING_MODE_MULTI_WINDOW, type, candidateTask,
+ assertGetOrCreateRootTask(WINDOWING_MODE_MULTI_WINDOW, type, candidateTask,
true /* reuseCandidate */);
- assertGetOrCreateStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, type, candidateTask,
+ assertGetOrCreateRootTask(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, type, candidateTask,
false /* reuseCandidate */);
- assertGetOrCreateStack(WINDOWING_MODE_PINNED, type, candidateTask,
+ assertGetOrCreateRootTask(WINDOWING_MODE_PINNED, type, candidateTask,
true /* reuseCandidate */);
final int windowingMode = WINDOWING_MODE_FULLSCREEN;
- assertGetOrCreateStack(windowingMode, ACTIVITY_TYPE_HOME, candidateTask,
+ assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_HOME, candidateTask,
false /* reuseCandidate */);
- assertGetOrCreateStack(windowingMode, ACTIVITY_TYPE_RECENTS, candidateTask,
+ assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_RECENTS, candidateTask,
false /* reuseCandidate */);
- assertGetOrCreateStack(windowingMode, ACTIVITY_TYPE_ASSISTANT, candidateTask,
+ assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_ASSISTANT, candidateTask,
false /* reuseCandidate */);
- assertGetOrCreateStack(windowingMode, ACTIVITY_TYPE_DREAM, candidateTask,
+ assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_DREAM, candidateTask,
false /* reuseCandidate */);
}
@@ -250,9 +250,9 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
FEATURE_VENDOR_FIRST);
- final Task firstStack = firstTaskDisplayArea.createStack(
+ final Task firstStack = firstTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
- final Task secondStack = secondTaskDisplayArea.createStack(
+ final Task secondStack = secondTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
.setTask(firstStack).build();
@@ -281,7 +281,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
@Test
public void testIgnoreOrientationRequest() {
final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
- final Task stack = taskDisplayArea.createStack(
+ final Task stack = taskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
@@ -326,10 +326,10 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
assertFalse(defaultTaskDisplayArea.mChildren.contains(task));
}
- private void assertGetOrCreateStack(int windowingMode, int activityType, Task candidateTask,
+ private void assertGetOrCreateRootTask(int windowingMode, int activityType, Task candidateTask,
boolean reuseCandidate) {
final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea();
- final Task stack = taskDisplayArea.getOrCreateStack(windowingMode, activityType,
+ final Task stack = taskDisplayArea.getOrCreateRootTask(windowingMode, activityType,
false /* onTop */, null /* intent */, candidateTask /* candidateTask */);
assertEquals(reuseCandidate, stack == candidateTask);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 4f55322e2085..269ce5d833f2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -1566,13 +1566,13 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
private ActivityRecord createSourceActivity(TestDisplayContent display) {
final Task stack = display.getDefaultTaskDisplayArea()
- .createStack(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
+ .createRootTask(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
return new ActivityBuilder(mAtm).setTask(stack).build();
}
private void addFreeformTaskTo(TestDisplayContent display, Rect bounds) {
final Task stack = display.getDefaultTaskDisplayArea()
- .createStack(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
+ .createRootTask(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
stack.setWindowingMode(WINDOWING_MODE_FREEFORM);
final Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
// Just work around the unnecessary adjustments for bounds.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index 61d4a473215b..4a5ff58fca3c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -177,7 +177,7 @@ public class TaskRecordTests extends WindowTestsBase {
public void testFitWithinBounds() {
final Rect parentBounds = new Rect(10, 10, 200, 200);
TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
- Task stack = taskDisplayArea.createStack(WINDOWING_MODE_FREEFORM,
+ Task stack = taskDisplayArea.createRootTask(WINDOWING_MODE_FREEFORM,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
final Configuration parentConfig = stack.getConfiguration();
@@ -497,7 +497,7 @@ public class TaskRecordTests extends WindowTestsBase {
@Test
public void testInsetDisregardedWhenFreeformOverlapsNavBar() {
TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
- Task stack = taskDisplayArea.createStack(WINDOWING_MODE_FULLSCREEN,
+ Task stack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
DisplayInfo displayInfo = new DisplayInfo();
mAtm.mContext.getDisplay().getDisplayInfo(displayInfo);
@@ -1027,9 +1027,9 @@ public class TaskRecordTests extends WindowTestsBase {
final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
FEATURE_VENDOR_FIRST);
- final Task firstStack = firstTaskDisplayArea.createStack(
+ final Task firstStack = firstTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
- final Task secondStack = secondTaskDisplayArea.createStack(
+ final Task secondStack = secondTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
.setTask(firstStack).build();
@@ -1083,7 +1083,7 @@ public class TaskRecordTests extends WindowTestsBase {
Rect expectedConfigBounds) {
TaskDisplayArea taskDisplayArea = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea();
- Task stack = taskDisplayArea.createStack(windowingMode, ACTIVITY_TYPE_STANDARD,
+ Task stack = taskDisplayArea.createRootTask(windowingMode, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
Task task = new TaskBuilder(mSupervisor).setParentTask(stack).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 573da896eff3..c4bcfdbcf89d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -812,7 +812,7 @@ public class WindowContainerTests extends WindowTestsBase {
final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
final DisplayContent newDc = createNewDisplay();
- stack.getDisplayArea().removeStack(stack);
+ stack.getDisplayArea().removeRootTask(stack);
newDc.getDefaultTaskDisplayArea().addChild(stack, POSITION_TOP);
verify(stack).onDisplayChanged(newDc);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 8fe65eb2747d..dba157e6ce06 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -387,7 +387,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
public void testSetIgnoreOrientationRequest_taskDisplayArea() {
removeGlobalMinSizeRestriction();
final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
- final Task stack = taskDisplayArea.createStack(
+ final Task stack = taskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
taskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -425,7 +425,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
public void testSetIgnoreOrientationRequest_displayContent() {
removeGlobalMinSizeRestriction();
final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
- final Task stack = taskDisplayArea.createStack(
+ final Task stack = taskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(stack).build();
mDisplayContent.setFocusedApp(activity);
@@ -743,8 +743,8 @@ public class WindowOrganizerTests extends WindowTestsBase {
private List<Task> getTasksCreatedByOrganizer(DisplayContent dc) {
ArrayList<Task> out = new ArrayList<>();
dc.forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task t = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task t = taskDisplayArea.getRootTaskAt(sNdx);
if (t.mCreatedByOrganizer) out.add(t);
}
});
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 6c046bda1444..14a62d1a4ff0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -27,6 +27,8 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.os.Process.SYSTEM_UID;
import static android.view.View.VISIBLE;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
@@ -40,8 +42,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
-import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -64,7 +64,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.res.Configuration;
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Bundle;
@@ -797,7 +796,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
mTask = new TaskBuilder(mService.mTaskSupervisor)
.setComponent(mComponent)
.setParentTask(mParentTask).build();
- } else if (mTask == null && mParentTask != null && DisplayContent.alwaysCreateStack(
+ } else if (mTask == null && mParentTask != null && DisplayContent.alwaysCreateRootTask(
mParentTask.getWindowingMode(), mParentTask.getActivityType())) {
// The stack can be the task root.
mTask = mParentTask;
@@ -831,13 +830,14 @@ class WindowTestsBase extends SystemServiceTestsBase {
if (mLaunchTaskBehind) {
options = ActivityOptions.makeTaskLaunchBehind();
}
+ final ActivityRecord activity = new ActivityRecord.Builder(mService)
+ .setLaunchedFromPid(mLaunchedFromPid)
+ .setLaunchedFromUid(mLaunchedFromUid)
+ .setIntent(intent)
+ .setActivityInfo(aInfo)
+ .setActivityOptions(options)
+ .build();
- final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
- mLaunchedFromPid /* launchedFromPid */, mLaunchedFromUid /* launchedFromUid */,
- null, null, intent, null, aInfo /*aInfo*/, new Configuration(),
- null /* resultTo */, null /* resultWho */, 0 /* reqCode */,
- false /*componentSpecified*/, false /* rootVoiceInteraction */,
- mService.mTaskSupervisor, options, null /* sourceRecord */);
spyOn(activity);
if (mTask != null) {
// fullscreen value is normally read from resources in ctor, so for testing we need
@@ -871,7 +871,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
activity.processName, activity.info.applicationInfo.uid);
// Resume top activities to make sure all other signals in the system are connected.
- mService.mRootWindowContainer.resumeFocusedStacksTopActivities();
+ mService.mRootWindowContainer.resumeFocusedTasksTopActivities();
return activity;
}
}
@@ -995,7 +995,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
// Create parent task.
if (mParentTask == null && mCreateParentTask) {
- mParentTask = mTaskDisplayArea.createStack(
+ mParentTask = mTaskDisplayArea.createRootTask(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
}
if (mParentTask != null && !Mockito.mockingDetails(mParentTask).isSpy()) {
@@ -1020,9 +1020,9 @@ class WindowTestsBase extends SystemServiceTestsBase {
}
Task task;
- final int taskId = mTaskId >= 0 ? mTaskId : mTaskDisplayArea.getNextStackId();
+ final int taskId = mTaskId >= 0 ? mTaskId : mTaskDisplayArea.getNextRootTaskId();
if (mParentTask == null) {
- task = mTaskDisplayArea.createStackUnchecked(
+ task = mTaskDisplayArea.createRootTaskUnchecked(
mWindowingMode, mActivityType, taskId, mOnTop, mActivityInfo, mIntent,
false /* createdByOrganizer */, false /* deferTaskAppear */,
null /* launchCookie */);
@@ -1114,8 +1114,8 @@ class WindowTestsBase extends SystemServiceTestsBase {
mSecondary.mRemoteToken.toWindowContainerToken());
DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId);
dc.forAllTaskDisplayAreas(taskDisplayArea -> {
- for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- final Task stack = taskDisplayArea.getStackAt(sNdx);
+ for (int sNdx = taskDisplayArea.getRootTaskCount() - 1; sNdx >= 0; --sNdx) {
+ final Task stack = taskDisplayArea.getRootTaskAt(sNdx);
if (!WindowConfiguration.isSplitScreenWindowingMode(stack.getWindowingMode())) {
stack.reparent(mSecondary, POSITION_BOTTOM);
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index c962932e7d44..baee4736b527 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2033,8 +2033,16 @@ public class CarrierConfigManager {
"allow_hold_call_during_emergency_bool";
/**
- * Flag indicating whether the carrier supports RCS presence indication for
- * User Capability Exchange (UCE). When presence is supported, the device should use the
+ * Flag indicating whether or not the carrier supports the periodic exchange of phone numbers
+ * in the user's address book with the carrier's presence server in order to retrieve the RCS
+ * capabilities for each contact used in the RCS User Capability Exchange (UCE) procedure. See
+ * RCC.71, section 3 for more information.
+ * <p>
+ * The flag {@link Ims#KEY_ENABLE_PRESENCE_PUBLISH_BOOL} must also be enabled if this flag is
+ * enabled, as sending a periodic SIP PUBLISH with this device's RCS capabilities is a
+ * requirement for capability exchange to begin.
+ * <p>
+ * When presence is supported, the device should use the
* {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE} bit mask and set the
* {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE_VT_CAPABLE} bit to indicate
* whether each contact supports video calling. The UI is made aware that presence is enabled
@@ -3850,12 +3858,27 @@ public class CarrierConfigManager {
public static final String KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL =
KEY_PREFIX + "ims_single_registration_required_bool";
+ /**
+ * A boolean flag specifying whether or not this carrier supports the device notifying the
+ * network of its RCS capabilities using the SIP PUBLISH procedure defined for User
+ * Capability Exchange (UCE). See RCC.71, section 3 for more information.
+ * <p>
+ * If this key's value is set to false, the procedure for RCS contact capability exchange
+ * via SIP SUBSCRIBE/NOTIFY will also be disabled internally, and
+ * {@link #KEY_USE_RCS_PRESENCE_BOOL} must also be set to false to ensure apps do not
+ * improperly think that capability exchange via SIP PUBLISH is enabled.
+ * <p> The default value for this key is {@code false}.
+ */
+ public static final String KEY_ENABLE_PRESENCE_PUBLISH_BOOL =
+ KEY_PREFIX + "enable_presence_publish_bool";
+
private Ims() {}
private static PersistableBundle getDefaults() {
PersistableBundle defaults = new PersistableBundle();
defaults.putInt(KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT, 4000);
defaults.putBoolean(KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
+ defaults.putBoolean(KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
return defaults;
}
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 9288f7925eab..d963970a3d2b 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8105,6 +8105,7 @@ public class TelephonyManager {
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isInEmergencySmsMode() {
try {
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 1b51936e873b..aaa68d6f7d57 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -18,6 +18,7 @@ package android.telephony.ims;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -207,6 +208,42 @@ public final class ImsCallProfile implements Parcelable {
"android.telephony.ims.extra.RETRY_CALL_FAIL_NETWORKTYPE";
/**
+ * Extra for the call composer call priority, either {@link ImsCallProfile#PRIORITY_NORMAL} or
+ * {@link ImsCallProfile#PRIORITY_URGENT}. It can be set via
+ * {@link #setCallExtraInt(String, int)}.
+ *
+ * Reference: RCC.20 Section 2.4.4.2
+ */
+ public static final String EXTRA_PRIORITY = "android.telephony.ims.extra.PRIORITY";
+
+ // TODO(hallliu) remove the reference to the maximum length and update it later.
+ /**
+ * Extra for the call composer call subject, a string of maximum length 60 characters.
+ * It can be set via {@link #setCallExtra(String, String)}.
+ *
+ * Reference: RCC.20 Section 2.4.3.2
+ */
+ public static final String EXTRA_CALL_SUBJECT = "android.telephony.ims.extra.CALL_SUBJECT";
+
+ /**
+ * Extra for the call composer call location, an {@Link android.location.Location} parcelable
+ * class to represent the geolocation as a latitude and longitude pair. It can be set via
+ * {@link #setCallExtraParcelable(String, Parcelable)}.
+ *
+ * Reference: RCC.20 Section 2.4.3.2
+ */
+ public static final String EXTRA_LOCATION = "android.telephony.ims.extra.LOCATION";
+
+ /**
+ * Extra for the call composer picture URL, a String that indicates the URL on the carrier’s
+ * server infrastructure to get the picture. It can be set via
+ * {@link #setCallExtra(String, String)}.
+ *
+ * Reference: RCC.20 Section 2.4.3.2
+ */
+ public static final String EXTRA_PICTURE_URL = "android.telephony.ims.extra.PICTURE_URL";
+
+ /**
* Values for EXTRA_OIR / EXTRA_CNAP
*/
/**
@@ -244,6 +281,21 @@ public final class ImsCallProfile implements Parcelable {
*/
public static final int DIALSTRING_USSD = 2;
+ // Values for EXTRA_PRIORITY
+ /**
+ * Indicates the call composer call priority is normal.
+ *
+ * Reference: RCC.20 Section 2.4.4.2
+ */
+ public static final int PRIORITY_NORMAL = 0;
+
+ /**
+ * Indicates the call composer call priority is urgent.
+ *
+ * Reference: RCC.20 Section 2.4.4.2
+ */
+ public static final int PRIORITY_URGENT = 1;
+
/**
* Call is not restricted on peer side and High Definition media is supported
*/
@@ -588,6 +640,19 @@ public final class ImsCallProfile implements Parcelable {
return mCallExtras.getInt(name, defaultValue);
}
+ /**
+ * Get the call extras (Parcelable), given the extra name.
+ * @param name call extra name
+ * @return the corresponding call extra Parcelable or null if not applicable
+ */
+ @Nullable
+ public <T extends Parcelable> T getCallExtraParcelable(@Nullable String name) {
+ if (mCallExtras != null) {
+ return mCallExtras.getParcelable(name);
+ }
+ return null;
+ }
+
public void setCallExtra(String name, String value) {
if (mCallExtras != null) {
mCallExtras.putString(name, value);
@@ -607,6 +672,17 @@ public final class ImsCallProfile implements Parcelable {
}
/**
+ * Set the call extra value (Parcelable), given the call extra name.
+ * @param name call extra name
+ * @param parcelable call extra value
+ */
+ public void setCallExtraParcelable(@NonNull String name, @NonNull Parcelable parcelable) {
+ if (mCallExtras != null) {
+ mCallExtras.putParcelable(name, parcelable);
+ }
+ }
+
+ /**
* Set the call restrict cause, which provides the reason why a call has been restricted from
* using High Definition media.
*/
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index a20f96d17278..67deca4fe387 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -16,6 +16,7 @@
package com.android.server.wm.flicker.close
+import androidx.test.filters.FlakyTest
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
@@ -54,6 +55,7 @@ import org.junit.runners.Parameterized
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 174635878)
class CloseAppBackButtonTest(
testName: String,
flickerSpec: Flicker
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index 4bbb38c4d71a..252ce2a32bf0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -16,6 +16,7 @@
package com.android.server.wm.flicker.close
+import androidx.test.filters.FlakyTest
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
@@ -54,6 +55,7 @@ import org.junit.runners.Parameterized
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 174635878)
class CloseAppHomeButtonTest(
testName: String,
flickerSpec: Flicker
diff --git a/tests/RollbackTest/RollbackTest/AndroidManifest.xml b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
index 9274da268735..590105b3209f 100644
--- a/tests/RollbackTest/RollbackTest/AndroidManifest.xml
+++ b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
@@ -19,8 +19,6 @@
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application>
- <receiver android:name="com.android.cts.install.lib.LocalIntentSender"
- android:exported="true" />
<uses-library android:name="android.test.runner" />
</application>
diff --git a/tests/StagedInstallTest/app/AndroidManifest.xml b/tests/StagedInstallTest/app/AndroidManifest.xml
index a678f1ec3691..d7ac9d0f9ce4 100644
--- a/tests/StagedInstallTest/app/AndroidManifest.xml
+++ b/tests/StagedInstallTest/app/AndroidManifest.xml
@@ -20,8 +20,6 @@
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application>
- <receiver android:name="com.android.cts.install.lib.LocalIntentSender"
- android:exported="true" />
<uses-library android:name="android.test.runner" />
</application>
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index ba87dc50e246..5d4573716145 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -56,8 +56,10 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_IA;
import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
@@ -5398,6 +5400,106 @@ public class ConnectivityServiceTest {
}
@Test
+ public void testApplyUnderlyingCapabilities() throws Exception {
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mCellNetworkAgent.connect(false /* validated */);
+ mWiFiNetworkAgent.connect(false /* validated */);
+
+ final NetworkCapabilities cellNc = new NetworkCapabilities()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addCapability(NET_CAPABILITY_NOT_CONGESTED)
+ .setLinkDownstreamBandwidthKbps(10);
+ final NetworkCapabilities wifiNc = new NetworkCapabilities()
+ .addTransportType(TRANSPORT_WIFI)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addCapability(NET_CAPABILITY_NOT_METERED)
+ .addCapability(NET_CAPABILITY_NOT_ROAMING)
+ .addCapability(NET_CAPABILITY_NOT_CONGESTED)
+ .addCapability(NET_CAPABILITY_NOT_SUSPENDED)
+ .setLinkUpstreamBandwidthKbps(20);
+ mCellNetworkAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */);
+ mWiFiNetworkAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */);
+ waitForIdle();
+
+ final Network mobile = mCellNetworkAgent.getNetwork();
+ final Network wifi = mWiFiNetworkAgent.getNetwork();
+
+ final NetworkCapabilities initialCaps = new NetworkCapabilities();
+ initialCaps.addCapability(NET_CAPABILITY_INTERNET);
+ initialCaps.removeCapability(NET_CAPABILITY_NOT_VPN);
+
+ final NetworkCapabilities withNoUnderlying = new NetworkCapabilities();
+ withNoUnderlying.addCapability(NET_CAPABILITY_INTERNET);
+ withNoUnderlying.addCapability(NET_CAPABILITY_NOT_CONGESTED);
+ withNoUnderlying.addCapability(NET_CAPABILITY_NOT_ROAMING);
+ withNoUnderlying.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ withNoUnderlying.addTransportType(TRANSPORT_VPN);
+ withNoUnderlying.removeCapability(NET_CAPABILITY_NOT_VPN);
+
+ final NetworkCapabilities withMobileUnderlying = new NetworkCapabilities(withNoUnderlying);
+ withMobileUnderlying.addTransportType(TRANSPORT_CELLULAR);
+ withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING);
+ withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ withMobileUnderlying.setLinkDownstreamBandwidthKbps(10);
+
+ final NetworkCapabilities withWifiUnderlying = new NetworkCapabilities(withNoUnderlying);
+ withWifiUnderlying.addTransportType(TRANSPORT_WIFI);
+ withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED);
+ withWifiUnderlying.setLinkUpstreamBandwidthKbps(20);
+
+ final NetworkCapabilities withWifiAndMobileUnderlying =
+ new NetworkCapabilities(withNoUnderlying);
+ withWifiAndMobileUnderlying.addTransportType(TRANSPORT_CELLULAR);
+ withWifiAndMobileUnderlying.addTransportType(TRANSPORT_WIFI);
+ withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED);
+ withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING);
+ withWifiAndMobileUnderlying.setLinkDownstreamBandwidthKbps(10);
+ withWifiAndMobileUnderlying.setLinkUpstreamBandwidthKbps(20);
+
+ NetworkCapabilities caps = new NetworkCapabilities(initialCaps);
+ final boolean notDeclaredMetered = false;
+ mService.applyUnderlyingCapabilities(new Network[]{}, caps, notDeclaredMetered);
+ assertEquals(withNoUnderlying, caps);
+
+ caps = new NetworkCapabilities(initialCaps);
+ mService.applyUnderlyingCapabilities(new Network[]{null}, caps, notDeclaredMetered);
+ assertEquals(withNoUnderlying, caps);
+
+ caps = new NetworkCapabilities(initialCaps);
+ mService.applyUnderlyingCapabilities(new Network[]{mobile}, caps, notDeclaredMetered);
+ assertEquals(withMobileUnderlying, caps);
+
+ mService.applyUnderlyingCapabilities(new Network[]{wifi}, caps, notDeclaredMetered);
+ assertEquals(withWifiUnderlying, caps);
+
+ final boolean isDeclaredMetered = true;
+ withWifiUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED);
+ caps = new NetworkCapabilities(initialCaps);
+ mService.applyUnderlyingCapabilities(new Network[]{wifi}, caps, isDeclaredMetered);
+ assertEquals(withWifiUnderlying, caps);
+
+ caps = new NetworkCapabilities(initialCaps);
+ mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, caps, isDeclaredMetered);
+ assertEquals(withWifiAndMobileUnderlying, caps);
+
+ withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED);
+ caps = new NetworkCapabilities(initialCaps);
+ mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi},
+ caps, notDeclaredMetered);
+ assertEquals(withWifiAndMobileUnderlying, caps);
+
+ caps = new NetworkCapabilities(initialCaps);
+ mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi},
+ caps, notDeclaredMetered);
+ assertEquals(withWifiAndMobileUnderlying, caps);
+
+ mService.applyUnderlyingCapabilities(null, caps, notDeclaredMetered);
+ assertEquals(withWifiUnderlying, caps);
+ }
+
+ @Test
public void testVpnConnectDisconnectUnderlyingNetwork() throws Exception {
final TestNetworkCallback callback = new TestNetworkCallback();
final NetworkRequest request = new NetworkRequest.Builder()
@@ -5947,17 +6049,28 @@ public class ConnectivityServiceTest {
&& caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_WIFI));
+ // Change the VPN's capabilities somehow (specifically, disconnect wifi).
+ mWiFiNetworkAgent.disconnect();
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expectCapabilitiesThat(mMockVpn, (caps)
+ -> caps.getUids().size() == 2
+ && caps.getUids().contains(new UidRange(uid, uid))
+ && caps.getUids().contains(UidRange.createForUser(restrictedUserId))
+ && caps.hasTransport(TRANSPORT_VPN)
+ && !caps.hasTransport(TRANSPORT_WIFI));
+
// Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, restrictedUserId);
handler.post(() -> mServiceContext.sendBroadcast(removedIntent));
- // Expect that the VPN gains the UID range for the restricted user.
+ // Expect that the VPN gains the UID range for the restricted user, and that the capability
+ // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved.
callback.expectCapabilitiesThat(mMockVpn, (caps)
-> caps.getUids().size() == 1
&& caps.getUids().contains(new UidRange(uid, uid))
&& caps.hasTransport(TRANSPORT_VPN)
- && caps.hasTransport(TRANSPORT_WIFI));
+ && !caps.hasTransport(TRANSPORT_WIFI));
}
@Test
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index d0db55f2bb13..337507ac1d46 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -21,15 +21,6 @@ import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
import static android.content.pm.UserInfo.FLAG_PRIMARY;
import static android.content.pm.UserInfo.FLAG_RESTRICTED;
import static android.net.ConnectivityManager.NetworkCallback;
-import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -621,102 +612,6 @@ public class VpnTest {
order.verify(mNotificationManager).cancel(anyString(), anyInt());
}
- @Test
- public void testCapabilities() {
- setMockedUsers(primaryUser);
-
- final Network mobile = new Network(1);
- final Network wifi = new Network(2);
-
- final Map<Network, NetworkCapabilities> networks = new HashMap<>();
- networks.put(
- mobile,
- new NetworkCapabilities()
- .addTransportType(TRANSPORT_CELLULAR)
- .addCapability(NET_CAPABILITY_INTERNET)
- .addCapability(NET_CAPABILITY_NOT_CONGESTED)
- .setLinkDownstreamBandwidthKbps(10));
- networks.put(
- wifi,
- new NetworkCapabilities()
- .addTransportType(TRANSPORT_WIFI)
- .addCapability(NET_CAPABILITY_INTERNET)
- .addCapability(NET_CAPABILITY_NOT_METERED)
- .addCapability(NET_CAPABILITY_NOT_ROAMING)
- .addCapability(NET_CAPABILITY_NOT_CONGESTED)
- .addCapability(NET_CAPABILITY_NOT_SUSPENDED)
- .setLinkUpstreamBandwidthKbps(20));
- setMockedNetworks(networks);
-
- final NetworkCapabilities caps = new NetworkCapabilities();
-
- Vpn.applyUnderlyingCapabilities(
- mConnectivityManager, new Network[] {}, caps, false /* isAlwaysMetered */);
- assertTrue(caps.hasTransport(TRANSPORT_VPN));
- assertFalse(caps.hasTransport(TRANSPORT_CELLULAR));
- assertFalse(caps.hasTransport(TRANSPORT_WIFI));
- assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps());
- assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps());
- assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
-
- Vpn.applyUnderlyingCapabilities(
- mConnectivityManager,
- new Network[] {mobile},
- caps,
- false /* isAlwaysMetered */);
- assertTrue(caps.hasTransport(TRANSPORT_VPN));
- assertTrue(caps.hasTransport(TRANSPORT_CELLULAR));
- assertFalse(caps.hasTransport(TRANSPORT_WIFI));
- assertEquals(10, caps.getLinkDownstreamBandwidthKbps());
- assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps());
- assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
- assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
- assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
-
- Vpn.applyUnderlyingCapabilities(
- mConnectivityManager, new Network[] {wifi}, caps, false /* isAlwaysMetered */);
- assertTrue(caps.hasTransport(TRANSPORT_VPN));
- assertFalse(caps.hasTransport(TRANSPORT_CELLULAR));
- assertTrue(caps.hasTransport(TRANSPORT_WIFI));
- assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps());
- assertEquals(20, caps.getLinkUpstreamBandwidthKbps());
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
-
- Vpn.applyUnderlyingCapabilities(
- mConnectivityManager, new Network[] {wifi}, caps, true /* isAlwaysMetered */);
- assertTrue(caps.hasTransport(TRANSPORT_VPN));
- assertFalse(caps.hasTransport(TRANSPORT_CELLULAR));
- assertTrue(caps.hasTransport(TRANSPORT_WIFI));
- assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkDownstreamBandwidthKbps());
- assertEquals(20, caps.getLinkUpstreamBandwidthKbps());
- assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
-
- Vpn.applyUnderlyingCapabilities(
- mConnectivityManager,
- new Network[] {mobile, wifi},
- caps,
- false /* isAlwaysMetered */);
- assertTrue(caps.hasTransport(TRANSPORT_VPN));
- assertTrue(caps.hasTransport(TRANSPORT_CELLULAR));
- assertTrue(caps.hasTransport(TRANSPORT_WIFI));
- assertEquals(10, caps.getLinkDownstreamBandwidthKbps());
- assertEquals(20, caps.getLinkUpstreamBandwidthKbps());
- assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
- assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
- assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
- }
-
/**
* The profile name should NOT change between releases for backwards compatibility
*
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index 852b1244cd6e..768b4b2c7bfd 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -190,8 +190,11 @@ class LinkCommand : public Command {
AddOptionalFlag("--version-name",
"Version name to inject into the AndroidManifest.xml if none is present.",
&options_.manifest_fixer_options.version_name_default);
+ AddOptionalFlag("--revision-code",
+ "Revision code (integer) to inject into the AndroidManifest.xml if none is\n"
+ "present.", &options_.manifest_fixer_options.revision_code_default);
AddOptionalSwitch("--replace-version",
- "If --version-code and/or --version-name are specified, these\n"
+ "If --version-code, --version-name, and/or --revision-code are specified, these\n"
"values will replace any value already in the manifest. By\n"
"default, nothing is changed if the manifest already defines\n"
"these attributes.",
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index c03661ca2366..8abd9dec56be 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -367,6 +367,16 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
}
}
+ if (options_.revision_code_default) {
+ if (options_.replace_version) {
+ el->RemoveAttribute(xml::kSchemaAndroid, "revisionCode");
+ }
+ if (el->FindAttribute(xml::kSchemaAndroid, "revisionCode") == nullptr) {
+ el->attributes.push_back(xml::Attribute{xml::kSchemaAndroid, "revisionCode",
+ options_.revision_code_default.value()});
+ }
+ }
+
return true;
});
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index ec4367b450fb..34ad8d586df1 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -60,6 +60,10 @@ struct ManifestFixerOptions {
// replace_version is set.
Maybe<std::string> version_code_major_default;
+ // The revision code to set if 'android:revisionCode' is not defined in <manifest> or if
+ // replace_version is set.
+ Maybe<std::string> revision_code_default;
+
// The version of the framework being compiled against to set for 'android:compileSdkVersion' in
// the <manifest> tag.
Maybe<std::string> compile_sdk_version;
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 781ff7b51637..432f10bdab97 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -445,6 +445,66 @@ TEST_F(ManifestFixerTest, ReplaceVersionNameAndCode) {
EXPECT_THAT(attr->value, StrEq("0x20000000"));
}
+TEST_F(ManifestFixerTest, UseDefaultRevisionCode) {
+ ManifestFixerOptions options;
+ options.revision_code_default = std::string("0x10000000");
+
+ std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x00000001" />)EOF",
+ options);
+ ASSERT_THAT(doc, NotNull());
+
+ xml::Element* manifest_el = doc->root.get();
+ ASSERT_THAT(manifest_el, NotNull());
+
+ xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("0x10000000"));
+}
+
+TEST_F(ManifestFixerTest, DontUseDefaultRevisionCode) {
+ ManifestFixerOptions options;
+ options.revision_code_default = std::string("0x10000000");
+
+ std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x00000001"
+ android:revisionCode="0x00000002" />)EOF",
+ options);
+ ASSERT_THAT(doc, NotNull());
+
+ xml::Element* manifest_el = doc->root.get();
+ ASSERT_THAT(manifest_el, NotNull());
+
+ xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("0x00000002"));
+}
+
+TEST_F(ManifestFixerTest, ReplaceRevisionCode) {
+ ManifestFixerOptions options;
+ options.replace_version = true;
+ options.revision_code_default = std::string("0x10000000");
+
+ std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x00000001"
+ android:revisionCode="0x00000002" />)EOF",
+ options);
+ ASSERT_THAT(doc, NotNull());
+
+ xml::Element* manifest_el = doc->root.get();
+ ASSERT_THAT(manifest_el, NotNull());
+
+ xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("0x10000000"));
+}
+
TEST_F(ManifestFixerTest, ReplaceVersionName) {
ManifestFixerOptions options;
options.replace_version = true;
diff --git a/wifi/aidl-export/android/net/wifi/CoexUnsafeChannel.aidl b/wifi/aidl-export/android/net/wifi/CoexUnsafeChannel.aidl
new file mode 100644
index 000000000000..cb359e9b2c1b
--- /dev/null
+++ b/wifi/aidl-export/android/net/wifi/CoexUnsafeChannel.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+parcelable CoexUnsafeChannel;
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
index 5e8fc0774cce..48d9fd453b05 100644
--- a/wifi/api/system-current.txt
+++ b/wifi/api/system-current.txt
@@ -1,6 +1,17 @@
// Signature format: 2.0
package android.net.wifi {
+ public final class CoexUnsafeChannel implements android.os.Parcelable {
+ ctor public CoexUnsafeChannel(int, int);
+ ctor public CoexUnsafeChannel(int, int, int);
+ method public int getBand();
+ method public int getChannel();
+ method public int getPowerCapDbm();
+ method public boolean isPowerCapAvailable();
+ method public void setPowerCapDbm(int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.CoexUnsafeChannel> CREATOR;
+ }
+
public abstract class EasyConnectStatusCallback {
ctor public EasyConnectStatusCallback();
method public void onBootstrapUriGenerated(@NonNull String);
@@ -456,6 +467,8 @@ package android.net.wifi {
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset();
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>);
+ method @RequiresPermission(android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS) public int getCoexRestrictions();
+ method @NonNull @RequiresPermission(android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS) public java.util.Set<android.net.wifi.CoexUnsafeChannel> getCoexUnsafeChannels();
method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCountryCode();
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public android.net.Network getCurrentNetwork();
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses();
@@ -476,6 +489,7 @@ package android.net.wifi {
method public boolean isVerboseLoggingEnabled();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
method public boolean isWifiScannerSupported();
+ method @RequiresPermission(android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS) public void registerCoexCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.CoexCallback);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerNetworkRequestMatchCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerTrafficStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.TrafficStateCallback);
@@ -487,6 +501,7 @@ package android.net.wifi {
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveSoftApBackupData();
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setAutoWakeupEnabled(boolean);
+ method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS) public void setCoexUnsafeChannels(@NonNull java.util.Set<android.net.wifi.CoexUnsafeChannel>, int);
method @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(int);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setMacRandomizationSettingPasspointEnabled(@NonNull String, boolean);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setPasspointMeteredOverride(@NonNull String, int);
@@ -507,6 +522,7 @@ package android.net.wifi {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp();
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void stopTemporarilyDisablingAllNonCarrierMergedWifi();
+ method @RequiresPermission(android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS) public void unregisterCoexCallback(@NonNull android.net.wifi.WifiManager.CoexCallback);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterNetworkRequestMatchCallback(@NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterSoftApCallback(@NonNull android.net.wifi.WifiManager.SoftApCallback);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterTrafficStateCallback(@NonNull android.net.wifi.WifiManager.TrafficStateCallback);
@@ -520,6 +536,9 @@ package android.net.wifi {
field public static final int CHANGE_REASON_ADDED = 0; // 0x0
field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
+ field public static final int COEX_RESTRICTION_SOFTAP = 2; // 0x2
+ field public static final int COEX_RESTRICTION_WIFI_AWARE = 4; // 0x4
+ field public static final int COEX_RESTRICTION_WIFI_DIRECT = 1; // 0x1
field public static final String CONFIGURED_NETWORKS_CHANGED_ACTION = "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
field public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1; // 0x1
field public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2; // 0x2
@@ -575,6 +594,11 @@ package android.net.wifi {
method public void onSuccess();
}
+ public abstract static class WifiManager.CoexCallback {
+ ctor public WifiManager.CoexCallback();
+ method public abstract void onCoexUnsafeChannelsChanged();
+ }
+
public static interface WifiManager.NetworkRequestMatchCallback {
method public default void onAbort();
method public default void onMatch(@NonNull java.util.List<android.net.wifi.ScanResult>);
diff --git a/wifi/java/android/net/wifi/CoexUnsafeChannel.java b/wifi/java/android/net/wifi/CoexUnsafeChannel.java
new file mode 100644
index 000000000000..3f9efa020d05
--- /dev/null
+++ b/wifi/java/android/net/wifi/CoexUnsafeChannel.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ;
+import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ;
+import static android.net.wifi.WifiScanner.WIFI_BAND_6_GHZ;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Data structure class representing a Wi-Fi channel that would cause interference to/receive
+ * interference from the active cellular channels and should be avoided.
+ *
+ * If {@link #isPowerCapAvailable()} is {@code true}, then a valid power cap value is available
+ * through {@link #getPowerCapDbm()} to be used if this channel cannot be avoided. If {@code false},
+ * then {@link #getPowerCapDbm()} throws an IllegalStateException and the channel will not need to
+ * cap its power.
+ *
+ * @hide
+ */
+@SystemApi
+public final class CoexUnsafeChannel implements Parcelable {
+ private @WifiAnnotations.WifiBandBasic int mBand;
+ private int mChannel;
+ private boolean mIsPowerCapAvailable = false;
+ private int mPowerCapDbm;
+
+ /**
+ * Constructor for a CoexUnsafeChannel with no power cap specified.
+ * @param band One of {@link WifiAnnotations.WifiBandBasic}
+ * @param channel Channel number
+ */
+ public CoexUnsafeChannel(@WifiAnnotations.WifiBandBasic int band, int channel) {
+ mBand = band;
+ mChannel = channel;
+ }
+
+ /**
+ * Constructor for a CoexUnsafeChannel with power cap specified.
+ * @param band One of {@link WifiAnnotations.WifiBandBasic}
+ * @param channel Channel number
+ * @param powerCapDbm Power cap in dBm
+ */
+ public CoexUnsafeChannel(@WifiAnnotations.WifiBandBasic int band, int channel,
+ int powerCapDbm) {
+ mBand = band;
+ mChannel = channel;
+ setPowerCapDbm(powerCapDbm);
+ }
+
+ /** Returns the Wi-Fi band of this channel as one of {@link WifiAnnotations.WifiBandBasic} */
+ public @WifiAnnotations.WifiBandBasic int getBand() {
+ return mBand;
+ }
+
+ /** Returns the channel number of this channel. */
+ public int getChannel() {
+ return mChannel;
+ }
+
+ /** Returns {@code true} if {@link #getPowerCapDbm()} is a valid value, else {@code false} */
+ public boolean isPowerCapAvailable() {
+ return mIsPowerCapAvailable;
+ }
+
+ /**
+ * Returns the power cap of this channel in dBm. Throws IllegalStateException if
+ * {@link #isPowerCapAvailable()} is {@code false}.
+ */
+ public int getPowerCapDbm() {
+ if (!mIsPowerCapAvailable) {
+ throw new IllegalStateException("getPowerCapDbm called but power cap is unavailable");
+ }
+ return mPowerCapDbm;
+ }
+
+ /** Set the power cap of this channel. */
+ public void setPowerCapDbm(int powerCapDbm) {
+ mIsPowerCapAvailable = true;
+ mPowerCapDbm = powerCapDbm;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ CoexUnsafeChannel that = (CoexUnsafeChannel) o;
+ return mBand == that.mBand
+ && mChannel == that.mChannel
+ && mIsPowerCapAvailable == that.mIsPowerCapAvailable
+ && mPowerCapDbm == that.mPowerCapDbm;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mBand, mChannel, mIsPowerCapAvailable, mPowerCapDbm);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sj = new StringBuilder("CoexUnsafeChannel{");
+ sj.append(mChannel);
+ sj.append(", ");
+ if (mBand == WIFI_BAND_24_GHZ) {
+ sj.append("2.4GHz");
+ } else if (mBand == WIFI_BAND_5_GHZ) {
+ sj.append("5GHz");
+ } else if (mBand == WIFI_BAND_6_GHZ) {
+ sj.append("6GHz");
+ } else {
+ sj.append("UNKNOWN BAND");
+ }
+ if (mIsPowerCapAvailable) {
+ sj.append(", ").append(mPowerCapDbm).append("dBm");
+ }
+ sj.append('}');
+ return sj.toString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mBand);
+ dest.writeInt(mChannel);
+ dest.writeBoolean(mIsPowerCapAvailable);
+ if (mIsPowerCapAvailable) {
+ dest.writeInt(mPowerCapDbm);
+ }
+ }
+
+ /** Implement the Parcelable interface */
+ public static final @NonNull Creator<CoexUnsafeChannel> CREATOR =
+ new Creator<CoexUnsafeChannel>() {
+ public CoexUnsafeChannel createFromParcel(Parcel in) {
+ final int band = in.readInt();
+ final int channel = in.readInt();
+ final boolean isPowerCapAvailable = in.readBoolean();
+ if (isPowerCapAvailable) {
+ final int powerCapDbm = in.readInt();
+ return new CoexUnsafeChannel(band, channel, powerCapDbm);
+ }
+ return new CoexUnsafeChannel(band, channel);
+ }
+
+ public CoexUnsafeChannel[] newArray(int size) {
+ return new CoexUnsafeChannel[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/ICoexCallback.aidl b/wifi/java/android/net/wifi/ICoexCallback.aidl
new file mode 100644
index 000000000000..89e4c4b93013
--- /dev/null
+++ b/wifi/java/android/net/wifi/ICoexCallback.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+/**
+ * Interface for Wi-Fi/cellular coex callback.
+ * @hide
+ */
+oneway interface ICoexCallback
+{
+ void onCoexUnsafeChannelsChanged();
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 0b3c0575dabd..6dee751f5894 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -24,7 +24,9 @@ import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.DhcpInfo;
import android.net.Network;
+import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.IActionListener;
+import android.net.wifi.ICoexCallback;
import android.net.wifi.IDppCallback;
import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.INetworkRequestMatchCallback;
@@ -144,6 +146,16 @@ interface IWifiManager
void updateInterfaceIpState(String ifaceName, int mode);
+ void setCoexUnsafeChannels(in List<CoexUnsafeChannel> unsafeChannels, int mandatoryRestrictions);
+
+ List<CoexUnsafeChannel> getCoexUnsafeChannels();
+
+ int getCoexRestrictions();
+
+ void registerCoexCallback(in ICoexCallback callback);
+
+ void unregisterCoexCallback(in ICoexCallback callback);
+
boolean startSoftAp(in WifiConfiguration wifiConfig, String packageName);
boolean startTetheredHotspot(in SoftApConfiguration softApConfig, String packageName);
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index d089e1a86a68..b8fa1e18ed28 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -72,6 +72,7 @@ import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -3110,6 +3111,238 @@ public class WifiManager {
}
}
+ /* Wi-Fi/Cellular Coex */
+
+ /**
+ * Mandatory coex restriction flag for Wi-Fi Direct.
+ *
+ * @see #setCoexUnsafeChannels(Set, int)
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int COEX_RESTRICTION_WIFI_DIRECT = 0x1 << 0;
+
+ /**
+ * Mandatory coex restriction flag for SoftAP
+ *
+ * @see #setCoexUnsafeChannels(Set, int)
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int COEX_RESTRICTION_SOFTAP = 0x1 << 1;
+
+ /**
+ * Mandatory coex restriction flag for Wi-Fi Aware.
+ *
+ * @see #setCoexUnsafeChannels(Set, int)
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int COEX_RESTRICTION_WIFI_AWARE = 0x1 << 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = {"COEX_RESTRICTION_"}, value = {
+ COEX_RESTRICTION_WIFI_DIRECT,
+ COEX_RESTRICTION_SOFTAP,
+ COEX_RESTRICTION_WIFI_AWARE
+ })
+ public @interface CoexRestriction {}
+
+ /**
+ * Specify the set of {@link CoexUnsafeChannel} to propagate through the framework for
+ * Wi-Fi/Cellular coex channel avoidance if the default algorithm is disabled via overlay
+ * (i.e. config_wifiCoexDefaultAlgorithmEnabled = false). Otherwise do nothing.
+ *
+ * @param unsafeChannels Set of {@link CoexUnsafeChannel} to avoid.
+ * @param restrictions Bitmap of {@link CoexRestriction} specifying the mandatory restricted
+ * uses of the specified channels. If any restrictions are set, then the
+ * supplied CoexUnsafeChannels will be completely avoided for the
+ * specified modes, rather than be avoided with best effort.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS)
+ public void setCoexUnsafeChannels(@NonNull Set<CoexUnsafeChannel> unsafeChannels,
+ int restrictions) {
+ if (unsafeChannels == null) {
+ throw new IllegalArgumentException("unsafeChannels must not be null");
+ }
+ try {
+ mService.setCoexUnsafeChannels(new ArrayList<>(unsafeChannels), restrictions);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns the set of current {@link CoexUnsafeChannel} being used for Wi-Fi/Cellular coex
+ * channel avoidance.
+ *
+ * This returns the set calculated by the default algorithm if
+ * config_wifiCoexDefaultAlgorithmEnabled is {@code true}. Otherwise, returns the set supplied
+ * in {@link #setCoexUnsafeChannels(Set, int)}.
+ *
+ * If any {@link CoexRestriction} flags are set in {@link #getCoexRestrictions()}, then the
+ * CoexUnsafeChannels should be totally avoided (i.e. not best effort) for the Wi-Fi modes
+ * specified by the flags.
+ *
+ * @return Set of current CoexUnsafeChannels.
+ *
+ * @hide
+ */
+ @NonNull
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS)
+ public Set<CoexUnsafeChannel> getCoexUnsafeChannels() {
+ try {
+ return new HashSet<>(mService.getCoexUnsafeChannels());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns the current coex restrictions being used for Wi-Fi/Cellular coex
+ * channel avoidance.
+ *
+ * This returns the restrictions calculated by the default algorithm if
+ * config_wifiCoexDefaultAlgorithmEnabled is {@code true}. Otherwise, returns the value supplied
+ * in {@link #setCoexUnsafeChannels(Set, int)}.
+ *
+ * @return int containing a bitwise-OR combination of {@link CoexRestriction}.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS)
+ public int getCoexRestrictions() {
+ try {
+ return mService.getCoexRestrictions();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Registers a CoexCallback to listen on the current CoexUnsafeChannels and restrictions being
+ * used for Wi-Fi/cellular coex channel avoidance.
+ * @param executor Executor to execute listener callback on
+ * @param callback CoexCallback to register
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS)
+ public void registerCoexCallback(
+ @NonNull @CallbackExecutor Executor executor, @NonNull CoexCallback callback) {
+ if (executor == null) throw new IllegalArgumentException("executor must not be null");
+ if (callback == null) throw new IllegalArgumentException("callback must not be null");
+ CoexCallback.CoexCallbackProxy proxy = callback.getProxy();
+ proxy.initProxy(executor, callback);
+ try {
+ mService.registerCoexCallback(proxy);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Unregisters a CoexCallback from listening on the current CoexUnsafeChannels and restrictions
+ * being used for Wi-Fi/cellular coex channel avoidance.
+ * @param callback CoexCallback to unregister
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS)
+ public void unregisterCoexCallback(@NonNull CoexCallback callback) {
+ if (callback == null) throw new IllegalArgumentException("callback must not be null");
+ CoexCallback.CoexCallbackProxy proxy = callback.getProxy();
+ try {
+ mService.unregisterCoexCallback(proxy);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } finally {
+ proxy.cleanUpProxy();
+ }
+ }
+
+ /**
+ * Abstract callback class for applications to receive updates about current CoexUnsafeChannels
+ * for Wi-Fi/Cellular coex channel avoidance.
+ *
+ * @hide
+ */
+ @SystemApi
+ public abstract static class CoexCallback {
+ private final CoexCallbackProxy mCoexCallbackProxy;
+
+ public CoexCallback() {
+ mCoexCallbackProxy = new CoexCallbackProxy();
+ }
+
+ /*package*/ @NonNull
+ CoexCallbackProxy getProxy() {
+ return mCoexCallbackProxy;
+ }
+
+ /**
+ * Indicates that the current CoexUnsafeChannels or restrictions have changed.
+ * Clients should call {@link #getCoexUnsafeChannels()} and {@link #getCoexRestrictions()}
+ * to get the updated values.
+ */
+ public abstract void onCoexUnsafeChannelsChanged();
+
+ /**
+ * Callback proxy for CoexCallback objects.
+ */
+ private static class CoexCallbackProxy extends ICoexCallback.Stub {
+ private final Object mLock = new Object();
+ @Nullable @GuardedBy("mLock") private Executor mExecutor;
+ @Nullable @GuardedBy("mLock") private CoexCallback mCallback;
+
+ CoexCallbackProxy() {
+ mExecutor = null;
+ mCallback = null;
+ }
+
+ /*package*/ void initProxy(@NonNull Executor executor,
+ @NonNull CoexCallback callback) {
+ synchronized (mLock) {
+ mExecutor = executor;
+ mCallback = callback;
+ }
+ }
+
+ /*package*/ void cleanUpProxy() {
+ synchronized (mLock) {
+ mExecutor = null;
+ mCallback = null;
+ }
+ }
+
+ @Override
+ public void onCoexUnsafeChannelsChanged() {
+ Executor executor;
+ CoexCallback callback;
+ synchronized (mLock) {
+ executor = mExecutor;
+ callback = mCallback;
+ }
+ if (executor == null || callback == null) {
+ return;
+ }
+ Binder.clearCallingIdentity();
+ executor.execute(callback::onCoexUnsafeChannelsChanged);
+ }
+ }
+ }
+
/**
* Start Soft AP (hotspot) mode for tethering purposes with the specified configuration.
* Note that starting Soft AP mode may disable station mode operation if the device does not
@@ -5991,7 +6224,6 @@ public class WifiManager {
executor.execute(callback::onScanResultsAvailable);
}
}
-
}
/**
diff --git a/wifi/tests/src/android/net/wifi/CoexUnsafeChannelTest.java b/wifi/tests/src/android/net/wifi/CoexUnsafeChannelTest.java
new file mode 100644
index 000000000000..320f25e715fe
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/CoexUnsafeChannelTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.CoexUnsafeChannel}.
+ */
+@SmallTest
+public class CoexUnsafeChannelTest {
+ /**
+ * Verifies {@link CoexUnsafeChannel#isPowerCapAvailable()} returns false if no cap is set.
+ */
+ @Test
+ public void testIsPowerCapAvailable_noPowerCap_returnsFalse() {
+ CoexUnsafeChannel unsafeChannel = new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6);
+
+ assertThat(unsafeChannel.isPowerCapAvailable()).isFalse();
+ }
+
+ /**
+ * Verifies {@link CoexUnsafeChannel#isPowerCapAvailable()} returns true if a cap is set, and
+ * {@link CoexUnsafeChannel#getPowerCapDbm()} returns the set value.
+ */
+ @Test
+ public void testIsPowerCapAvailable_powerCapSet_returnsTrue() {
+ final int powerCapDbm = -50;
+ CoexUnsafeChannel unsafeChannel = new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6);
+
+ unsafeChannel.setPowerCapDbm(powerCapDbm);
+
+ assertThat(unsafeChannel.isPowerCapAvailable()).isTrue();
+ assertThat(unsafeChannel.getPowerCapDbm()).isEqualTo(powerCapDbm);
+ }
+
+ /**
+ * Verifies {@link CoexUnsafeChannel#getPowerCapDbm()} throws an IllegalStateException if
+ * {@link CoexUnsafeChannel#isPowerCapAvailable()} is {@code false}.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testGetPowerCap_powerCapUnavailable_throwsException() {
+ CoexUnsafeChannel unsafeChannel = new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6);
+
+ unsafeChannel.getPowerCapDbm();
+ }
+
+ /**
+ * Verify parcel read/write for CoexUnsafeChannel with or without power cap.
+ */
+ @Test
+ public void testParcelReadWrite_withOrWithoutCap_readEqualsWritten() throws Exception {
+ CoexUnsafeChannel writeUnsafeChannelNoCap =
+ new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6);
+ CoexUnsafeChannel writeUnsafeChannelCapped =
+ new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6, -50);
+
+ CoexUnsafeChannel readUnsafeChannelNoCap = parcelReadWrite(writeUnsafeChannelNoCap);
+ CoexUnsafeChannel readUnsafeChannelCapped = parcelReadWrite(writeUnsafeChannelCapped);
+
+ assertThat(writeUnsafeChannelNoCap).isEqualTo(readUnsafeChannelNoCap);
+ assertThat(writeUnsafeChannelCapped).isEqualTo(readUnsafeChannelCapped);
+ }
+
+ /**
+ * Write the provided {@link CoexUnsafeChannel} to a parcel and deserialize it.
+ */
+ private static CoexUnsafeChannel parcelReadWrite(CoexUnsafeChannel writeResult)
+ throws Exception {
+ Parcel parcel = Parcel.obtain();
+ writeResult.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
+ return CoexUnsafeChannel.CREATOR.createFromParcel(parcel);
+ }
+}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index aefebbcec607..39f6f57b05b3 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -19,6 +19,9 @@ package android.net.wifi;
import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED;
import static android.net.wifi.WifiManager.ActionListener;
import static android.net.wifi.WifiManager.BUSY;
+import static android.net.wifi.WifiManager.COEX_RESTRICTION_SOFTAP;
+import static android.net.wifi.WifiManager.COEX_RESTRICTION_WIFI_AWARE;
+import static android.net.wifi.WifiManager.COEX_RESTRICTION_WIFI_DIRECT;
import static android.net.wifi.WifiManager.ERROR;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
@@ -43,6 +46,7 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_SCANNER;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
import static android.net.wifi.WifiManager.WpsCallback;
+import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -74,6 +78,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.net.DhcpInfo;
import android.net.MacAddress;
+import android.net.wifi.WifiManager.CoexCallback;
import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
import android.net.wifi.WifiManager.LocalOnlyHotspotObserver;
import android.net.wifi.WifiManager.LocalOnlyHotspotReservation;
@@ -108,9 +113,11 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.Executor;
/**
@@ -151,6 +158,7 @@ public class WifiManagerTest {
private WifiManager mWifiManager;
private WifiNetworkSuggestion mWifiNetworkSuggestion;
private ScanResultsCallback mScanResultsCallback;
+ private CoexCallback mCoexCallback;
private WifiActivityEnergyInfo mWifiActivityEnergyInfo;
/**
@@ -214,10 +222,149 @@ public class WifiManagerTest {
mRunnable.run();
}
};
+ mCoexCallback = new CoexCallback() {
+ @Override
+ public void onCoexUnsafeChannelsChanged() {
+ mRunnable.run();
+ }
+ };
mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);
}
/**
+ * Check the call to setCoexUnsafeChannels calls WifiServiceImpl to setCoexUnsafeChannels with
+ * the provided CoexUnsafeChannels and restrictions bitmask.
+ */
+ @Test
+ public void testSetCoexUnsafeChannelsGoesToWifiServiceImpl() throws Exception {
+ Set<CoexUnsafeChannel> unsafeChannels = new HashSet<>();
+ int restrictions = COEX_RESTRICTION_WIFI_DIRECT | COEX_RESTRICTION_SOFTAP
+ | COEX_RESTRICTION_WIFI_AWARE;
+
+ mWifiManager.setCoexUnsafeChannels(unsafeChannels, restrictions);
+
+ verify(mWifiService).setCoexUnsafeChannels(new ArrayList<>(unsafeChannels), restrictions);
+ }
+
+ /**
+ * Verify an IllegalArgumentException if passed a null value for unsafeChannels.
+ */
+ @Test
+ public void testSetCoexUnsafeChannelsThrowsIllegalArgumentExceptionOnNullUnsafeChannels() {
+ try {
+ mWifiManager.setCoexUnsafeChannels(null, 0);
+ fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ /**
+ * Check the call to getCoexUnsafeChannels calls WifiServiceImpl to return the values from
+ * getCoexUnsafeChannels.
+ */
+ @Test
+ public void testGetCoexUnsafeChannelsGoesToWifiServiceImpl() throws Exception {
+ Set<CoexUnsafeChannel> unsafeChannels = new HashSet<>();
+ unsafeChannels.add(new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6));
+ when(mWifiService.getCoexUnsafeChannels()).thenReturn(new ArrayList<>(unsafeChannels));
+
+ assertEquals(mWifiManager.getCoexUnsafeChannels(), unsafeChannels);
+ }
+
+ /**
+ * Verify call to getCoexRestrictions calls WifiServiceImpl to return the value from
+ * getCoexRestrictions.
+ */
+ @Test
+ public void testGetCoexRestrictionsGoesToWifiServiceImpl() throws Exception {
+ int restrictions = COEX_RESTRICTION_WIFI_DIRECT | COEX_RESTRICTION_SOFTAP
+ | COEX_RESTRICTION_WIFI_AWARE;
+ when(mWifiService.getCoexRestrictions()).thenReturn(restrictions);
+
+ assertEquals(mWifiService.getCoexRestrictions(), restrictions);
+ }
+
+
+ /**
+ * Verify an IllegalArgumentException is thrown if callback is not provided.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testRegisterCoexCallbackWithNullCallback() throws Exception {
+ mWifiManager.registerCoexCallback(mExecutor, null);
+ }
+
+ /**
+ * Verify an IllegalArgumentException is thrown if executor is not provided.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testRegisterCoexCallbackWithNullExecutor() throws Exception {
+ mWifiManager.registerCoexCallback(null, mCoexCallback);
+ }
+
+ /**
+ * Verify client provided callback is being called to the right callback.
+ */
+ @Test
+ public void testAddCoexCallbackAndReceiveEvent() throws Exception {
+ ArgumentCaptor<ICoexCallback.Stub> callbackCaptor =
+ ArgumentCaptor.forClass(ICoexCallback.Stub.class);
+ mWifiManager.registerCoexCallback(new SynchronousExecutor(), mCoexCallback);
+ verify(mWifiService).registerCoexCallback(callbackCaptor.capture());
+ callbackCaptor.getValue().onCoexUnsafeChannelsChanged();
+ verify(mRunnable).run();
+ }
+
+ /**
+ * Verify client provided callback is being called to the right executor.
+ */
+ @Test
+ public void testRegisterCoexCallbackWithTheTargetExecutor() throws Exception {
+ ArgumentCaptor<ICoexCallback.Stub> callbackCaptor =
+ ArgumentCaptor.forClass(ICoexCallback.Stub.class);
+ mWifiManager.registerCoexCallback(mExecutor, mCoexCallback);
+ verify(mWifiService).registerCoexCallback(callbackCaptor.capture());
+ mWifiManager.registerCoexCallback(mAnotherExecutor, mCoexCallback);
+ callbackCaptor.getValue().onCoexUnsafeChannelsChanged();
+ verify(mExecutor, never()).execute(any(Runnable.class));
+ verify(mAnotherExecutor).execute(any(Runnable.class));
+ }
+
+ /**
+ * Verify client register unregister then register again, to ensure callback still works.
+ */
+ @Test
+ public void testRegisterUnregisterThenRegisterAgainWithCoexCallback() throws Exception {
+ ArgumentCaptor<ICoexCallback.Stub> callbackCaptor =
+ ArgumentCaptor.forClass(ICoexCallback.Stub.class);
+ mWifiManager.registerCoexCallback(new SynchronousExecutor(), mCoexCallback);
+ verify(mWifiService).registerCoexCallback(callbackCaptor.capture());
+ mWifiManager.unregisterCoexCallback(mCoexCallback);
+ callbackCaptor.getValue().onCoexUnsafeChannelsChanged();
+ verify(mRunnable, never()).run();
+ mWifiManager.registerCoexCallback(new SynchronousExecutor(), mCoexCallback);
+ callbackCaptor.getValue().onCoexUnsafeChannelsChanged();
+ verify(mRunnable).run();
+ }
+
+ /**
+ * Verify client unregisterCoexCallback.
+ */
+ @Test
+ public void testUnregisterCoexCallback() throws Exception {
+ mWifiManager.unregisterCoexCallback(mCoexCallback);
+ verify(mWifiService).unregisterCoexCallback(any());
+ }
+
+ /**
+ * Verify client unregisterCoexCallback with null callback will cause an exception.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testUnregisterCoexCallbackWithNullCallback() throws Exception {
+ mWifiManager.unregisterCoexCallback(null);
+ }
+
+
+ /**
* Check the call to startSoftAp calls WifiService to startSoftAp with the provided
* WifiConfiguration. Verify that the return value is propagated to the caller.
*/