summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java19
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java27
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java26
-rw-r--r--core/api/current.txt28
-rw-r--r--core/java/android/app/ActivityThread.java3
-rw-r--r--core/java/android/app/ApplicationPackageManager.java284
-rw-r--r--core/java/android/app/ContextImpl.java6
-rw-r--r--core/java/android/app/TaskInfo.java45
-rw-r--r--core/java/android/companion/CompanionDeviceManager.java72
-rw-r--r--core/java/android/companion/DeviceNotAssociatedException.java31
-rw-r--r--core/java/android/companion/ICompanionDeviceManager.aidl4
-rw-r--r--core/java/android/content/pm/PackageManager.java27
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java4
-rw-r--r--core/java/android/os/INetworkManagementService.aidl12
-rw-r--r--core/java/android/os/RemoteException.java5
-rw-r--r--core/java/android/permission/PermissionManager.java710
-rw-r--r--core/java/android/security/keymaster/KeymasterDefs.java24
-rw-r--r--core/java/android/service/textservice/OWNERS4
-rw-r--r--core/java/android/util/ExceptionUtils.java2
-rw-r--r--core/java/android/view/IRecentsAnimationController.aidl9
-rw-r--r--core/java/android/view/OWNERS1
-rw-r--r--core/java/android/view/SurfaceView.java2
-rw-r--r--core/java/android/view/contentcapture/MainContentCaptureSession.java16
-rw-r--r--core/java/android/view/textservice/OWNERS4
-rw-r--r--core/java/android/widget/OWNERS2
-rw-r--r--core/java/com/android/internal/util/LatencyTracker.java12
-rw-r--r--core/java/com/android/internal/view/OWNERS5
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/drawable-car/car_switch_thumb.xml21
-rw-r--r--core/res/res/drawable-car/car_switch_track.xml53
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/dimens_car.xml8
-rw-r--r--core/res/res/values/symbols.xml4
-rw-r--r--core/tests/batterystatstests/BatteryStatsLoadTests/Android.bp (renamed from core/tests/powertests/PowerStatsLoadTests/Android.bp)2
-rw-r--r--core/tests/batterystatstests/BatteryStatsLoadTests/AndroidManifest.xml (renamed from core/tests/powertests/PowerStatsLoadTests/AndroidManifest.xml)4
-rw-r--r--core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/ConnectivitySetupRule.java (renamed from core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/ConnectivitySetupRule.java)2
-rw-r--r--core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/PowerMetrics.java (renamed from core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetrics.java)2
-rw-r--r--core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/PowerMetricsCollector.java (renamed from core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetricsCollector.java)3
-rw-r--r--core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/SystemServiceCallLoadTest.java (renamed from core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/SystemServiceCallLoadTest.java)2
-rw-r--r--core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/WiFiLoadTest.java (renamed from core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/WiFiLoadTest.java)2
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/Android.bp (renamed from core/tests/powertests/PowerStatsViewer/Android.bp)2
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml (renamed from core/tests/powertests/PowerStatsViewer/AndroidManifest.xml)12
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml (renamed from core/tests/powertests/PowerStatsViewer/res/layout/power_stats_entry_layout.xml)0
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_info_layout.xml (renamed from core/tests/powertests/PowerStatsViewer/res/layout/power_consumer_info_layout.xml)0
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_activity_layout.xml (renamed from core/tests/powertests/PowerStatsViewer/res/layout/power_consumer_picker_activity_layout.xml)0
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml (renamed from core/tests/powertests/PowerStatsViewer/res/layout/power_consumer_picker_layout.xml)0
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml (renamed from core/tests/powertests/PowerStatsViewer/res/layout/power_stats_viewer_layout.xml)6
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml (renamed from core/tests/powertests/PowerStatsViewer/res/values/styles.xml)0
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java (renamed from core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java)29
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java (renamed from core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerConsumerInfoHelper.java)12
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java (renamed from core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerConsumerPickerActivity.java)20
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java (renamed from core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerConsumerPickerFragment.java)101
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java (renamed from core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java)114
-rw-r--r--core/tests/batterystatstests/OWNERS (renamed from core/tests/powertests/OWNERS)0
-rw-r--r--core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java2
-rw-r--r--data/etc/car/com.android.car.provision.xml1
-rw-r--r--data/etc/services.core.protolog.json30
-rw-r--r--keystore/java/android/security/KeyStoreOperation.java2
-rw-r--r--keystore/java/android/security/KeyStoreSecurityLevel.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStore3DESCipherSpi.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreAuthenticatedAESCipherSpi.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java4
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java4
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreSignatureSpiBase.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java6
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreUnauthenticatedAESCipherSpi.java2
-rw-r--r--keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java4
-rw-r--r--libs/WindowManager/Shell/res/values/config.xml12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java66
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java108
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxConfigController.java108
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxTaskListener.java267
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java16
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt46
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt46
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt16
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenTest.kt138
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/RotateOneLaunchedAppTest.kt146
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/RotateTwoLaunchedAppTest.kt157
-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/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml11
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_non_resizeable.xml32
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java7
-rw-r--r--libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/NonResizeableActivity.java29
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java36
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxConfigControllerTest.java131
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxTaskListenerTest.java367
-rw-r--r--media/java/android/media/IMediaRouterService.aidl2
-rw-r--r--media/java/android/media/MediaCodecInfo.java54
-rw-r--r--media/java/android/media/MediaRouter2Manager.java30
-rw-r--r--media/java/android/media/RouteDiscoveryPreference.java1
-rw-r--r--media/java/android/media/tv/tuner/Tuner.java21
-rw-r--r--media/jni/android_media_MediaExtractor.cpp2
-rw-r--r--media/jni/android_media_MediaMetadataRetriever.cpp12
-rw-r--r--media/native/midi/amidi.cpp6
-rw-r--r--packages/SettingsLib/res/values/strings.xml2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java25
-rw-r--r--services/autofill/java/com/android/server/autofill/TEST_MAPPING2
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java38
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java118
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java58
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java11
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java21
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java15
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java12
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java90
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java7
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java63
-rw-r--r--services/core/java/com/android/server/media/BluetoothRouteProvider.java12
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2Provider.java2
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java8
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java130
-rw-r--r--services/core/java/com/android/server/media/MediaRouterService.java12
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java2
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java13
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java13
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java232
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java119
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java21
-rw-r--r--services/core/java/com/android/server/wm/Task.java46
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java104
-rw-r--r--services/core/java/com/android/server/wm/TaskOrganizerController.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java55
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java51
-rw-r--r--services/tests/wmtests/Android.bp1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java64
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java11
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java17
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/utils/CommonUtils.java37
-rw-r--r--telephony/java/android/telephony/DataFailCause.java106
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java45
-rw-r--r--tests/net/java/com/android/server/connectivity/VpnTest.java176
-rw-r--r--wifi/api/current.txt6
-rw-r--r--wifi/api/system-current.txt9
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java14
-rw-r--r--wifi/java/android/net/wifi/SecurityParams.java42
-rw-r--r--wifi/java/android/net/wifi/SoftApCapability.java29
-rw-r--r--wifi/java/android/net/wifi/SoftApConfiguration.java20
-rw-r--r--wifi/java/android/net/wifi/SoftApInfo.java32
-rw-r--r--wifi/java/android/net/wifi/WifiAnnotations.java5
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java32
-rw-r--r--wifi/java/android/net/wifi/rtt/RangingRequest.java123
-rw-r--r--wifi/tests/src/android/net/wifi/SecurityParamsTest.java47
-rw-r--r--wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java4
-rw-r--r--wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java10
-rw-r--r--wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java71
167 files changed, 3582 insertions, 2633 deletions
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
index 1d86595a4063..b7cd4f5f8bce 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -18,6 +18,7 @@ package android.app.appsearch;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
+import android.app.appsearch.exceptions.AppSearchException;
import android.os.Bundle;
import android.os.ParcelableException;
import android.os.RemoteException;
@@ -166,9 +167,9 @@ public final class AppSearchSession {
* of the returned {@link AppSearchBatchResult} are the URIs of the input
* documents. The values are {@code null} if they were successfully indexed,
* or a failed {@link AppSearchResult} otherwise.
- * Or {@link BatchResultCallback#onSystemError} will be invoked with a
- * {@link Throwable} if an unexpected internal error occurred in AppSearch
- * service.
+ * Or {@link BatchResultCallback#onSystemError} will be invoked with an
+ * {@link AppSearchException} if an error occurred in AppSearch initialization
+ * or a cause {@link Throwable} if other error occurred in AppSearch service.
*/
public void putDocuments(
@NonNull PutDocumentsRequest request,
@@ -209,9 +210,9 @@ public final class AppSearchSession {
* {@link AppSearchResult} otherwise. URIs that are not found will return a
* failed {@link AppSearchResult} with a result code of
* {@link AppSearchResult#RESULT_NOT_FOUND}.
- * Or {@link BatchResultCallback#onSystemError} will be invoked with a
- * {@link Throwable} if an unexpected internal error occurred in AppSearch
- * service.
+ * Or {@link BatchResultCallback#onSystemError} will be invoked with an
+ * {@link AppSearchException} if an error occurred in AppSearch initialization
+ * or a cause {@link Throwable} if other error occurred in AppSearch service.
*/
public void getByUri(
@NonNull GetByUriRequest request,
@@ -337,9 +338,9 @@ public final class AppSearchSession {
* are {@code null} on success, or a failed {@link AppSearchResult} otherwise.
* URIs that are not found will return a failed {@link AppSearchResult} with a
* result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
- * Or {@link BatchResultCallback#onSystemError} will be invoked with a
- * {@link Throwable} if an unexpected internal error occurred in AppSearch
- * service.
+ * Or {@link BatchResultCallback#onSystemError} will be invoked with an
+ * {@link AppSearchException} if an error occurred in AppSearch initialization
+ * or a cause {@link Throwable} if other error occurred in AppSearch service.
*/
public void removeByUri(
@NonNull RemoveByUriRequest request,
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 53d097e844c8..551347c5c202 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -77,7 +77,7 @@ public class AppSearchManagerService extends SystemService {
for (int i = 0; i < schemaBundles.size(); i++) {
schemas.add(new AppSearchSchema(schemaBundles.get(i)));
}
- AppSearchImpl impl = ImplInstanceManager.getInstance(callingUserId);
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
impl.setSchema(databaseName, schemas, schemasNotPlatformSurfaceable, forceOverride);
invokeCallbackOnResult(callback,
@@ -103,7 +103,7 @@ public class AppSearchManagerService extends SystemService {
try {
AppSearchBatchResult.Builder<String, Void> resultBuilder =
new AppSearchBatchResult.Builder<>();
- AppSearchImpl impl = ImplInstanceManager.getInstance(callingUserId);
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
for (int i = 0; i < documentBundles.size(); i++) {
GenericDocument document = new GenericDocument(documentBundles.get(i));
@@ -138,7 +138,7 @@ public class AppSearchManagerService extends SystemService {
try {
AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
new AppSearchBatchResult.Builder<>();
- AppSearchImpl impl = ImplInstanceManager.getInstance(callingUserId);
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
for (int i = 0; i < uris.size(); i++) {
String uri = uris.get(i);
@@ -172,7 +172,7 @@ public class AppSearchManagerService extends SystemService {
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
try {
- AppSearchImpl impl = ImplInstanceManager.getInstance(callingUserId);
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
SearchResultPage searchResultPage = impl.query(
databaseName,
@@ -198,7 +198,7 @@ public class AppSearchManagerService extends SystemService {
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
try {
- AppSearchImpl impl = ImplInstanceManager.getInstance(callingUserId);
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
SearchResultPage searchResultPage = impl.globalQuery(
queryExpression,
new SearchSpec(searchSpecBundle));
@@ -221,7 +221,7 @@ public class AppSearchManagerService extends SystemService {
// TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
// opened it
try {
- AppSearchImpl impl = ImplInstanceManager.getInstance(callingUserId);
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
invokeCallbackOnResult(callback,
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
@@ -238,7 +238,7 @@ public class AppSearchManagerService extends SystemService {
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
try {
- AppSearchImpl impl = ImplInstanceManager.getInstance(callingUserId);
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
impl.invalidateNextPageToken(nextPageToken);
} catch (Throwable t) {
Log.d(TAG, "Unable to invalidate the query page token", t);
@@ -257,10 +257,10 @@ public class AppSearchManagerService extends SystemService {
int callingUid = Binder.getCallingUidOrThrow();
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
+ AppSearchBatchResult.Builder<String, Void> resultBuilder =
+ new AppSearchBatchResult.Builder<>();
try {
- AppSearchBatchResult.Builder<String, Void> resultBuilder =
- new AppSearchBatchResult.Builder<>();
- AppSearchImpl impl = ImplInstanceManager.getInstance(callingUserId);
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
for (int i = 0; i < uris.size(); i++) {
String uri = uris.get(i);
@@ -293,7 +293,7 @@ public class AppSearchManagerService extends SystemService {
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
try {
- AppSearchImpl impl = ImplInstanceManager.getInstance(callingUserId);
+ AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
impl.removeByQuery(databaseName, queryExpression,
new SearchSpec(searchSpecBundle));
@@ -312,7 +312,7 @@ public class AppSearchManagerService extends SystemService {
int callingUserId = UserHandle.getUserId(callingUid);
final long callingIdentity = Binder.clearCallingIdentity();
try {
- ImplInstanceManager.getOrCreateInstance(getContext(), callingUserId);
+ ImplInstanceManager.getInstance(getContext(), callingUserId);
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
} catch (Throwable t) {
invokeCallbackOnError(callback, t);
@@ -374,14 +374,13 @@ public class AppSearchManagerService extends SystemService {
}
/**
- * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
+ * Invokes the {@link IAppSearchBatchResultCallback} with an throwable.
*
* <p>The throwable is converted to {@link ParcelableException}.
*/
private void invokeCallbackOnError(IAppSearchBatchResultCallback callback,
Throwable throwable) {
try {
- //TODO(b/175067650) verify ParcelableException could propagate throwable correctly.
callback.onSystemError(new ParcelableException(throwable));
} catch (RemoteException e) {
Log.d(TAG, "Unable to send error to the callback", e);
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
index d26269132c5a..2871eb622f11 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
@@ -41,7 +41,7 @@ public final class ImplInstanceManager {
private ImplInstanceManager() {}
/**
- * Gets an instance of AppSearchImpl for the given user, or creates one if none exists.
+ * Gets an instance of AppSearchImpl for the given user.
*
* <p>If no AppSearchImpl instance exists for this user, Icing will be initialized and one will
* be created.
@@ -51,7 +51,7 @@ public final class ImplInstanceManager {
* @return An initialized {@link AppSearchImpl} for this user
*/
@NonNull
- public static AppSearchImpl getOrCreateInstance(@NonNull Context context, @UserIdInt int userId)
+ public static AppSearchImpl getInstance(@NonNull Context context, @UserIdInt int userId)
throws AppSearchException {
AppSearchImpl instance = sInstances.get(userId);
if (instance == null) {
@@ -66,28 +66,6 @@ public final class ImplInstanceManager {
return instance;
}
- /**
- * Gets an instance of AppSearchImpl for the given user.
- *
- * <p>This method should only be called by an initialized SearchSession, which has been already
- * created the AppSearchImpl instance for the given user.
- *
- * @param userId The multi-user userId of the device user calling AppSearch
- * @return An initialized {@link AppSearchImpl} for this user
- */
- @NonNull
- public static AppSearchImpl getInstance(@UserIdInt int userId) {
- AppSearchImpl instance = sInstances.get(userId);
- if (instance == null) {
- // Impossible scenario, user cannot call an uninitialized SearchSession,
- // getInstance should always find the instance for the given user and never try to
- // create an instance for this user again.
- throw new IllegalStateException(
- "AppSearchImpl has never been created for this user: " + userId);
- }
- return instance;
- }
-
private static AppSearchImpl createImpl(@NonNull Context context, @UserIdInt int userId)
throws AppSearchException {
File appSearchDir = getAppSearchDir(context, userId);
diff --git a/core/api/current.txt b/core/api/current.txt
index 026e155fa258..e88811569049 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -141,6 +141,7 @@ package android {
field public static final String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES";
field public static final String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
+ field public static final String REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE = "android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE";
field public static final String REQUEST_PASSWORD_COMPLEXITY = "android.permission.REQUEST_PASSWORD_COMPLEXITY";
field @Deprecated public static final String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
@@ -9520,6 +9521,8 @@ package android.companion {
method @NonNull public java.util.List<java.lang.String> getAssociations();
method public boolean hasNotificationAccess(android.content.ComponentName);
method public void requestNotificationAccess(android.content.ComponentName);
+ method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
+ method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
field public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE";
}
@@ -9540,6 +9543,9 @@ package android.companion {
public interface DeviceFilter<D extends android.os.Parcelable> extends android.os.Parcelable {
}
+ public class DeviceNotAssociatedException extends java.lang.Exception {
+ }
+
public final class WifiDeviceFilter implements android.companion.DeviceFilter<android.net.wifi.ScanResult> {
method public int describeContents();
method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -41076,6 +41082,28 @@ package android.telephony {
field public static final int IP_VERSION_MISMATCH = 2055; // 0x807
field public static final int IRAT_HANDOVER_FAILED = 2194; // 0x892
field public static final int IS707B_MAX_ACCESS_PROBES = 2089; // 0x829
+ field public static final int IWLAN_AUTHORIZATION_REJECTED = 9003; // 0x232b
+ field public static final int IWLAN_DNS_RESOLUTION_NAME_FAILURE = 16388; // 0x4004
+ field public static final int IWLAN_DNS_RESOLUTION_TIMEOUT = 16389; // 0x4005
+ field public static final int IWLAN_IKEV2_AUTH_FAILURE = 16385; // 0x4001
+ field public static final int IWLAN_IKEV2_CERT_INVALID = 16387; // 0x4003
+ field public static final int IWLAN_IKEV2_CONFIG_FAILURE = 16384; // 0x4000
+ field public static final int IWLAN_IKEV2_MSG_TIMEOUT = 16386; // 0x4002
+ field public static final int IWLAN_ILLEGAL_ME = 9006; // 0x232e
+ field public static final int IWLAN_IMEI_NOT_ACCEPTED = 11005; // 0x2afd
+ field public static final int IWLAN_MAX_CONNECTION_REACHED = 8193; // 0x2001
+ field public static final int IWLAN_NETWORK_FAILURE = 10500; // 0x2904
+ field public static final int IWLAN_NON_3GPP_ACCESS_TO_EPC_NOT_ALLOWED = 9000; // 0x2328
+ field public static final int IWLAN_NO_APN_SUBSCRIPTION = 9002; // 0x232a
+ field public static final int IWLAN_PDN_CONNECTION_REJECTION = 8192; // 0x2000
+ field public static final int IWLAN_PLMN_NOT_ALLOWED = 11011; // 0x2b03
+ field public static final int IWLAN_RAT_TYPE_NOT_ALLOWED = 11001; // 0x2af9
+ field public static final int IWLAN_SEMANTIC_ERRORS_IN_PACKET_FILTERS = 8244; // 0x2034
+ field public static final int IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION = 8241; // 0x2031
+ field public static final int IWLAN_SYNTACTICAL_ERRORS_IN_PACKET_FILTERS = 8245; // 0x2035
+ field public static final int IWLAN_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION = 8242; // 0x2032
+ field public static final int IWLAN_UNAUTHENTICATED_EMERGENCY_NOT_SUPPORTED = 11055; // 0x2b2f
+ field public static final int IWLAN_USER_UNKNOWN = 9001; // 0x2329
field public static final int LIMITED_TO_IPV4 = 2234; // 0x8ba
field public static final int LIMITED_TO_IPV6 = 2235; // 0x8bb
field public static final int LLC_SNDCP = 25; // 0x19
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ed6dea815e4c..6d564a3ce61c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -6681,8 +6681,7 @@ public final class ActivityThread extends ClientTransactionHandler {
private InstrumentationInfo prepareInstrumentation(AppBindData data) {
final InstrumentationInfo ii;
try {
- ii = new ApplicationPackageManager(
- null, getPackageManager(), getPermissionManager())
+ ii = new ApplicationPackageManager(null, getPackageManager())
.getInstrumentationInfo(data.instrumentationName, 0);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 3642d318e820..186d1fede5e0 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -59,8 +59,6 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageManager.Property;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
@@ -95,8 +93,6 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
-import android.permission.IOnPermissionsChangeListener;
-import android.permission.IPermissionManager;
import android.permission.PermissionManager;
import android.provider.Settings;
import android.system.ErrnoException;
@@ -106,7 +102,6 @@ import android.system.StructStat;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
-import android.util.DebugUtils;
import android.util.LauncherIcons;
import android.util.Log;
@@ -129,7 +124,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -137,14 +131,6 @@ import java.util.Set;
public class ApplicationPackageManager extends PackageManager {
private static final String TAG = "ApplicationPackageManager";
private static final boolean DEBUG_ICONS = false;
- /**
- * Note: Changing this won't do anything on it's own - you should also change the filtering in
- * {@link #shouldTraceGrant}
- *
- * @hide
- */
- public static final boolean DEBUG_TRACE_GRANTS = false;
- public static final boolean DEBUG_TRACE_PERMISSION_UPDATES = false;
private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384; // 16KB
@@ -171,6 +157,8 @@ public class ApplicationPackageManager extends PackageManager {
@GuardedBy("mLock")
private UserManager mUserManager;
@GuardedBy("mLock")
+ private PermissionManager mPermissionManager;
+ @GuardedBy("mLock")
private PackageInstaller mInstaller;
@GuardedBy("mLock")
private ArtManager mArtManager;
@@ -190,6 +178,15 @@ public class ApplicationPackageManager extends PackageManager {
}
}
+ private PermissionManager getPermissionManager() {
+ synchronized (mLock) {
+ if (mPermissionManager == null) {
+ mPermissionManager = mContext.getSystemService(PermissionManager.class);
+ }
+ return mPermissionManager;
+ }
+ }
+
@Override
public int getUserId() {
return mContext.getUserId();
@@ -355,66 +352,41 @@ public class ApplicationPackageManager extends PackageManager {
@Override
@SuppressWarnings("unchecked")
public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
- try {
- final ParceledListSlice<PermissionGroupInfo> parceledList =
- mPermissionManager.getAllPermissionGroups(flags);
- if (parceledList == null) {
- return Collections.emptyList();
- }
- return parceledList.getList();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().getAllPermissionGroups(flags);
}
@Override
public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags)
throws NameNotFoundException {
- try {
- final PermissionGroupInfo pgi =
- mPermissionManager.getPermissionGroupInfo(groupName, flags);
- if (pgi != null) {
- return pgi;
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ final PermissionGroupInfo permissionGroupInfo = getPermissionManager()
+ .getPermissionGroupInfo(groupName, flags);
+ if (permissionGroupInfo == null) {
+ throw new NameNotFoundException(groupName);
}
- throw new NameNotFoundException(groupName);
+ return permissionGroupInfo;
}
@Override
public PermissionInfo getPermissionInfo(String permName, int flags)
throws NameNotFoundException {
- try {
- final String packageName = mContext.getOpPackageName();
- final PermissionInfo pi =
- mPermissionManager.getPermissionInfo(permName, packageName, flags);
- if (pi != null) {
- return pi;
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ final PermissionInfo permissionInfo = getPermissionManager().getPermissionInfo(permName,
+ flags);
+ if (permissionInfo == null) {
+ throw new NameNotFoundException(permName);
}
- throw new NameNotFoundException(permName);
+ return permissionInfo;
}
@Override
@SuppressWarnings("unchecked")
public List<PermissionInfo> queryPermissionsByGroup(String groupName, int flags)
throws NameNotFoundException {
- try {
- final ParceledListSlice<PermissionInfo> parceledList =
- mPermissionManager.queryPermissionsByGroup(groupName, flags);
- if (parceledList != null) {
- final List<PermissionInfo> pi = parceledList.getList();
- if (pi != null) {
- return pi;
- }
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ final List<PermissionInfo> permissionInfos = getPermissionManager().queryPermissionsByGroup(
+ groupName, flags);
+ if (permissionInfos == null) {
+ throw new NameNotFoundException(groupName);
}
- throw new NameNotFoundException(groupName);
+ return permissionInfos;
}
@Override
@@ -724,11 +696,7 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
- try {
- return mPermissionManager.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().isPermissionRevokedByPolicy(pkgName, permName);
}
/**
@@ -750,50 +718,23 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public boolean addPermission(PermissionInfo info) {
- try {
- return mPermissionManager.addPermission(info, false);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().addPermission(info, false);
}
@Override
public boolean addPermissionAsync(PermissionInfo info) {
- try {
- return mPermissionManager.addPermission(info, true);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().addPermission(info, true);
}
@Override
public void removePermission(String name) {
- try {
- mPermissionManager.removePermission(name);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ getPermissionManager().removePermission(name);
}
@Override
public void grantRuntimePermission(String packageName, String permissionName,
UserHandle user) {
- if (DEBUG_TRACE_GRANTS
- && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
- Log.i(TAG, "App " + mContext.getPackageName() + " is granting " + packageName + " "
- + permissionName + " for user " + user.getIdentifier(), new RuntimeException());
- }
- try {
- mPM.grantRuntimePermission(packageName, permissionName, user.getIdentifier());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- public static boolean shouldTraceGrant(String packageName, String permissionName, int userId) {
- // To be modified when debugging
- return false;
+ getPermissionManager().grantRuntimePermission(packageName, permissionName, user);
}
@Override
@@ -804,124 +745,55 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public void revokeRuntimePermission(String packageName, String permName, UserHandle user,
String reason) {
- if (DEBUG_TRACE_PERMISSION_UPDATES
- && shouldTraceGrant(packageName, permName, user.getIdentifier())) {
- Log.i(TAG, "App " + mContext.getPackageName() + " is revoking " + packageName + " "
- + permName + " for user " + user.getIdentifier() + " with reason " + reason,
- new RuntimeException());
- }
- try {
- mPermissionManager
- .revokeRuntimePermission(packageName, permName, user.getIdentifier(), reason);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ getPermissionManager().revokeRuntimePermission(packageName, permName, user, reason);
}
@Override
public int getPermissionFlags(String permName, String packageName, UserHandle user) {
- try {
- return mPermissionManager
- .getPermissionFlags(permName, packageName, user.getIdentifier());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().getPermissionFlags(packageName, permName, user);
}
@Override
public void updatePermissionFlags(String permName, String packageName,
int flagMask, int flagValues, UserHandle user) {
- if (DEBUG_TRACE_PERMISSION_UPDATES
- && shouldTraceGrant(packageName, permName, user.getIdentifier())) {
- Log.i(TAG, "App " + mContext.getPackageName() + " is updating flags for "
- + packageName + " "
- + permName + " for user " + user.getIdentifier() + ": "
- + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_", flagMask)
- + " := " + DebugUtils.flagsToString(
- PackageManager.class, "FLAG_PERMISSION_", flagValues),
- new RuntimeException());
- }
- try {
- final boolean checkAdjustPolicyFlagPermission =
- mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q;
- mPermissionManager.updatePermissionFlags(permName, packageName, flagMask,
- flagValues, checkAdjustPolicyFlagPermission, user.getIdentifier());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ getPermissionManager().updatePermissionFlags(packageName, permName, flagMask, flagValues,
+ user);
}
@Override
public @NonNull Set<String> getWhitelistedRestrictedPermissions(
@NonNull String packageName, @PermissionWhitelistFlags int flags) {
- try {
- final int userId = getUserId();
- final List<String> whitelist = mPermissionManager
- .getWhitelistedRestrictedPermissions(packageName, flags, userId);
- if (whitelist != null) {
- return new ArraySet<>(whitelist);
- }
- return Collections.emptySet();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().getAllowlistedRestrictedPermissions(packageName, flags);
}
@Override
public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
@NonNull String permName, @PermissionWhitelistFlags int flags) {
- try {
- final int userId = getUserId();
- return mPermissionManager
- .addWhitelistedRestrictedPermission(packageName, permName, flags, userId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().addAllowlistedRestrictedPermission(packageName, permName,
+ flags);
}
@Override
- public boolean setAutoRevokeWhitelisted(
- @NonNull String packageName, boolean whitelisted) {
- try {
- final int userId = getUserId();
- return mPermissionManager.setAutoRevokeWhitelisted(packageName, whitelisted, userId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ public boolean setAutoRevokeWhitelisted(@NonNull String packageName, boolean whitelisted) {
+ return getPermissionManager().setAutoRevokeExempted(packageName, whitelisted);
}
@Override
public boolean isAutoRevokeWhitelisted(@NonNull String packageName) {
- try {
- final int userId = getUserId();
- return mPermissionManager.isAutoRevokeWhitelisted(packageName, userId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().isAutoRevokeExempted(packageName);
}
@Override
public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
@NonNull String permName, @PermissionWhitelistFlags int flags) {
- try {
- final int userId = getUserId();
- return mPermissionManager
- .removeWhitelistedRestrictedPermission(packageName, permName, flags, userId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().removeAllowlistedRestrictedPermission(packageName, permName,
+ flags);
}
@Override
@UnsupportedAppUsage
public boolean shouldShowRequestPermissionRationale(String permName) {
- try {
- final String packageName = mContext.getPackageName();
- return mPermissionManager
- .shouldShowRequestPermissionRationale(permName, packageName, getUserId());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getPermissionManager().shouldShowRequestPermissionRationale(permName);
}
@Override
@@ -1880,34 +1752,12 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
- synchronized (mPermissionListeners) {
- if (mPermissionListeners.get(listener) != null) {
- return;
- }
- OnPermissionsChangeListenerDelegate delegate =
- new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper());
- try {
- mPermissionManager.addOnPermissionsChangeListener(delegate);
- mPermissionListeners.put(listener, delegate);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
+ getPermissionManager().addOnPermissionsChangeListener(listener);
}
@Override
public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
- synchronized (mPermissionListeners) {
- IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener);
- if (delegate != null) {
- try {
- mPermissionManager.removeOnPermissionsChangeListener(delegate);
- mPermissionListeners.remove(listener);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
+ getPermissionManager().removeOnPermissionsChangeListener(listener);
}
@UnsupportedAppUsage
@@ -1918,11 +1768,9 @@ public class ApplicationPackageManager extends PackageManager {
}
}
- protected ApplicationPackageManager(ContextImpl context, IPackageManager pm,
- IPermissionManager permissionManager) {
+ protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
mContext = context;
mPM = pm;
- mPermissionManager = permissionManager;
}
/**
@@ -3234,7 +3082,6 @@ public class ApplicationPackageManager extends PackageManager {
private final ContextImpl mContext;
@UnsupportedAppUsage
private final IPackageManager mPM;
- private final IPermissionManager mPermissionManager;
/** Assume locked until we hear otherwise */
private volatile boolean mUserUnlocked = false;
@@ -3245,41 +3092,6 @@ public class ApplicationPackageManager extends PackageManager {
private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
= new ArrayMap<ResourceName, WeakReference<CharSequence>>();
- private final Map<OnPermissionsChangedListener, IOnPermissionsChangeListener>
- mPermissionListeners = new ArrayMap<>();
-
- public class OnPermissionsChangeListenerDelegate extends IOnPermissionsChangeListener.Stub
- implements Handler.Callback{
- private static final int MSG_PERMISSIONS_CHANGED = 1;
-
- private final OnPermissionsChangedListener mListener;
- private final Handler mHandler;
-
-
- public OnPermissionsChangeListenerDelegate(OnPermissionsChangedListener listener,
- Looper looper) {
- mListener = listener;
- mHandler = new Handler(looper, this);
- }
-
- @Override
- public void onPermissionsChanged(int uid) {
- mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_PERMISSIONS_CHANGED: {
- final int uid = msg.arg1;
- mListener.onPermissionsChanged(uid);
- return true;
- }
- }
- return false;
- }
- }
-
@Override
public boolean canRequestPackageInstalls() {
try {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 2fec9f79717a..124cf71edc9c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -72,7 +72,6 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
-import android.permission.IPermissionManager;
import android.permission.PermissionManager;
import android.system.ErrnoException;
import android.system.Os;
@@ -370,10 +369,9 @@ class ContextImpl extends Context {
}
final IPackageManager pm = ActivityThread.getPackageManager();
- final IPermissionManager permissionManager = ActivityThread.getPermissionManager();
- if (pm != null && permissionManager != null) {
+ if (pm != null) {
// Doesn't matter if we make more than one instance.
- return (mPackageManager = new ApplicationPackageManager(this, pm, permissionManager));
+ return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index fe382a33a8c5..2da5e001a3e4 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -27,7 +27,6 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
-import android.graphics.Rect;
import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;
@@ -187,22 +186,6 @@ public class TaskInfo {
public boolean isResizeable;
/**
- * Activity bounds if this task or its top activity is presented in letterbox mode and
- * {@code null} otherwise.
- * @hide
- */
- @Nullable
- public Rect letterboxActivityBounds;
-
- /**
- * Activity insets if this task or its top activity is presented in letterbox mode and
- * {@code null} otherwise.
- * @hide
- */
- @Nullable
- public Rect letterboxActivityInsets;
-
- /**
* Relative position of the task's top left corner in the parent container.
* @hide
*/
@@ -223,12 +206,6 @@ public class TaskInfo {
public int parentTaskId;
/**
- * Parent bounds.
- * @hide
- */
- public Rect parentBounds;
-
- /**
* Whether this task is focused.
* @hide
*/
@@ -320,7 +297,6 @@ public class TaskInfo {
return topActivityType == that.topActivityType
&& isResizeable == that.isResizeable
&& Objects.equals(positionInParent, that.positionInParent)
- && equalsLetterboxParams(that)
&& Objects.equals(pictureInPictureParams, that.pictureInPictureParams)
&& getWindowingMode() == that.getWindowingMode()
&& Objects.equals(taskDescription, that.taskDescription)
@@ -328,18 +304,6 @@ public class TaskInfo {
&& isVisible == that.isVisible;
}
- private boolean equalsLetterboxParams(TaskInfo that) {
- return Objects.equals(letterboxActivityBounds, that.letterboxActivityBounds)
- && Objects.equals(
- getConfiguration().windowConfiguration.getBounds(),
- that.getConfiguration().windowConfiguration.getBounds())
- && Objects.equals(
- getConfiguration().windowConfiguration.getMaxBounds(),
- that.getConfiguration().windowConfiguration.getMaxBounds())
- && Objects.equals(parentBounds, that.parentBounds)
- && Objects.equals(letterboxActivityInsets, that.letterboxActivityInsets);
- }
-
/**
* Reads the TaskInfo from a parcel.
*/
@@ -368,13 +332,10 @@ public class TaskInfo {
topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
isResizeable = source.readBoolean();
source.readBinderList(launchCookies);
- letterboxActivityBounds = source.readTypedObject(Rect.CREATOR);
positionInParent = source.readTypedObject(Point.CREATOR);
parentTaskId = source.readInt();
- parentBounds = source.readTypedObject(Rect.CREATOR);
isFocused = source.readBoolean();
isVisible = source.readBoolean();
- letterboxActivityInsets = source.readTypedObject(Rect.CREATOR);
}
/**
@@ -406,13 +367,10 @@ public class TaskInfo {
dest.writeTypedObject(topActivityInfo, flags);
dest.writeBoolean(isResizeable);
dest.writeBinderList(launchCookies);
- dest.writeTypedObject(letterboxActivityBounds, flags);
dest.writeTypedObject(positionInParent, flags);
dest.writeInt(parentTaskId);
- dest.writeTypedObject(parentBounds, flags);
dest.writeBoolean(isFocused);
dest.writeBoolean(isVisible);
- dest.writeTypedObject(letterboxActivityInsets, flags);
}
@Override
@@ -433,13 +391,10 @@ public class TaskInfo {
+ " pictureInPictureParams=" + pictureInPictureParams
+ " topActivityInfo=" + topActivityInfo
+ " launchCookies=" + launchCookies
- + " letterboxActivityBounds=" + letterboxActivityBounds
+ " positionInParent=" + positionInParent
+ " parentTaskId=" + parentTaskId
- + " parentBounds=" + parentBounds
+ " isFocused=" + isFocused
+ " isVisible=" + isVisible
- + " letterboxActivityInsets=" + letterboxActivityInsets
+ "}";
}
}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index c3c270e52eb6..59646f106db5 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -34,6 +34,7 @@ import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
+import android.util.ExceptionUtils;
import android.util.Log;
import java.util.Collections;
@@ -321,6 +322,77 @@ public final class CompanionDeviceManager {
}
}
+ /**
+ * Register to receive callbacks whenever the associated device comes in and out of range.
+ *
+ * The provided device must be {@link #associate associated} with the calling app before
+ * calling this method.
+ *
+ * Caller must implement a single {@link CompanionDeviceService} which will be bound to and
+ * receive callbacks to {@link CompanionDeviceService#onDeviceAppeared} and
+ * {@link CompanionDeviceService#onDeviceDisappeared}.
+ * The app doesn't need to remain running in order to receive its callbacks.
+ *
+ * Calling app must declare uses-permission
+ * {@link android.Manifest.permission#REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE}.
+ *
+ * Calling app must check for feature presence of
+ * {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} before calling this API.
+ *
+ * @param deviceAddress a previously-associated companion device's address
+ *
+ * @throws DeviceNotAssociatedException if the given device was not previously associated
+ * with this app.
+ */
+ @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE)
+ public void startObservingDevicePresence(@NonNull String deviceAddress)
+ throws DeviceNotAssociatedException {
+ if (!checkFeaturePresent()) {
+ return;
+ }
+ Objects.requireNonNull(deviceAddress, "address cannot be null");
+ try {
+ mService.registerDevicePresenceListenerService(
+ mContext.getPackageName(), deviceAddress);
+ } catch (RemoteException e) {
+ ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Unregister for receiving callbacks whenever the associated device comes in and out of range.
+ *
+ * The provided device must be {@link #associate associated} with the calling app before
+ * calling this method.
+ *
+ * Calling app must declare uses-permission
+ * {@link android.Manifest.permission#REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE}.
+ *
+ * Calling app must check for feature presence of
+ * {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} before calling this API.
+ *
+ * @param deviceAddress a previously-associated companion device's address
+ *
+ * @throws DeviceNotAssociatedException if the given device was not previously associated
+ * with this app.
+ */
+ @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE)
+ public void stopObservingDevicePresence(@NonNull String deviceAddress)
+ throws DeviceNotAssociatedException {
+ if (!checkFeaturePresent()) {
+ return;
+ }
+ Objects.requireNonNull(deviceAddress, "address cannot be null");
+ try {
+ mService.unregisterDevicePresenceListenerService(
+ mContext.getPackageName(), deviceAddress);
+ } catch (RemoteException e) {
+ ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private boolean checkFeaturePresent() {
boolean featurePresent = mService != null;
if (!featurePresent && DEBUG) {
diff --git a/core/java/android/companion/DeviceNotAssociatedException.java b/core/java/android/companion/DeviceNotAssociatedException.java
new file mode 100644
index 000000000000..bebb6c9ff7eb
--- /dev/null
+++ b/core/java/android/companion/DeviceNotAssociatedException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.companion;
+
+import android.annotation.Nullable;
+
+/**
+ * An exception for a case when a given device was not
+ * {@link CompanionDeviceManager#associate associated} to the calling app.
+ */
+public class DeviceNotAssociatedException extends Exception {
+ /** @hide */
+ public DeviceNotAssociatedException(@Nullable String deviceName) {
+ super("Device not associated with the current app: " + deviceName);
+ }
+}
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index bcb9be80e6a4..527d8df94ea0 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -45,4 +45,8 @@ interface ICompanionDeviceManager {
boolean isDeviceAssociatedForWifiConnection(in String packageName, in String macAddress,
int userId);
+
+ void registerDevicePresenceListenerService(in String packageName, in String deviceAddress);
+
+ void unregisterDevicePresenceListenerService(in String packageName, in String deviceAddress);
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index cf3f7069c63f..67a1ad676348 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4438,6 +4438,7 @@ public abstract class PackageManager {
* @throws NameNotFoundException if a package with the given name cannot be
* found on the system.
*/
+ //@Deprecated
public abstract PermissionInfo getPermissionInfo(@NonNull String permName,
@PermissionInfoFlags int flags) throws NameNotFoundException;
@@ -4450,9 +4451,10 @@ public abstract class PackageManager {
* @param flags Additional option flags to modify the data returned.
* @return Returns a list of {@link PermissionInfo} containing information
* about all of the permissions in the given group.
- * @throws NameNotFoundException if a package with the given name cannot be
+ * @throws NameNotFoundException if a group with the given name cannot be
* found on the system.
*/
+ //@Deprecated
@NonNull
public abstract List<PermissionInfo> queryPermissionsByGroup(@NonNull String permissionGroup,
@PermissionInfoFlags int flags) throws NameNotFoundException;
@@ -4481,7 +4483,7 @@ public abstract class PackageManager {
* Retrieve all of the information we know about a particular group of
* permissions.
*
- * @param permName The fully qualified name (i.e.
+ * @param groupName The fully qualified name (i.e.
* com.google.permission_group.APPS) of the permission you are
* interested in.
* @param flags Additional option flags to modify the data returned.
@@ -4490,8 +4492,9 @@ public abstract class PackageManager {
* @throws NameNotFoundException if a package with the given name cannot be
* found on the system.
*/
+ //@Deprecated
@NonNull
- public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String permName,
+ public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String groupName,
@PermissionGroupInfoFlags int flags) throws NameNotFoundException;
/**
@@ -4501,6 +4504,7 @@ public abstract class PackageManager {
* @return Returns a list of {@link PermissionGroupInfo} containing
* information about all of the known permission groups.
*/
+ //@Deprecated
@NonNull
public abstract List<PermissionGroupInfo> getAllPermissionGroups(
@PermissionGroupInfoFlags int flags);
@@ -4757,6 +4761,7 @@ public abstract class PackageManager {
* @return Whether the permission is restricted by policy.
*/
@CheckResult
+ //@Deprecated
public abstract boolean isPermissionRevokedByPolicy(@NonNull String permName,
@NonNull String packageName);
@@ -4805,6 +4810,7 @@ public abstract class PackageManager {
*
* @see #removePermission(String)
*/
+ //@Deprecated
public abstract boolean addPermission(@NonNull PermissionInfo info);
/**
@@ -4814,6 +4820,7 @@ public abstract class PackageManager {
* expense of no guarantee the added permission will be retained if
* the device is rebooted before it is written.
*/
+ //@Deprecated
public abstract boolean addPermissionAsync(@NonNull PermissionInfo info);
/**
@@ -4829,6 +4836,7 @@ public abstract class PackageManager {
*
* @see #addPermission(PermissionInfo)
*/
+ //@Deprecated
public abstract void removePermission(@NonNull String permName);
/**
@@ -4881,6 +4889,7 @@ public abstract class PackageManager {
*
* @hide
*/
+ //@Deprecated
@SuppressWarnings("HiddenAbstractMethod")
@SystemApi
@RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
@@ -4908,6 +4917,7 @@ public abstract class PackageManager {
*
* @hide
*/
+ //@Deprecated
@SuppressWarnings("HiddenAbstractMethod")
@SystemApi
@RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
@@ -4936,6 +4946,7 @@ public abstract class PackageManager {
*
* @hide
*/
+ //@Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
public void revokeRuntimePermission(@NonNull String packageName,
@@ -4953,6 +4964,7 @@ public abstract class PackageManager {
*
* @hide
*/
+ //@Deprecated
@SuppressWarnings("HiddenAbstractMethod")
@SystemApi
@RequiresPermission(anyOf = {
@@ -4976,6 +4988,7 @@ public abstract class PackageManager {
*
* @hide
*/
+ //@Deprecated
@SuppressWarnings("HiddenAbstractMethod")
@SystemApi
@RequiresPermission(anyOf = {
@@ -5040,6 +5053,7 @@ public abstract class PackageManager {
*
* @throws SecurityException if you try to access a whitelist that you have no access to.
*/
+ //@Deprecated
@RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
conditional = true)
public @NonNull Set<String> getWhitelistedRestrictedPermissions(
@@ -5106,6 +5120,7 @@ public abstract class PackageManager {
*
* @throws SecurityException if you try to modify a whitelist that you have no access to.
*/
+ //@Deprecated
@RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
conditional = true)
public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
@@ -5175,6 +5190,7 @@ public abstract class PackageManager {
*
* @throws SecurityException if you try to modify a whitelist that you have no access to.
*/
+ //@Deprecated
@RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
conditional = true)
public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
@@ -5207,6 +5223,7 @@ public abstract class PackageManager {
*
* @throws SecurityException if you you have no access to modify this.
*/
+ //@Deprecated
@RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS,
conditional = true)
public boolean setAutoRevokeWhitelisted(@NonNull String packageName, boolean whitelisted) {
@@ -5234,6 +5251,7 @@ public abstract class PackageManager {
*
* @throws SecurityException if you you have no access to this.
*/
+ //@Deprecated
@RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS,
conditional = true)
public boolean isAutoRevokeWhitelisted(@NonNull String packageName) {
@@ -5252,6 +5270,7 @@ public abstract class PackageManager {
*
* @hide
*/
+ //@Deprecated
@SuppressWarnings("HiddenAbstractMethod")
@UnsupportedAppUsage
public abstract boolean shouldShowRequestPermissionRationale(@NonNull String permName);
@@ -7554,6 +7573,7 @@ public abstract class PackageManager {
*
* @hide
*/
+ //@Deprecated
@SuppressWarnings("HiddenAbstractMethod")
@SystemApi
@RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
@@ -7567,6 +7587,7 @@ public abstract class PackageManager {
*
* @hide
*/
+ //@Deprecated
@SuppressWarnings("HiddenAbstractMethod")
@SystemApi
@RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 7afba1a214b8..41cc12f3b2e3 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -2856,10 +2856,10 @@ public abstract class CameraMetadata<TKey> {
* respective color channel provided in
* {@link CaptureRequest#SENSOR_TEST_PATTERN_DATA android.sensor.testPatternData}.</p>
* <p>For example:</p>
- * <pre><code>android.testPatternData = [0, 0xFFFFFFFF, 0xFFFFFFFF, 0]
+ * <pre><code>android.control.testPatternData = [0, 0xFFFFFFFF, 0xFFFFFFFF, 0]
* </code></pre>
* <p>All green pixels are 100% green. All red/blue pixels are black.</p>
- * <pre><code>android.testPatternData = [0xFFFFFFFF, 0, 0xFFFFFFFF, 0]
+ * <pre><code>android.control.testPatternData = [0xFFFFFFFF, 0, 0xFFFFFFFF, 0]
* </code></pre>
* <p>All red pixels are 100% red. Only the odd green pixels
* are 100% green. All blue pixels are 100% black.</p>
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index e1d900528f07..25d84bab89e2 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -321,16 +321,6 @@ interface INetworkManagementService
void setFirewallChainEnabled(int chain, boolean enable);
/**
- * Set all packets from users in ranges to go through VPN specified by netId.
- */
- void addVpnUidRanges(int netId, in UidRange[] ranges);
-
- /**
- * Clears the special VPN rules for users in ranges and VPN specified by netId.
- */
- void removeVpnUidRanges(int netId, in UidRange[] ranges);
-
- /**
* Start listening for mobile activity state changes.
*/
void registerNetworkActivityListener(INetworkActivityListener listener);
@@ -361,7 +351,5 @@ interface INetworkManagementService
void removeInterfaceFromLocalNetwork(String iface);
int removeRoutesFromLocalNetwork(in List<RouteInfo> routes);
- void setAllowOnlyVpnForUids(boolean enable, in UidRange[] uidRanges);
-
boolean isNetworkRestricted(int uid);
}
diff --git a/core/java/android/os/RemoteException.java b/core/java/android/os/RemoteException.java
index 98c66d1beaf4..e9fc2f38072b 100644
--- a/core/java/android/os/RemoteException.java
+++ b/core/java/android/os/RemoteException.java
@@ -37,6 +37,11 @@ public class RemoteException extends AndroidException {
super(message, cause, enableSuppression, writableStackTrace);
}
+ /** @hide */
+ public RemoteException(Throwable cause) {
+ this(cause.getMessage(), cause, true, false);
+ }
+
/**
* Rethrow this as an unchecked runtime exception.
* <p>
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 3940bd62950c..d31e0129fb27 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -19,6 +19,7 @@ package android.permission;
import static android.os.Build.VERSION_CODES.S;
import android.Manifest;
+import android.annotation.CheckResult;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -36,11 +37,22 @@ import android.compat.annotation.EnabledAfter;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
import android.content.pm.permission.SplitPermissionInfoParcelable;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.DebugUtils;
+import android.util.Log;
import android.util.Slog;
import com.android.internal.annotations.Immutable;
@@ -60,7 +72,7 @@ import java.util.Set;
@SystemApi
@SystemService(Context.PERMISSION_SERVICE)
public final class PermissionManager {
- private static final String TAG = PermissionManager.class.getName();
+ private static final String LOG_TAG = PermissionManager.class.getName();
/** @hide */
public static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
@@ -80,6 +92,18 @@ public final class PermissionManager {
@EnabledAfter(targetSdkVersion = S)
public static final long CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS = 146211400;
+ /**
+ * Note: Changing this won't do anything on its own - you should also change the filtering in
+ * {@link #shouldTraceGrant}.
+ *
+ * @hide
+ */
+ public static final boolean DEBUG_TRACE_GRANTS = false;
+ /**
+ * @hide
+ */
+ public static final boolean DEBUG_TRACE_PERMISSION_UPDATES = false;
+
private final @NonNull Context mContext;
private final IPackageManager mPackageManager;
@@ -88,6 +112,9 @@ public final class PermissionManager {
private final LegacyPermissionManager mLegacyPermissionManager;
+ private final ArrayMap<PackageManager.OnPermissionsChangedListener,
+ IOnPermissionsChangeListener> mPermissionListeners = new ArrayMap<>();
+
private List<SplitPermissionInfo> mSplitPermissionInfos;
/**
@@ -107,6 +134,649 @@ public final class PermissionManager {
}
/**
+ * Retrieve all of the information we know about a particular permission.
+ *
+ * @param permissionName the fully qualified name (e.g. com.android.permission.LOGIN) of the
+ * permission you are interested in
+ * @param flags additional option flags to modify the data returned
+ * @return a {@link PermissionInfo} containing information about the permission, or {@code null}
+ * if not found
+ *
+ * @hide Pending API
+ */
+ @Nullable
+ public PermissionInfo getPermissionInfo(@NonNull String permissionName,
+ @PackageManager.PermissionInfoFlags int flags) {
+ try {
+ final String packageName = mContext.getOpPackageName();
+ return mPermissionManager.getPermissionInfo(permissionName, packageName, flags);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Query for all of the permissions associated with a particular group.
+ *
+ * @param groupName the fully qualified name (e.g. com.android.permission.LOGIN) of the
+ * permission group you are interested in. Use {@code null} to find all of the
+ * permissions not associated with a group
+ * @param flags additional option flags to modify the data returned
+ * @return a list of {@link PermissionInfo} containing information about all of the permissions
+ * in the given group, or {@code null} if the group is not found
+ *
+ * @hide Pending API
+ */
+ @Nullable
+ public List<PermissionInfo> queryPermissionsByGroup(@NonNull String groupName,
+ @PackageManager.PermissionInfoFlags int flags) {
+ try {
+ final ParceledListSlice<PermissionInfo> parceledList =
+ mPermissionManager.queryPermissionsByGroup(groupName, flags);
+ if (parceledList == null) {
+ return null;
+ }
+ return parceledList.getList();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Add a new dynamic permission to the system. For this to work, your package must have defined
+ * a permission tree through the
+ * {@link android.R.styleable#AndroidManifestPermissionTree &lt;permission-tree&gt;} tag in its
+ * manifest. A package can only add permissions to trees that were defined by either its own
+ * package or another with the same user id; a permission is in a tree if it matches the name of
+ * the permission tree + ".": for example, "com.foo.bar" is a member of the permission tree
+ * "com.foo".
+ * <p>
+ * It is good to make your permission tree name descriptive, because you are taking possession
+ * of that entire set of permission names. Thus, it must be under a domain you control, with a
+ * suffix that will not match any normal permissions that may be declared in any applications
+ * that are part of that domain.
+ * <p>
+ * New permissions must be added before any .apks are installed that use those permissions.
+ * Permissions you add through this method are remembered across reboots of the device. If the
+ * given permission already exists, the info you supply here will be used to update it.
+ *
+ * @param permissionInfo description of the permission to be added
+ * @param async whether the persistence of the permission should be asynchronous, allowing it to
+ * return quicker and batch a series of adds, at the expense of no guarantee the
+ * added permission will be retained if the device is rebooted before it is
+ * written.
+ * @return {@code true} if a new permission was created, {@code false} if an existing one was
+ * updated
+ * @throws SecurityException if you are not allowed to add the given permission name
+ *
+ * @see #removePermission(String)
+ *
+ * @hide Pending API
+ */
+ public boolean addPermission(@NonNull PermissionInfo permissionInfo, boolean async) {
+ try {
+ return mPermissionManager.addPermission(permissionInfo, async);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Removes a permission that was previously added with
+ * {@link #addPermission(PermissionInfo, boolean)}. The same ownership rules apply -- you are
+ * only allowed to remove permissions that you are allowed to add.
+ *
+ * @param permissionName the name of the permission to remove
+ * @throws SecurityException if you are not allowed to remove the given permission name
+ *
+ * @see #addPermission(PermissionInfo, boolean)
+ *
+ * @hide Pending API
+ */
+ public void removePermission(@NonNull String permissionName) {
+ try {
+ mPermissionManager.removePermission(permissionName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Retrieve all of the information we know about a particular group of permissions.
+ *
+ * @param groupName the fully qualified name (e.g. com.android.permission_group.APPS) of the
+ * permission you are interested in
+ * @param flags additional option flags to modify the data returned
+ * @return a {@link PermissionGroupInfo} containing information about the permission, or
+ * {@code null} if not found
+ *
+ * @hide Pending API
+ */
+ @Nullable
+ public PermissionGroupInfo getPermissionGroupInfo(@NonNull String groupName,
+ @PackageManager.PermissionGroupInfoFlags int flags) {
+ try {
+ return mPermissionManager.getPermissionGroupInfo(groupName, flags);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Retrieve all of the known permission groups in the system.
+ *
+ * @param flags additional option flags to modify the data returned
+ * @return a list of {@link PermissionGroupInfo} containing information about all of the known
+ * permission groups
+ *
+ * @hide Pending API
+ */
+ @NonNull
+ public List<PermissionGroupInfo> getAllPermissionGroups(
+ @PackageManager.PermissionGroupInfoFlags int flags) {
+ try {
+ final ParceledListSlice<PermissionGroupInfo> parceledList =
+ mPermissionManager.getAllPermissionGroups(flags);
+ if (parceledList == null) {
+ return Collections.emptyList();
+ }
+ return parceledList.getList();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Checks whether a particular permissions has been revoked for a package by policy. Typically
+ * the device owner or the profile owner may apply such a policy. The user cannot grant policy
+ * revoked permissions, hence the only way for an app to get such a permission is by a policy
+ * change.
+ *
+ * @param packageName the name of the package you are checking against
+ * @param permissionName the name of the permission you are checking for
+ *
+ * @return whether the permission is restricted by policy
+ *
+ * @hide Pending API
+ */
+ @CheckResult
+ public boolean isPermissionRevokedByPolicy(@NonNull String packageName,
+ @NonNull String permissionName) {
+ try {
+ return mPermissionManager.isPermissionRevokedByPolicy(permissionName, packageName,
+ mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /** @hide */
+ public static boolean shouldTraceGrant(String packageName, String permissionName, int userId) {
+ // To be modified when debugging
+ return false;
+ }
+
+ /**
+ * Grant a runtime permission to an application which the application does not already have. The
+ * permission must have been requested by the application. If the application is not allowed to
+ * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or
+ * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown.
+ * <p>
+ * <strong>Note: </strong>Using this API requires holding
+ * {@code android.permission.GRANT_RUNTIME_PERMISSIONS} and if the user ID is not the current
+ * user {@code android.permission.INTERACT_ACROSS_USERS_FULL}.
+ *
+ * @param packageName the package to which to grant the permission
+ * @param permissionName the permission name to grant
+ * @param user the user for which to grant the permission
+ *
+ * @see #revokeRuntimePermission(String, String, android.os.UserHandle)
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
+ //@SystemApi
+ public void grantRuntimePermission(@NonNull String packageName,
+ @NonNull String permissionName, @NonNull UserHandle user) {
+ if (DEBUG_TRACE_GRANTS
+ && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
+ Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is granting " + packageName + " "
+ + permissionName + " for user " + user.getIdentifier(), new RuntimeException());
+ }
+ try {
+ mPermissionManager.grantRuntimePermission(packageName, permissionName,
+ user.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Revoke a runtime permission that was previously granted by
+ * {@link #grantRuntimePermission(String, String, android.os.UserHandle)}. The permission must
+ * have been requested by and granted to the application. If the application is not allowed to
+ * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or
+ * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown.
+ * <p>
+ * <strong>Note: </strong>Using this API requires holding
+ * {@code android.permission.REVOKE_RUNTIME_PERMISSIONS} and if the user ID is not the current
+ * user {@code android.permission.INTERACT_ACROSS_USERS_FULL}.
+ *
+ * @param packageName the package from which to revoke the permission
+ * @param permName the permission name to revoke
+ * @param user the user for which to revoke the permission
+ * @param reason the reason for the revoke, or {@code null} for unspecified
+ *
+ * @see #grantRuntimePermission(String, String, android.os.UserHandle)
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
+ //@SystemApi
+ public void revokeRuntimePermission(@NonNull String packageName,
+ @NonNull String permName, @NonNull UserHandle user, @Nullable String reason) {
+ if (DEBUG_TRACE_PERMISSION_UPDATES
+ && shouldTraceGrant(packageName, permName, user.getIdentifier())) {
+ Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is revoking " + packageName + " "
+ + permName + " for user " + user.getIdentifier() + " with reason "
+ + reason, new RuntimeException());
+ }
+ try {
+ mPermissionManager
+ .revokeRuntimePermission(packageName, permName, user.getIdentifier(), reason);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Gets the state flags associated with a permission.
+ *
+ * @param packageName the package name for which to get the flags
+ * @param permissionName the permission for which to get the flags
+ * @param user the user for which to get permission flags
+ * @return the permission flags
+ *
+ * @hide
+ */
+ @PackageManager.PermissionFlags
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
+ android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
+ android.Manifest.permission.GET_RUNTIME_PERMISSIONS
+ })
+ //@SystemApi
+ public int getPermissionFlags(@NonNull String packageName, @NonNull String permissionName,
+ @NonNull UserHandle user) {
+ try {
+ return mPermissionManager.getPermissionFlags(permissionName, packageName,
+ user.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Updates the flags associated with a permission by replacing the flags in the specified mask
+ * with the provided flag values.
+ *
+ * @param packageName The package name for which to update the flags
+ * @param permissionName The permission for which to update the flags
+ * @param flagMask The flags which to replace
+ * @param flagValues The flags with which to replace
+ * @param user The user for which to update the permission flags
+ *
+ * @hide
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
+ android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
+ })
+ //@SystemApi
+ public void updatePermissionFlags(@NonNull String packageName, @NonNull String permissionName,
+ @PackageManager.PermissionFlags int flagMask,
+ @PackageManager.PermissionFlags int flagValues, @NonNull UserHandle user) {
+ if (DEBUG_TRACE_PERMISSION_UPDATES && shouldTraceGrant(packageName, permissionName,
+ user.getIdentifier())) {
+ Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is updating flags for "
+ + packageName + " " + permissionName + " for user "
+ + user.getIdentifier() + ": " + DebugUtils.flagsToString(
+ PackageManager.class, "FLAG_PERMISSION_", flagMask) + " := "
+ + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_",
+ flagValues), new RuntimeException());
+ }
+ try {
+ final boolean checkAdjustPolicyFlagPermission =
+ mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q;
+ mPermissionManager.updatePermissionFlags(permissionName, packageName, flagMask,
+ flagValues, checkAdjustPolicyFlagPermission, user.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Gets the restricted permissions that have been allowlisted and the app is allowed to have
+ * them granted in their full form.
+ * <p>
+ * Permissions can be hard restricted which means that the app cannot hold them or soft
+ * restricted where the app can hold the permission but in a weaker form. Whether a permission
+ * is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard restricted} or
+ * {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted} depends on the permission
+ * declaration. Allowlisting a hard restricted permission allows for the to hold that permission
+ * and allowlisting a soft restricted permission allows the app to hold the permission in its
+ * full, unrestricted form.
+ * <p>
+ * There are four allowlists:
+ * <ol>
+ * <li>
+ * One for cases where the system permission policy allowlists a permission. This list
+ * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM} flag. Can only be
+ * accessed by pre-installed holders of a dedicated permission.
+ * <li>
+ * One for cases where the system allowlists the permission when upgrading from an OS version in
+ * which the permission was not restricted to an OS version in which the permission is
+ * restricted. This list corresponds to the
+ * {@link PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by
+ * pre-installed holders of a dedicated permission or the installer on record.
+ * <li>
+ * One for cases where the installer of the package allowlists a permission. This list
+ * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be
+ * accessed by pre-installed holders of a dedicated permission or the installer on record.
+ * <li>
+ * One for cases where the system exempts the permission when granting a role. This list
+ * corresponds to the {@link PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE} flag. Can be
+ * accessed by pre-installed holders of a dedicated permission.
+ * </ol>
+ *
+ * @param packageName the app for which to get allowlisted permissions
+ * @param allowlistFlag the flag to determine which allowlist to query. Only one flag can be
+ * passed.
+ * @return the allowlisted permissions that are on any of the allowlists you query for
+ * @throws SecurityException if you try to access a allowlist that you have no access to
+ *
+ * @see #addAllowlistedRestrictedPermission(String, String, int)
+ * @see #removeAllowlistedRestrictedPermission(String, String, int)
+ * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM
+ * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE
+ * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER
+ * @see PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE
+ *
+ * @hide Pending API
+ */
+ @NonNull
+ @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
+ conditional = true)
+ public Set<String> getAllowlistedRestrictedPermissions(@NonNull String packageName,
+ @PackageManager.PermissionWhitelistFlags int allowlistFlag) {
+ try {
+ final List<String> allowlist = mPermissionManager.getWhitelistedRestrictedPermissions(
+ packageName, allowlistFlag, mContext.getUserId());
+ if (allowlist == null) {
+ return Collections.emptySet();
+ }
+ return new ArraySet<>(allowlist);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Adds a allowlisted restricted permission for an app.
+ * <p>
+ * Permissions can be hard restricted which means that the app cannot hold them or soft
+ * restricted where the app can hold the permission but in a weaker form. Whether a permission
+ * is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard restricted} or
+ * {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted} depends on the permission
+ * declaration. Allowlisting a hard restricted permission allows for the to hold that permission
+ * and allowlisting a soft restricted permission allows the app to hold the permission in its
+ * full, unrestricted form.
+ * <p>There are four allowlists:
+ * <ol>
+ * <li>
+ * One for cases where the system permission policy allowlists a permission. This list
+ * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM} flag. Can only be
+ * accessed by pre-installed holders of a dedicated permission.
+ * <li>
+ * One for cases where the system allowlists the permission when upgrading from an OS version in
+ * which the permission was not restricted to an OS version in which the permission is
+ * restricted. This list corresponds to the
+ * {@link PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by
+ * pre-installed holders of a dedicated permission or the installer on record.
+ * <li>
+ * One for cases where the installer of the package allowlists a permission. This list
+ * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be
+ * accessed by pre-installed holders of a dedicated permission or the installer on record.
+ * <li>
+ * One for cases where the system exempts the permission when granting a role. This list
+ * corresponds to the {@link PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE} flag. Can be
+ * accessed by pre-installed holders of a dedicated permission.
+ * </ol>
+ * <p>
+ * You need to specify the allowlists for which to set the allowlisted permissions which will
+ * clear the previous allowlisted permissions and replace them with the provided ones.
+ *
+ * @param packageName the app for which to get allowlisted permissions
+ * @param permissionName the allowlisted permission to add
+ * @param allowlistFlags the allowlists to which to add. Passing multiple flags updates all
+ * specified allowlists.
+ * @return whether the permission was added to the allowlist
+ * @throws SecurityException if you try to modify a allowlist that you have no access to.
+ *
+ * @see #getAllowlistedRestrictedPermissions(String, int)
+ * @see #removeAllowlistedRestrictedPermission(String, String, int)
+ * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM
+ * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE
+ * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER
+ * @see PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE
+ *
+ * @hide Pending API
+ */
+ @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
+ conditional = true)
+ public boolean addAllowlistedRestrictedPermission(@NonNull String packageName,
+ @NonNull String permissionName,
+ @PackageManager.PermissionWhitelistFlags int allowlistFlags) {
+ try {
+ return mPermissionManager.addWhitelistedRestrictedPermission(packageName,
+ permissionName, allowlistFlags, mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Removes a allowlisted restricted permission for an app.
+ * <p>
+ * Permissions can be hard restricted which means that the app cannot hold them or soft
+ * restricted where the app can hold the permission but in a weaker form. Whether a permission
+ * is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard restricted} or
+ * {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted} depends on the permission
+ * declaration. Allowlisting a hard restricted permission allows for the to hold that permission
+ * and allowlisting a soft restricted permission allows the app to hold the permission in its
+ * full, unrestricted form.
+ * <p>There are four allowlists:
+ * <ol>
+ * <li>
+ * One for cases where the system permission policy allowlists a permission. This list
+ * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM} flag. Can only be
+ * accessed by pre-installed holders of a dedicated permission.
+ * <li>
+ * One for cases where the system allowlists the permission when upgrading from an OS version in
+ * which the permission was not restricted to an OS version in which the permission is
+ * restricted. This list corresponds to the
+ * {@link PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by
+ * pre-installed holders of a dedicated permission or the installer on record.
+ * <li>
+ * One for cases where the installer of the package allowlists a permission. This list
+ * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be
+ * accessed by pre-installed holders of a dedicated permission or the installer on record.
+ * <li>
+ * One for cases where the system exempts the permission when granting a role. This list
+ * corresponds to the {@link PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE} flag. Can be
+ * accessed by pre-installed holders of a dedicated permission.
+ * </ol>
+ * <p>
+ * You need to specify the allowlists for which to set the allowlisted permissions which will
+ * clear the previous allowlisted permissions and replace them with the provided ones.
+ *
+ * @param packageName the app for which to get allowlisted permissions
+ * @param permissionName the allowlisted permission to remove
+ * @param allowlistFlags the allowlists from which to remove. Passing multiple flags updates all
+ * specified allowlists.
+ * @return whether the permission was removed from the allowlist
+ * @throws SecurityException if you try to modify a allowlist that you have no access to.
+ *
+ * @see #getAllowlistedRestrictedPermissions(String, int)
+ * @see #addAllowlistedRestrictedPermission(String, String, int)
+ * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM
+ * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE
+ * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER
+ * @see PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE
+ *
+ * @hide Pending API
+ */
+ @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
+ conditional = true)
+ public boolean removeAllowlistedRestrictedPermission(@NonNull String packageName,
+ @NonNull String permissionName,
+ @PackageManager.PermissionWhitelistFlags int allowlistFlags) {
+ try {
+ return mPermissionManager.removeWhitelistedRestrictedPermission(packageName,
+ permissionName, allowlistFlags, mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Checks whether an application is exempted from having its permissions be automatically
+ * revoked when the app is unused for an extended period of time.
+ * <p>
+ * Only the installer on record that installed the given package, or a holder of
+ * {@code WHITELIST_AUTO_REVOKE_PERMISSIONS} is allowed to call this.
+ *
+ * @param packageName the app for which to set exemption
+ * @return whether the app is exempted
+ * @throws SecurityException if you you have no access to this
+ *
+ * @see #setAutoRevokeExempted
+ *
+ * @hide Pending API
+ */
+ @RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS,
+ conditional = true)
+ public boolean isAutoRevokeExempted(@NonNull String packageName) {
+ try {
+ return mPermissionManager.isAutoRevokeWhitelisted(packageName, mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Marks an application exempted from having its permissions be automatically revoked when the
+ * app is unused for an extended period of time.
+ * <p>
+ * Only the installer on record that installed the given package is allowed to call this.
+ * <p>
+ * Packages start in exempted state, and it is the installer's responsibility to un-exempt the
+ * packages it installs, unless auto-revoking permissions from that package would cause
+ * breakages beyond having to re-request the permission(s).
+ *
+ * @param packageName the app for which to set exemption
+ * @param exempted whether the app should be exempted
+ * @return whether any change took effect
+ * @throws SecurityException if you you have no access to modify this
+ *
+ * @see #isAutoRevokeExempted
+ *
+ * @hide Pending API
+ */
+ @RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS,
+ conditional = true)
+ public boolean setAutoRevokeExempted(@NonNull String packageName, boolean exempted) {
+ try {
+ return mPermissionManager.setAutoRevokeWhitelisted(packageName, exempted,
+ mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get whether you should show UI with rationale for requesting a permission. You should do this
+ * only if you do not have the permission and the context in which the permission is requested
+ * does not clearly communicate to the user what would be the benefit from grating this
+ * permission.
+ *
+ * @param permissionName a permission your app wants to request
+ * @return whether you can show permission rationale UI
+ *
+ * @hide
+ */
+ //@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public boolean shouldShowRequestPermissionRationale(@NonNull String permissionName) {
+ try {
+ final String packageName = mContext.getPackageName();
+ return mPermissionManager.shouldShowRequestPermissionRationale(permissionName,
+ packageName, mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Add a listener for permission changes for installed packages.
+ *
+ * @param listener the listener to add
+ *
+ * @hide
+ */
+ //@SystemApi
+ @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
+ public void addOnPermissionsChangeListener(
+ @NonNull PackageManager.OnPermissionsChangedListener listener) {
+ synchronized (mPermissionListeners) {
+ if (mPermissionListeners.get(listener) != null) {
+ return;
+ }
+ final OnPermissionsChangeListenerDelegate delegate =
+ new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper());
+ try {
+ mPermissionManager.addOnPermissionsChangeListener(delegate);
+ mPermissionListeners.put(listener, delegate);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Remove a listener for permission changes for installed packages.
+ *
+ * @param listener the listener to remove
+ *
+ * @hide
+ */
+ //@SystemApi
+ @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
+ public void removeOnPermissionsChangeListener(
+ @NonNull PackageManager.OnPermissionsChangedListener listener) {
+ synchronized (mPermissionListeners) {
+ final IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener);
+ if (delegate != null) {
+ try {
+ mPermissionManager.removeOnPermissionsChangeListener(delegate);
+ mPermissionListeners.remove(listener);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+ }
+
+ /**
* Gets the version of the runtime permission database.
*
* @return The database version, -1 when this is an upgrade from pre-Q, 0 when this is a fresh
@@ -174,7 +844,7 @@ public final class PermissionManager {
try {
parcelableList = ActivityThread.getPermissionManager().getSplitPermissions();
} catch (RemoteException e) {
- Slog.e(TAG, "Error getting split permissions", e);
+ Slog.e(LOG_TAG, "Error getting split permissions", e);
return Collections.emptyList();
}
@@ -403,10 +1073,11 @@ public final class PermissionManager {
// permission this is.
final int appId = UserHandle.getAppId(uid);
if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
- Slog.w(TAG, "Missing ActivityManager; assuming " + uid + " holds " + permission);
+ Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " holds "
+ + permission);
return PackageManager.PERMISSION_GRANTED;
}
- Slog.w(TAG, "Missing ActivityManager; assuming " + uid + " does not hold "
+ Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " does not hold "
+ permission);
return PackageManager.PERMISSION_DENIED;
}
@@ -586,4 +1257,35 @@ public final class PermissionManager {
sPackageNamePermissionCache.disableLocal();
}
+ private final class OnPermissionsChangeListenerDelegate
+ extends IOnPermissionsChangeListener.Stub implements Handler.Callback{
+ private static final int MSG_PERMISSIONS_CHANGED = 1;
+
+ private final PackageManager.OnPermissionsChangedListener mListener;
+ private final Handler mHandler;
+
+ public OnPermissionsChangeListenerDelegate(
+ PackageManager.OnPermissionsChangedListener listener, Looper looper) {
+ mListener = listener;
+ mHandler = new Handler(looper, this);
+ }
+
+ @Override
+ public void onPermissionsChanged(int uid) {
+ mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
+ }
+
+ @Override
+ public boolean handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_PERMISSIONS_CHANGED: {
+ final int uid = msg.arg1;
+ mListener.onPermissionsChanged(uid);
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+ }
}
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index 6ef9e7e3d9b8..017f40521a81 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -16,18 +16,18 @@
package android.security.keymaster;
-import android.hardware.keymint.Algorithm;
-import android.hardware.keymint.BlockMode;
-import android.hardware.keymint.Digest;
-import android.hardware.keymint.ErrorCode;
-import android.hardware.keymint.HardwareAuthenticatorType;
-import android.hardware.keymint.KeyFormat;
-import android.hardware.keymint.KeyOrigin;
-import android.hardware.keymint.KeyPurpose;
-import android.hardware.keymint.PaddingMode;
-import android.hardware.keymint.SecurityLevel;
-import android.hardware.keymint.Tag;
-import android.hardware.keymint.TagType;
+import android.hardware.security.keymint.Algorithm;
+import android.hardware.security.keymint.BlockMode;
+import android.hardware.security.keymint.Digest;
+import android.hardware.security.keymint.ErrorCode;
+import android.hardware.security.keymint.HardwareAuthenticatorType;
+import android.hardware.security.keymint.KeyFormat;
+import android.hardware.security.keymint.KeyOrigin;
+import android.hardware.security.keymint.KeyPurpose;
+import android.hardware.security.keymint.PaddingMode;
+import android.hardware.security.keymint.SecurityLevel;
+import android.hardware.security.keymint.Tag;
+import android.hardware.security.keymint.TagType;
import java.util.HashMap;
import java.util.Map;
diff --git a/core/java/android/service/textservice/OWNERS b/core/java/android/service/textservice/OWNERS
index a637754ba17a..10b8b7637431 100644
--- a/core/java/android/service/textservice/OWNERS
+++ b/core/java/android/service/textservice/OWNERS
@@ -1,5 +1,3 @@
# Bug component: 34867
-ogunwale@google.com
-roosa@google.com
-yukawa@google.com
+include ../../inputmethodservice/OWNERS \ No newline at end of file
diff --git a/core/java/android/util/ExceptionUtils.java b/core/java/android/util/ExceptionUtils.java
index 1a397b39ef3c..4b511acc280f 100644
--- a/core/java/android/util/ExceptionUtils.java
+++ b/core/java/android/util/ExceptionUtils.java
@@ -98,4 +98,6 @@ public class ExceptionUtils {
}
return t;
}
+
+
} \ No newline at end of file
diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl
index f209d88ac825..cac91a9f07d7 100644
--- a/core/java/android/view/IRecentsAnimationController.aidl
+++ b/core/java/android/view/IRecentsAnimationController.aidl
@@ -136,4 +136,13 @@ interface IRecentsAnimationController {
* @return {@code true} when target removed successfully, {@code false} otherwise.
*/
boolean removeTask(int taskId);
+
+ /**
+ * Detach navigation bar from app.
+ *
+ * The system reparents the leash of navigation bar to the app when the recents animation starts
+ * and Launcher should call this method to let system restore the navigation bar to its
+ * original position when the quick switch gesture is finished.
+ */
+ void detachNavigationBarFromApp();
}
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index 5196c3e88eec..72fa4c39f1bc 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -8,6 +8,7 @@ nduca@google.com
sumir@google.com
ogunwale@google.com
jjaggi@google.com
+roosa@google.com
# Display
per-file Display*.java = file:/services/core/java/com/android/server/display/OWNERS
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 607888c81357..15adc5a0ec2f 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -239,7 +239,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private static boolean useBlastAdapter(Context context) {
ContentResolver contentResolver = context.getContentResolver();
return Settings.Global.getInt(contentResolver,
- Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_SV, 1 /* default */) == 1;
+ Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_SV, 0 /* default */) == 1;
}
private final boolean mUseBlastAdapter;
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 16fd383fa7ff..3c18b6b89af8 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -43,6 +43,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
+import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
import android.util.TimeUtils;
@@ -334,15 +335,22 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
if (!mEvents.isEmpty() && eventType == TYPE_VIEW_TEXT_CHANGED) {
final ContentCaptureEvent lastEvent = mEvents.get(mEvents.size() - 1);
- // TODO(b/121045053): check if flags match
+ // We merge two consecutive text change event, unless one of them clears the text.
if (lastEvent.getType() == TYPE_VIEW_TEXT_CHANGED
&& lastEvent.getId().equals(event.getId())) {
- if (sVerbose) {
+ boolean bothNonEmpty = !TextUtils.isEmpty(lastEvent.getText())
+ && !TextUtils.isEmpty(event.getText());
+ boolean equalContent = TextUtils.equals(lastEvent.getText(), event.getText());
+ if (equalContent) {
+ addEvent = false;
+ } else if (bothNonEmpty) {
+ lastEvent.mergeEvent(event);
+ addEvent = false;
+ }
+ if (!addEvent && sVerbose) {
Log.v(TAG, "Buffering VIEW_TEXT_CHANGED event, updated text="
+ getSanitizedString(event.getText()));
}
- lastEvent.mergeEvent(event);
- addEvent = false;
}
}
diff --git a/core/java/android/view/textservice/OWNERS b/core/java/android/view/textservice/OWNERS
index a637754ba17a..582be8dc4594 100644
--- a/core/java/android/view/textservice/OWNERS
+++ b/core/java/android/view/textservice/OWNERS
@@ -1,5 +1,3 @@
# Bug component: 34867
-ogunwale@google.com
-roosa@google.com
-yukawa@google.com
+include ../inputmethod/OWNERS
diff --git a/core/java/android/widget/OWNERS b/core/java/android/widget/OWNERS
index fbb975b806f1..718076b49f77 100644
--- a/core/java/android/widget/OWNERS
+++ b/core/java/android/widget/OWNERS
@@ -7,3 +7,5 @@ aurimas@google.com
siyamed@google.com
per-file TextView.java, EditText.java, Editor.java = siyamed@google.com, nona@google.com, clarabayarri@google.com
+
+per-file SpellChecker.java = file:../view/inputmethod/OWNERS
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 8012540ed314..254c2997fa65 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -86,6 +86,11 @@ public class LatencyTracker {
*/
public static final int ACTION_FACE_WAKE_AND_UNLOCK = 7;
+ /**
+ * Time between the swipe-up gesture and window drawn of recents activity.
+ */
+ public static final int ACTION_START_RECENTS_ANIMATION = 8;
+
private static final String[] NAMES = new String[]{
"expand panel",
"toggle recents",
@@ -94,7 +99,9 @@ public class LatencyTracker {
"check credential unlocked",
"turn on screen",
"rotate the screen",
- "face wake-and-unlock"};
+ "face wake-and-unlock",
+ "start recents-animation",
+ };
private static final int[] STATSD_ACTION = new int[]{
FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL,
@@ -105,6 +112,7 @@ public class LatencyTracker {
FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_TURN_ON_SCREEN,
FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN,
FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK,
+ FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION,
};
private static LatencyTracker sLatencyTracker;
@@ -170,6 +178,8 @@ public class LatencyTracker {
return "ACTION_ROTATE_SCREEN";
case 8:
return "ACTION_FACE_WAKE_AND_UNLOCK";
+ case 9:
+ return "ACTION_START_RECENTS_ANIMATION";
default:
throw new IllegalArgumentException("Invalid action");
}
diff --git a/core/java/com/android/internal/view/OWNERS b/core/java/com/android/internal/view/OWNERS
new file mode 100644
index 000000000000..99a76861c542
--- /dev/null
+++ b/core/java/com/android/internal/view/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 25700
+
+file:/core/java/android/view/OWNERS
+
+per-file *Input* = file:/services/core/java/com/android/server/inputmethod/OWNERS \ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 648ea390369f..ef7edc2f2dd2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3969,6 +3969,12 @@
<permission android:name="android.permission.MANAGE_COMPANION_DEVICES"
android:protectionLevel="signature" />
+ <!-- Allows an application to subscribe to notifications about the presence status change
+ of their associated companion device
+ -->
+ <permission android:name="android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE"
+ android:protectionLevel="normal" />
+
<!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
<p>Not for use by third-party applications.
@hide
diff --git a/core/res/res/drawable-car/car_switch_thumb.xml b/core/res/res/drawable-car/car_switch_thumb.xml
index 03efc189aa95..66cf4438418d 100644
--- a/core/res/res/drawable-car/car_switch_thumb.xml
+++ b/core/res/res/drawable-car/car_switch_thumb.xml
@@ -14,12 +14,15 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<shape
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="oval">
- <solid android:color="@color/car_switch"/>
- <size
- android:width="@dimen/car_seekbar_thumb_size"
- android:height="@dimen/car_seekbar_thumb_size"/>
-</shape>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:gravity="center_vertical|fill_horizontal"
+ android:top="@dimen/car_switch_thumb_margin_size"
+ android:bottom="@dimen/car_switch_thumb_margin_size">
+ <shape android:shape="oval">
+ <solid android:color="@color/car_switch"/>
+ <size
+ android:width="@dimen/car_switch_thumb_size"
+ android:height="@dimen/car_switch_thumb_size"/>
+ </shape>
+ </item>
+</layer-list>
diff --git a/core/res/res/drawable-car/car_switch_track.xml b/core/res/res/drawable-car/car_switch_track.xml
new file mode 100644
index 000000000000..cb0b9beeeab6
--- /dev/null
+++ b/core/res/res/drawable-car/car_switch_track.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:height="@dimen/car_touch_target_size_minus_one"
+ android:width="@dimen/car_touch_target_size_minus_one"
+ android:gravity="center">
+ <selector>
+ <item android:state_focused="true" android:state_pressed="true">
+ <shape android:shape="oval">
+ <solid android:color="#8A94CBFF"/>
+ <stroke android:width="4dp"
+ android:color="#94CBFF"/>
+ </shape>
+ </item>
+ <item android:state_focused="true">
+ <shape android:shape="oval">
+ <solid android:color="#3D94CBFF"/>
+ <stroke android:width="8dp"
+ android:color="#94CBFF"/>
+ </shape>
+ </item>
+ </selector>
+ </item>
+ <item android:gravity="center_vertical|fill_horizontal"
+ android:left="@dimen/car_switch_track_margin_size"
+ android:right="@dimen/car_switch_track_margin_size">
+ <shape
+ android:shape="rectangle"
+ android:tint="@color/switch_track_material">
+ <corners android:radius="7dp" />
+ <solid android:color="@color/white_disabled_material" />
+ <size android:height="14dp" />
+ <padding
+ android:right="@dimen/car_switch_track_margin_size"
+ android:left="@dimen/car_switch_track_margin_size"/>
+ </shape>
+ </item>
+</layer-list>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 03ba83c6bd2e..cddb8b5802d0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4574,6 +4574,6 @@
<!-- Indicates that default fitness tracker app needs to request sensor and location permissions. -->
<bool name="config_trackerAppNeedsPermissions">false</bool>
- <!-- Component with platform query permissions for AppSearch -->
- <string name="config_defaultAppSearchPlatformQuerierComponent" translatable="false"></string>
+ <!-- Package with global data query permissions for AppSearch -->
+ <string name="config_globalAppSearchDataQuerierPackage" translatable="false"></string>
</resources>
diff --git a/core/res/res/values/dimens_car.xml b/core/res/res/values/dimens_car.xml
index 2c4f4c89ab81..c3cd80b1edda 100644
--- a/core/res/res/values/dimens_car.xml
+++ b/core/res/res/values/dimens_car.xml
@@ -84,6 +84,14 @@
<dimen name="car_button_radius">@dimen/car_radius_1</dimen>
<dimen name="car_pill_button_size">56dp</dimen>
<dimen name="car_touch_target_size">76dp</dimen>
+ <dimen name="car_touch_target_size_minus_one">75dp</dimen>
+
+ <!-- Switch. -->
+ <!-- Thumb size + 2*thumb margin size must equal car_touch_target_size -->
+ <!-- 2 * Thumb size + 2*track margin size must equal car_touch_target_size -->
+ <dimen name="car_switch_thumb_size">24dp</dimen>
+ <dimen name="car_switch_thumb_margin_size">26dp</dimen>
+ <dimen name="car_switch_track_margin_size">14dp</dimen>
<!-- Seekbar -->
<dimen name="car_seekbar_height">6dp</dimen>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index aff0695bb14e..a2556a112941 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4116,8 +4116,8 @@
<java-symbol type="bool" name="config_trackerAppNeedsPermissions"/>
- <!-- Component with platform query permissions for AppSearch -->
- <java-symbol type="string" name="config_defaultAppSearchPlatformQuerierComponent" />
+ <!-- Package with global data query permissions for AppSearch -->
+ <java-symbol type="string" name="config_globalAppSearchDataQuerierPackage" />
<!-- Color used by the accessibility focus rectangle -->
<java-symbol type="color" name="accessibility_focus_highlight_color" />
diff --git a/core/tests/powertests/PowerStatsLoadTests/Android.bp b/core/tests/batterystatstests/BatteryStatsLoadTests/Android.bp
index 66c91adc6540..ade97b81e775 100644
--- a/core/tests/powertests/PowerStatsLoadTests/Android.bp
+++ b/core/tests/batterystatstests/BatteryStatsLoadTests/Android.bp
@@ -1,5 +1,5 @@
android_test {
- name: "PowerStatsLoadTests",
+ name: "BatteryStatsLoadTests",
srcs: ["src/**/*.java"],
static_libs: [
"androidx.test.rules",
diff --git a/core/tests/powertests/PowerStatsLoadTests/AndroidManifest.xml b/core/tests/batterystatstests/BatteryStatsLoadTests/AndroidManifest.xml
index 9cecaedf1380..adc20c6ae496 100644
--- a/core/tests/powertests/PowerStatsLoadTests/AndroidManifest.xml
+++ b/core/tests/batterystatstests/BatteryStatsLoadTests/AndroidManifest.xml
@@ -16,7 +16,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.frameworks.core.powerstatsloadtests">
+ package="com.android.frameworks.core.batterystatsloadtests">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
@@ -27,7 +27,7 @@
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.frameworks.core.powerstatsloadtests"
+ android:targetPackage="com.android.frameworks.core.batterystatsloadtests"
android:label="Power Stats Load Tests" />
<queries>
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/ConnectivitySetupRule.java b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/ConnectivitySetupRule.java
index ca2942647f08..1afc22b7406d 100644
--- a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/ConnectivitySetupRule.java
+++ b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/ConnectivitySetupRule.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsloadtests;
+package com.android.frameworks.core.batterystatsloadtests;
import static org.junit.Assert.assertEquals;
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetrics.java b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/PowerMetrics.java
index 88cb719add60..dbe5773a3107 100644
--- a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetrics.java
+++ b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/PowerMetrics.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsloadtests;
+package com.android.frameworks.core.batterystatsloadtests;
import android.os.Process;
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetricsCollector.java b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/PowerMetricsCollector.java
index a71559b5ad6b..254458cc8935 100644
--- a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetricsCollector.java
+++ b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/PowerMetricsCollector.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsloadtests;
+package com.android.frameworks.core.batterystatsloadtests;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -106,6 +106,7 @@ public class PowerMetricsCollector implements TestRule {
mContext = instrumentation.getContext();
mUid = Process.myUid();
mUserManager = mContext.getSystemService(UserManager.class);
+ // TODO(b/175324611): Use BatteryUsageStats instead
mStatsHelper = new BatteryStatsHelper(mContext, false /* collectBatteryBroadcast */);
mStatsHelper.create((Bundle) null);
}
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/SystemServiceCallLoadTest.java b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/SystemServiceCallLoadTest.java
index 911ccba3ac78..488469d54f29 100644
--- a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/SystemServiceCallLoadTest.java
+++ b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/SystemServiceCallLoadTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsloadtests;
+package com.android.frameworks.core.batterystatsloadtests;
import static org.junit.Assert.assertNotNull;
diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/WiFiLoadTest.java b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/WiFiLoadTest.java
index 90627192946d..27495da8d839 100644
--- a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/WiFiLoadTest.java
+++ b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/WiFiLoadTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsloadtests;
+package com.android.frameworks.core.batterystatsloadtests;
import android.util.Log;
diff --git a/core/tests/powertests/PowerStatsViewer/Android.bp b/core/tests/batterystatstests/BatteryStatsViewer/Android.bp
index a3dc4fb4ff74..1e0498be5800 100644
--- a/core/tests/powertests/PowerStatsViewer/Android.bp
+++ b/core/tests/batterystatstests/BatteryStatsViewer/Android.bp
@@ -1,5 +1,5 @@
android_test {
- name: "PowerStatsViewer",
+ name: "BatteryStatsViewer",
srcs: ["src/**/*.java"],
defaults: ["SettingsLibDefaults"],
static_libs: [
diff --git a/core/tests/powertests/PowerStatsViewer/AndroidManifest.xml b/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
index 28ea05fca61e..edb1b108b7bc 100644
--- a/core/tests/powertests/PowerStatsViewer/AndroidManifest.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/AndroidManifest.xml
@@ -16,7 +16,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.frameworks.core.powerstatsviewer"
+ package="com.android.frameworks.core.batterystatsviewer"
android:sharedUserId="android.uid.system">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
@@ -24,9 +24,9 @@
<application
android:theme="@style/Theme"
- android:label="Power Stats Viewer">
- <activity android:name=".PowerStatsViewerActivity"
- android:label="Power Stats Viewer"
+ android:label="Battery Stats Viewer">
+ <activity android:name=".BatteryStatsViewerActivity"
+ android:label="Battery Stats Viewer"
android:launchMode="singleTop"
android:exported="true">
<intent-filter>
@@ -35,7 +35,7 @@
</intent-filter>
</activity>
- <activity android:name=".PowerConsumerPickerActivity"
- android:label="Select a power consumer"/>
+ <activity android:name=".BatteryConsumerPickerActivity"
+ android:label="Select a battery consumer"/>
</application>
</manifest>
diff --git a/core/tests/powertests/PowerStatsViewer/res/layout/power_stats_entry_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
index 1ced825adf31..1ced825adf31 100644
--- a/core/tests/powertests/PowerStatsViewer/res/layout/power_stats_entry_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_entry_layout.xml
diff --git a/core/tests/powertests/PowerStatsViewer/res/layout/power_consumer_info_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_info_layout.xml
index fbd0ebd61bc7..fbd0ebd61bc7 100644
--- a/core/tests/powertests/PowerStatsViewer/res/layout/power_consumer_info_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_info_layout.xml
diff --git a/core/tests/powertests/PowerStatsViewer/res/layout/power_consumer_picker_activity_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_activity_layout.xml
index ecc89f0cb33e..ecc89f0cb33e 100644
--- a/core/tests/powertests/PowerStatsViewer/res/layout/power_consumer_picker_activity_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_activity_layout.xml
diff --git a/core/tests/powertests/PowerStatsViewer/res/layout/power_consumer_picker_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
index bea38c18c20b..bea38c18c20b 100644
--- a/core/tests/powertests/PowerStatsViewer/res/layout/power_consumer_picker_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_consumer_picker_layout.xml
diff --git a/core/tests/powertests/PowerStatsViewer/res/layout/power_stats_viewer_layout.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
index 238e238deeaa..e58a08fd362c 100644
--- a/core/tests/powertests/PowerStatsViewer/res/layout/power_stats_viewer_layout.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/layout/battery_stats_viewer_layout.xml
@@ -42,13 +42,13 @@
android:paddingStart="10dp"
android:paddingEnd="10dp">
- <include layout="@layout/power_consumer_info_layout"/>
+ <include layout="@layout/battery_consumer_info_layout"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.recyclerview.widget.RecyclerView
- android:id="@+id/power_stats_data_view"
+ android:id="@+id/battery_consumer_data_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
@@ -59,7 +59,7 @@
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
- android:text="No power stats available"/>
+ android:text="No battery stats available"/>
</LinearLayout>
<FrameLayout
diff --git a/core/tests/powertests/PowerStatsViewer/res/values/styles.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml
index 629d729e7b9a..629d729e7b9a 100644
--- a/core/tests/powertests/PowerStatsViewer/res/values/styles.xml
+++ b/core/tests/batterystatstests/BatteryStatsViewer/res/values/styles.xml
diff --git a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
index 6d8e2c59be97..b077ea313b9d 100644
--- a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsviewer;
+package com.android.frameworks.core.batterystatsviewer;
import android.content.Context;
import android.os.BatteryConsumer;
@@ -30,7 +30,7 @@ import com.android.internal.os.BatteryStatsHelper;
import java.util.ArrayList;
import java.util.List;
-public class PowerStatsData {
+public class BatteryConsumerData {
private static final String PACKAGE_CALENDAR_PROVIDER = "com.android.providers.calendar";
private static final String PACKAGE_MEDIA_PROVIDER = "com.android.providers.media";
private static final String PACKAGE_SYSTEMUI = "com.android.systemui";
@@ -58,11 +58,11 @@ public class PowerStatsData {
public double total;
}
- private final PowerConsumerInfoHelper.PowerConsumerInfo mPowerConsumerInfo;
+ private final BatteryConsumerInfoHelper.BatteryConsumerInfo mBatteryConsumerInfo;
private final List<Entry> mEntries = new ArrayList<>();
- public PowerStatsData(Context context, BatteryStatsHelper batteryStatsHelper,
- BatteryUsageStats batteryUsageStats, String powerConsumerId) {
+ public BatteryConsumerData(Context context, BatteryStatsHelper batteryStatsHelper,
+ BatteryUsageStats batteryUsageStats, String batteryConsumerId) {
List<BatterySipper> usageList = batteryStatsHelper.getUsageList();
BatteryStats batteryStats = batteryStatsHelper.getStats();
@@ -102,7 +102,7 @@ public class PowerStatsData {
totalScreenPower = sipper.sumPower();
}
- if (powerConsumerId(sipper).equals(powerConsumerId)) {
+ if (batteryConsumerId(sipper).equals(batteryConsumerId)) {
requestedBatterySipper = sipper;
}
@@ -143,21 +143,20 @@ public class PowerStatsData {
BatteryConsumer requestedBatteryConsumer = null;
for (BatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
- if (powerConsumerId(consumer).equals(powerConsumerId)) {
+ if (batteryConsumerId(consumer).equals(batteryConsumerId)) {
requestedBatteryConsumer = consumer;
break;
}
}
if (requestedBatterySipper == null) {
- mPowerConsumerInfo = null;
+ mBatteryConsumerInfo = null;
return;
}
- long totalScreenMeasuredEnergyUJ = batteryStats.getScreenOnEnergy();
-
- mPowerConsumerInfo = PowerConsumerInfoHelper.makePowerConsumerInfo(
+ mBatteryConsumerInfo = BatteryConsumerInfoHelper.makeBatteryConsumerInfo(
context.getPackageManager(), requestedBatterySipper);
+ long totalScreenMeasuredEnergyUJ = batteryStats.getScreenOnEnergy();
addEntry("Total power", EntryType.POWER,
requestedBatterySipper.totalSmearedPowerMah, totalSmearedPowerMah);
@@ -279,19 +278,19 @@ public class PowerStatsData {
}
}
- public PowerConsumerInfoHelper.PowerConsumerInfo getPowerConsumerInfo() {
- return mPowerConsumerInfo;
+ public BatteryConsumerInfoHelper.BatteryConsumerInfo getBatteryConsumerInfo() {
+ return mBatteryConsumerInfo;
}
public List<Entry> getEntries() {
return mEntries;
}
- public static String powerConsumerId(BatterySipper sipper) {
+ public static String batteryConsumerId(BatterySipper sipper) {
return sipper.drainType + "|" + sipper.userId + "|" + sipper.getUid();
}
- public static String powerConsumerId(BatteryConsumer consumer) {
+ public static String batteryConsumerId(BatteryConsumer consumer) {
if (consumer instanceof UidBatteryConsumer) {
return BatterySipper.DrainType.APP + "|"
+ UserHandle.getUserId(((UidBatteryConsumer) consumer).getUid()) + "|"
diff --git a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerConsumerInfoHelper.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
index 6fec2405b0c6..8ee6c604cb3e 100644
--- a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerConsumerInfoHelper.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsviewer;
+package com.android.frameworks.core.batterystatsviewer;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -26,11 +26,11 @@ import com.android.internal.os.BatterySipper;
import java.util.Locale;
-class PowerConsumerInfoHelper {
+class BatteryConsumerInfoHelper {
private static final String SYSTEM_SERVER_PACKAGE_NAME = "android";
- public static class PowerConsumerInfo {
+ public static class BatteryConsumerInfo {
public String id;
public CharSequence label;
public double powerMah;
@@ -40,10 +40,10 @@ class PowerConsumerInfoHelper {
}
@NonNull
- public static PowerConsumerInfo makePowerConsumerInfo(PackageManager packageManager,
+ public static BatteryConsumerInfo makeBatteryConsumerInfo(PackageManager packageManager,
@NonNull BatterySipper sipper) {
- PowerConsumerInfo info = new PowerConsumerInfo();
- info.id = PowerStatsData.powerConsumerId(sipper);
+ BatteryConsumerInfo info = new BatteryConsumerInfo();
+ info.id = BatteryConsumerData.batteryConsumerId(sipper);
sipper.sumPower();
info.powerMah = sipper.totalSmearedPowerMah;
switch (sipper.drainType) {
diff --git a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerConsumerPickerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
index f56d113980c8..2db848b084a6 100644
--- a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerConsumerPickerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsviewer;
+package com.android.frameworks.core.batterystatsviewer;
import android.content.Context;
import android.content.Intent;
@@ -34,14 +34,14 @@ import com.google.android.material.tabs.TabLayout;
* Picker, showing a sorted lists of applications and other types of entities consuming power.
* Returns the selected entity ID or null.
*/
-public class PowerConsumerPickerActivity extends FragmentActivity {
+public class BatteryConsumerPickerActivity extends FragmentActivity {
public static final ActivityResultContract<Void, String> CONTRACT =
new ActivityResultContract<Void, String>() {
@NonNull
@Override
public Intent createIntent(@NonNull Context context, Void aVoid) {
- return new Intent(context, PowerConsumerPickerActivity.class);
+ return new Intent(context, BatteryConsumerPickerActivity.class);
}
@Override
@@ -58,7 +58,7 @@ public class PowerConsumerPickerActivity extends FragmentActivity {
super.onCreate(icicle);
getActionBar().setDisplayHomeAsUpEnabled(true);
- setContentView(R.layout.power_consumer_picker_activity_layout);
+ setContentView(R.layout.battery_consumer_picker_activity_layout);
ViewPager viewPager = findViewById(R.id.pager);
@@ -75,12 +75,12 @@ public class PowerConsumerPickerActivity extends FragmentActivity {
public Fragment getItem(int position) {
switch (position) {
case 0:
- return new PowerConsumerPickerFragment(
- PowerConsumerPickerFragment.PICKER_TYPE_APP);
+ return new BatteryConsumerPickerFragment(
+ BatteryConsumerPickerFragment.PICKER_TYPE_APP);
case 1:
default:
- return new PowerConsumerPickerFragment(
- PowerConsumerPickerFragment.PICKER_TYPE_DRAIN);
+ return new BatteryConsumerPickerFragment(
+ BatteryConsumerPickerFragment.PICKER_TYPE_DRAIN);
}
}
@@ -101,9 +101,9 @@ public class PowerConsumerPickerActivity extends FragmentActivity {
tabLayout.setupWithViewPager(viewPager);
}
- public void setSelectedPowerConsumer(String id) {
+ public void setSelectedBatteryConsumer(String batteryConsumerId) {
Intent intent = new Intent();
- intent.putExtra(Intent.EXTRA_RETURN_RESULT, id);
+ intent.putExtra(Intent.EXTRA_RETURN_RESULT, batteryConsumerId);
setResult(RESULT_OK, intent);
finish();
}
diff --git a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerConsumerPickerFragment.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java
index 25225b87f602..bb11fd598511 100644
--- a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerConsumerPickerFragment.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsviewer;
+package com.android.frameworks.core.batterystatsviewer;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -36,7 +36,7 @@ import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.frameworks.core.powerstatsviewer.PowerConsumerInfoHelper.PowerConsumerInfo;
+import com.android.frameworks.core.batterystatsviewer.BatteryConsumerInfoHelper.BatteryConsumerInfo;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.settingslib.utils.AsyncLoaderCompat;
@@ -50,7 +50,7 @@ import java.util.Locale;
* Picker, showing a sorted lists of applications or other types of entities consuming power.
* Returns the selected entity ID or null.
*/
-public class PowerConsumerPickerFragment extends Fragment {
+public class BatteryConsumerPickerFragment extends Fragment {
private static final String TAG = "AppPicker";
public static final String PICKER_TYPE = "pickertype";
@@ -58,53 +58,53 @@ public class PowerConsumerPickerFragment extends Fragment {
public static final int PICKER_TYPE_APP = 0;
public static final int PICKER_TYPE_DRAIN = 1;
- private PowerConsumerListAdapter mPowerConsumerListAdapter;
+ private BatteryConsumerListAdapter mBatteryConsumerListAdapter;
private RecyclerView mAppList;
private View mLoadingView;
- private interface OnPowerConsumerSelectedListener {
- void onPowerConsumerSelected(String uid);
+ private interface OnBatteryConsumerSelectedListener {
+ void onBatteryConsumerSelected(String batteryConsumerId);
}
- public PowerConsumerPickerFragment(int pickerType) {
+ public BatteryConsumerPickerFragment(int pickerType) {
Bundle args = new Bundle();
args.putInt(PICKER_TYPE, pickerType);
setArguments(args);
}
- public PowerConsumerPickerFragment() {
+ public BatteryConsumerPickerFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.power_consumer_picker_layout, container, false);
+ View view = inflater.inflate(R.layout.battery_consumer_picker_layout, container, false);
mLoadingView = view.findViewById(R.id.loading_view);
mAppList = view.findViewById(R.id.list_view);
mAppList.setLayoutManager(new LinearLayoutManager(getContext()));
- mPowerConsumerListAdapter = new PowerConsumerListAdapter(
- PowerConsumerPickerFragment.this::setSelectedPowerConsumer);
- mAppList.setAdapter(mPowerConsumerListAdapter);
+ mBatteryConsumerListAdapter = new BatteryConsumerListAdapter(
+ BatteryConsumerPickerFragment.this::setSelectedBatteryConsumer);
+ mAppList.setAdapter(mBatteryConsumerListAdapter);
LoaderManager.getInstance(this).initLoader(0, getArguments(),
- new PowerConsumerListLoaderCallbacks());
+ new BatteryConsumerListLoaderCallbacks());
return view;
}
- public void setSelectedPowerConsumer(String id) {
- ((PowerConsumerPickerActivity) getActivity()).setSelectedPowerConsumer(id);
+ public void setSelectedBatteryConsumer(String id) {
+ ((BatteryConsumerPickerActivity) getActivity()).setSelectedBatteryConsumer(id);
}
- private static class PowerConsumerListLoader extends
- AsyncLoaderCompat<List<PowerConsumerInfo>> {
+ private static class BatteryConsumerListLoader extends
+ AsyncLoaderCompat<List<BatteryConsumerInfo>> {
private final BatteryStatsHelper mStatsHelper;
private final int mPickerType;
private final UserManager mUserManager;
private final PackageManager mPackageManager;
- PowerConsumerListLoader(Context context, int pickerType) {
+ BatteryConsumerListLoader(Context context, int pickerType) {
super(context);
mUserManager = context.getSystemService(UserManager.class);
mStatsHelper = new BatteryStatsHelper(context, false /* collectBatteryBroadcast */);
@@ -115,8 +115,8 @@ public class PowerConsumerPickerFragment extends Fragment {
}
@Override
- public List<PowerConsumerInfo> loadInBackground() {
- List<PowerConsumerInfoHelper.PowerConsumerInfo> powerConsumerList = new ArrayList<>();
+ public List<BatteryConsumerInfo> loadInBackground() {
+ List<BatteryConsumerInfo> batteryConsumerList = new ArrayList<>();
mStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.myUserId());
@@ -135,74 +135,75 @@ public class PowerConsumerPickerFragment extends Fragment {
}
}
- powerConsumerList.add(
- PowerConsumerInfoHelper.makePowerConsumerInfo(mPackageManager, sipper));
+ batteryConsumerList.add(
+ BatteryConsumerInfoHelper.makeBatteryConsumerInfo(mPackageManager, sipper));
}
- powerConsumerList.sort(
- Comparator.comparing((PowerConsumerInfo a) -> a.powerMah).reversed());
- return powerConsumerList;
+ batteryConsumerList.sort(
+ Comparator.comparing((BatteryConsumerInfo a) -> a.powerMah).reversed());
+ return batteryConsumerList;
}
@Override
- protected void onDiscardResult(List<PowerConsumerInfo> result) {
+ protected void onDiscardResult(List<BatteryConsumerInfo> result) {
}
}
- private class PowerConsumerListLoaderCallbacks implements
- LoaderManager.LoaderCallbacks<List<PowerConsumerInfo>> {
+ private class BatteryConsumerListLoaderCallbacks implements
+ LoaderManager.LoaderCallbacks<List<BatteryConsumerInfo>> {
@NonNull
@Override
- public Loader<List<PowerConsumerInfo>> onCreateLoader(int id, Bundle args) {
- return new PowerConsumerListLoader(getContext(), args.getInt(PICKER_TYPE));
+ public Loader<List<BatteryConsumerInfo>> onCreateLoader(int id, Bundle args) {
+ return new BatteryConsumerListLoader(getContext(), args.getInt(PICKER_TYPE));
}
@Override
- public void onLoadFinished(@NonNull Loader<List<PowerConsumerInfo>> loader,
- List<PowerConsumerInfoHelper.PowerConsumerInfo> powerConsumerList) {
- mPowerConsumerListAdapter.setPowerConsumerList(powerConsumerList);
+ public void onLoadFinished(@NonNull Loader<List<BatteryConsumerInfo>> loader,
+ List<BatteryConsumerInfo> batteryConsumerList) {
+ mBatteryConsumerListAdapter.setBatteryConsumerList(batteryConsumerList);
mAppList.setVisibility(View.VISIBLE);
mLoadingView.setVisibility(View.GONE);
}
@Override
public void onLoaderReset(
- @NonNull Loader<List<PowerConsumerInfoHelper.PowerConsumerInfo>> loader) {
+ @NonNull Loader<List<BatteryConsumerInfo>> loader) {
}
}
- public class PowerConsumerListAdapter extends RecyclerView.Adapter<PowerConsumerViewHolder> {
- private final OnPowerConsumerSelectedListener mListener;
- private List<PowerConsumerInfo> mPowerConsumerList;
+ public class BatteryConsumerListAdapter extends
+ RecyclerView.Adapter<BatteryConsumerViewHolder> {
+ private final OnBatteryConsumerSelectedListener mListener;
+ private List<BatteryConsumerInfo> mBatteryConsumerList;
- public PowerConsumerListAdapter(OnPowerConsumerSelectedListener listener) {
+ public BatteryConsumerListAdapter(OnBatteryConsumerSelectedListener listener) {
mListener = listener;
}
- void setPowerConsumerList(List<PowerConsumerInfo> powerConsumerList) {
- mPowerConsumerList = powerConsumerList;
+ void setBatteryConsumerList(List<BatteryConsumerInfo> batteryConsumerList) {
+ mBatteryConsumerList = batteryConsumerList;
notifyDataSetChanged();
}
@Override
public int getItemCount() {
- return mPowerConsumerList.size();
+ return mBatteryConsumerList.size();
}
@NonNull
@Override
- public PowerConsumerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
+ public BatteryConsumerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
int position) {
LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
- View view = layoutInflater.inflate(R.layout.power_consumer_info_layout, viewGroup,
+ View view = layoutInflater.inflate(R.layout.battery_consumer_info_layout, viewGroup,
false);
- return new PowerConsumerViewHolder(view, mListener);
+ return new BatteryConsumerViewHolder(view, mListener);
}
@Override
- public void onBindViewHolder(@NonNull PowerConsumerViewHolder viewHolder, int position) {
- PowerConsumerInfoHelper.PowerConsumerInfo item = mPowerConsumerList.get(position);
+ public void onBindViewHolder(@NonNull BatteryConsumerViewHolder viewHolder, int position) {
+ BatteryConsumerInfo item = mBatteryConsumerList.get(position);
viewHolder.id = item.id;
viewHolder.titleView.setText(item.label);
if (item.details != null) {
@@ -225,9 +226,9 @@ public class PowerConsumerPickerFragment extends Fragment {
}
// View Holder used when displaying apps
- public static class PowerConsumerViewHolder extends RecyclerView.ViewHolder
+ public static class BatteryConsumerViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
- private final OnPowerConsumerSelectedListener mListener;
+ private final OnBatteryConsumerSelectedListener mListener;
public String id;
public TextView titleView;
@@ -236,7 +237,7 @@ public class PowerConsumerPickerFragment extends Fragment {
public TextView packagesView;
public TextView powerView;
- PowerConsumerViewHolder(View view, OnPowerConsumerSelectedListener listener) {
+ BatteryConsumerViewHolder(View view, OnBatteryConsumerSelectedListener listener) {
super(view);
mListener = listener;
view.setOnClickListener(this);
@@ -250,7 +251,7 @@ public class PowerConsumerPickerFragment extends Fragment {
@Override
public void onClick(View v) {
- mListener.onPowerConsumerSelected(id);
+ mListener.onBatteryConsumerSelected(id);
}
}
}
diff --git a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
index 91533913e35d..4978010f8591 100644
--- a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.frameworks.core.powerstatsviewer;
+package com.android.frameworks.core.batterystatsviewer;
import android.content.Context;
import android.content.SharedPreferences;
@@ -47,25 +47,25 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
-public class PowerStatsViewerActivity extends ComponentActivity {
- private static final int POWER_STATS_REFRESH_RATE_MILLIS = 60 * 1000;
- public static final String PREF_SELECTED_POWER_CONSUMER = "powerConsumerId";
+public class BatteryStatsViewerActivity extends ComponentActivity {
+ private static final int BATTERY_STATS_REFRESH_RATE_MILLIS = 60 * 1000;
+ public static final String PREF_SELECTED_BATTERY_CONSUMER = "batteryConsumerId";
public static final int LOADER_BATTERY_STATS_HELPER = 0;
public static final int LOADER_BATTERY_USAGE_STATS = 1;
- private PowerStatsDataAdapter mPowerStatsDataAdapter;
- private Runnable mPowerStatsRefresh = this::periodicPowerStatsRefresh;
+ private BatteryStatsDataAdapter mBatteryStatsDataAdapter;
+ private Runnable mBatteryStatsRefresh = this::periodicBatteryStatsRefresh;
private SharedPreferences mSharedPref;
- private String mPowerConsumerId;
+ private String mBatteryConsumerId;
private TextView mTitleView;
private TextView mDetailsView;
private ImageView mIconView;
private TextView mPackagesView;
- private RecyclerView mPowerStatsDataView;
+ private RecyclerView mBatteryConsumerDataView;
private View mLoadingView;
private View mEmptyView;
private ActivityResultLauncher<Void> mStartAppPicker = registerForActivityResult(
- PowerConsumerPickerActivity.CONTRACT, this::onApplicationSelected);
+ BatteryConsumerPickerActivity.CONTRACT, this::onApplicationSelected);
private BatteryStatsHelper mBatteryStatsHelper;
private BatteryUsageStats mBatteryUsageStats;
@@ -75,7 +75,7 @@ public class PowerStatsViewerActivity extends ComponentActivity {
mSharedPref = getPreferences(Context.MODE_PRIVATE);
- setContentView(R.layout.power_stats_viewer_layout);
+ setContentView(R.layout.battery_stats_viewer_layout);
View appCard = findViewById(R.id.app_card);
appCard.setOnClickListener((e) -> startAppPicker());
@@ -85,17 +85,17 @@ public class PowerStatsViewerActivity extends ComponentActivity {
mIconView = findViewById(android.R.id.icon);
mPackagesView = findViewById(R.id.packages);
- mPowerStatsDataView = findViewById(R.id.power_stats_data_view);
- mPowerStatsDataView.setLayoutManager(new LinearLayoutManager(this));
- mPowerStatsDataAdapter = new PowerStatsDataAdapter();
- mPowerStatsDataView.setAdapter(mPowerStatsDataAdapter);
+ mBatteryConsumerDataView = findViewById(R.id.battery_consumer_data_view);
+ mBatteryConsumerDataView.setLayoutManager(new LinearLayoutManager(this));
+ mBatteryStatsDataAdapter = new BatteryStatsDataAdapter();
+ mBatteryConsumerDataView.setAdapter(mBatteryStatsDataAdapter);
mLoadingView = findViewById(R.id.loading_view);
mEmptyView = findViewById(R.id.empty_view);
- mPowerConsumerId = mSharedPref.getString(PREF_SELECTED_POWER_CONSUMER, null);
- loadPowerStats();
- if (mPowerConsumerId == null) {
+ mBatteryConsumerId = mSharedPref.getString(PREF_SELECTED_BATTERY_CONSUMER, null);
+ loadBatteryStats();
+ if (mBatteryConsumerId == null) {
startAppPicker();
}
}
@@ -103,38 +103,40 @@ public class PowerStatsViewerActivity extends ComponentActivity {
@Override
protected void onResume() {
super.onResume();
- periodicPowerStatsRefresh();
+ periodicBatteryStatsRefresh();
}
@Override
protected void onPause() {
super.onPause();
- getMainThreadHandler().removeCallbacks(mPowerStatsRefresh);
+ getMainThreadHandler().removeCallbacks(mBatteryStatsRefresh);
}
private void startAppPicker() {
mStartAppPicker.launch(null);
}
- private void onApplicationSelected(String powerConsumerId) {
- if (powerConsumerId == null) {
- if (mPowerConsumerId == null) {
+ private void onApplicationSelected(String batteryConsumerId) {
+ if (batteryConsumerId == null) {
+ if (mBatteryConsumerId == null) {
finish();
}
} else {
- mPowerConsumerId = powerConsumerId;
- mSharedPref.edit().putString(PREF_SELECTED_POWER_CONSUMER, mPowerConsumerId).apply();
+ mBatteryConsumerId = batteryConsumerId;
+ mSharedPref.edit()
+ .putString(PREF_SELECTED_BATTERY_CONSUMER, mBatteryConsumerId)
+ .apply();
mLoadingView.setVisibility(View.VISIBLE);
- loadPowerStats();
+ loadBatteryStats();
}
}
- private void periodicPowerStatsRefresh() {
- loadPowerStats();
- getMainThreadHandler().postDelayed(mPowerStatsRefresh, POWER_STATS_REFRESH_RATE_MILLIS);
+ private void periodicBatteryStatsRefresh() {
+ loadBatteryStats();
+ getMainThreadHandler().postDelayed(mBatteryStatsRefresh, BATTERY_STATS_REFRESH_RATE_MILLIS);
}
- private void loadPowerStats() {
+ private void loadBatteryStats() {
LoaderManager loaderManager = LoaderManager.getInstance(this);
loaderManager.restartLoader(LOADER_BATTERY_STATS_HELPER, null,
new BatteryStatsHelperLoaderCallbacks());
@@ -171,7 +173,7 @@ public class PowerStatsViewerActivity extends ComponentActivity {
@NonNull
@Override
public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
- return new BatteryStatsHelperLoader(PowerStatsViewerActivity.this);
+ return new BatteryStatsHelperLoader(BatteryStatsViewerActivity.this);
}
@Override
@@ -207,7 +209,7 @@ public class PowerStatsViewerActivity extends ComponentActivity {
@NonNull
@Override
public Loader<BatteryUsageStats> onCreateLoader(int id, Bundle args) {
- return new BatteryUsageStatsLoader(PowerStatsViewerActivity.this);
+ return new BatteryUsageStatsLoader(BatteryStatsViewerActivity.this);
}
@Override
@@ -223,60 +225,60 @@ public class PowerStatsViewerActivity extends ComponentActivity {
public void onBatteryStatsHelperLoaded(BatteryStatsHelper batteryStatsHelper) {
mBatteryStatsHelper = batteryStatsHelper;
- onPowerStatsDataLoaded();
+ onBatteryStatsDataLoaded();
}
private void onBatteryUsageStatsLoaded(BatteryUsageStats batteryUsageStats) {
mBatteryUsageStats = batteryUsageStats;
- onPowerStatsDataLoaded();
+ onBatteryStatsDataLoaded();
}
- public void onPowerStatsDataLoaded() {
+ public void onBatteryStatsDataLoaded() {
if (mBatteryStatsHelper == null || mBatteryUsageStats == null) {
return;
}
- PowerStatsData powerStatsData = new PowerStatsData(this, mBatteryStatsHelper,
- mBatteryUsageStats, mPowerConsumerId);
+ BatteryConsumerData batteryConsumerData = new BatteryConsumerData(this, mBatteryStatsHelper,
+ mBatteryUsageStats, mBatteryConsumerId);
- PowerConsumerInfoHelper.PowerConsumerInfo
- powerConsumerInfo = powerStatsData.getPowerConsumerInfo();
- if (powerConsumerInfo == null) {
- mTitleView.setText("Power consumer not found");
+ BatteryConsumerInfoHelper.BatteryConsumerInfo
+ batteryConsumerInfo = batteryConsumerData.getBatteryConsumerInfo();
+ if (batteryConsumerInfo == null) {
+ mTitleView.setText("Battery consumer not found");
mPackagesView.setVisibility(View.GONE);
} else {
- mTitleView.setText(powerConsumerInfo.label);
- if (powerConsumerInfo.details != null) {
- mDetailsView.setText(powerConsumerInfo.details);
+ mTitleView.setText(batteryConsumerInfo.label);
+ if (batteryConsumerInfo.details != null) {
+ mDetailsView.setText(batteryConsumerInfo.details);
mDetailsView.setVisibility(View.VISIBLE);
} else {
mDetailsView.setVisibility(View.GONE);
}
mIconView.setImageDrawable(
- powerConsumerInfo.iconInfo.loadIcon(getPackageManager()));
+ batteryConsumerInfo.iconInfo.loadIcon(getPackageManager()));
- if (powerConsumerInfo.packages != null) {
- mPackagesView.setText(powerConsumerInfo.packages);
+ if (batteryConsumerInfo.packages != null) {
+ mPackagesView.setText(batteryConsumerInfo.packages);
mPackagesView.setVisibility(View.VISIBLE);
} else {
mPackagesView.setVisibility(View.GONE);
}
}
- mPowerStatsDataAdapter.setEntries(powerStatsData.getEntries());
- if (powerStatsData.getEntries().isEmpty()) {
+ mBatteryStatsDataAdapter.setEntries(batteryConsumerData.getEntries());
+ if (batteryConsumerData.getEntries().isEmpty()) {
mEmptyView.setVisibility(View.VISIBLE);
- mPowerStatsDataView.setVisibility(View.GONE);
+ mBatteryConsumerDataView.setVisibility(View.GONE);
} else {
mEmptyView.setVisibility(View.GONE);
- mPowerStatsDataView.setVisibility(View.VISIBLE);
+ mBatteryConsumerDataView.setVisibility(View.VISIBLE);
}
mLoadingView.setVisibility(View.GONE);
}
- private static class PowerStatsDataAdapter extends
- RecyclerView.Adapter<PowerStatsDataAdapter.ViewHolder> {
+ private static class BatteryStatsDataAdapter extends
+ RecyclerView.Adapter<BatteryStatsDataAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView titleTextView;
public TextView amountTextView;
@@ -291,9 +293,9 @@ public class PowerStatsViewerActivity extends ComponentActivity {
}
}
- private List<PowerStatsData.Entry> mEntries = Collections.emptyList();
+ private List<BatteryConsumerData.Entry> mEntries = Collections.emptyList();
- public void setEntries(List<PowerStatsData.Entry> entries) {
+ public void setEntries(List<BatteryConsumerData.Entry> entries) {
mEntries = entries;
notifyDataSetChanged();
}
@@ -307,14 +309,14 @@ public class PowerStatsViewerActivity extends ComponentActivity {
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
- View itemView = layoutInflater.inflate(R.layout.power_stats_entry_layout, parent,
+ View itemView = layoutInflater.inflate(R.layout.battery_consumer_entry_layout, parent,
false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
- PowerStatsData.Entry entry = mEntries.get(position);
+ BatteryConsumerData.Entry entry = mEntries.get(position);
switch (entry.entryType) {
case POWER:
viewHolder.titleTextView.setText(entry.title);
diff --git a/core/tests/powertests/OWNERS b/core/tests/batterystatstests/OWNERS
index c22f6a4bbbf6..c22f6a4bbbf6 100644
--- a/core/tests/powertests/OWNERS
+++ b/core/tests/batterystatstests/OWNERS
diff --git a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
index 95da532045ac..4b0ed65e5fde 100644
--- a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
+++ b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
@@ -90,7 +90,7 @@ public class ApplicationPackageManagerTest extends TestCase {
private boolean mAllow3rdPartyOnInternal = true;
public MockedApplicationPackageManager() {
- super(null, null, null);
+ super(null, null);
}
public void setForceAllowOnExternal(boolean forceAllowOnExternal) {
diff --git a/data/etc/car/com.android.car.provision.xml b/data/etc/car/com.android.car.provision.xml
index 7e77848ec337..4fd9cae53bd7 100644
--- a/data/etc/car/com.android.car.provision.xml
+++ b/data/etc/car/com.android.car.provision.xml
@@ -19,6 +19,7 @@
<permission name="android.car.permission.CAR_POWERTRAIN"/>
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+ <permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.MASTER_CLEAR"/>
<permission name="android.permission.QUERY_ALL_PACKAGES"/>
<permission name="android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 75b3babbc3a2..d8a735c78ca3 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1063,6 +1063,12 @@
"group": "WM_DEBUG_TASKS",
"at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
},
+ "-856590985": {
+ "message": "dcTarget: %s mImeRequester: %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_IME",
+ "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
+ },
"-856025122": {
"message": "SURFACE transparentRegionHint=%s: %s",
"level": "INFO",
@@ -1711,12 +1717,6 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/Session.java"
},
- "-49129622": {
- "message": "performLayout: Activity exiting now removed %s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_ADD_REMOVE",
- "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
- },
"-33096143": {
"message": "applyAnimation: transition animation is disabled or skipped. container=%s",
"level": "VERBOSE",
@@ -1771,6 +1771,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "44438983": {
+ "message": "performLayout: Activity exiting now removed %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"45285419": {
"message": "startingWindow was set but startingSurface==null, couldn't remove",
"level": "VERBOSE",
@@ -1831,12 +1837,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowContextListenerController.java"
},
- "91350919": {
- "message": "Attempted to set IME flag to a display that does not exist: %d",
- "level": "WARN",
- "group": "WM_ERROR",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"94402792": {
"message": "Moving to RESUMED: %s (in existing)",
"level": "VERBOSE",
@@ -2383,12 +2383,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "632168013": {
- "message": "dcTarget: %s mImeTargetFromIme: %s",
- "level": "DEBUG",
- "group": "WM_DEBUG_IME",
- "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
- },
"633654009": {
"message": "SURFACE POS (setPositionInTransaction) @ (%f,%f): %s",
"level": "INFO",
diff --git a/keystore/java/android/security/KeyStoreOperation.java b/keystore/java/android/security/KeyStoreOperation.java
index 49a48871fd30..7ea9e1438845 100644
--- a/keystore/java/android/security/KeyStoreOperation.java
+++ b/keystore/java/android/security/KeyStoreOperation.java
@@ -17,7 +17,7 @@
package android.security;
import android.annotation.NonNull;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.security.keymaster.KeymasterDefs;
diff --git a/keystore/java/android/security/KeyStoreSecurityLevel.java b/keystore/java/android/security/KeyStoreSecurityLevel.java
index 7c3de8bee475..3ef4aa5b7ec3 100644
--- a/keystore/java/android/security/KeyStoreSecurityLevel.java
+++ b/keystore/java/android/security/KeyStoreSecurityLevel.java
@@ -18,7 +18,7 @@ package android.security;
import android.annotation.NonNull;
import android.app.compat.CompatChanges;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.security.keystore.BackendBusyException;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStore3DESCipherSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStore3DESCipherSpi.java
index 69c7a2589d6f..0775a1a99886 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStore3DESCipherSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStore3DESCipherSpi.java
@@ -17,7 +17,7 @@
package android.security.keystore2;
import android.annotation.NonNull;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.ArrayUtils;
import android.security.keystore.KeyProperties;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreAuthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreAuthenticatedAESCipherSpi.java
index 2b5f6c31607b..bc56f015f3bd 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreAuthenticatedAESCipherSpi.java
@@ -18,7 +18,7 @@ package android.security.keystore2;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.security.KeyStoreException;
import android.security.KeyStoreOperation;
import android.security.keymaster.KeymasterDefs;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java b/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
index 18d26922f1ae..a3b04abfba3f 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
@@ -19,7 +19,7 @@ package android.security.keystore2;
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.security.KeyStoreException;
import android.security.KeyStoreOperation;
import android.security.keymaster.KeymasterDefs;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
index 2250c89aac41..d1ef1df817e6 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
@@ -17,7 +17,7 @@
package android.security.keystore2;
import android.annotation.NonNull;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.security.KeyStoreException;
import android.security.KeyStoreOperation;
import android.security.keymaster.KeymasterDefs;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java
index eea45c287622..8475ad9fd57b 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreHmacSpi.java
@@ -16,7 +16,7 @@
package android.security.keystore2;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.security.KeyStoreException;
import android.security.KeyStoreOperation;
import android.security.keymaster.KeymasterDefs;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java
index 479fd8a6a73a..233f352989ab 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyGeneratorSpi.java
@@ -16,8 +16,8 @@
package android.security.keystore2;
-import android.hardware.keymint.KeyParameter;
-import android.hardware.keymint.SecurityLevel;
+import android.hardware.security.keymint.KeyParameter;
+import android.hardware.security.keymint.SecurityLevel;
import android.security.KeyStore2;
import android.security.KeyStoreSecurityLevel;
import android.security.keymaster.KeymasterArguments;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index 61725e3e8c24..df0e1462a492 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -18,8 +18,8 @@ package android.security.keystore2;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.keymint.KeyParameter;
-import android.hardware.keymint.SecurityLevel;
+import android.hardware.security.keymint.KeyParameter;
+import android.hardware.security.keymint.SecurityLevel;
import android.os.Build;
import android.security.KeyPairGeneratorSpec;
import android.security.KeyStore2;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java
index 2686ddc20c1d..951f91887894 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java
@@ -18,7 +18,7 @@ package android.security.keystore2;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeymasterUtils;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java
index 444dad4cffbe..ab7559116a41 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java
@@ -17,7 +17,7 @@
package android.security.keystore2;
import android.annotation.NonNull;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyProperties;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSignatureSpiBase.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSignatureSpiBase.java
index a168f8feb3db..9b4f01e744f7 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSignatureSpiBase.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSignatureSpiBase.java
@@ -18,7 +18,7 @@ package android.security.keystore2;
import android.annotation.CallSuper;
import android.annotation.NonNull;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.security.KeyStoreException;
import android.security.KeyStoreOperation;
import android.security.keymaster.KeymasterDefs;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index 9790a4ae5b65..aca531458382 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -18,9 +18,9 @@ package android.security.keystore2;
import android.annotation.NonNull;
import android.hardware.biometrics.BiometricManager;
-import android.hardware.keymint.HardwareAuthenticatorType;
-import android.hardware.keymint.KeyParameter;
-import android.hardware.keymint.SecurityLevel;
+import android.hardware.security.keymint.HardwareAuthenticatorType;
+import android.hardware.security.keymint.KeyParameter;
+import android.hardware.security.keymint.SecurityLevel;
import android.security.GateKeeper;
import android.security.KeyStore2;
import android.security.KeyStoreParameter;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreUnauthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
index a2d4528b99fd..4d4b0d8f183b 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
@@ -18,7 +18,7 @@ package android.security.keystore2;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.keymint.KeyParameter;
+import android.hardware.security.keymint.KeyParameter;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.ArrayUtils;
import android.security.keystore.KeyProperties;
diff --git a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
index 8fa532b6e188..18c786aa3093 100644
--- a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
+++ b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
@@ -18,8 +18,8 @@ package android.security.keystore2;
import android.annotation.NonNull;
import android.hardware.biometrics.BiometricManager;
-import android.hardware.keymint.KeyParameter;
-import android.hardware.keymint.SecurityLevel;
+import android.hardware.security.keymint.KeyParameter;
+import android.hardware.security.keymint.SecurityLevel;
import android.security.GateKeeper;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyProperties;
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index f0eae97b107e..807e5afae890 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -42,16 +42,4 @@
<!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
when the PIP menu is shown in center. -->
<string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string>
-
- <!-- Gravity of letterboxed apps in portrait screen orientation.
- Can be Gravity.TOP, Gravity.CENTER or Gravity.BOTTOM.
- Any other value will result in runtime exception for a letterboxed activity.
- Default is Gravity.TOP. -->
- <integer name="config_letterboxPortraitGravity">0x00000030</integer>
-
- <!-- Gravity of letterboxed apps in landscape screen orientation.
- Can be Gravity.LEFT, Gravity.CENTER or Gravity.RIGHT.
- Any other value will result in runtime exception for a letterboxed activity.
- Default is Gravity.CENTER. -->
- <integer name="config_letterboxLandscapeGravity">0x00000011</integer>
</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
index 4f13b83bc29d..63d31182a748 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java
@@ -20,8 +20,9 @@ import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCR
import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;
import android.app.ActivityManager;
-import android.util.ArraySet;
+import android.graphics.Point;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.SurfaceControl;
import androidx.annotation.NonNull;
@@ -40,7 +41,7 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
private final SyncTransactionQueue mSyncQueue;
- private final ArraySet<Integer> mTasks = new ArraySet<>();
+ private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>();
public FullscreenTaskListener(SyncTransactionQueue syncQueue) {
mSyncQueue = syncQueue;
@@ -48,39 +49,44 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
@Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
- synchronized (mTasks) {
- if (mTasks.contains(taskInfo.taskId)) {
- throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId);
- }
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d",
- taskInfo.taskId);
- mTasks.add(taskInfo.taskId);
- mSyncQueue.runInSync(t -> {
- // Reset several properties back to fullscreen (PiP, for example, leaves all these
- // properties in a bad state).
- t.setWindowCrop(leash, null);
- t.setPosition(leash, 0, 0);
- // TODO(shell-transitions): Eventually set everything in transition so there's no
- // SF Transaction here.
- if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
- t.setAlpha(leash, 1f);
- t.setMatrix(leash, 1, 0, 0, 1);
- t.show(leash);
- }
- });
+ if (mLeashByTaskId.get(taskInfo.taskId) != null) {
+ throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId);
}
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d",
+ taskInfo.taskId);
+ mLeashByTaskId.put(taskInfo.taskId, leash);
+ final Point positionInParent = taskInfo.positionInParent;
+ mSyncQueue.runInSync(t -> {
+ // Reset several properties back to fullscreen (PiP, for example, leaves all these
+ // properties in a bad state).
+ t.setWindowCrop(leash, null);
+ t.setPosition(leash, positionInParent.x, positionInParent.y);
+ // TODO(shell-transitions): Eventually set everything in transition so there's no
+ // SF Transaction here.
+ if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
+ t.setAlpha(leash, 1f);
+ t.setMatrix(leash, 1, 0, 0, 1);
+ t.show(leash);
+ }
+ });
+ }
+
+ @Override
+ public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);
+ final Point positionInParent = taskInfo.positionInParent;
+ mSyncQueue.runInSync(t -> t.setPosition(leash, positionInParent.x, positionInParent.y));
}
@Override
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
- synchronized (mTasks) {
- if (!mTasks.remove(taskInfo.taskId)) {
- Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
- return;
- }
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d",
- taskInfo.taskId);
+ if (mLeashByTaskId.get(taskInfo.taskId) == null) {
+ Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
+ return;
}
+ mLeashByTaskId.remove(taskInfo.taskId);
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d",
+ taskInfo.taskId);
}
@Override
@@ -88,7 +94,7 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener {
final String innerPrefix = prefix + " ";
final String childPrefix = innerPrefix + " ";
pw.println(prefix + this);
- pw.println(innerPrefix + mTasks.size() + " Tasks");
+ pw.println(innerPrefix + mLeashByTaskId.size() + " Tasks");
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java
index 45948dd9e800..20850428d3bd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java
@@ -16,12 +16,9 @@
package com.android.wm.shell;
-import android.view.Gravity;
-
import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
-import com.android.wm.shell.letterbox.LetterboxConfigController;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.splitscreen.SplitScreen;
@@ -42,7 +39,6 @@ public final class ShellCommandHandler {
private final Optional<HideDisplayCutout> mHideDisplayCutout;
private final ShellTaskOrganizer mShellTaskOrganizer;
private final Optional<AppPairs> mAppPairsOptional;
- private final LetterboxConfigController mLetterboxConfigController;
public ShellCommandHandler(
ShellTaskOrganizer shellTaskOrganizer,
@@ -50,15 +46,13 @@ public final class ShellCommandHandler {
Optional<Pip> pipOptional,
Optional<OneHanded> oneHandedOptional,
Optional<HideDisplayCutout> hideDisplayCutout,
- Optional<AppPairs> appPairsOptional,
- LetterboxConfigController letterboxConfigController) {
+ Optional<AppPairs> appPairsOptional) {
mShellTaskOrganizer = shellTaskOrganizer;
mSplitScreenOptional = splitScreenOptional;
mPipOptional = pipOptional;
mOneHandedOptional = oneHandedOptional;
mHideDisplayCutout = hideDisplayCutout;
mAppPairsOptional = appPairsOptional;
- mLetterboxConfigController = letterboxConfigController;
}
/** Dumps WM Shell internal state. */
@@ -85,14 +79,6 @@ public final class ShellCommandHandler {
return false;
}
switch (args[1]) {
- case "set-letterbox-portrait-gravity":
- return runSetLetterboxPortraitGravity(args, pw);
- case "get-letterbox-portrait-gravity":
- return runGetLetterboxPortraitGravity(pw);
- case "set-letterbox-landscape-gravity":
- return runSetLetterboxLandscapeGravity(args, pw);
- case "get-letterbox-landscape-gravity":
- return runGetLetterboxLandscapeGravity(pw);
case "pair":
return runPair(args, pw);
case "unpair":
@@ -104,92 +90,6 @@ public final class ShellCommandHandler {
}
}
- private boolean runSetLetterboxPortraitGravity(String[] args, PrintWriter pw) {
- if (args.length < 3) {
- // First two arguments are "WMShell" and command name.
- pw.println("Error: reset, TOP, CENTER or BOTTOM should be provided as an argument");
- return true;
- }
- switch (args[2]) {
- case "reset":
- mLetterboxConfigController.resetPortraitGravity();
- break;
- case "TOP":
- mLetterboxConfigController.setPortraitGravity(Gravity.TOP);
- break;
- case "CENTER":
- mLetterboxConfigController.setPortraitGravity(Gravity.CENTER);
- break;
- case "BOTTOM":
- mLetterboxConfigController.setPortraitGravity(Gravity.BOTTOM);
- break;
- default:
- pw.println("Error: expected reset, TOP, CENTER or BOTTOM but got " + args[2]);
- }
- return true;
- }
-
- private boolean runGetLetterboxPortraitGravity(PrintWriter pw) {
- final int gravity = mLetterboxConfigController.getPortraitGravity();
- switch (gravity) {
- case Gravity.TOP:
- pw.println("TOP");
- break;
- case Gravity.CENTER:
- pw.println("CENTER");
- break;
- case Gravity.BOTTOM:
- pw.println("BOTTOM");
- break;
- default:
- throw new AssertionError("Unexpected gravity: " + gravity);
- }
- return true;
- }
-
- private boolean runSetLetterboxLandscapeGravity(String[] args, PrintWriter pw) {
- if (args.length < 3) {
- // First two arguments are "WMShell" and command name.
- pw.println("Error: reset, LEFT, CENTER or RIGHT should be provided as an argument");
- return false;
- }
- switch (args[2]) {
- case "reset":
- mLetterboxConfigController.resetLandscapeGravity();
- break;
- case "LEFT":
- mLetterboxConfigController.setLandscapeGravity(Gravity.LEFT);
- break;
- case "CENTER":
- mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER);
- break;
- case "RIGHT":
- mLetterboxConfigController.setLandscapeGravity(Gravity.RIGHT);
- break;
- default:
- pw.println(
- "Error: expected reset, LEFT, CENTER or RIGHT but got " + args[2]);
- }
- return true;
- }
-
- private boolean runGetLetterboxLandscapeGravity(PrintWriter pw) {
- final int gravity = mLetterboxConfigController.getLandscapeGravity();
- switch (gravity) {
- case Gravity.LEFT:
- pw.println("LEFT");
- break;
- case Gravity.CENTER:
- pw.println("CENTER");
- break;
- case Gravity.RIGHT:
- pw.println("RIGHT");
- break;
- default:
- throw new AssertionError("Unexpected gravity: " + gravity);
- }
- return true;
- }
private boolean runPair(String[] args, PrintWriter pw) {
if (args.length < 4) {
@@ -220,12 +120,6 @@ public final class ShellCommandHandler {
pw.println(" Print this help text.");
pw.println(" <no arguments provided>");
pw.println(" Dump Window Manager Shell internal state");
- pw.println(" set-letterbox-portrait-gravity [reset|TOP|CENTER|BOTTOM]");
- pw.println(" get-letterbox-portrait-gravity");
- pw.println(" Set, reset or print letterbox gravity for portrait screen mode.");
- pw.println(" set-letterbox-landscape-gravity [reset|LEFT|CENTER|RIGHT]");
- pw.println(" get-letterbox-landscape-gravity");
- pw.println(" Set, reset or print letterbox gravity for landscape screen mode.");
pw.println(" pair <taskId1> <taskId2>");
pw.println(" unpair <taskId>");
pw.println(" Pairs/unpairs tasks with given ids.");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java
index 6c08079e586e..f8956030936c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java
@@ -17,13 +17,11 @@
package com.android.wm.shell;
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
-import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_LETTERBOX;
import com.android.wm.shell.apppairs.AppPairs;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.draganddrop.DragAndDropController;
-import com.android.wm.shell.letterbox.LetterboxTaskListener;
import com.android.wm.shell.splitscreen.SplitScreen;
import java.util.Optional;
@@ -38,7 +36,6 @@ public class ShellInit {
private final ShellTaskOrganizer mShellTaskOrganizer;
private final Optional<SplitScreen> mSplitScreenOptional;
private final Optional<AppPairs> mAppPairsOptional;
- private final LetterboxTaskListener mLetterboxTaskListener;
private final FullscreenTaskListener mFullscreenTaskListener;
private final Transitions mTransitions;
@@ -47,7 +44,6 @@ public class ShellInit {
ShellTaskOrganizer shellTaskOrganizer,
Optional<SplitScreen> splitScreenOptional,
Optional<AppPairs> appPairsOptional,
- LetterboxTaskListener letterboxTaskListener,
FullscreenTaskListener fullscreenTaskListener,
Transitions transitions) {
mDisplayImeController = displayImeController;
@@ -55,7 +51,6 @@ public class ShellInit {
mShellTaskOrganizer = shellTaskOrganizer;
mSplitScreenOptional = splitScreenOptional;
mAppPairsOptional = appPairsOptional;
- mLetterboxTaskListener = letterboxTaskListener;
mFullscreenTaskListener = fullscreenTaskListener;
mTransitions = transitions;
}
@@ -66,8 +61,6 @@ public class ShellInit {
mDisplayImeController.startMonitorDisplays();
mShellTaskOrganizer.addListenerForType(
- mLetterboxTaskListener, TASK_LISTENER_TYPE_LETTERBOX);
- mShellTaskOrganizer.addListenerForType(
mFullscreenTaskListener, TASK_LISTENER_TYPE_FULLSCREEN);
// Register the shell organizer
mShellTaskOrganizer.registerOrganizer();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 62d265aab38f..10cec6d59cbe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -62,14 +62,12 @@ public class ShellTaskOrganizer extends TaskOrganizer {
public static final int TASK_LISTENER_TYPE_FULLSCREEN = -2;
public static final int TASK_LISTENER_TYPE_MULTI_WINDOW = -3;
public static final int TASK_LISTENER_TYPE_PIP = -4;
- public static final int TASK_LISTENER_TYPE_LETTERBOX = -5;
@IntDef(prefix = {"TASK_LISTENER_TYPE_"}, value = {
TASK_LISTENER_TYPE_UNDEFINED,
TASK_LISTENER_TYPE_FULLSCREEN,
TASK_LISTENER_TYPE_MULTI_WINDOW,
TASK_LISTENER_TYPE_PIP,
- TASK_LISTENER_TYPE_LETTERBOX,
})
public @interface TaskListenerType {}
@@ -371,9 +369,7 @@ public class ShellTaskOrganizer extends TaskOrganizer {
static @TaskListenerType int taskInfoToTaskListenerType(RunningTaskInfo runningTaskInfo) {
switch (runningTaskInfo.getWindowingMode()) {
case WINDOWING_MODE_FULLSCREEN:
- return runningTaskInfo.letterboxActivityBounds != null
- ? TASK_LISTENER_TYPE_LETTERBOX
- : TASK_LISTENER_TYPE_FULLSCREEN;
+ return TASK_LISTENER_TYPE_FULLSCREEN;
case WINDOWING_MODE_MULTI_WINDOW:
return TASK_LISTENER_TYPE_MULTI_WINDOW;
case WINDOWING_MODE_PINNED:
@@ -389,8 +385,6 @@ public class ShellTaskOrganizer extends TaskOrganizer {
switch (type) {
case TASK_LISTENER_TYPE_FULLSCREEN:
return "TASK_LISTENER_TYPE_FULLSCREEN";
- case TASK_LISTENER_TYPE_LETTERBOX:
- return "TASK_LISTENER_TYPE_LETTERBOX";
case TASK_LISTENER_TYPE_MULTI_WINDOW:
return "TASK_LISTENER_TYPE_MULTI_WINDOW";
case TASK_LISTENER_TYPE_PIP:
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 4c70b5d32108..e1a94b071bf4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -123,14 +123,16 @@ public class SplitLayout {
mBounds1.set(mRootBounds);
mBounds2.set(mRootBounds);
if (isLandscape(mRootBounds)) {
+ position += mRootBounds.left;
mDividerBounds.left = position - mDividerInsets;
mDividerBounds.right = mDividerBounds.left + mDividerWindowWidth;
- mBounds1.right = mBounds1.left + position;
+ mBounds1.right = position;
mBounds2.left = mBounds1.right + mDividerSize;
} else {
+ position += mRootBounds.top;
mDividerBounds.top = position - mDividerInsets;
mDividerBounds.bottom = mDividerBounds.top + mDividerWindowWidth;
- mBounds1.bottom = mBounds1.top + position;
+ mBounds1.bottom = position;
mBounds2.top = mBounds1.bottom + mDividerSize;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxConfigController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxConfigController.java
deleted file mode 100644
index 0a549c6aa7d9..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxConfigController.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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.letterbox;
-
-import android.content.Context;
-import android.view.Gravity;
-
-import com.android.wm.shell.R;
-
-/**
- * Controls access to and overrides of resource config values used by {@link
- * LetterboxTaskOrganizer}.
- */
-public final class LetterboxConfigController {
-
- private final Context mContext;
-
- /** {@link Gravity} of letterboxed apps in portrait screen orientation. */
- private int mLetterboxPortraitGravity;
-
- /** {@link Gravity} of letterboxed apps in landscape screen orientation. */
- private int mLetterboxLandscapeGravity;
-
- public LetterboxConfigController(Context context) {
- mContext = context;
- mLetterboxPortraitGravity =
- mContext.getResources().getInteger(R.integer.config_letterboxPortraitGravity);
- mLetterboxLandscapeGravity =
- mContext.getResources().getInteger(R.integer.config_letterboxLandscapeGravity);
- }
-
- /**
- * Overrides {@link Gravity} of letterboxed apps in portrait screen orientation.
- *
- * @throws IllegalArgumentException if gravity isn't equal to {@link Gravity#TOP}, {@link
- * Gravity#CENTER} or {@link Gravity#BOTTOM}.
- */
- public void setPortraitGravity(int gravity) {
- if (gravity != Gravity.TOP && gravity != Gravity.CENTER && gravity != Gravity.BOTTOM) {
- throw new IllegalArgumentException(
- "Expected Gravity#TOP, Gravity#CENTER or Gravity#BOTTOM but got"
- + gravity);
- }
- mLetterboxPortraitGravity = gravity;
- }
-
- /**
- * Resets {@link Gravity} of letterboxed apps in portrait screen orientation to {@link
- * R.integer.config_letterboxPortraitGravity}.
- */
- public void resetPortraitGravity() {
- mLetterboxPortraitGravity =
- mContext.getResources().getInteger(R.integer.config_letterboxPortraitGravity);
- }
-
- /**
- * Gets {@link Gravity} of letterboxed apps in portrait screen orientation.
- */
- public int getPortraitGravity() {
- return mLetterboxPortraitGravity;
- }
-
- /**
- * Overrides {@link Gravity} of letterboxed apps in landscape screen orientation.
- *
- * @throws IllegalArgumentException if gravity isn't equal to {@link Gravity#RIGHT}, {@link
- * Gravity#CENTER} or {@link Gravity#LEFT}.
- */
- public void setLandscapeGravity(int gravity) {
- if (gravity != Gravity.LEFT && gravity != Gravity.CENTER && gravity != Gravity.RIGHT) {
- throw new IllegalArgumentException(
- "Expected Gravity#LEFT, Gravity#CENTER or Gravity#RIGHT but got"
- + gravity);
- }
- mLetterboxLandscapeGravity = gravity;
- }
-
- /**
- * Resets {@link Gravity} of letterboxed apps in landscape screen orientation to {@link
- * R.integer.config_letterboxLandscapeGravity}.
- */
- public void resetLandscapeGravity() {
- mLetterboxLandscapeGravity =
- mContext.getResources().getInteger(R.integer.config_letterboxLandscapeGravity);
- }
-
- /**
- * Gets {@link Gravity} of letterboxed apps in landscape screen orientation.
- */
- public int getLandscapeGravity() {
- return mLetterboxLandscapeGravity;
- }
-
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxTaskListener.java
deleted file mode 100644
index 490ef3296be6..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/letterbox/LetterboxTaskListener.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * 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.letterbox;
-
-import android.app.ActivityManager;
-import android.graphics.Insets;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.view.Gravity;
-import android.view.SurfaceControl;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-
-import com.android.internal.protolog.common.ProtoLog;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.Transitions;
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.protolog.ShellProtoLogGroup;
-
-/**
- * Organizes a task in {@link android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN} when
- * it's presented in the letterbox mode either because orientations of a top activity and a device
- * don't match or because a top activity is in a size compat mode.
- */
-public class LetterboxTaskListener implements ShellTaskOrganizer.TaskListener {
- private static final String TAG = "LetterboxTaskListener";
-
- private final SyncTransactionQueue mSyncQueue;
- private final LetterboxConfigController mLetterboxConfigController;
- private final WindowManager mWindowManager;
- private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>();
-
- public LetterboxTaskListener(
- SyncTransactionQueue syncQueue,
- LetterboxConfigController letterboxConfigController,
- WindowManager windowManager) {
- mSyncQueue = syncQueue;
- mLetterboxConfigController = letterboxConfigController;
- mWindowManager = windowManager;
- }
-
- @Override
- public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
- if (mLeashByTaskId.get(taskInfo.taskId) != null) {
- throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId);
- }
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Appeared: #%d",
- taskInfo.taskId);
- mLeashByTaskId.put(taskInfo.taskId, leash);
- Point positionInParent = new Point();
- Rect crop = new Rect();
- resolveTaskPositionAndCrop(taskInfo, positionInParent, crop);
- mSyncQueue.runInSync(t -> {
- setPositionAndWindowCrop(t, leash, positionInParent, crop);
- if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
- t.setAlpha(leash, 1f);
- t.setMatrix(leash, 1, 0, 0, 1);
- t.show(leash);
- }
- });
- }
-
- @Override
- public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
- if (mLeashByTaskId.get(taskInfo.taskId) == null) {
- Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
- return;
- }
- mLeashByTaskId.remove(taskInfo.taskId);
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Vanished: #%d",
- taskInfo.taskId);
- }
-
- @Override
- public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Changed: #%d",
- taskInfo.taskId);
- final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);
- Point positionInParent = new Point();
- Rect crop = new Rect();
- resolveTaskPositionAndCrop(taskInfo, positionInParent, crop);
- mSyncQueue.runInSync(t -> setPositionAndWindowCrop(t, leash, positionInParent, crop));
- }
-
- private static void setPositionAndWindowCrop(
- SurfaceControl.Transaction transaction,
- SurfaceControl leash,
- final Point positionInParent,
- final Rect crop) {
- transaction.setPosition(leash, positionInParent.x, positionInParent.y);
- transaction.setWindowCrop(leash, crop);
- }
-
- // TODO(b/173440321): Correct presentation of letterboxed activities in One-handed mode.
- private void resolveTaskPositionAndCrop(
- ActivityManager.RunningTaskInfo taskInfo,
- Point positionInParent,
- Rect crop) {
- // In screen coordinates
- Rect parentBounds = new Rect(taskInfo.parentBounds);
- // Intersect parent and max bounds. This is required for situations when parent bounds
- // go beyond display bounds, for example, in One-handed mode.
- final Rect maxBounds = taskInfo.getConfiguration().windowConfiguration.getMaxBounds();
- if (!parentBounds.intersect(maxBounds)) {
- Slog.w(TAG, "Task parent and max bounds don't intersect: #" + taskInfo.taskId);
- }
-
- // In screen coordinates
- final Rect taskBounds = taskInfo.getConfiguration().windowConfiguration.getBounds();
- final Rect activityBounds = taskInfo.letterboxActivityBounds;
-
- Insets insets = getInsets();
- Rect displayBoundsWithInsets =
- new Rect(mWindowManager.getMaximumWindowMetrics().getBounds());
- displayBoundsWithInsets.inset(insets);
-
- Rect taskBoundsWithInsets = new Rect(taskBounds);
- taskBoundsWithInsets.intersect(displayBoundsWithInsets);
-
- Rect activityBoundsWithInsets = new Rect(activityBounds);
- activityBoundsWithInsets.intersect(displayBoundsWithInsets);
-
- Rect parentBoundsWithInsets = new Rect(parentBounds);
- parentBoundsWithInsets.intersect(displayBoundsWithInsets);
-
- // Crop need to be in the task coordinates.
- crop.set(activityBoundsWithInsets);
- crop.offset(-taskBounds.left, -taskBounds.top);
-
- // Account for insets since coordinates calculations below are done with them.
- positionInParent.x = parentBoundsWithInsets.left - parentBounds.left
- - (taskBoundsWithInsets.left - taskBounds.left);
- positionInParent.y = parentBoundsWithInsets.top - parentBounds.top
- - (taskBoundsWithInsets.top - taskBounds.top);
-
- // Calculating a position of task bounds (without insets) in parent coordinates (without
- // insets) to align activity bounds (without insets) as requested in config. Activity
- // accounts for insets that overlap with its bounds (this overlap can be partial) so
- // ignoring overlap with insets when computing the position. Also, cropping unwanted insets
- // while keeping the top one if the activity is aligned at the top of the window to show
- // status bar decor view.
- if (parentBounds.height() >= parentBounds.width()) {
- final int gravity = mLetterboxConfigController.getPortraitGravity();
- // Center activity horizontally.
- positionInParent.x +=
- (parentBoundsWithInsets.width() - activityBoundsWithInsets.width()) / 2
- + taskBoundsWithInsets.left - activityBoundsWithInsets.left;
- switch (gravity) {
- case Gravity.TOP:
- positionInParent.y += taskBoundsWithInsets.top - activityBoundsWithInsets.top;
- break;
- case Gravity.CENTER:
- positionInParent.y +=
- taskBoundsWithInsets.top - activityBoundsWithInsets.top
- + (parentBoundsWithInsets.height()
- - activityBoundsWithInsets.height()) / 2;
- break;
- case Gravity.BOTTOM:
- positionInParent.y +=
- parentBoundsWithInsets.height() - activityBoundsWithInsets.bottom
- + taskBoundsWithInsets.top;
- break;
- default:
- throw new AssertionError(
- "Unexpected portrait gravity " + gravity
- + " for task: #" + taskInfo.taskId);
- }
- } else {
- final int gravity = mLetterboxConfigController.getLandscapeGravity();
- // Align activity to the top.
- positionInParent.y += taskBoundsWithInsets.top - activityBoundsWithInsets.top;
- switch (gravity) {
- case Gravity.LEFT:
- positionInParent.x += taskBoundsWithInsets.left - activityBoundsWithInsets.left;
- break;
- case Gravity.CENTER:
- positionInParent.x +=
- (parentBoundsWithInsets.width() - activityBoundsWithInsets.width()) / 2
- + taskBoundsWithInsets.left - activityBoundsWithInsets.left;
- break;
- case Gravity.RIGHT:
- positionInParent.x +=
- parentBoundsWithInsets.width()
- - activityBoundsWithInsets.right + taskBoundsWithInsets.left;
- break;
- default:
- throw new AssertionError(
- "Unexpected landscape gravity " + gravity
- + " for task: #" + taskInfo.taskId);
- }
- }
-
- // New bounds of the activity after it's repositioned with required gravity.
- Rect newActivityBounds = new Rect(activityBounds);
- // Task's surfce will be repositioned to positionInParent together with the activity
- // inside it so the new activity bounds are the original activity bounds offset by
- // the task's offset.
- newActivityBounds.offset(
- positionInParent.x - taskBounds.left, positionInParent.y - taskBounds.top);
- Rect newActivityBoundsWithInsets = new Rect(newActivityBounds);
- newActivityBoundsWithInsets.intersect(displayBoundsWithInsets);
- // Activity handles insets on its own (e.g. under status bar or navigation bar).
- // crop that is calculated above crops all insets from an activity and below insets that
- // can be shown are added back to the crop bounds (e.g. if activity is still shown at the
- // top of the display then the top inset won't be cropped).
- // After task's surface is repositioned, intersection between an activity and insets can
- // change but if it doesn't, the activity should be shown under insets to maximize visible
- // area.
- // Also, an activity can use area under insets and insets shouldn't be cropped in this case
- // regardless of a position on the screen.
- final Rect activityInsetsFromCore = taskInfo.letterboxActivityInsets;
- if (newActivityBounds.top - newActivityBoundsWithInsets.top
- == activityBounds.top - activityBoundsWithInsets.top
- // Check whether an activity is shown under inset. If it is, then the inset from
- // WM Core and the inset computed here will be different because local insets
- // doesn't take into account visibility of insets requested by the activity.
- || activityBoundsWithInsets.top - activityBounds.top
- != activityInsetsFromCore.top) {
- crop.top -= activityBoundsWithInsets.top - activityBounds.top;
- }
- if (newActivityBounds.bottom - newActivityBoundsWithInsets.bottom
- == activityBounds.bottom - activityBoundsWithInsets.bottom
- || activityBounds.bottom - activityBoundsWithInsets.bottom
- != activityInsetsFromCore.bottom) {
- crop.bottom += activityBounds.bottom - activityBoundsWithInsets.bottom;
- }
- if (newActivityBounds.left - newActivityBoundsWithInsets.left
- == activityBounds.left - activityBoundsWithInsets.left
- || activityBoundsWithInsets.left - activityBounds.left
- != activityInsetsFromCore.left) {
- crop.left -= activityBoundsWithInsets.left - activityBounds.left;
- }
- if (newActivityBounds.right - newActivityBoundsWithInsets.right
- == activityBounds.right - activityBoundsWithInsets.right
- || activityBounds.right - activityBoundsWithInsets.right
- != activityInsetsFromCore.right) {
- crop.right += activityBounds.right - activityBoundsWithInsets.right;
- }
- }
-
- private Insets getInsets() {
- return mWindowManager
- .getMaximumWindowMetrics()
- .getWindowInsets()
- .getInsets(
- WindowInsets.Type.navigationBars()
- | WindowInsets.Type.statusBars()
- | WindowInsets.Type.displayCutout());
- }
-
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
index 3b1e6cbe5ccd..951a68884e11 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
@@ -75,6 +75,7 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback,
@Nullable
OneHandedGestureEventCallback mGestureEventCallback;
private Rect mGestureRegion = new Rect();
+ private boolean mIsStopGesture;
/**
* Constructor of OneHandedGestureHandler, we only handle the gesture of
@@ -153,20 +154,20 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback,
float distance = (float) Math.hypot(mLastPos.x - mDownPos.x,
mLastPos.y - mDownPos.y);
if (distance > mDragDistThreshold) {
- mGestureEventCallback.onStop();
+ mIsStopGesture = true;
}
}
break;
case MotionEvent.ACTION_UP:
if (mLastPos.y >= mDownPos.y && mPassedSlop) {
mGestureEventCallback.onStart();
+ } else if (mIsStopGesture) {
+ mGestureEventCallback.onStop();
}
- mPassedSlop = false;
- mAllowGesture = false;
+ clearState();
break;
case MotionEvent.ACTION_CANCEL:
- mPassedSlop = false;
- mAllowGesture = false;
+ clearState();
break;
default:
break;
@@ -174,6 +175,11 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback,
}
}
+ private void clearState() {
+ mPassedSlop = false;
+ mIsStopGesture = false;
+ }
+
private void disposeInputChannel() {
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index 1638d72f9914..c5b54bc4abcb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -16,8 +16,10 @@
package com.android.wm.shell.flicker
+import android.graphics.Region
import com.android.server.wm.flicker.dsl.EventLogAssertion
import com.android.server.wm.flicker.dsl.LayersAssertion
+import com.android.server.wm.flicker.helpers.WindowUtils
@JvmOverloads
fun LayersAssertion.appPairsDividerIsVisible(
@@ -59,6 +61,50 @@ fun LayersAssertion.dockedStackDividerIsInvisible(
}
}
+@JvmOverloads
+fun LayersAssertion.dockedStackPrimaryBoundsIsVisible(
+ rotation: Int,
+ primaryLayerName: String,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ end("PrimaryAppBounds", bugId, enabled) {
+ val entry = this.trace.entries.firstOrNull()
+ ?: throw IllegalStateException("Trace is empty")
+ val dividerRegion = entry.getVisibleBounds(FlickerTestBase.DOCKED_STACK_DIVIDER)
+ this.hasVisibleRegion(primaryLayerName, getPrimaryRegion(dividerRegion, rotation))
+ }
+}
+
+@JvmOverloads
+fun LayersAssertion.dockedStackSecondaryBoundsIsVisible(
+ rotation: Int,
+ secondaryLayerName: String,
+ bugId: Int = 0,
+ enabled: Boolean = bugId == 0
+) {
+ end("SecondaryAppBounds", bugId, enabled) {
+ val entry = this.trace.entries.firstOrNull()
+ ?: throw IllegalStateException("Trace is empty")
+ val dividerRegion = entry.getVisibleBounds(FlickerTestBase.DOCKED_STACK_DIVIDER)
+ this.hasVisibleRegion(secondaryLayerName, getSecondaryRegion(dividerRegion, rotation))
+ }
+}
+
+fun getPrimaryRegion(dividerRegion: Region, rotation: Int): Region {
+ val displayBounds = WindowUtils.getDisplayBounds(rotation)
+ return Region(0, 0, displayBounds.getBounds().right,
+ dividerRegion.getBounds().bottom - WindowUtils.dockedStackDividerInset)
+}
+
+fun getSecondaryRegion(dividerRegion: Region, rotation: Int): Region {
+ val displayBounds = WindowUtils.getDisplayBounds(rotation)
+ return Region(0,
+ dividerRegion.getBounds().bottom - WindowUtils.dockedStackDividerInset,
+ displayBounds.getBounds().right,
+ displayBounds.getBounds().bottom - WindowUtils.navigationBarHeight)
+}
+
fun EventLogAssertion.focusChanges(
vararg windows: String,
bugId: Int = 0,
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
index 96234fcc8570..5125a3972cf4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
@@ -37,3 +37,4 @@ const val TEST_APP_FIXED_ACTIVITY_LABEL = "FixedApp"
// Test App > SplitScreen Activity
const val TEST_APP_SPLITSCREEN_PRIMARY_LABEL = "SplitScreenPrimaryApp"
const val TEST_APP_SPLITSCREEN_SECONDARY_LABEL = "SplitScreenSecondaryApp"
+const val TEST_APP_NONRESIZEABLE_LABEL = "NonResizeableApp"
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt
index 0f8d30a94ec6..379ec95b6792 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt
@@ -61,10 +61,9 @@ class AppPairsTest(
setup {
eachRun {
uiDevice.wakeUpAndGoToHomeScreen()
- primaryApp.open()
- uiDevice.pressHome()
- secondaryApp.open()
- uiDevice.pressHome()
+ primaryApp.launchViaIntent()
+ secondaryApp.launchViaIntent()
+ nonResizeableApp.launchViaIntent()
updateTaskId()
}
}
@@ -90,7 +89,7 @@ class AppPairsTest(
@Test
fun testAppPairs_pairPrimaryAndSecondaryApps() {
- val testTag = "testAppPaired_pairPrimaryAndSecondary"
+ val testTag = "testAppPairs_pairPrimaryAndSecondaryApps"
runWithFlicker(appPairsSetup) {
withTestName { testTag }
repeat {
@@ -176,6 +175,36 @@ class AppPairsTest(
}
}
+ @Test
+ fun testAppPairs_canNotPairNonResizeableApps() {
+ val testTag = "testAppPairs_canNotPairNonResizeableApps"
+ runWithFlicker(appPairsSetup) {
+ withTestName { testTag }
+ repeat {
+ TEST_REPETITIONS
+ }
+ transitions {
+ nonResizeableApp.launchViaIntent()
+ // TODO pair apps through normal UX flow
+ executeShellCommand(composePairsCommand(
+ primaryTaskId, nonResizeableTaskId, true /* pair */))
+ SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
+ }
+ assertions {
+ layersTrace {
+ appPairsDividerIsInvisible()
+ }
+ windowManagerTrace {
+ end {
+ showsAppWindow(nonResizeableApp.defaultWindowName)
+ .and()
+ .hidesAppWindow(primaryApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ }
+
private fun composePairsCommand(
primaryApp: String,
secondaryApp: String,
@@ -202,6 +231,7 @@ class AppPairsTest(
private fun updateTaskId() {
val primaryAppComponent = primaryApp.openAppIntent.component
val secondaryAppComponent = secondaryApp.openAppIntent.component
+ val nonResizeableAppComponent = nonResizeableApp.openAppIntent.component
if (primaryAppComponent != null) {
primaryTaskId = appPairsHelper.getTaskIdForActivity(
primaryAppComponent.packageName, primaryAppComponent.className).toString()
@@ -210,11 +240,17 @@ class AppPairsTest(
secondaryTaskId = appPairsHelper.getTaskIdForActivity(
secondaryAppComponent.packageName, secondaryAppComponent.className).toString()
}
+ if (nonResizeableAppComponent != null) {
+ nonResizeableTaskId = appPairsHelper.getTaskIdForActivity(
+ nonResizeableAppComponent.packageName,
+ nonResizeableAppComponent.className).toString()
+ }
}
companion object {
var primaryTaskId = ""
var secondaryTaskId = ""
+ var nonResizeableTaskId = ""
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<Array<Any>> {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt
index f32cd8842074..4d46f2856704 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestBase.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.apppairs
import com.android.wm.shell.flicker.NonRotationTestBase
+import com.android.wm.shell.flicker.TEST_APP_NONRESIZEABLE_LABEL
import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_PRIMARY_LABEL
import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_SECONDARY_LABEL
import com.android.wm.shell.flicker.helpers.AppPairsHelper
@@ -36,4 +37,7 @@ abstract class AppPairsTestBase(
protected val secondaryApp = SplitScreenHelper(instrumentation,
TEST_APP_SPLITSCREEN_SECONDARY_LABEL,
Components.SplitScreenSecondaryActivity())
+ protected val nonResizeableApp = SplitScreenHelper(instrumentation,
+ TEST_APP_NONRESIZEABLE_LABEL,
+ Components.NonResizeableActivity())
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
index e67fc97dad2e..fb795c72b106 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
@@ -17,9 +17,7 @@
package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
-import android.graphics.Region
import android.os.SystemClock
-import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.wm.shell.flicker.testapp.Components
class SplitScreenHelper(
@@ -43,20 +41,6 @@ class SplitScreenHelper(
SystemClock.sleep(TIMEOUT_MS)
}
- fun getPrimaryBounds(dividerBounds: Region): android.graphics.Region {
- val primaryAppBounds = Region(0, 0, dividerBounds.bounds.right,
- dividerBounds.bounds.bottom + WindowUtils.dockedStackDividerInset)
- return primaryAppBounds
- }
-
- fun getSecondaryBounds(dividerBounds: Region): android.graphics.Region {
- val displayBounds = WindowUtils.displayBounds
- val secondaryAppBounds = Region(0,
- dividerBounds.bounds.bottom - WindowUtils.dockedStackDividerInset,
- displayBounds.right, displayBounds.bottom - WindowUtils.navigationBarHeight)
- return secondaryAppBounds
- }
-
companion object {
const val TEST_REPETITIONS = 1
const val TIMEOUT_MS = 3_000L
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenTest.kt
index 5570a562a515..348676189524 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenTest.kt
@@ -21,14 +21,23 @@ import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.dsl.runWithFlicker
+import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.helpers.canSplitScreen
+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.openQuickstep
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
import com.android.wm.shell.flicker.dockedStackDividerIsVisible
import com.android.wm.shell.flicker.helpers.SplitScreenHelper.Companion.TEST_REPETITIONS
import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
+import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisible
+import org.junit.Assert
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -56,14 +65,16 @@ class EnterSplitScreenTest(
setup {
eachRun {
uiDevice.wakeUpAndGoToHomeScreen()
- splitScreenApp.open()
- uiDevice.pressHome()
}
}
teardown {
eachRun {
+ if (uiDevice.isInSplitScreen()) {
+ uiDevice.exitSplitScreen()
+ }
splitScreenApp.exit()
secondaryApp.exit()
+ nonResizeableApp.exit()
}
}
assertions {
@@ -87,18 +98,14 @@ class EnterSplitScreenTest(
TEST_REPETITIONS
}
transitions {
+ splitScreenApp.launchViaIntent()
uiDevice.launchSplitScreen()
}
assertions {
layersTrace {
dockedStackDividerIsVisible()
- end("appsEndingBounds", enabled = false) {
- val entry = this.trace.entries.firstOrNull()
- ?: throw IllegalStateException("Trace is empty")
- this.hasVisibleRegion(splitScreenApp.defaultWindowName,
- splitScreenApp.getPrimaryBounds(
- entry.getVisibleBounds(DOCKED_STACK_DIVIDER)))
- }
+ dockedStackPrimaryBoundsIsVisible(
+ rotation, splitScreenApp.defaultWindowName, 169271943)
}
windowManagerTrace {
end {
@@ -118,27 +125,18 @@ class EnterSplitScreenTest(
TEST_REPETITIONS
}
transitions {
- secondaryApp.open()
- uiDevice.pressHome()
- splitScreenApp.open()
- uiDevice.pressHome()
+ secondaryApp.launchViaIntent()
+ splitScreenApp.launchViaIntent()
uiDevice.launchSplitScreen()
splitScreenApp.reopenAppFromOverview()
}
assertions {
layersTrace {
dockedStackDividerIsVisible()
- end("appsEndingBounds", enabled = false) {
- val entry = this.trace.entries.firstOrNull()
- ?: throw IllegalStateException("Trace is empty")
- this.hasVisibleRegion(splitScreenApp.defaultWindowName,
- splitScreenApp.getPrimaryBounds(
- entry.getVisibleBounds(DOCKED_STACK_DIVIDER)))
- .and()
- .hasVisibleRegion(secondaryApp.defaultWindowName,
- splitScreenApp.getSecondaryBounds(
- entry.getVisibleBounds(DOCKED_STACK_DIVIDER)))
- }
+ dockedStackPrimaryBoundsIsVisible(
+ rotation, splitScreenApp.defaultWindowName, 169271943)
+ dockedStackSecondaryBoundsIsVisible(
+ rotation, secondaryApp.defaultWindowName, 169271943)
}
windowManagerTrace {
end {
@@ -150,6 +148,98 @@ class EnterSplitScreenTest(
}
}
+ @Test
+ fun testNonResizeableNotDocked() {
+ val testTag = "testNonResizeableNotDocked"
+ runWithFlicker(splitScreenSetup) {
+ withTestName { testTag }
+ repeat {
+ TEST_REPETITIONS
+ }
+ transitions {
+ nonResizeableApp.launchViaIntent()
+ uiDevice.openQuickstep()
+ if (uiDevice.canSplitScreen()) {
+ Assert.fail("Non-resizeable app should not enter split screen")
+ }
+ }
+ assertions {
+ layersTrace {
+ dockedStackDividerIsInvisible()
+ }
+ windowManagerTrace {
+ end {
+ hidesAppWindow(nonResizeableApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun testNonResizeableWhenAlreadyInSplitScreenPrimary() {
+ val testTag = "testNonResizeableWhenAlreadyInSplitScreenPrimary"
+ runWithFlicker(splitScreenSetup) {
+ withTestName { testTag }
+ repeat {
+ TEST_REPETITIONS
+ }
+ transitions {
+ nonResizeableApp.launchViaIntent()
+ splitScreenApp.launchViaIntent()
+ uiDevice.launchSplitScreen()
+ nonResizeableApp.reopenAppFromOverview()
+ }
+ assertions {
+ layersTrace {
+ dockedStackDividerIsInvisible()
+ end("appsEndingBounds", enabled = false) {
+ val displayBounds = WindowUtils.getDisplayBounds(rotation)
+ this.hasVisibleRegion(nonResizeableApp.defaultWindowName, displayBounds)
+ }
+ }
+ windowManagerTrace {
+ end {
+ showsAppWindow(nonResizeableApp.defaultWindowName)
+ hidesAppWindow(splitScreenApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun testNonResizeableWhenAlreadyInSplitScreenSecondary() {
+ val testTag = "testNonResizeableWhenAlreadyInSplitScreenSecondary"
+ runWithFlicker(splitScreenSetup) {
+ withTestName { testTag }
+ repeat {
+ TEST_REPETITIONS
+ }
+ transitions {
+ splitScreenApp.launchViaIntent()
+ uiDevice.launchSplitScreen()
+ uiDevice.pressBack()
+ nonResizeableApp.launchViaIntent()
+ }
+ assertions {
+ layersTrace {
+ dockedStackDividerIsInvisible()
+ end("appsEndingBounds", enabled = false) {
+ val displayBounds = WindowUtils.getDisplayBounds(rotation)
+ this.hasVisibleRegion(nonResizeableApp.defaultWindowName, displayBounds)
+ }
+ }
+ windowManagerTrace {
+ end {
+ showsAppWindow(nonResizeableApp.defaultWindowName)
+ hidesAppWindow(splitScreenApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ }
+
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/RotateOneLaunchedAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/RotateOneLaunchedAppTest.kt
new file mode 100644
index 000000000000..be8f9bcdedb6
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/RotateOneLaunchedAppTest.kt
@@ -0,0 +1,146 @@
+/*
+ * 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 android.view.Surface
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.dsl.runWithFlicker
+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.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.dockedStackDividerIsVisible
+import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.Test
+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:RotateOneLaunchedAppTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class RotateOneLaunchedAppTest(
+ rotationName: String,
+ rotation: Int
+) : SplitScreenTestBase(rotationName, rotation) {
+ private val splitScreenRotationSetup: FlickerBuilder
+ get() = FlickerBuilder(instrumentation).apply {
+ val testSetupRotation = "testSetupRotation"
+ withTestName {
+ testSetupRotation
+ }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ }
+ }
+ teardown {
+ eachRun {
+ if (uiDevice.isInSplitScreen()) {
+ uiDevice.exitSplitScreen()
+ }
+ setRotation(Surface.ROTATION_0)
+ splitScreenApp.exit()
+ secondaryApp.exit()
+ }
+ }
+ }
+
+ @Test
+ fun testRotateInSplitScreenMode() {
+ val testTag = "testEnterSplitScreen_launchToSide"
+ runWithFlicker(splitScreenRotationSetup) {
+ withTestName { testTag }
+ repeat {
+ SplitScreenHelper.TEST_REPETITIONS
+ }
+ transitions {
+ splitScreenApp.launchViaIntent()
+ device.launchSplitScreen()
+ setRotation(rotation)
+ }
+ assertions {
+ layersTrace {
+ navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation, 169271943)
+ statusBarLayerRotatesScales(Surface.ROTATION_0, rotation, 169271943)
+ dockedStackDividerIsVisible()
+ dockedStackPrimaryBoundsIsVisible(
+ rotation, splitScreenApp.defaultWindowName, 169271943)
+ }
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ end {
+ showsAppWindow(splitScreenApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun testRotateAndEnterSplitScreenMode() {
+ val testTag = "testRotateAndEnterSplitScreenMode"
+ runWithFlicker(splitScreenRotationSetup) {
+ withTestName { testTag }
+ repeat {
+ SplitScreenHelper.TEST_REPETITIONS
+ }
+ transitions {
+ splitScreenApp.launchViaIntent()
+ setRotation(rotation)
+ device.launchSplitScreen()
+ }
+ assertions {
+ layersTrace {
+ navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation, 169271943)
+ statusBarLayerRotatesScales(Surface.ROTATION_0, rotation, 169271943)
+ dockedStackDividerIsVisible()
+ dockedStackPrimaryBoundsIsVisible(
+ rotation, splitScreenApp.defaultWindowName, 169271943)
+ }
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ end {
+ showsAppWindow(splitScreenApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val supportedRotations = intArrayOf(Surface.ROTATION_90, Surface.ROTATION_270)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/RotateTwoLaunchedAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/RotateTwoLaunchedAppTest.kt
new file mode 100644
index 000000000000..2e05c2a99273
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/RotateTwoLaunchedAppTest.kt
@@ -0,0 +1,157 @@
+/*
+ * 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 android.view.Surface
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.dsl.runWithFlicker
+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.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.wm.shell.flicker.dockedStackDividerIsVisible
+import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisible
+import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisible
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import org.junit.FixMethodOrder
+import org.junit.Test
+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:RotateTwoLaunchedAppTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class RotateTwoLaunchedAppTest(
+ rotationName: String,
+ rotation: Int
+) : SplitScreenTestBase(rotationName, rotation) {
+ private val splitScreenRotationSetup: FlickerBuilder
+ get() = FlickerBuilder(instrumentation).apply {
+ val testSetupRotation = "testSetupRotation"
+ withTestName {
+ testSetupRotation
+ }
+ setup {
+ test {
+ device.wakeUpAndGoToHomeScreen()
+ }
+ }
+ teardown {
+ eachRun {
+ if (uiDevice.isInSplitScreen()) {
+ uiDevice.exitSplitScreen()
+ }
+ setRotation(Surface.ROTATION_0)
+ splitScreenApp.exit()
+ secondaryApp.exit()
+ }
+ }
+ }
+
+ @Test
+ fun testRotateInSplitScreenMode() {
+ val testTag = "testRotateInSplitScreenMode"
+ runWithFlicker(splitScreenRotationSetup) {
+ withTestName { testTag }
+ repeat {
+ SplitScreenHelper.TEST_REPETITIONS
+ }
+ transitions {
+ secondaryApp.launchViaIntent()
+ splitScreenApp.launchViaIntent()
+ device.launchSplitScreen()
+ splitScreenApp.reopenAppFromOverview()
+ setRotation(rotation)
+ }
+ assertions {
+ layersTrace {
+ navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation, 169271943)
+ statusBarLayerRotatesScales(Surface.ROTATION_0, rotation, 169271943)
+ dockedStackDividerIsVisible()
+ dockedStackPrimaryBoundsIsVisible(
+ rotation, splitScreenApp.defaultWindowName, 169271943)
+ dockedStackSecondaryBoundsIsVisible(
+ rotation, secondaryApp.defaultWindowName, 169271943)
+ }
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ end {
+ showsAppWindow(splitScreenApp.defaultWindowName)
+ .and().showsAppWindow(secondaryApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun testRotateAndEnterSplitScreenMode() {
+ val testTag = "testRotateAndEnterSplitScreenMode"
+ runWithFlicker(splitScreenRotationSetup) {
+ withTestName { testTag }
+ repeat {
+ SplitScreenHelper.TEST_REPETITIONS
+ }
+ transitions {
+ secondaryApp.launchViaIntent()
+ splitScreenApp.launchViaIntent()
+ setRotation(rotation)
+ device.launchSplitScreen()
+ splitScreenApp.reopenAppFromOverview()
+ }
+ assertions {
+ layersTrace {
+ navBarLayerRotatesAndScales(Surface.ROTATION_0, rotation, 169271943)
+ statusBarLayerRotatesScales(Surface.ROTATION_0, rotation, 169271943)
+ dockedStackDividerIsVisible()
+ dockedStackPrimaryBoundsIsVisible(
+ rotation, splitScreenApp.defaultWindowName, 169271943)
+ dockedStackSecondaryBoundsIsVisible(
+ rotation, secondaryApp.defaultWindowName, 169271943)
+ }
+ windowManagerTrace {
+ navBarWindowIsAlwaysVisible()
+ statusBarWindowIsAlwaysVisible()
+ end {
+ showsAppWindow(splitScreenApp.defaultWindowName)
+ .and().showsAppWindow(secondaryApp.defaultWindowName)
+ }
+ }
+ }
+ }
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<Array<Any>> {
+ val supportedRotations = intArrayOf(Surface.ROTATION_90, Surface.ROTATION_270)
+ return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
+ }
+ }
+} \ No newline at end of file
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
deleted file mode 100644
index d2371bd766f5..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateOneLaunchedAppTest.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 67346424acd2..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenRotateTwoLaunchedAppTest.kt
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt
index a3440df9ddf8..42c509d6eba8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenTestBase.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen
import com.android.wm.shell.flicker.NonRotationTestBase
+import com.android.wm.shell.flicker.TEST_APP_NONRESIZEABLE_LABEL
import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_PRIMARY_LABEL
import com.android.wm.shell.flicker.TEST_APP_SPLITSCREEN_SECONDARY_LABEL
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
@@ -32,4 +33,7 @@ abstract class SplitScreenTestBase(
protected val secondaryApp = SplitScreenHelper(instrumentation,
TEST_APP_SPLITSCREEN_SECONDARY_LABEL,
Components.SplitScreenSecondaryActivity())
+ protected val nonResizeableApp = SplitScreenHelper(instrumentation,
+ TEST_APP_NONRESIZEABLE_LABEL,
+ Components.NonResizeableActivity())
}
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
index a583b725899b..28ed3431db62 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
@@ -86,6 +86,17 @@
</intent-filter>
</activity>
+ <activity android:name=".NonResizeableActivity"
+ android:resizeableActivity="false"
+ android:taskAffinity="com.android.wm.shell.flicker.testapp.NonResizeableActivity"
+ android:label="NonResizeableApp"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+
<activity android:name=".SimpleActivity"
android:taskAffinity="com.android.wm.shell.flicker.testapp.SimpleActivity"
android:label="SimpleApp"
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_non_resizeable.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_non_resizeable.xml
new file mode 100644
index 000000000000..45d5917f86d6
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_non_resizeable.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="@android:color/holo_orange_light">
+
+ <TextView
+ android:id="@+id/NonResizeableTest"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:gravity="center_vertical|center_horizontal"
+ android:text="NonResizeableActivity"
+ android:textAppearance="?android:attr/textAppearanceLarge"/>
+
+</LinearLayout>
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java
index 8e9b4cb2d53e..f729ea554072 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java
@@ -38,6 +38,13 @@ public class Components {
}
}
+ public static class NonResizeableActivity extends ComponentsInfo {
+ @Override
+ public String getActivityName() {
+ return NonResizeableActivity.class.getSimpleName();
+ }
+ }
+
public static class PipActivity extends ComponentsInfo {
// Intent action that this activity dynamically registers to enter picture-in-picture
public static final String ACTION_ENTER_PIP = PACKAGE_NAME + ".PipActivity.ENTER_PIP";
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/NonResizeableActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/NonResizeableActivity.java
new file mode 100644
index 000000000000..24275e002c7f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/NonResizeableActivity.java
@@ -0,0 +1,29 @@
+/*
+ * 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.testapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class NonResizeableActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.activity_non_resizeable);
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index 3ff750af7ec9..862776ec7df2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -16,18 +16,14 @@
package com.android.wm.shell;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
-import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
-import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_LETTERBOX;
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW;
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -38,7 +34,6 @@ import static org.mockito.Mockito.verify;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.pm.ParceledListSlice;
-import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -47,7 +42,6 @@ import android.window.ITaskOrganizer;
import android.window.ITaskOrganizerController;
import android.window.TaskAppearedInfo;
-import androidx.annotation.Nullable;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -263,28 +257,6 @@ public class ShellTaskOrganizerTests {
assertTrue(mwListener.appeared.contains(task2));
}
- @Test
- public void testTaskInfoToTaskListenerType_whenLetterboxBoundsPassed_returnsLetterboxType() {
- RunningTaskInfo taskInfo = createTaskInfo(
- /* taskId */ 1,
- WINDOWING_MODE_FULLSCREEN,
- /* letterboxActivityBounds */ new Rect(1, 1, 1, 1));
-
- assertEquals(
- ShellTaskOrganizer.taskInfoToTaskListenerType(taskInfo),
- TASK_LISTENER_TYPE_LETTERBOX);
- }
-
- @Test
- public void testTaskInfoToTaskListenerType_whenLetterboxBoundsIsNull_returnsFullscreenType() {
- RunningTaskInfo taskInfo = createTaskInfo(
- /* taskId */ 1, WINDOWING_MODE_FULLSCREEN, /* letterboxActivityBounds */ null);
-
- assertEquals(
- ShellTaskOrganizer.taskInfoToTaskListenerType(taskInfo),
- TASK_LISTENER_TYPE_FULLSCREEN);
- }
-
private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode) {
RunningTaskInfo taskInfo = new RunningTaskInfo();
taskInfo.taskId = taskId;
@@ -292,12 +264,4 @@ public class ShellTaskOrganizerTests {
return taskInfo;
}
- private static RunningTaskInfo createTaskInfo(
- int taskId, int windowingMode, @Nullable Rect letterboxActivityBounds) {
- RunningTaskInfo taskInfo = new RunningTaskInfo();
- taskInfo.taskId = taskId;
- taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode);
- taskInfo.letterboxActivityBounds = Rect.copyOrNull(letterboxActivityBounds);
- return taskInfo;
- }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxConfigControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxConfigControllerTest.java
deleted file mode 100644
index 29233366d4f3..000000000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxConfigControllerTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.letterbox;
-
-import static org.junit.Assert.assertEquals;
-
-import android.view.Gravity;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.R;
-import com.android.wm.shell.ShellTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for {@link LetterboxConfigController}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class LetterboxConfigControllerTest extends ShellTestCase {
-
- private LetterboxConfigController mLetterboxConfigController;
-
- @Before
- public void setUp() {
- mLetterboxConfigController = new LetterboxConfigController(getContext());
- }
-
- @Test
- public void testGetPortraitGravity_noOverrides_returnConfigValue() {
- assertEquals(
- mLetterboxConfigController.getPortraitGravity(),
- getContext().getResources().getInteger(R.integer.config_letterboxPortraitGravity));
- }
-
- @Test
- public void testGetLandscapeGravity_noOverrides_returnConfigValue() {
- assertEquals(
- mLetterboxConfigController.getLandscapeGravity(),
- getContext().getResources().getInteger(R.integer.config_letterboxLandscapeGravity));
- }
-
- @Test
- public void testSetPortraitGravity_validValue_savesValue() {
- mLetterboxConfigController.setPortraitGravity(Gravity.BOTTOM);
- assertEquals(mLetterboxConfigController.getPortraitGravity(), Gravity.BOTTOM);
-
- mLetterboxConfigController.setPortraitGravity(Gravity.CENTER);
- assertEquals(mLetterboxConfigController.getPortraitGravity(), Gravity.CENTER);
-
- mLetterboxConfigController.setPortraitGravity(Gravity.TOP);
- assertEquals(mLetterboxConfigController.getPortraitGravity(), Gravity.TOP);
- }
-
- @Test
- public void testSetLandscapeGravity_validValue_savesValue() {
- mLetterboxConfigController.setLandscapeGravity(Gravity.LEFT);
- assertEquals(mLetterboxConfigController.getLandscapeGravity(), Gravity.LEFT);
-
- mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER);
- assertEquals(mLetterboxConfigController.getLandscapeGravity(), Gravity.CENTER);
-
- mLetterboxConfigController.setLandscapeGravity(Gravity.RIGHT);
- assertEquals(mLetterboxConfigController.getLandscapeGravity(), Gravity.RIGHT);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSetPortraitGravity_invalidValue_throwsException() {
- mLetterboxConfigController.setPortraitGravity(Gravity.RIGHT);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSetLandscapeGravity_invalidValue_throwsException() {
- mLetterboxConfigController.setLandscapeGravity(Gravity.TOP);
- }
-
- @Test
- public void testResetPortraitGravity() {
- int defaultGravity =
- getContext().getResources().getInteger(R.integer.config_letterboxPortraitGravity);
-
- mLetterboxConfigController.setPortraitGravity(Gravity.BOTTOM);
- mLetterboxConfigController.resetPortraitGravity();
- assertEquals(mLetterboxConfigController.getPortraitGravity(), defaultGravity);
-
- mLetterboxConfigController.setPortraitGravity(Gravity.CENTER);
- mLetterboxConfigController.resetPortraitGravity();
- assertEquals(mLetterboxConfigController.getPortraitGravity(), defaultGravity);
-
- mLetterboxConfigController.setPortraitGravity(Gravity.TOP);
- mLetterboxConfigController.resetPortraitGravity();
- assertEquals(mLetterboxConfigController.getPortraitGravity(), defaultGravity);
- }
-
- @Test
- public void testResetLandscapeGravity() {
- int defaultGravity =
- getContext().getResources().getInteger(R.integer.config_letterboxLandscapeGravity);
-
- mLetterboxConfigController.setLandscapeGravity(Gravity.RIGHT);
- mLetterboxConfigController.resetLandscapeGravity();
- assertEquals(mLetterboxConfigController.getLandscapeGravity(), defaultGravity);
-
- mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER);
- mLetterboxConfigController.resetLandscapeGravity();
- assertEquals(mLetterboxConfigController.getLandscapeGravity(), defaultGravity);
-
- mLetterboxConfigController.setLandscapeGravity(Gravity.LEFT);
- mLetterboxConfigController.resetLandscapeGravity();
- assertEquals(mLetterboxConfigController.getLandscapeGravity(), defaultGravity);
- }
-
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxTaskListenerTest.java
deleted file mode 100644
index 5cbc7d927d61..000000000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/letterbox/LetterboxTaskListenerTest.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * 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.letterbox;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager.RunningTaskInfo;
-import android.graphics.Insets;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.Looper;
-import android.view.Gravity;
-import android.view.SurfaceControl;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-import android.view.WindowMetrics;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.TransactionPool;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for {@link LetterboxTaskListener}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class LetterboxTaskListenerTest extends ShellTestCase {
-
- @Mock private SurfaceControl mLeash;
- @Mock private SurfaceControl.Transaction mTransaction;
- @Mock private WindowManager mWindowManager;
- @Mock private WindowMetrics mWindowMetrics;
- @Mock private WindowInsets mWindowInsets;
- private LetterboxTaskListener mLetterboxTaskListener;
- private LetterboxConfigController mLetterboxConfigController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mLetterboxConfigController = new LetterboxConfigController(getContext());
- mLetterboxTaskListener = new LetterboxTaskListener(
- new SyncTransactionQueue(
- new TransactionPool() {
- @Override
- public SurfaceControl.Transaction acquire() {
- return mTransaction;
- }
-
- @Override
- public void release(SurfaceControl.Transaction t) {
- }
- },
- new Handler(Looper.getMainLooper())),
- mLetterboxConfigController,
- mWindowManager);
-
- when(mWindowManager.getMaximumWindowMetrics()).thenReturn(mWindowMetrics);
- when(mWindowMetrics.getWindowInsets()).thenReturn(mWindowInsets);
- }
-
- @Test
- public void testOnTaskInfoChanged_updatesPositionAndCrop() {
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds
- Insets.NONE);
-
- mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER);
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 200, 100),
- /* activityBounds */ new Rect(75, 0, 125, 75),
- /* taskBounds */ new Rect(50, 0, 125, 100),
- /* activityInsets */ new Rect(0, 0, 0, 0)),
- mLeash);
-
- // Task doesn't need to repositioned
- verifySetPosition(50, 0);
- // Should return activity coordinates offset by task coordinates
- verifySetWindowCrop(new Rect(25, 0, 75, 75));
-
- mLetterboxTaskListener.onTaskInfoChanged(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 200, 100),
- // Activity is offset by 25 to the left
- /* activityBounds */ new Rect(50, 0, 100, 75),
- /* taskBounds */ new Rect(50, 0, 125, 100),
- /* activityInsets */ new Rect(0, 0, 0, 0)));
-
- // Task needs to be repositioned by 25 to the left
- verifySetPosition(75, 0);
- // Should return activity coordinates offset by task coordinates
- verifySetWindowCrop(new Rect(0, 0, 50, 75));
- }
-
- @Test
- public void testOnTaskInfoAppeared_landscapeWithLeftGravity() {
- mLetterboxConfigController.setLandscapeGravity(Gravity.LEFT);
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds
- Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 10));
-
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 200, 100),
- /* activityBounds */ new Rect(150, 0, 200, 75),
- /* taskBounds */ new Rect(125, 0, 200, 100),
- /* activityInsets */ new Rect(0, 10, 10, 0)),
- mLeash);
-
- verifySetPosition(-15, 0);
- // Should return activity coordinates offset by task coordinates minus unwanted right inset
- verifySetWindowCrop(new Rect(25, 0, 65, 75));
- }
-
- @Test
- public void testOnTaskInfoAppeared_landscapeWithCenterGravity() {
- mLetterboxConfigController.setLandscapeGravity(Gravity.CENTER);
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds
- Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 10));
-
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 200, 100),
- /* activityBounds */ new Rect(150, 0, 200, 75),
- /* taskBounds */ new Rect(125, 0, 200, 100),
- /* activityInsets */ new Rect(0, 10, 10, 0)),
- mLeash);
-
- verifySetPosition(55, 0);
- // Should return activity coordinates offset by task coordinates minus unwanted right inset
- verifySetWindowCrop(new Rect(25, 0, 65, 75));
- }
-
- @Test
- public void testOnTaskInfoAppeared_landscapeWithRightGravity() {
- mLetterboxConfigController.setLandscapeGravity(Gravity.RIGHT);
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds
- Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 10));
-
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 200, 100), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 200, 100),
- /* activityBounds */ new Rect(50, 0, 100, 75),
- /* taskBounds */ new Rect(25, 0, 100, 100),
- /* activityInsets */ new Rect(0, 10, 10, 0)),
- mLeash);
-
- verifySetPosition(115, 0);
- // Should return activity coordinates offset by task coordinates
- verifySetWindowCrop(new Rect(25, 0, 75, 75));
- }
-
- @Test
- public void testOnTaskInfoAppeared_portraitWithTopGravity() {
- mLetterboxConfigController.setPortraitGravity(Gravity.TOP);
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds
- Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 20));
-
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 100, 150),
- /* activityBounds */ new Rect(0, 75, 50, 125),
- /* taskBounds */ new Rect(0, 50, 100, 125),
- /* activityInsets */ new Rect(10, 0, 0, 0)),
- mLeash);
-
- verifySetPosition(20, -15);
- // Should return activity coordinates offset by task coordinates minus unwanted left inset
- verifySetWindowCrop(new Rect(10, 25, 50, 75));
- }
-
- @Test
- public void testOnTaskInfoAppeared_portraitWithCenterGravity() {
- mLetterboxConfigController.setPortraitGravity(Gravity.CENTER);
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds
- Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 20));
-
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 100, 150),
- /* activityBounds */ new Rect(0, 75, 50, 125),
- /* taskBounds */ new Rect(0, 50, 100, 125),
- /* activityInsets */ new Rect(10, 0, 0, 0)),
- mLeash);
-
- verifySetPosition(20, 20);
- // Should return activity coordinates offset by task coordinates minus unwanted left inset
- verifySetWindowCrop(new Rect(10, 25, 50, 75));
- }
-
- @Test
- public void testOnTaskInfoAppeared_portraitWithCenterGravity_visibleLeftInset() {
- mLetterboxConfigController.setPortraitGravity(Gravity.CENTER);
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds
- Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 20));
-
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 100, 150),
- /* activityBounds */ new Rect(0, 75, 50, 125),
- /* taskBounds */ new Rect(0, 50, 100, 125),
- // Activity is drawn under the left inset.
- /* activityInsets */ new Rect(0, 0, 0, 0)),
- mLeash);
-
- verifySetPosition(20, 20);
- // Should return activity coordinates offset by task coordinates
- verifySetWindowCrop(new Rect(0, 25, 50, 75));
- }
-
- @Test
- public void testOnTaskInfoAppeared_portraitWithBottomGravity() {
- mLetterboxConfigController.setPortraitGravity(Gravity.BOTTOM);
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds
- Insets.of(/* left= */ 10, /* top= */ 10, /* right= */ 10, /* bottom= */ 20));
-
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 100, 150), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 100, 150),
- /* activityBounds */ new Rect(0, 75, 50, 125),
- /* taskBounds */ new Rect(0, 50, 100, 125),
- /* activityInsets */ new Rect(10, 0, 0, 0)),
- mLeash);
-
- verifySetPosition(20, 55);
- // Should return activity coordinates offset by task coordinates minus unwanted left inset
- verifySetWindowCrop(new Rect(10, 25, 50, 75));
- }
-
- @Test
- public void testOnTaskInfoAppeared_partlyOverlapsWithAllInsets() {
- mLetterboxConfigController.setPortraitGravity(Gravity.TOP);
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 200, 125), // equal to parent bounds
- Insets.of(/* left= */ 25, /* top= */ 25, /* right= */ 35, /* bottom= */ 15));
-
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 200, 125), // equal to parent bounds
- /* parentBounds */ new Rect(0, 0, 200, 125),
- /* activityBounds */ new Rect(15, 0, 175, 120),
- /* taskBounds */ new Rect(0, 0, 200, 125),
- /* activityInsets */ new Rect(10, 25, 10, 10)), // equal to parent bounds
- mLeash);
-
- // Activity fully covers parent bounds with insets so doesn't need to be moved.
- verifySetPosition(0, 0);
- // Should return activity coordinates offset by task coordinates
- verifySetWindowCrop(new Rect(15, 0, 175, 120));
- }
-
- @Test
- public void testOnTaskInfoAppeared_parentShiftedLikeInOneHandedMode() {
- mLetterboxConfigController.setPortraitGravity(Gravity.TOP);
- setWindowBoundsAndInsets(
- /* windowBounds= */ new Rect(0, 0, 100, 150),
- Insets.of(/* left= */ 0, /* top= */ 10, /* right= */ 0, /* bottom= */ 0));
-
- mLetterboxTaskListener.onTaskAppeared(
- createTaskInfo(
- /* taskId */ 1,
- /* maxBounds= */ new Rect(0, 0, 100, 150),
- /* parentBounds */ new Rect(0, 75, 100, 225),
- /* activityBounds */ new Rect(25, 75, 75, 125),
- /* taskBounds */ new Rect(0, 75, 100, 125),
- /* activityInsets */ new Rect(10, 0, 0, 0)),
- mLeash);
-
- verifySetPosition(0, 0);
- verifySetWindowCrop(new Rect(25, 0, 75, 50));
- }
-
- @Test(expected = IllegalStateException.class)
- public void testOnTaskAppeared_calledSecondTimeWithSameTaskId_throwsException() {
- setWindowBoundsAndInsets(new Rect(), Insets.NONE);
- RunningTaskInfo taskInfo =
- createTaskInfo(/* taskId */ 1, new Rect(), new Rect(), new Rect(), new Rect(),
- new Rect());
- mLetterboxTaskListener.onTaskAppeared(taskInfo, mLeash);
- mLetterboxTaskListener.onTaskAppeared(taskInfo, mLeash);
- }
-
- private void setWindowBoundsAndInsets(Rect windowBounds, Insets insets) {
- when(mWindowMetrics.getBounds()).thenReturn(windowBounds);
- when(mWindowInsets.getInsets(anyInt())).thenReturn(insets);
- }
-
- private void verifySetPosition(int x, int y) {
- verify(mTransaction).setPosition(eq(mLeash), eq((float) x), eq((float) y));
- }
-
- private void verifySetWindowCrop(final Rect crop) {
- // Should return activty coordinates offset by task coordinates
- verify(mTransaction).setWindowCrop(eq(mLeash), eq(crop));
- }
-
- private static RunningTaskInfo createTaskInfo(
- int taskId,
- final Rect maxBounds,
- final Rect parentBounds,
- final Rect activityBounds,
- final Rect taskBounds,
- final Rect activityInsets) {
- RunningTaskInfo taskInfo = new RunningTaskInfo();
- taskInfo.taskId = taskId;
- taskInfo.configuration.windowConfiguration.setMaxBounds(maxBounds);
- taskInfo.parentBounds = parentBounds;
- taskInfo.configuration.windowConfiguration.setBounds(taskBounds);
- taskInfo.letterboxActivityBounds = Rect.copyOrNull(activityBounds);
- taskInfo.letterboxActivityInsets = Rect.copyOrNull(activityInsets);
-
- return taskInfo;
- }
-}
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 068f9689d06f..4b8a8adade1f 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -73,6 +73,8 @@ interface IMediaRouterService {
void unregisterManager(IMediaRouter2Manager manager);
void setRouteVolumeWithManager(IMediaRouter2Manager manager, int requestId,
in MediaRoute2Info route, int volume);
+ void startScan(IMediaRouter2Manager manager);
+ void stopScan(IMediaRouter2Manager manager);
void requestCreateSessionWithManager(IMediaRouter2Manager manager, int requestId,
in RoutingSessionInfo oldSession, in @nullable MediaRoute2Info route);
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index c2168f12a351..e7e83ebb001f 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -25,6 +25,7 @@ import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
+import android.os.Process;
import android.os.SystemProperties;
import android.util.Log;
import android.util.Pair;
@@ -188,13 +189,14 @@ public final class MediaCodecInfo {
// COMMON CONSTANTS
private static final Range<Integer> POSITIVE_INTEGERS =
- Range.create(1, Integer.MAX_VALUE);
+ Range.create(1, Integer.MAX_VALUE);
private static final Range<Long> POSITIVE_LONGS =
- Range.create(1l, Long.MAX_VALUE);
+ Range.create(1L, Long.MAX_VALUE);
private static final Range<Rational> POSITIVE_RATIONALS =
- Range.create(new Rational(1, Integer.MAX_VALUE),
- new Rational(Integer.MAX_VALUE, 1));
- private static final Range<Integer> SIZE_RANGE = Range.create(1, 32768);
+ Range.create(new Rational(1, Integer.MAX_VALUE),
+ new Rational(Integer.MAX_VALUE, 1));
+ private static final Range<Integer> SIZE_RANGE =
+ Process.is64Bit() ? Range.create(1, 32768) : Range.create(1, 4096);
private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960);
private static final Range<Integer> BITRATE_RANGE = Range.create(0, 500000000);
private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32;
@@ -1399,6 +1401,9 @@ public final class MediaCodecInfo {
/**
* Returns the range of supported video widths.
+ * <p class=note>
+ * 32-bit processes will not support resolutions larger than 4096x4096 due to
+ * the limited address space.
*/
public Range<Integer> getSupportedWidths() {
return mWidthRange;
@@ -1406,6 +1411,9 @@ public final class MediaCodecInfo {
/**
* Returns the range of supported video heights.
+ * <p class=note>
+ * 32-bit processes will not support resolutions larger than 4096x4096 due to
+ * the limited address space.
*/
public Range<Integer> getSupportedHeights() {
return mHeightRange;
@@ -1857,6 +1865,10 @@ public final class MediaCodecInfo {
&& aligned.mMaxMacroBlockRate >= otherAligned.mMaxMacroBlockRate);
}
+ /* package private */ boolean isEqualDimension(@NonNull PerformancePoint other) {
+ return mWidth == other.mWidth && mHeight == other.mHeight;
+ }
+
private @NonNull Size getCommonBlockSize(@NonNull PerformancePoint other) {
return new Size(
Math.max(mBlockSize.getWidth(), other.mBlockSize.getWidth()) * 16,
@@ -1997,6 +2009,9 @@ public final class MediaCodecInfo {
* Performance points assume a single active codec. For use cases where multiple
* codecs are active, should use that highest pixel count, and add the frame rates of
* each individual codec.
+ * <p class=note>
+ * Supported resolution could be further restricted for 32-bit processes due to
+ * the limited virtual memory space.
*/
@Nullable
public List<PerformancePoint> getSupportedPerformancePoints() {
@@ -2164,6 +2179,12 @@ public final class MediaCodecInfo {
if (size == null || size.getWidth() * size.getHeight() <= 0) {
continue;
}
+ if (size.getWidth() > SIZE_RANGE.getUpper()
+ || size.getHeight() > SIZE_RANGE.getUpper()) {
+ size = new Size(
+ Math.min(size.getWidth(), SIZE_RANGE.getUpper()),
+ Math.min(size.getHeight(), SIZE_RANGE.getUpper()));
+ }
Range<Long> range = Utils.parseLongRange(map.get(key), null);
if (range == null || range.getLower() < 0 || range.getUpper() < 0) {
continue;
@@ -2193,6 +2214,29 @@ public final class MediaCodecInfo {
(a.getMaxMacroBlockRate() < b.getMaxMacroBlockRate() ? -1 : 1) :
(a.getMaxFrameRate() != b.getMaxFrameRate()) ?
(a.getMaxFrameRate() < b.getMaxFrameRate() ? -1 : 1) : 0));
+
+ // remove redundant points
+ for (int i = 1; i < ret.size(); ++i) {
+ PerformancePoint a = ret.get(i);
+ for (int j = 0; j < i; ++j) {
+ PerformancePoint b = ret.get(j);
+ if (b.isEqualDimension(a) && b.covers(a)) {
+ ret.set(i, null);
+ break;
+ }
+ }
+ }
+ int newSize = 0;
+ for (int i = 0; i < ret.size(); ++i) {
+ PerformancePoint a = ret.get(i);
+ if (a == null) {
+ continue;
+ }
+ ret.set(newSize, a);
+ ++newSize;
+ }
+ ret.setSize(newSize);
+
return Collections.unmodifiableList(ret);
}
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 4b09a5f19fb0..68237de2ca98 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -147,6 +147,36 @@ public final class MediaRouter2Manager {
}
/**
+ * Starts scanning remote routes.
+ * @see #stopScan(String)
+ */
+ public void startScan() {
+ Client client = getOrCreateClient();
+ if (client != null) {
+ try {
+ mMediaRouterService.startScan(client);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
+ }
+ }
+ }
+
+ /**
+ * Stops scanning remote routes to reduce resource consumption.
+ * @see #startScan(String)
+ */
+ public void stopScan() {
+ Client client = getOrCreateClient();
+ if (client != null) {
+ try {
+ mMediaRouterService.stopScan(client);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
+ }
+ }
+ }
+
+ /**
* Gets a {@link android.media.session.MediaController} associated with the
* given routing session.
* If there is no matching media session, {@code null} is returned.
diff --git a/media/java/android/media/RouteDiscoveryPreference.java b/media/java/android/media/RouteDiscoveryPreference.java
index 68f2964dbeb2..2f952474b7f0 100644
--- a/media/java/android/media/RouteDiscoveryPreference.java
+++ b/media/java/android/media/RouteDiscoveryPreference.java
@@ -153,6 +153,7 @@ public final class RouteDiscoveryPreference implements Parcelable {
return false;
}
RouteDiscoveryPreference other = (RouteDiscoveryPreference) o;
+ //TODO: Make this order-free
return Objects.equals(mPreferredFeatures, other.mPreferredFeatures)
&& mShouldPerformActiveScan == other.mShouldPerformActiveScan;
}
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index d094c2cd3c63..20f02a46ea63 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -279,6 +279,7 @@ public class Tuner implements AutoCloseable {
@Nullable
private FrontendInfo mFrontendInfo;
private Integer mFrontendHandle;
+ private Boolean mIsSharedFrontend = false;
private int mFrontendType = FrontendSettings.TYPE_UNDEFINED;
private int mUserId;
private Lnb mLnb;
@@ -441,8 +442,11 @@ public class Tuner implements AutoCloseable {
*/
public void shareFrontendFromTuner(@NonNull Tuner tuner) {
mTunerResourceManager.shareFrontend(mClientId, tuner.mClientId);
- mFrontendHandle = tuner.mFrontendHandle;
- mFrontend = nativeOpenFrontendByHandle(mFrontendHandle);
+ synchronized (mIsSharedFrontend) {
+ mFrontendHandle = tuner.mFrontendHandle;
+ mFrontend = tuner.mFrontend;
+ mIsSharedFrontend = true;
+ }
}
/**
@@ -473,14 +477,19 @@ public class Tuner implements AutoCloseable {
private void releaseAll() {
if (mFrontendHandle != null) {
- int res = nativeCloseFrontend(mFrontendHandle);
- if (res != Tuner.RESULT_SUCCESS) {
- TunerUtils.throwExceptionForResult(res, "failed to close frontend");
+ synchronized (mIsSharedFrontend) {
+ if (!mIsSharedFrontend) {
+ int res = nativeCloseFrontend(mFrontendHandle);
+ if (res != Tuner.RESULT_SUCCESS) {
+ TunerUtils.throwExceptionForResult(res, "failed to close frontend");
+ }
+ }
+ mIsSharedFrontend = false;
}
mTunerResourceManager.releaseFrontend(mFrontendHandle, mClientId);
FrameworkStatsLog
.write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
- FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__UNKNOWN);
+ FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__UNKNOWN);
mFrontendHandle = null;
mFrontend = null;
}
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 948ebcd9fdd5..6a622c5a1566 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -68,7 +68,7 @@ JMediaExtractor::JMediaExtractor(JNIEnv *env, jobject thiz)
mClass = (jclass)env->NewGlobalRef(clazz);
mObject = env->NewWeakGlobalRef(thiz);
- mImpl = new NuMediaExtractor;
+ mImpl = new NuMediaExtractor(NuMediaExtractor::EntryPoint::SDK);
}
JMediaExtractor::~JMediaExtractor() {
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 126897a908f8..ddc51cdb861c 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -464,11 +464,13 @@ static jobject android_media_MediaMetadataRetriever_getThumbnailImageAtIndex(
|| thumbPixels * 6 >= maxPixels) {
frameMemory = retriever->getImageAtIndex(
index, colorFormat, false /*metaOnly*/, true /*thumbnail*/);
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- videoFrame = static_cast<VideoFrame *>(frameMemory->unsecurePointer());
+ if (frameMemory != 0) {
+ // TODO: Using unsecurePointer() has some associated security pitfalls
+ // (see declaration for details).
+ // Either document why it is safe in this case or address the
+ // issue (e.g. by copying).
+ videoFrame = static_cast<VideoFrame *>(frameMemory->unsecurePointer());
+ }
if (thumbPixels > maxPixels) {
int downscale = ceil(sqrt(thumbPixels / (float)maxPixels));
diff --git a/media/native/midi/amidi.cpp b/media/native/midi/amidi.cpp
index 35c4d42a0aa8..923377c8180e 100644
--- a/media/native/midi/amidi.cpp
+++ b/media/native/midi/amidi.cpp
@@ -131,7 +131,7 @@ static media_status_t AMIDI_getDeviceInfo(const AMidiDevice *device,
MidiDeviceInfo deviceInfo;
Status txResult = device->server->getDeviceInfo(&deviceInfo);
if (!txResult.isOk()) {
- ALOGE("AMIDI_getDeviceInfo transaction error: %d", txResult.transactionError());
+ ALOGE("%s server exception code: %d", __func__, txResult.exceptionCode());
return AMEDIA_ERROR_UNKNOWN;
}
@@ -253,7 +253,7 @@ static media_status_t AMIDI_openPort(const AMidiDevice *device, int32_t portNumb
? device->server->openOutputPort(portToken, portNumber, &ufd)
: device->server->openInputPort(portToken, portNumber, &ufd);
if (!txResult.isOk()) {
- ALOGE("AMIDI_openPort transaction error: %d", txResult.transactionError());
+ ALOGE("%s server exception code: %d", __func__, txResult.exceptionCode());
return AMEDIA_ERROR_UNKNOWN;
}
@@ -282,7 +282,7 @@ static void AMIDI_closePort(AMIDI_Port *port) {
Status txResult = port->device->server->closePort(port->binderToken);
if (!txResult.isOk()) {
- ALOGE("Transaction error closing MIDI port:%d", txResult.transactionError());
+ ALOGE("%s server exception code: %d", __func__, txResult.exceptionCode());
}
delete port;
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 4e9721218a02..ca0686751873 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1112,7 +1112,7 @@
<string name="power_remaining_charging_duration_only"><xliff:g id="time">%1$s</xliff:g> left until charged</string>
<!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
<string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> until charged</string>
- <!-- [CHAR_LIMIT=40] Label for battery level chart when charge been limited -->
+ <!-- [CHAR_LIMIT=80] Label for battery level chart when charge been limited -->
<string name="power_charging_limited"><xliff:g id="level">%1$s</xliff:g> - Optimizing for battery health</string>
<!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
index 611c4b766b4e..fa2f8b97b039 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
@@ -137,4 +137,15 @@ public class RecentsAnimationControllerCompat {
return false;
}
}
+
+ /**
+ * @see IRecentsAnimationController#detachNavigationBarFromApp
+ */
+ public void detachNavigationBarFromApp() {
+ try {
+ mAnimationController.detachNavigationBarFromApp();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to detach the navigation bar from app", e);
+ }
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index eb86128a82a5..9e2538977fab 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.media.MediaMetadata;
import android.media.MediaRoute2Info;
+import android.media.MediaRouter2Manager;
import android.media.RoutingSessionInfo;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
@@ -76,6 +77,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
private final boolean mAboveStatusbar;
private final NotificationEntryManager mNotificationEntryManager;
+ private final MediaRouter2Manager mRouterManager;
@VisibleForTesting
final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
@@ -104,6 +106,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName);
mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
mUiEventLogger = uiEventLogger;
+ mRouterManager = MediaRouter2Manager.getInstance(mContext);
}
void start(@NonNull Callback cb) {
@@ -134,6 +137,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
mLocalMediaManager.stopScan();
mLocalMediaManager.registerCallback(this);
mLocalMediaManager.startScan();
+ mRouterManager.startScan();
}
void stop() {
@@ -144,6 +148,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
mLocalMediaManager.unregisterCallback(this);
mLocalMediaManager.stopScan();
}
+ if (mRouterManager != null) {
+ mRouterManager.stopScan();
+ }
mMediaDevices.clear();
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index 654e92270c9a..ee58947a691c 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -57,8 +57,6 @@ import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
-import com.android.wm.shell.letterbox.LetterboxConfigController;
-import com.android.wm.shell.letterbox.LetterboxTaskListener;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.pip.Pip;
@@ -173,7 +171,6 @@ public abstract class WMShellBaseModule {
ShellTaskOrganizer shellTaskOrganizer,
Optional<SplitScreen> splitScreenOptional,
Optional<AppPairs> appPairsOptional,
- LetterboxTaskListener letterboxTaskListener,
FullscreenTaskListener fullscreenTaskListener,
Transitions transitions) {
return new ShellInit(displayImeController,
@@ -181,7 +178,6 @@ public abstract class WMShellBaseModule {
shellTaskOrganizer,
splitScreenOptional,
appPairsOptional,
- letterboxTaskListener,
fullscreenTaskListener,
transitions);
}
@@ -198,11 +194,9 @@ public abstract class WMShellBaseModule {
Optional<Pip> pipOptional,
Optional<OneHanded> oneHandedOptional,
Optional<HideDisplayCutout> hideDisplayCutout,
- Optional<AppPairs> appPairsOptional,
- LetterboxConfigController letterboxConfigController) {
+ Optional<AppPairs> appPairsOptional) {
return Optional.of(new ShellCommandHandler(shellTaskOrganizer, splitScreenOptional,
- pipOptional, oneHandedOptional, hideDisplayCutout, appPairsOptional,
- letterboxConfigController));
+ pipOptional, oneHandedOptional, hideDisplayCutout, appPairsOptional));
}
@WMSingleton
@@ -338,21 +332,6 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
- static LetterboxTaskListener provideLetterboxTaskListener(
- SyncTransactionQueue syncQueue,
- LetterboxConfigController letterboxConfigController,
- WindowManager windowManager) {
- return new LetterboxTaskListener(syncQueue, letterboxConfigController, windowManager);
- }
-
- @WMSingleton
- @Provides
- static LetterboxConfigController provideLetterboxConfigController(Context context) {
- return new LetterboxConfigController(context);
- }
-
- @WMSingleton
- @Provides
static Transitions provideTransitions(ShellTaskOrganizer organizer, TransactionPool pool,
@ShellMainThread ShellExecutor mainExecutor,
@ShellAnimationThread ShellExecutor animExecutor) {
diff --git a/services/autofill/java/com/android/server/autofill/TEST_MAPPING b/services/autofill/java/com/android/server/autofill/TEST_MAPPING
index cf058add0262..d8a69177387d 100644
--- a/services/autofill/java/com/android/server/autofill/TEST_MAPPING
+++ b/services/autofill/java/com/android/server/autofill/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit": [
+ "presubmit-large": [
{
"name": "CtsAutoFillServiceTestCases",
"options": [
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 0a80b02a964c..e6e52de0440f 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -40,6 +40,7 @@ import android.bluetooth.BluetoothDevice;
import android.companion.Association;
import android.companion.AssociationRequest;
import android.companion.CompanionDeviceManager;
+import android.companion.DeviceNotAssociatedException;
import android.companion.ICompanionDeviceDiscoveryService;
import android.companion.ICompanionDeviceManager;
import android.companion.IFindDeviceCallback;
@@ -486,6 +487,43 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
a -> Objects.equals(a.getDeviceMacAddress(), macAddress));
}
+ @Override
+ public void registerDevicePresenceListenerService(
+ String packageName, String deviceAddress)
+ throws RemoteException {
+ checkCanRegisterObserverService(packageName, deviceAddress);
+
+ //TODO(eugenesusla) implement
+ }
+
+ @Override
+ public void unregisterDevicePresenceListenerService(
+ String packageName, String deviceAddress)
+ throws RemoteException {
+ checkCanRegisterObserverService(packageName, deviceAddress);
+
+ //TODO(eugenesusla) implement
+ }
+
+ private void checkCanRegisterObserverService(String packageName, String deviceAddress)
+ throws RemoteException {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE,
+ "[un]registerDevicePresenceListenerService");
+ checkCallerIsSystemOr(packageName);
+
+ int userId = getCallingUserId();
+ Set<Association> deviceAssociations = CollectionUtils.filter(
+ getAllAssociations(userId, packageName),
+ association -> deviceAddress.equals(association.getDeviceMacAddress()));
+
+ if (deviceAssociations.isEmpty()) {
+ throw new RemoteException(new DeviceNotAssociatedException("App " + packageName
+ + " is not associated with device " + deviceAddress
+ + " for user " + userId));
+ }
+ }
+
private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
checkCallerIsSystemOr(callingPackage);
int userId = getCallingUserId();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index f87892950a00..a6559f9521e0 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -129,6 +129,7 @@ import android.net.RouteInfoParcel;
import android.net.SocketKeepalive;
import android.net.TetheringManager;
import android.net.UidRange;
+import android.net.UidRangeParcel;
import android.net.Uri;
import android.net.VpnManager;
import android.net.VpnService;
@@ -2822,6 +2823,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
break;
}
case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: {
+ // TODO: prevent loops, e.g., if a network declares itself as underlying.
if (!nai.supportsUnderlyingNetworks()) {
Log.wtf(TAG, "Non-virtual networks cannot have underlying networks");
break;
@@ -3421,6 +3423,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
nai.clearLingerState();
+ propagateUnderlyingNetworkCapabilities(nai.network);
if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
mDefaultNetworkNai = null;
updateDataActivityTracking(null /* newNetwork */, nai);
@@ -3428,9 +3431,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
ensureNetworkTransitionWakelock(nai.toShortString());
}
mLegacyTypeTracker.remove(nai, wasDefault);
- if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) {
- propagateUnderlyingNetworkCapabilities();
- }
rematchAllNetworksAndRequests();
mLingerMonitor.noteDisconnect(nai);
if (nai.created) {
@@ -4819,17 +4819,35 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ private Network[] underlyingNetworksOrDefault(Network[] underlyingNetworks) {
+ final Network defaultNetwork = getNetwork(getDefaultNetwork());
+ if (underlyingNetworks == null && defaultNetwork != null) {
+ // null underlying networks means to track the default.
+ underlyingNetworks = new Network[] { defaultNetwork };
+ }
+ return underlyingNetworks;
+ }
+
+ // Returns true iff |network| is an underlying network of |nai|.
+ private boolean hasUnderlyingNetwork(NetworkAgentInfo nai, Network network) {
+ // TODO: support more than one level of underlying networks, either via a fixed-depth search
+ // (e.g., 2 levels of underlying networks), or via loop detection, or....
+ if (!nai.supportsUnderlyingNetworks()) return false;
+ final Network[] underlying = underlyingNetworksOrDefault(nai.declaredUnderlyingNetworks);
+ return ArrayUtils.contains(underlying, network);
+ }
+
/**
- * Ask all networks with underlying networks to recompute and update their capabilities.
+ * Recompute the capabilities for any networks that had a specific network as underlying.
*
* When underlying networks change, such networks may have to update capabilities to reflect
* things like the metered bit, their transports, and so on. The capabilities are calculated
* immediately. This method runs on the ConnectivityService thread.
*/
- private void propagateUnderlyingNetworkCapabilities() {
+ private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) {
ensureRunningOnConnectivityServiceThread();
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
- if (nai.supportsUnderlyingNetworks()) {
+ if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) {
updateCapabilitiesForNetwork(nai);
}
}
@@ -5152,7 +5170,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
loge("Starting user already has a VPN");
return;
}
- userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, userId, mKeyStore);
+ userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, mNetd, userId, mKeyStore);
mVpns.put(userId, userVpn);
if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
updateLockdownVpn();
@@ -6368,27 +6386,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
* This method should never alter the agent's NetworkCapabilities, only store data in |nai|.
*/
private void processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc) {
- nai.declaredMetered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED);
+ // Note: resetting the owner UID before storing the agent capabilities in NAI means that if
+ // the agent attempts to change the owner UID, then nai.declaredCapabilities will not
+ // actually be the same as the capabilities sent by the agent. Still, it is safer to reset
+ // the owner UID here and behave as if the agent had never tried to change it.
if (nai.networkCapabilities.getOwnerUid() != nc.getOwnerUid()) {
Log.e(TAG, nai.toShortString() + ": ignoring attempt to change owner from "
+ nai.networkCapabilities.getOwnerUid() + " to " + nc.getOwnerUid());
nc.setOwnerUid(nai.networkCapabilities.getOwnerUid());
}
+ nai.declaredCapabilities = new NetworkCapabilities(nc);
}
- /** Modifies |caps| based on the capabilities of the specified underlying networks. */
+ /** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */
@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 };
+ @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) {
+ underlyingNetworks = underlyingNetworksOrDefault(underlyingNetworks);
+ int[] transportTypes = agentCaps.getTransportTypes();
int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
- boolean metered = declaredMetered; // metered if any underlying is metered, or agentMetered
+ // metered if any underlying is metered, or originally declared metered by the agent.
+ boolean metered = !agentCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
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
@@ -6434,13 +6453,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
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);
+ newNc.setTransportTypes(transportTypes);
+ newNc.setLinkDownstreamBandwidthKbps(downKbps);
+ newNc.setLinkUpstreamBandwidthKbps(upKbps);
+ newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
+ newNc.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming);
+ newNc.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested);
+ newNc.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended);
}
/**
@@ -6497,7 +6516,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
if (nai.supportsUnderlyingNetworks()) {
- applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, newNc, nai.declaredMetered);
+ applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, nai.declaredCapabilities,
+ newNc);
}
return newNc;
@@ -6576,11 +6596,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- if (!newNc.hasTransport(TRANSPORT_VPN)) {
- // Tell VPNs about updated capabilities, since they may need to
- // bubble those changes through.
- propagateUnderlyingNetworkCapabilities();
- }
+ // This network might have been underlying another network. Propagate its capabilities.
+ propagateUnderlyingNetworkCapabilities(nai.network);
if (!newNc.equalsTransportTypes(prevNc)) {
mDnsManager.updateTransportsForNetwork(
@@ -6622,6 +6639,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
&& (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute());
}
+ private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) {
+ final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()];
+ int index = 0;
+ for (UidRange range : ranges) {
+ stableRanges[index] = new UidRangeParcel(range.start, range.stop);
+ index++;
+ }
+ return stableRanges;
+ }
+
private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
NetworkCapabilities newNc) {
Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids();
@@ -6641,14 +6668,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
// removing old range works because, unlike the filtering rules below, it's possible to
// add duplicate UID routing rules.
if (!newRanges.isEmpty()) {
- final UidRange[] addedRangesArray = new UidRange[newRanges.size()];
- newRanges.toArray(addedRangesArray);
- mNMS.addVpnUidRanges(nai.network.getNetId(), addedRangesArray);
+ mNetd.networkAddUidRanges(nai.network.netId, toUidRangeStableParcels(newRanges));
}
if (!prevRanges.isEmpty()) {
- final UidRange[] removedRangesArray = new UidRange[prevRanges.size()];
- prevRanges.toArray(removedRangesArray);
- mNMS.removeVpnUidRanges(nai.network.getNetId(), removedRangesArray);
+ mNetd.networkRemoveUidRanges(
+ nai.network.netId, toUidRangeStableParcels(prevRanges));
}
final boolean wasFiltering = requiresVpnIsolation(nai, prevNc, nai.linkProperties);
final boolean shouldFilter = requiresVpnIsolation(nai, newNc, nai.linkProperties);
@@ -6903,8 +6927,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
updateTcpBufferSizes(null != newNetwork
? newNetwork.linkProperties.getTcpBufferSizes() : null);
notifyIfacesChangedForNetworkStats();
- // Fix up the NetworkCapabilities of any VPNs that don't specify underlying networks.
- propagateUnderlyingNetworkCapabilities();
+ // Fix up the NetworkCapabilities of any networks that have this network as underlying.
+ if (newNetwork != null) {
+ propagateUnderlyingNetworkCapabilities(newNetwork.network);
+ }
}
private void processListenRequests(@NonNull final NetworkAgentInfo nai) {
@@ -7360,13 +7386,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
if (!createNativeNetwork(networkAgent)) return;
- if (networkAgent.isVPN()) {
- // Initialize the VPN capabilities to their starting values according to the
- // underlying networks. This will avoid a spurious callback to
- // onCapabilitiesUpdated being sent in updateAllVpnCapabilities below as
- // the VPN would switch from its default, blank capabilities to those
- // that reflect the capabilities of its underlying networks.
- propagateUnderlyingNetworkCapabilities();
+ if (networkAgent.supportsUnderlyingNetworks()) {
+ // Initialize the network's capabilities to their starting values according to the
+ // underlying networks. This ensures that the capabilities are correct before
+ // anything happens to the network.
+ updateCapabilitiesForNetwork(networkAgent);
}
networkAgent.created = true;
}
@@ -7408,10 +7432,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
// doing.
updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
- if (networkAgent.supportsUnderlyingNetworks()) {
- propagateUnderlyingNetworkCapabilities();
- }
-
// Consider network even though it is not yet validated.
rematchAllNetworksAndRequests();
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 5e86f855c1e7..086cc1ca32ed 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -60,7 +60,6 @@ import android.net.NetworkStack;
import android.net.NetworkStats;
import android.net.RouteInfo;
import android.net.TetherStatsParcel;
-import android.net.UidRange;
import android.net.UidRangeParcel;
import android.net.shared.NetdUtils;
import android.net.shared.RouteUtils;
@@ -1393,38 +1392,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
}
}
- private static UidRangeParcel makeUidRangeParcel(int start, int stop) {
- UidRangeParcel range = new UidRangeParcel();
- range.start = start;
- range.stop = stop;
- return range;
- }
-
- private static UidRangeParcel[] toStableParcels(UidRange[] ranges) {
- UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
- for (int i = 0; i < ranges.length; i++) {
- stableRanges[i] = makeUidRangeParcel(ranges[i].start, ranges[i].stop);
- }
- return stableRanges;
- }
-
- @Override
- public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges)
- throws ServiceSpecificException {
- NetworkStack.checkNetworkStackPermission(mContext);
- try {
- mNetdService.networkRejectNonSecureVpn(add, toStableParcels(uidRanges));
- } catch (ServiceSpecificException e) {
- Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
- + ": netd command failed", e);
- throw e;
- } catch (RemoteException e) {
- Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
- + ": netd command failed", e);
- throw e.rethrowAsRuntimeException();
- }
- }
-
private void applyUidCleartextNetworkPolicy(int uid, int policy) {
final int policyValue;
switch (policy) {
@@ -1553,27 +1520,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
}
@Override
- public void addVpnUidRanges(int netId, UidRange[] ranges) {
- NetworkStack.checkNetworkStackPermission(mContext);
-
- try {
- mNetdService.networkAddUidRanges(netId, toStableParcels(ranges));
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public void removeVpnUidRanges(int netId, UidRange[] ranges) {
- NetworkStack.checkNetworkStackPermission(mContext);
- try {
- mNetdService.networkRemoveUidRanges(netId, toStableParcels(ranges));
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
public void setFirewallEnabled(boolean enabled) {
enforceSystemUid();
try {
@@ -1616,7 +1562,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
ranges = new UidRangeParcel[] {
// TODO: is there a better way of finding all existing users? If so, we could
// specify their ranges here.
- makeUidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE),
+ new UidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE),
};
// ... except for the UIDs that have allow rules.
synchronized (mRulesLock) {
@@ -1647,7 +1593,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
for (int i = 0; i < ranges.length; i++) {
if (rules.valueAt(i) == FIREWALL_RULE_DENY) {
int uid = rules.keyAt(i);
- ranges[numUids] = makeUidRangeParcel(uid, uid);
+ ranges[numUids] = new UidRangeParcel(uid, uid);
numUids++;
}
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index c95bfd031af4..730c64e6968c 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -4488,10 +4488,13 @@ class StorageManagerService extends IStorageManager.Stub
// When using FUSE, we may need to kill the app if the op changes
switch(code) {
case OP_REQUEST_INSTALL_PACKAGES:
- if (previousMode == MODE_ALLOWED || mode == MODE_ALLOWED) {
- // If we transition to/from MODE_ALLOWED, kill the app to make
- // sure it has the correct view of /storage. Changing between
- // MODE_DEFAULT / MODE_ERRORED is a no-op
+ // In R, we used to kill the app here if it transitioned to/from
+ // MODE_ALLOWED, to make sure the app had the correct (writable) OBB
+ // view. But the majority of apps don't handle OBBs anyway, and for those
+ // that do, they can restart themselves. Therefore, starting from S,
+ // only kill the app when it transitions away from MODE_ALLOWED (eg,
+ // when the permission is taken away).
+ if (previousMode == MODE_ALLOWED && mode != MODE_ALLOWED) {
killAppForOpChange(code, uid);
}
return;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 4872efdce88b..7d6e54243d89 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -19,7 +19,6 @@ package com.android.server.am;
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
-import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
import static android.os.Process.NFC_UID;
@@ -168,6 +167,7 @@ public final class ActiveServices {
public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION = 16;
public static final int FGS_FEATURE_ALLOWED_BY_FGS_BINDING = 17;
public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE = 18;
+ public static final int FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD = 19;
@IntDef(flag = true, prefix = { "FGS_FEATURE_" }, value = {
FGS_FEATURE_DENIED,
@@ -187,7 +187,8 @@ public final class ActiveServices {
FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST,
FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION,
FGS_FEATURE_ALLOWED_BY_FGS_BINDING,
- FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE
+ FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE,
+ FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD
})
@Retention(RetentionPolicy.SOURCE)
public @interface FgsFeatureRetCode {}
@@ -5244,10 +5245,14 @@ public final class ActiveServices {
if (ret == FGS_FEATURE_DENIED) {
for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) {
final ProcessRecord pr = mAm.mProcessList.mLruProcesses.get(i);
- if (pr.uid == callingUid
- && pr.mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
- ret = FGS_FEATURE_ALLOWED_BY_PROC_STATE;
- break;
+ if (pr.uid == callingUid) {
+ if (pr.mAllowStartFgs) {
+ ret = FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD;
+ break;
+ } else if (pr.isAllowedStartFgsState()) {
+ ret = FGS_FEATURE_ALLOWED_BY_PROC_STATE;
+ break;
+ }
}
}
}
@@ -5286,7 +5291,7 @@ public final class ActiveServices {
}
if (ret == FGS_FEATURE_DENIED) {
- if (mAm.isWhitelistedForFgsStartLocked(r.appInfo.uid)) {
+ if (mAm.isWhitelistedForFgsStartLocked(callingUid)) {
// uid is on DeviceIdleController's user/system allowlist
// or AMS's FgsStartTempAllowList.
ret = FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST;
@@ -5354,6 +5359,8 @@ public final class ActiveServices {
return "ALLOWED_BY_FGS_BINDING";
case FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE:
return "ALLOWED_BY_DEVICE_DEMO_MODE";
+ case FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD:
+ return "ALLOWED_BY_PROCESS_RECORD";
default:
return "";
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 0b4d27f4990b..f2c1e90e2476 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -756,8 +756,9 @@ class AppErrors {
boolean handleAppCrashLocked(ProcessRecord app, String reason,
String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
final long now = SystemClock.uptimeMillis();
- final boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
+ final boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ANR_SHOW_BACKGROUND, 0,
+ mService.mUserController.getCurrentUserId()) != 0;
final boolean procIsBoundForeground =
(app.getCurProcState() == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
@@ -889,8 +890,9 @@ class AppErrors {
void handleShowAppErrorUi(Message msg) {
AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
- boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
+ boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ANR_SHOW_BACKGROUND, 0,
+ mService.mUserController.getCurrentUserId()) != 0;
final int userId;
synchronized (mService) {
@@ -982,8 +984,9 @@ class AppErrors {
return;
}
- boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
+ boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ANR_SHOW_BACKGROUND, 0,
+ mService.mUserController.getCurrentUserId()) != 0;
if (mService.mAtmInternal.canShowErrorDialogs() || showBackground) {
proc.getDialogController().showAnrDialogs(data);
} else {
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 771f273781fa..5b3e6514c6a6 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1329,7 +1329,7 @@ public final class OomAdjuster {
app.setCached(false);
app.shouldNotFreeze = false;
- app.mAllowStartFgsState = PROCESS_STATE_NONEXISTENT;
+ app.resetAllowStartFgs();
final int appUid = app.info.uid;
final int logUid = mService.mCurOomAdjUid;
@@ -1351,7 +1351,6 @@ public final class OomAdjuster {
app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
app.curCapability = PROCESS_CAPABILITY_ALL;
app.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);
- app.bumpAllowStartFgsState(PROCESS_STATE_PERSISTENT);
// System processes can do UI, and when they do we want to have
// them trim their memory after the user leaves the UI. To
// facilitate this, here we need to determine whether or not it
@@ -1382,6 +1381,8 @@ public final class OomAdjuster {
app.setCurRawProcState(app.getCurProcState());
app.curAdj = app.maxAdj;
app.completedAdjSeq = app.adjSeq;
+ app.bumpAllowStartFgsState(app.getCurProcState());
+ app.setAllowStartFgs();
// if curAdj is less than prevAppAdj, then this process was promoted
return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState;
}
@@ -1773,6 +1774,11 @@ public final class OomAdjuster {
int clientAdj = client.getCurRawAdj();
int clientProcState = client.getCurRawProcState();
+ // pass client's mAllowStartFgs to the app if client is not persistent process.
+ if (client.mAllowStartFgs && client.maxAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+ app.mAllowStartFgs = true;
+ }
+
if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) {
if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) {
continue;
@@ -2236,7 +2242,7 @@ public final class OomAdjuster {
app.setCurRawProcState(procState);
app.setHasForegroundActivities(foregroundActivities);
app.completedAdjSeq = mAdjSeq;
-
+ app.setAllowStartFgs();
// if curAdj or curProcState improved, then this process was promoted
return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState
|| app.curCapability != prevCapability ;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index cf4adc65a7fc..255badd3239f 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -16,7 +16,16 @@
package com.android.server.am;
+import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
+import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
+import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Process.NFC_UID;
+import static android.os.Process.ROOT_UID;
+import static android.os.Process.SHELL_UID;
+import static android.os.Process.SYSTEM_UID;
import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
@@ -361,6 +370,17 @@ class ProcessRecord implements WindowProcessListener {
private final ArraySet<Binder> mBackgroundFgsStartTokens = new ArraySet<>();
+ // The list of permissions that can start FGS from background.
+ private static String[] ALLOW_BG_START_FGS_PERMISSIONS =
+ {START_ACTIVITIES_FROM_BACKGROUND, START_FOREGROUND_SERVICES_FROM_BACKGROUND,
+ SYSTEM_ALERT_WINDOW};
+ // Does the process has permission to start FGS from background.
+ boolean mAllowStartFgsByPermission;
+ // Can this process start FGS from background?
+ // If this process has the ability to start FGS from background, this ability can be passed to
+ // another process through service binding.
+ boolean mAllowStartFgs;
+
void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo,
long startTime) {
this.startUid = startUid;
@@ -476,6 +496,9 @@ class ProcessRecord implements WindowProcessListener {
pw.println();
pw.print(prefix); pw.print("allowStartFgsState=");
pw.println(mAllowStartFgsState);
+ if (mAllowStartFgs) {
+ pw.print(prefix); pw.print("allowStartFgs="); pw.println(mAllowStartFgs);
+ }
if (hasShownUi || mPendingUiClean || hasAboveClient || treatLikeActivity) {
pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
pw.print(" pendingUiClean="); pw.print(mPendingUiClean);
@@ -672,6 +695,7 @@ class ProcessRecord implements WindowProcessListener {
mWindowProcessController = new WindowProcessController(
mService.mActivityTaskManager, info, processName, uid, userId, this, this);
pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode));
+ setAllowStartFgsByPermission();
}
public void setPid(int _pid) {
@@ -1983,12 +2007,78 @@ class ProcessRecord implements WindowProcessListener {
return mDialogController;
}
+ void resetAllowStartFgs() {
+ mAllowStartFgsState = PROCESS_STATE_NONEXISTENT;
+ mAllowStartFgs = mAllowStartFgsByPermission;
+ }
+
void bumpAllowStartFgsState(int newProcState) {
if (newProcState < mAllowStartFgsState) {
mAllowStartFgsState = newProcState;
}
}
+ void setAllowStartFgsByPermission() {
+ boolean ret = false;
+ if (!ret) {
+ boolean isSystem = false;
+ final int uid = UserHandle.getAppId(info.uid);
+ switch (uid) {
+ case ROOT_UID:
+ case SYSTEM_UID:
+ case NFC_UID:
+ case SHELL_UID:
+ isSystem = true;
+ break;
+ default:
+ isSystem = false;
+ break;
+ }
+
+ if (isSystem) {
+ ret = true;
+ }
+ }
+
+ if (!ret) {
+ for (int i = 0; i < ALLOW_BG_START_FGS_PERMISSIONS.length; ++i) {
+ if (ActivityManager.checkComponentPermission(ALLOW_BG_START_FGS_PERMISSIONS[i],
+ info.uid, -1, true)
+ == PERMISSION_GRANTED) {
+ ret = true;
+ break;
+ }
+ }
+ }
+ mAllowStartFgs = mAllowStartFgsByPermission = ret;
+ }
+
+ boolean isAllowedStartFgsState() {
+ return mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+ }
+
+ void setAllowStartFgs() {
+ if (mAllowStartFgs) {
+ return;
+ }
+ if (!mAllowStartFgs) {
+ mAllowStartFgs = isAllowedStartFgsState();
+ }
+
+ if (!mAllowStartFgs) {
+ // Is the calling UID a device owner app?
+ if (mService.mInternal != null) {
+ mAllowStartFgs = mService.mInternal.isDeviceOwner(info.uid);
+ }
+ }
+
+ if (!mAllowStartFgs) {
+ // uid is on DeviceIdleController's user/system allowlist
+ // or AMS's FgsStartTempAllowList.
+ mAllowStartFgs = mService.isWhitelistedForFgsStartLocked(info.uid);
+ }
+ }
+
/** A controller to generate error dialogs in {@link ProcessRecord} */
class ErrorDialogController {
/** dialogs being displayed due to crash */
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index ccd1f3bb16f6..52b9f5c15c50 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -138,9 +138,10 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
// not guaranteed to be current or correct, or even to exist.
public @Nullable Network[] declaredUnderlyingNetworks;
- // Whether this network is always metered even if its underlying networks are unmetered.
- // Only relevant if #supportsUnderlyingNetworks is true.
- public boolean declaredMetered;
+ // The capabilities originally announced by the NetworkAgent, regardless of any capabilities
+ // that were added or removed due to this network's underlying networks.
+ // Only set if #supportsUnderlyingNetworks is true.
+ public @Nullable NetworkCapabilities declaredCapabilities;
// Indicates if netd has been told to create this Network. From this point on the appropriate
// routing rules are setup and routes are added so packets can begin flowing over the Network.
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 66bb4d704e80..cabfbc02491c 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -48,6 +48,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.net.ConnectivityManager;
import android.net.DnsResolver;
+import android.net.INetd;
import android.net.INetworkManagementEventObserver;
import android.net.Ikev2VpnProfile;
import android.net.IpPrefix;
@@ -68,6 +69,7 @@ import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.net.RouteInfo;
import android.net.UidRange;
+import android.net.UidRangeParcel;
import android.net.VpnManager;
import android.net.VpnService;
import android.net.ipsec.ike.ChildSessionCallback;
@@ -188,7 +190,8 @@ public class Vpn {
private PendingIntent mStatusIntent;
private volatile boolean mEnableTeardown = true;
- private final INetworkManagementService mNetd;
+ private final INetworkManagementService mNms;
+ private final INetd mNetd;
@VisibleForTesting
protected VpnConfig mConfig;
private final NetworkProvider mNetworkProvider;
@@ -234,7 +237,7 @@ public class Vpn {
* @see mLockdown
*/
@GuardedBy("this")
- private final Set<UidRange> mBlockedUidsAsToldToNetd = new ArraySet<>();
+ private final Set<UidRangeParcel> mBlockedUidsAsToldToNetd = new ArraySet<>();
// The user id of initiating VPN.
private final int mUserId;
@@ -363,22 +366,23 @@ public class Vpn {
}
}
- public Vpn(Looper looper, Context context, INetworkManagementService netService,
+ public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd,
@UserIdInt int userId, @NonNull KeyStore keyStore) {
- this(looper, context, new Dependencies(), netService, userId, keyStore,
+ this(looper, context, new Dependencies(), netService, netd, userId, keyStore,
new SystemServices(context), new Ikev2SessionCreator());
}
@VisibleForTesting
protected Vpn(Looper looper, Context context, Dependencies deps,
- INetworkManagementService netService,
+ INetworkManagementService netService, INetd netd,
int userId, @NonNull KeyStore keyStore, SystemServices systemServices,
Ikev2SessionCreator ikev2SessionCreator) {
mContext = context;
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
mDeps = deps;
- mNetd = netService;
+ mNms = netService;
+ mNetd = netd;
mUserId = userId;
mLooper = looper;
mSystemServices = systemServices;
@@ -912,7 +916,7 @@ public class Vpn {
}
try {
- mNetd.denyProtect(mOwnerUID);
+ mNms.denyProtect(mOwnerUID);
} catch (Exception e) {
Log.wtf(TAG, "Failed to disallow UID " + mOwnerUID + " to call protect() " + e);
}
@@ -922,7 +926,7 @@ public class Vpn {
mOwnerUID = getAppUid(newPackage, mUserId);
mIsPackageTargetingAtLeastQ = doesPackageTargetAtLeastQ(newPackage);
try {
- mNetd.allowProtect(mOwnerUID);
+ mNms.allowProtect(mOwnerUID);
} catch (Exception e) {
Log.wtf(TAG, "Failed to allow UID " + mOwnerUID + " to call protect() " + e);
}
@@ -1579,24 +1583,25 @@ public class Vpn {
exemptedPackages = new ArrayList<>(mLockdownAllowlist);
exemptedPackages.add(mPackage);
}
- final Set<UidRange> rangesToTellNetdToRemove = new ArraySet<>(mBlockedUidsAsToldToNetd);
+ final Set<UidRangeParcel> rangesToTellNetdToRemove =
+ new ArraySet<>(mBlockedUidsAsToldToNetd);
- final Set<UidRange> rangesToTellNetdToAdd;
+ final Set<UidRangeParcel> rangesToTellNetdToAdd;
if (enforce) {
- final Set<UidRange> rangesThatShouldBeBlocked =
+ final Set<UidRange> restrictedProfilesRanges =
createUserAndRestrictedProfilesRanges(mUserId,
- /* allowedApplications */ null,
- /* disallowedApplications */ exemptedPackages);
+ /* allowedApplications */ null,
+ /* disallowedApplications */ exemptedPackages);
+ final Set<UidRangeParcel> rangesThatShouldBeBlocked = new ArraySet<>();
// The UID range of the first user (0-99999) would block the IPSec traffic, which comes
// directly from the kernel and is marked as uid=0. So we adjust the range to allow
// it through (b/69873852).
- for (UidRange range : rangesThatShouldBeBlocked) {
- if (range.start == 0) {
- rangesThatShouldBeBlocked.remove(range);
- if (range.stop != 0) {
- rangesThatShouldBeBlocked.add(new UidRange(1, range.stop));
- }
+ for (UidRange range : restrictedProfilesRanges) {
+ if (range.start == 0 && range.stop != 0) {
+ rangesThatShouldBeBlocked.add(new UidRangeParcel(1, range.stop));
+ } else if (range.start != 0) {
+ rangesThatShouldBeBlocked.add(new UidRangeParcel(range.start, range.stop));
}
}
@@ -1628,13 +1633,13 @@ public class Vpn {
* including added ranges that already existed or removed ones that didn't.
*/
@GuardedBy("this")
- private boolean setAllowOnlyVpnForUids(boolean enforce, Collection<UidRange> ranges) {
+ private boolean setAllowOnlyVpnForUids(boolean enforce, Collection<UidRangeParcel> ranges) {
if (ranges.size() == 0) {
return true;
}
- final UidRange[] rangesArray = ranges.toArray(new UidRange[ranges.size()]);
+ final UidRangeParcel[] stableRanges = ranges.toArray(new UidRangeParcel[ranges.size()]);
try {
- mNetd.setAllowOnlyVpnForUids(enforce, rangesArray);
+ mNetd.networkRejectNonSecureVpn(enforce, stableRanges);
} catch (RemoteException | RuntimeException e) {
Log.e(TAG, "Updating blocked=" + enforce
+ " for UIDs " + Arrays.toString(ranges.toArray()) + " failed", e);
@@ -1849,10 +1854,20 @@ public class Vpn {
if (mNetworkInfo.isConnected()) {
return !appliesToUid(uid);
} else {
- return UidRange.containsUid(mBlockedUidsAsToldToNetd, uid);
+ return containsUid(mBlockedUidsAsToldToNetd, uid);
}
}
+ private boolean containsUid(Collection<UidRangeParcel> ranges, int uid) {
+ if (ranges == null) return false;
+ for (UidRangeParcel range : ranges) {
+ if (range.start <= uid && uid <= range.stop) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void updateAlwaysOnNotification(DetailedState networkState) {
final boolean visible = (mAlwaysOn && networkState != DetailedState.CONNECTED);
@@ -2495,7 +2510,7 @@ public class Vpn {
address /* unused */,
address /* unused */,
network);
- mNetd.setInterfaceUp(mTunnelIface.getInterfaceName());
+ mNms.setInterfaceUp(mTunnelIface.getInterfaceName());
mSession = mIkev2SessionCreator.createIkeSession(
mContext,
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index 0b3cdae9231e..7afa81aa047d 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -165,11 +165,13 @@ class BluetoothRouteProvider {
private void buildBluetoothRoutes() {
mBluetoothRoutes.clear();
- for (BluetoothDevice device : mBluetoothAdapter.getBondedDevices()) {
- if (device.isConnected()) {
- BluetoothRouteInfo newBtRoute = createBluetoothRoute(device);
- if (newBtRoute.connectedProfiles.size() > 0) {
- mBluetoothRoutes.put(device.getAddress(), newBtRoute);
+ if (mBluetoothAdapter.getBondedDevices() != null) {
+ for (BluetoothDevice device : mBluetoothAdapter.getBondedDevices()) {
+ if (device.isConnected()) {
+ BluetoothRouteInfo newBtRoute = createBluetoothRoute(device);
+ if (newBtRoute.connectedProfiles.size() > 0) {
+ mBluetoothRoutes.put(device.getAddress(), newBtRoute);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
index f882c57e49ba..edc9d7c64146 100644
--- a/services/core/java/com/android/server/media/MediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -77,7 +77,7 @@ abstract class MediaRoute2Provider {
@NonNull
public List<RoutingSessionInfo> getSessionInfos() {
synchronized (mLock) {
- return mSessionInfos;
+ return new ArrayList<>(mSessionInfos);
}
}
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
index 85af346aa88a..ab38dca2387d 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
@@ -108,8 +108,8 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
mLastDiscoveryPreference = discoveryPreference;
if (mConnectionReady) {
mActiveConnection.updateDiscoveryPreference(discoveryPreference);
- updateBinding();
}
+ updateBinding();
}
@Override
@@ -205,9 +205,11 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
}
private boolean shouldBind() {
- //TODO: Binding could be delayed until it's necessary.
if (mRunning) {
- return true;
+ // Bind when there is a discovery preference or an active route session.
+ return (mLastDiscoveryPreference != null
+ && !mLastDiscoveryPreference.getPreferredFeatures().isEmpty())
+ || !getSessionInfos().isEmpty();
}
return false;
}
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 1114fe0d9bf8..31edf43679e9 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -16,6 +16,7 @@
package com.android.server.media;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
import static android.media.MediaRouter2Utils.getOriginalId;
import static android.media.MediaRouter2Utils.getProviderId;
@@ -73,10 +74,12 @@ class MediaRouter2ServiceImpl {
// TODO: (In Android S or later) if we add callback methods for generic failures
// in MediaRouter2, remove this constant and replace the usages with the real request IDs.
private static final long DUMMY_REQUEST_ID = -1;
+ private static final int PACKAGE_IMPORTANCE_FOR_DISCOVERY = IMPORTANCE_FOREGROUND;
private final Context mContext;
private final Object mLock = new Object();
final AtomicInteger mNextRouterOrManagerId = new AtomicInteger(1);
+ final ActivityManager mActivityManager;
@GuardedBy("mLock")
private final SparseArray<UserRecord> mUserRecords = new SparseArray<>();
@@ -87,8 +90,21 @@ class MediaRouter2ServiceImpl {
@GuardedBy("mLock")
private int mCurrentUserId = -1;
+ private final ActivityManager.OnUidImportanceListener mOnUidImportanceListener =
+ (uid, importance) -> {
+ synchronized (mLock) {
+ final int count = mUserRecords.size();
+ for (int i = 0; i < count; i++) {
+ mUserRecords.valueAt(i).mHandler.maybeUpdateDiscoveryPreferenceForUid(uid);
+ }
+ }
+ };
+
MediaRouter2ServiceImpl(Context context) {
mContext = context;
+ mActivityManager = mContext.getSystemService(ActivityManager.class);
+ mActivityManager.addOnUidImportanceListener(mOnUidImportanceListener,
+ PACKAGE_IMPORTANCE_FOR_DISCOVERY);
}
////////////////////////////////////////////////////////////////
@@ -388,6 +404,30 @@ class MediaRouter2ServiceImpl {
}
}
+ public void startScan(IMediaRouter2Manager manager) {
+ Objects.requireNonNull(manager, "manager must not be null");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ startScanLocked(manager);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ public void stopScan(IMediaRouter2Manager manager) {
+ Objects.requireNonNull(manager, "manager must not be null");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ stopScanLocked(manager);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
public void setRouteVolumeWithManager(IMediaRouter2Manager manager, int requestId,
MediaRoute2Info route, int volume) {
Objects.requireNonNull(manager, "manager must not be null");
@@ -839,6 +879,24 @@ class MediaRouter2ServiceImpl {
disposeUserIfNeededLocked(userRecord); // since manager removed from user
}
+ private void startScanLocked(@NonNull IMediaRouter2Manager manager) {
+ final IBinder binder = manager.asBinder();
+ ManagerRecord managerRecord = mAllManagerRecords.get(binder);
+ if (managerRecord == null) {
+ return;
+ }
+ managerRecord.startScan();
+ }
+
+ private void stopScanLocked(@NonNull IMediaRouter2Manager manager) {
+ final IBinder binder = manager.asBinder();
+ ManagerRecord managerRecord = mAllManagerRecords.get(binder);
+ if (managerRecord == null) {
+ return;
+ }
+ managerRecord.stopScan();
+ }
+
private void setRouteVolumeWithManagerLocked(int requestId,
@NonNull IMediaRouter2Manager manager,
@NonNull MediaRoute2Info route, int volume) {
@@ -1122,6 +1180,7 @@ class MediaRouter2ServiceImpl {
public final String mPackageName;
public final int mManagerId;
public SessionCreationRequest mLastSessionCreationRequest;
+ public boolean mIsScanning;
ManagerRecord(UserRecord userRecord, IMediaRouter2Manager manager,
int uid, int pid, String packageName) {
@@ -1146,6 +1205,24 @@ class MediaRouter2ServiceImpl {
pw.println(prefix + this);
}
+ public void startScan() {
+ if (mIsScanning) {
+ return;
+ }
+ mIsScanning = true;
+ mUserRecord.mHandler.sendMessage(PooledLambda.obtainMessage(
+ UserHandler::updateDiscoveryPreferenceOnHandler, mUserRecord.mHandler));
+ }
+
+ public void stopScan() {
+ if (!mIsScanning) {
+ return;
+ }
+ mIsScanning = false;
+ mUserRecord.mHandler.sendMessage(PooledLambda.obtainMessage(
+ UserHandler::updateDiscoveryPreferenceOnHandler, mUserRecord.mHandler));
+ }
+
@Override
public String toString() {
return "Manager " + mPackageName + " (pid " + mPid + ")";
@@ -1262,6 +1339,24 @@ class MediaRouter2ServiceImpl {
return null;
}
+ public void maybeUpdateDiscoveryPreferenceForUid(int uid) {
+ MediaRouter2ServiceImpl service = mServiceRef.get();
+ if (service == null) {
+ return;
+ }
+ boolean isUidRelevant;
+ synchronized (service.mLock) {
+ isUidRelevant = mUserRecord.mRouterRecords.stream().anyMatch(
+ router -> router.mUid == uid)
+ | mUserRecord.mManagerRecords.stream().anyMatch(
+ manager -> manager.mUid == uid);
+ }
+ if (isUidRelevant) {
+ sendMessage(PooledLambda.obtainMessage(
+ UserHandler::updateDiscoveryPreferenceOnHandler, this));
+ }
+ }
+
private void onProviderStateChangedOnHandler(@NonNull MediaRoute2Provider provider) {
int providerInfoIndex = getLastProviderInfoIndex(provider.getUniqueId());
MediaRoute2ProviderInfo currentInfo = provider.getProviderInfo();
@@ -1767,6 +1862,16 @@ class MediaRouter2ServiceImpl {
return managers;
}
+ private List<RouterRecord> getRouterRecords() {
+ MediaRouter2ServiceImpl service = mServiceRef.get();
+ if (service == null) {
+ return Collections.emptyList();
+ }
+ synchronized (service.mLock) {
+ return new ArrayList<>(mUserRecord.mRouterRecords);
+ }
+ }
+
private List<ManagerRecord> getManagerRecords() {
MediaRouter2ServiceImpl service = mServiceRef.get();
if (service == null) {
@@ -2001,13 +2106,28 @@ class MediaRouter2ServiceImpl {
return;
}
List<RouteDiscoveryPreference> discoveryPreferences = new ArrayList<>();
- synchronized (service.mLock) {
- for (RouterRecord routerRecord : mUserRecord.mRouterRecords) {
+ List<RouterRecord> routerRecords = getRouterRecords();
+ List<ManagerRecord> managerRecords = getManagerRecords();
+ boolean isAnyManagerScanning =
+ managerRecords.stream().anyMatch(manager -> manager.mIsScanning
+ && service.mActivityManager.getPackageImportance(manager.mPackageName)
+ <= PACKAGE_IMPORTANCE_FOR_DISCOVERY);
+
+ for (RouterRecord routerRecord : routerRecords) {
+ if (isAnyManagerScanning
+ || service.mActivityManager.getPackageImportance(routerRecord.mPackageName)
+ <= PACKAGE_IMPORTANCE_FOR_DISCOVERY) {
discoveryPreferences.add(routerRecord.mDiscoveryPreference);
}
- mUserRecord.mCompositeDiscoveryPreference =
- new RouteDiscoveryPreference.Builder(discoveryPreferences)
- .build();
+ }
+
+ synchronized (service.mLock) {
+ RouteDiscoveryPreference newPreference =
+ new RouteDiscoveryPreference.Builder(discoveryPreferences).build();
+ if (newPreference.equals(mUserRecord.mCompositeDiscoveryPreference)) {
+ return;
+ }
+ mUserRecord.mCompositeDiscoveryPreference = newPreference;
}
for (MediaRoute2Provider provider : mRouteProviders) {
provider.updateDiscoveryPreference(mUserRecord.mCompositeDiscoveryPreference);
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 0e52a67c8d39..b6d6cc48d0cd 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -544,6 +544,18 @@ public final class MediaRouterService extends IMediaRouterService.Stub
// Binder call
@Override
+ public void startScan(IMediaRouter2Manager manager) {
+ mService2.startScan(manager);
+ }
+
+ // Binder call
+ @Override
+ public void stopScan(IMediaRouter2Manager manager) {
+ mService2.stopScan(manager);
+ }
+
+ // Binder call
+ @Override
public void setRouteVolumeWithManager(IMediaRouter2Manager manager, int requestId,
MediaRoute2Info route, int volume) {
mService2.setRouteVolumeWithManager(manager, requestId, route, volume);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 0ac0c8d95423..9f07695fcecf 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -737,7 +737,7 @@ class ShortcutPackage extends ShortcutPackageItem {
|| ((pinnedByCallerSet != null) && pinnedByCallerSet.contains(si.getId()));
if (!getPinnedByAnyLauncher) {
- if (si.isFloating()) {
+ if (si.isFloating() && !si.isCached()) {
if (!isPinnedByCaller) {
continue;
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 708e050f8a8c..1dbf8396bcfb 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -66,7 +66,6 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AppOpsManager;
-import android.app.ApplicationPackageManager;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.role.RoleManager;
@@ -795,8 +794,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
int flagValues, int callingUid, int userId, boolean overridePolicy,
PermissionCallback callback) {
- if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
- && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
+ if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES
+ && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
Log.i(TAG, "System is updating flags for " + packageName + " "
+ permName + " for user " + userId + " "
+ DebugUtils.flagsToString(
@@ -1456,8 +1455,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// TODO swap permission name and package name
private void grantRuntimePermissionInternal(String permName, String packageName,
boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
- if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
- && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
+ if (PermissionManager.DEBUG_TRACE_GRANTS
+ && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
Log.i(TAG, "System is granting " + packageName + " "
+ permName + " for user " + userId + " on behalf of uid " + callingUid
+ " " + mPackageManagerInt.getNameForUid(callingUid),
@@ -1633,8 +1632,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
private void revokeRuntimePermissionInternal(String permName, String packageName,
boolean overridePolicy, int callingUid, final int userId, String reason,
PermissionCallback callback) {
- if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
- && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
+ if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES
+ && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
Log.i(TAG, "System is revoking " + packageName + " "
+ permName + " for user " + userId + " on behalf of uid " + callingUid
+ " " + mPackageManagerInt.getNameForUid(callingUid),
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 6a50b793de0f..b0847879f456 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -631,6 +631,10 @@ class ActivityMetricsLogger {
if (info.mLoggedTransitionStarting && info.allDrawn()) {
done(false /* abort */, info, "notifyWindowsDrawn - all windows drawn", timestampNs);
}
+ if (r.mWmService.isRecentsAnimationTarget(r)) {
+ r.mWmService.getRecentsAnimationController().logRecentsAnimationStartTime(
+ info.mSourceEventDelayMs + info.mWindowsDrawnDelayMs);
+ }
return infoSnapshot;
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 5daf1c4679be..4c18310df226 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1366,19 +1366,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
} else if (mLetterbox != null) {
mLetterbox.hide();
}
- maybeUpdateLetterboxInTaskOrganizer(w);
- }
-
- private void maybeUpdateLetterboxInTaskOrganizer(WindowState w) {
- boolean isLetterboxed = w.isLetterboxedAppWindow() && fillsParent();
- if (!isLetterboxed) {
- task.maybeUpdateLetterboxInTaskOrganizer(
- this, /* activityBounds= */ null, /* activityInsets= */ null);
- return;
- }
- final Rect insets = w.getInsetsStateWithVisibilityOverride().calculateInsets(
- getBounds(), Type.systemBars(), false /* ignoreVisibility */);
- task.maybeUpdateLetterboxInTaskOrganizer(this, getBounds(), insets);
}
void updateLetterboxSurface(WindowState winHint) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e60f2e70f25c..8d6d981be2b8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -80,6 +80,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BOOT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
@@ -552,24 +553,56 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* This just indicates the window the input method is on top of, not
* necessarily the window its input is going to.
*/
- WindowState mInputMethodTarget;
+ private WindowState mImeLayeringTarget;
/**
* The window which receives input from the input method. This is also a candidate of the
* input method control target.
*/
- WindowState mInputMethodInputTarget;
+ private WindowState mImeInputTarget;
/**
* This controls the visibility and animation of the input method window.
*/
- InsetsControlTarget mInputMethodControlTarget;
+ private InsetsControlTarget mImeControlTarget;
+
+ /**
+ * Used by {@link #getImeTarget} to return the IME target which the input method window on
+ * top of for adjusting input method window surface layer Z-Ordering.
+ *
+ * @see #mImeLayeringTarget
+ */
+ static final int IME_TARGET_LAYERING = 0;
+
+ /**
+ * Used by {@link #getImeTarget} to return the IME target which received the input connection
+ * from IME.
+ *
+ * @see #mImeInputTarget
+ */
+ static final int IME_TARGET_INPUT = 1;
+
+ /**
+ * Used by {@link #getImeTarget} to return the IME target which controls the IME insets
+ * visibility and animation.
+ *
+ * @see #mImeControlTarget
+ */
+ static final int IME_TARGET_CONTROL = 2;
+
+ @IntDef(flag = false, prefix = { "IME_TARGET_" }, value = {
+ IME_TARGET_LAYERING,
+ IME_TARGET_INPUT,
+ IME_TARGET_CONTROL,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface InputMethodTarget {}
/** The surface parent of the IME container. */
private SurfaceControl mInputMethodSurfaceParent;
- /** If true hold off on modifying the animation layer of mInputMethodTarget */
- boolean mInputMethodTargetWaitingAnim;
+ /** If {@code true} hold off on modifying the animation layer of {@link #mImeLayeringTarget} */
+ boolean mImeLayeringTargetWaitingAnim;
private final PointerEventDispatcher mPointerEventDispatcher;
@@ -814,7 +847,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private final Consumer<WindowState> mApplyPostLayoutPolicy =
w -> getDisplayPolicy().applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(),
- mInputMethodTarget);
+ mImeLayeringTarget);
private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {
final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
@@ -2256,8 +2289,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@Nullable
Task getRootTask(int rootTaskId) {
- return getItemFromTaskDisplayAreas(taskDisplayArea ->
- taskDisplayArea.getRootTask(rootTaskId));
+ return getRootTask(rootTask -> rootTask.getRootTaskId() == rootTaskId);
}
int getRootTaskCount() {
@@ -2834,7 +2866,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
void prepareFreezingTaskBounds() {
- forAllTaskDisplayAreas(TaskDisplayArea::prepareFreezingTaskBounds);
+ forAllRootTasks(Task::prepareFreezingTaskBounds);
}
void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
@@ -2943,15 +2975,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
proto.write(FOCUSED_ROOT_TASK_ID, INVALID_TASK_ID);
}
proto.write(DISPLAY_READY, isReady());
- if (mInputMethodTarget != null) {
- mInputMethodTarget.dumpDebug(proto, INPUT_METHOD_TARGET, logLevel);
+ if (mImeLayeringTarget != null) {
+ mImeLayeringTarget.dumpDebug(proto, INPUT_METHOD_TARGET, logLevel);
}
- if (mInputMethodInputTarget != null) {
- mInputMethodInputTarget.dumpDebug(proto, INPUT_METHOD_INPUT_TARGET, logLevel);
+ if (mImeInputTarget != null) {
+ mImeInputTarget.dumpDebug(proto, INPUT_METHOD_INPUT_TARGET, logLevel);
}
- if (mInputMethodControlTarget != null
- && mInputMethodControlTarget.getWindow() != null) {
- mInputMethodControlTarget.getWindow().dumpDebug(proto, INPUT_METHOD_CONTROL_TARGET,
+ if (mImeControlTarget != null
+ && mImeControlTarget.getWindow() != null) {
+ mImeControlTarget.getWindow().dumpDebug(proto, INPUT_METHOD_CONTROL_TARGET,
logLevel);
}
if (mCurrentFocus != null) {
@@ -3207,7 +3239,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
boolean imWindowChanged = false;
final WindowState imWindow = mInputMethodWindow;
if (imWindow != null) {
- final WindowState prevTarget = mInputMethodTarget;
+ final WindowState prevTarget = mImeLayeringTarget;
final WindowState newTarget = computeImeTarget(true /* updateImeTarget*/);
imWindowChanged = prevTarget != newTarget;
@@ -3461,7 +3493,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
/**
- * Determine and return the window that should be the IME target.
+ * Determine and return the window that should be the IME target for layering the IME window.
* @param updateImeTarget If true the system IME target will be updated to match what we found.
* @return The window that should be used as the IME target or null if there isn't any.
*/
@@ -3470,13 +3502,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// There isn't an IME so there shouldn't be a target...That was easy!
if (updateImeTarget) {
if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from "
- + mInputMethodTarget + " to null since mInputMethodWindow is null");
- setInputMethodTarget(null, mInputMethodTargetWaitingAnim);
+ + mImeLayeringTarget + " to null since mInputMethodWindow is null");
+ setImeLayeringTarget(null, mImeLayeringTargetWaitingAnim);
}
return null;
}
- final WindowState curTarget = mInputMethodTarget;
+ final WindowState curTarget = mImeLayeringTarget;
if (!canUpdateImeTarget()) {
if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target");
return curTarget;
@@ -3531,7 +3563,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
+ " to null." + (SHOW_STACK_CRAWLS ? " Callers="
+ Debug.getCallers(4) : ""));
- setInputMethodTarget(null, mInputMethodTargetWaitingAnim);
+ setImeLayeringTarget(null, mImeLayeringTargetWaitingAnim);
}
return null;
@@ -3558,7 +3590,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (mAppTransition.isTransitionSet()) {
// If we are currently setting up for an animation, hold everything until we
// can find out what will happen.
- setInputMethodTarget(highestTarget, true);
+ setImeLayeringTarget(highestTarget, true);
return highestTarget;
}
}
@@ -3566,7 +3598,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
+ target + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
- setInputMethodTarget(target, false);
+ setImeLayeringTarget(target, false);
}
return target;
@@ -3577,24 +3609,24 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* the candidate app window token if needed.
*/
void computeImeTargetIfNeeded(ActivityRecord candidate) {
- if (mInputMethodTarget != null && mInputMethodTarget.mActivityRecord == candidate) {
+ if (mImeLayeringTarget != null && mImeLayeringTarget.mActivityRecord == candidate) {
computeImeTarget(true /* updateImeTarget */);
}
}
private boolean isImeControlledByApp() {
- return mInputMethodInputTarget != null && !WindowConfiguration.isSplitScreenWindowingMode(
- mInputMethodInputTarget.getWindowingMode());
+ return mImeInputTarget != null && !WindowConfiguration.isSplitScreenWindowingMode(
+ mImeInputTarget.getWindowingMode());
}
boolean isImeAttachedToApp() {
return isImeControlledByApp()
- && mInputMethodTarget != null
- && mInputMethodTarget.mActivityRecord != null
- && mInputMethodTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+ && mImeLayeringTarget != null
+ && mImeLayeringTarget.mActivityRecord != null
+ && mImeLayeringTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
// An activity with override bounds should be letterboxed inside its parent bounds,
// so it doesn't fill the screen.
- && mInputMethodTarget.mActivityRecord.matchParentBounds();
+ && mImeLayeringTarget.mActivityRecord.matchParentBounds();
}
/**
@@ -3621,6 +3653,24 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return statusBar != null ? statusBar : defaultDc.mRemoteInsetsControlTarget;
}
+ /**
+ * Returns the corresponding IME insets control target according the IME target type.
+ *
+ * @param type The type of the IME target.
+ * @see #IME_TARGET_LAYERING
+ * @see #IME_TARGET_INPUT
+ * @see #IME_TARGET_CONTROL
+ */
+ InsetsControlTarget getImeTarget(@InputMethodTarget int type) {
+ switch (type) {
+ case IME_TARGET_LAYERING: return mImeLayeringTarget;
+ case IME_TARGET_INPUT: return mImeInputTarget;
+ case IME_TARGET_CONTROL: return mImeControlTarget;
+ default:
+ return null;
+ }
+ }
+
@DisplayImePolicy int getImePolicy() {
if (!isTrusted()) {
return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
@@ -3638,6 +3688,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return mWmService.mForceDesktopModeOnExternalDisplays && !isDefaultDisplay && !isPrivate();
}
+ @VisibleForTesting
+ void setImeLayeringTarget(WindowState target) {
+ mImeLayeringTarget = target;
+ }
+
/**
* Sets the window the IME is on top of.
* @param target window to place the IME surface on top of. If {@code null}, the IME will be
@@ -3645,13 +3700,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* @param targetWaitingAnim if {@code true}, hold off on modifying the animation layer of
* the target.
*/
- private void setInputMethodTarget(@Nullable WindowState target, boolean targetWaitingAnim) {
- if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) {
+ private void setImeLayeringTarget(@Nullable WindowState target, boolean targetWaitingAnim) {
+ if (target == mImeLayeringTarget && mImeLayeringTargetWaitingAnim == targetWaitingAnim) {
return;
}
ProtoLog.i(WM_DEBUG_IME, "setInputMethodTarget %s", target);
- mInputMethodTarget = target;
- mInputMethodTargetWaitingAnim = targetWaitingAnim;
+ mImeLayeringTarget = target;
+ mImeLayeringTargetWaitingAnim = targetWaitingAnim;
// 1. Reparent the IME container window to the target root DA to get the correct bounds and
// config. (Only happens when the target window is in a different root DA)
@@ -3673,23 +3728,33 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
updateImeControlTarget();
}
+ @VisibleForTesting
+ void setImeInputTarget(WindowState target) {
+ mImeInputTarget = target;
+ }
+
+ @VisibleForTesting
+ void setImeControlTarget(InsetsControlTarget target) {
+ mImeControlTarget = target;
+ }
+
/**
* The IME input target is the window which receives input from IME. It is also a candidate
* which controls the visibility and animation of the input method window.
*/
- void setInputMethodInputTarget(WindowState target) {
- if (mInputMethodInputTarget != target) {
+ void updateImeInputAndControlTarget(WindowState target) {
+ if (mImeInputTarget != target) {
ProtoLog.i(WM_DEBUG_IME, "setInputMethodInputTarget %s", target);
- mInputMethodInputTarget = target;
+ mImeInputTarget = target;
updateImeControlTarget();
}
}
void updateImeControlTarget() {
- mInputMethodControlTarget = computeImeControlTarget();
- mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget);
+ mImeControlTarget = computeImeControlTarget();
+ mInsetsStateController.onImeControlTargetChanged(mImeControlTarget);
- final WindowState win = InsetsControlTarget.asWindowOrNull(mInputMethodControlTarget);
+ final WindowState win = InsetsControlTarget.asWindowOrNull(mImeControlTarget);
final IBinder token = win != null ? win.mClient.asBinder() : null;
// Note: not allowed to call into IMMS with the WM lock held, hence the post.
mWmService.mH.post(() ->
@@ -3712,12 +3777,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@VisibleForTesting
InsetsControlTarget computeImeControlTarget() {
if (!isImeControlledByApp() && mRemoteInsetsControlTarget != null
- || (mInputMethodInputTarget != null
- && getImeHostOrFallback(mInputMethodInputTarget.getWindow())
+ || (mImeInputTarget != null
+ && getImeHostOrFallback(mImeInputTarget.getWindow())
== mRemoteInsetsControlTarget)) {
return mRemoteInsetsControlTarget;
} else {
- return mInputMethodInputTarget;
+ return mImeInputTarget;
}
}
@@ -3734,7 +3799,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// screen. If it's not covering the entire screen the IME might extend beyond the apps
// bounds.
if (allowAttachToApp && isImeAttachedToApp()) {
- return mInputMethodTarget.mActivityRecord.getSurfaceControl();
+ return mImeLayeringTarget.mActivityRecord.getSurfaceControl();
}
// Otherwise, we just attach it to where the display area policy put it.
@@ -4191,8 +4256,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
// Initialize state of exiting applications.
- forAllTaskDisplayAreas(taskDisplayArea -> {
- taskDisplayArea.setExitingTokensHasVisible(hasVisible);
+ forAllRootTasks(task -> {
+ final ArrayList<ActivityRecord> activities = task.mExitingActivities;
+ for (int j = activities.size() - 1; j >= 0; --j) {
+ activities.get(j).hasVisible = hasVisible;
+ }
});
}
@@ -4205,7 +4273,22 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
// Time to remove any exiting applications?
- forAllTaskDisplayAreas(TaskDisplayArea::removeExistingAppTokensIfPossible);
+ forAllRootTasks(task -> {
+ final ArrayList<ActivityRecord> activities = task.mExitingActivities;
+ for (int j = activities.size() - 1; j >= 0; --j) {
+ final ActivityRecord activity = activities.get(j);
+ if (!activity.hasVisible && !mDisplayContent.mClosingApps.contains(activity)
+ && (!activity.mIsExiting || activity.isEmpty())) {
+ // Make sure there is no animation running on this activity, so any windows
+ // associated with it will be removed as soon as their animations are
+ // complete.
+ cancelAnimation();
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "performLayout: Activity exiting now removed %s", activity);
+ activity.removeIfPossible();
+ }
+ }
+ });
}
@Override
@@ -4355,7 +4438,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private boolean skipImeWindowsDuringTraversal(DisplayContent dc) {
// We skip IME windows so they're processed just above their target, except
// in split-screen mode where we process the IME containers above the docked divider.
- return dc.mInputMethodTarget != null
+ return dc.getImeTarget(IME_TARGET_LAYERING) != null
&& !dc.getDefaultTaskDisplayArea().isSplitScreenModeActivated();
}
@@ -4470,7 +4553,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@Override
void assignChildLayers(SurfaceControl.Transaction t) {
mImeWindowsContainers.setNeedsLayer();
- final WindowState imeTarget = mInputMethodTarget;
+ final WindowState imeTarget = mImeLayeringTarget;
// In the case where we have an IME target that is not in split-screen mode IME
// assignment is easy. We just need the IME to go directly above the target. This way
// children of the target will naturally go above the IME and everyone is happy.
@@ -5128,15 +5211,56 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
*/
void removeRootTasksInWindowingModes(int... windowingModes) {
- forAllTaskDisplayAreas(taskDisplayArea -> {
- taskDisplayArea.removeRootTasksInWindowingModes(windowingModes);
+ if (windowingModes == null || windowingModes.length == 0) {
+ return;
+ }
+
+ // Collect the root tasks that are necessary to be removed instead of performing the removal
+ // by looping the children, so that we don't miss any root tasks after the children size
+ // changed or reordered.
+ final ArrayList<Task> rootTasks = new ArrayList<>();
+ forAllRootTasks(rootTask -> {
+ for (int windowingMode : windowingModes) {
+ if (rootTask.mCreatedByOrganizer
+ || rootTask.getWindowingMode() != windowingMode
+ || !rootTask.isActivityTypeStandardOrUndefined()) {
+ continue;
+ }
+ rootTasks.add(rootTask);
+ }
});
+ for (int i = rootTasks.size() - 1; i >= 0; --i) {
+ mRootWindowContainer.mTaskSupervisor.removeRootTask(rootTasks.get(i));
+ }
}
void removeRootTasksWithActivityTypes(int... activityTypes) {
- forAllTaskDisplayAreas(taskDisplayArea -> {
- taskDisplayArea.removeRootTasksWithActivityTypes(activityTypes);
+ if (activityTypes == null || activityTypes.length == 0) {
+ return;
+ }
+
+ // Collect the root tasks that are necessary to be removed instead of performing the removal
+ // by looping the children, so that we don't miss any root tasks after the children size
+ // changed or reordered.
+ final ArrayList<Task> rootTasks = new ArrayList<>();
+ forAllRootTasks(rootTask -> {
+ for (int activityType : activityTypes) {
+ // Collect the root tasks that are currently being organized.
+ if (rootTask.mCreatedByOrganizer) {
+ for (int k = rootTask.getChildCount() - 1; k >= 0; --k) {
+ final Task task = (Task) rootTask.getChildAt(k);
+ if (task.getActivityType() == activityType) {
+ rootTasks.add(task);
+ }
+ }
+ } else if (rootTask.getActivityType() == activityType) {
+ rootTasks.add(rootTask);
+ }
+ }
});
+ for (int i = rootTasks.size() - 1; i >= 0; --i) {
+ mRootWindowContainer.mTaskSupervisor.removeRootTask(rootTasks.get(i));
+ }
}
ActivityRecord topRunningActivity() {
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 91106eff9805..17c3b20c9e40 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -19,10 +19,14 @@ package com.android.server.wm;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
+import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL;
+import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
+import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.ImeInsetsSourceProviderProto.IME_TARGET_FROM_IME;
import static com.android.server.wm.ImeInsetsSourceProviderProto.INSETS_SOURCE_PROVIDER;
import static com.android.server.wm.ImeInsetsSourceProviderProto.IS_IME_LAYOUT_DRAWN;
+import android.annotation.NonNull;
import android.os.Trace;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsSource;
@@ -37,9 +41,9 @@ import java.io.PrintWriter;
* Controller for IME inset source on the server. It's called provider as it provides the
* {@link InsetsSource} to the client that uses it in {@link InsetsSourceConsumer}.
*/
-class ImeInsetsSourceProvider extends InsetsSourceProvider {
+final class ImeInsetsSourceProvider extends InsetsSourceProvider {
- private InsetsControlTarget mImeTargetFromIme;
+ private InsetsControlTarget mImeRequester;
private Runnable mShowImeRunner;
private boolean mIsImeLayoutDrawn;
private boolean mImeShowing;
@@ -56,12 +60,8 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
* @param imeTarget imeTarget on which IME request is coming from.
*/
void scheduleShowImePostLayout(InsetsControlTarget imeTarget) {
- boolean targetChanged = mImeTargetFromIme != imeTarget
- && mImeTargetFromIme != null && imeTarget != null && mShowImeRunner != null
- && imeTarget.getWindow() != null && mImeTargetFromIme.getWindow() != null
- && mImeTargetFromIme.getWindow().mActivityRecord
- == imeTarget.getWindow().mActivityRecord;
- mImeTargetFromIme = imeTarget;
+ boolean targetChanged = isTargetChangedWithinActivity(imeTarget);
+ mImeRequester = imeTarget;
if (targetChanged) {
// target changed, check if new target can show IME.
ProtoLog.d(WM_DEBUG_IME, "IME target changed within ActivityRecord");
@@ -72,24 +72,24 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
return;
}
- ProtoLog.d(WM_DEBUG_IME, "Schedule IME show for %s", mImeTargetFromIme.getWindow() == null
- ? mImeTargetFromIme : mImeTargetFromIme.getWindow().getName());
+ ProtoLog.d(WM_DEBUG_IME, "Schedule IME show for %s", mImeRequester.getWindow() == null
+ ? mImeRequester : mImeRequester.getWindow().getName());
mShowImeRunner = () -> {
ProtoLog.d(WM_DEBUG_IME, "Run showImeRunner");
// Target should still be the same.
- if (isImeTargetFromDisplayContentAndImeSame()) {
- final InsetsControlTarget target = mDisplayContent.mInputMethodControlTarget;
+ if (isReadyToShowIme()) {
+ final InsetsControlTarget target = mDisplayContent.getImeTarget(IME_TARGET_CONTROL);
ProtoLog.i(WM_DEBUG_IME, "call showInsets(ime) on %s",
target.getWindow() != null ? target.getWindow().getName() : "");
setImeShowing(true);
target.showInsets(WindowInsets.Type.ime(), true /* fromIme */);
Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "WMS.showImePostLayout", 0);
- if (target != mImeTargetFromIme && mImeTargetFromIme != null) {
+ if (target != mImeRequester && mImeRequester != null) {
ProtoLog.w(WM_DEBUG_IME,
"showInsets(ime) was requested by different window: %s ",
- (mImeTargetFromIme.getWindow() != null
- ? mImeTargetFromIme.getWindow().getName() : ""));
+ (mImeRequester.getWindow() != null
+ ? mImeRequester.getWindow().getName() : ""));
}
}
abortShowImePostLayout();
@@ -100,8 +100,7 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
void checkShowImePostLayout() {
// check if IME is drawn
if (mIsImeLayoutDrawn
- || (mImeTargetFromIme != null
- && isImeTargetFromDisplayContentAndImeSame()
+ || (isReadyToShowIme()
&& mWin != null
&& mWin.isDrawn()
&& !mWin.mGivenInsetsPending)) {
@@ -118,13 +117,13 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
*/
void abortShowImePostLayout() {
ProtoLog.d(WM_DEBUG_IME, "abortShowImePostLayout");
- mImeTargetFromIme = null;
+ mImeRequester = null;
mIsImeLayoutDrawn = false;
mShowImeRunner = null;
}
@VisibleForTesting
- boolean isImeTargetFromDisplayContentAndImeSame() {
+ boolean isReadyToShowIme() {
// IMMS#mLastImeTargetWindow always considers focused window as
// IME target, however DisplayContent#computeImeTarget() can compute
// a different IME target.
@@ -134,35 +133,75 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
// Also, if imeTarget is closing, it would be considered as outdated target.
// TODO(b/139861270): Remove the child & sublayer check once IMMS is aware of
// actual IME target.
- final WindowState dcTarget = mDisplayContent.mInputMethodTarget;
- final InsetsControlTarget controlTarget = mDisplayContent.mInputMethodControlTarget;
- if (dcTarget == null || mImeTargetFromIme == null) {
+ final InsetsControlTarget dcTarget = mDisplayContent.getImeTarget(IME_TARGET_LAYERING);
+ if (dcTarget == null || mImeRequester == null) {
return false;
}
- ProtoLog.d(WM_DEBUG_IME, "dcTarget: %s mImeTargetFromIme: %s",
- dcTarget.getName(), mImeTargetFromIme.getWindow() == null
- ? mImeTargetFromIme : mImeTargetFromIme.getWindow().getName());
-
- return (!dcTarget.isClosing() && mImeTargetFromIme == dcTarget)
- || (mImeTargetFromIme != null && mImeTargetFromIme.getWindow() != null
- && dcTarget.getParentWindow() == mImeTargetFromIme
- && dcTarget.mSubLayer > mImeTargetFromIme.getWindow().mSubLayer)
- || mImeTargetFromIme == mDisplayContent.getImeFallback()
- || mImeTargetFromIme == mDisplayContent.mInputMethodInputTarget
- || controlTarget == mImeTargetFromIme
- && (mImeTargetFromIme.getWindow() == null
- || !mImeTargetFromIme.getWindow().isClosing());
+ ProtoLog.d(WM_DEBUG_IME, "dcTarget: %s mImeRequester: %s",
+ dcTarget.getWindow().getName(), mImeRequester.getWindow() == null
+ ? mImeRequester : mImeRequester.getWindow().getName());
+
+ return isImeLayeringTarget(mImeRequester, dcTarget)
+ || isAboveImeLayeringTarget(mImeRequester, dcTarget)
+ || isImeFallbackTarget(mImeRequester)
+ || isImeInputTarget(mImeRequester)
+ || sameAsImeControlTarget();
}
+ // ---------------------------------------------------------------------------------------
+ // Methods for checking IME insets target changing state.
+ //
+ private static boolean isImeLayeringTarget(@NonNull InsetsControlTarget target,
+ @NonNull InsetsControlTarget dcTarget) {
+ return !dcTarget.getWindow().isClosing() && target == dcTarget;
+ }
+
+ private static boolean isAboveImeLayeringTarget(@NonNull InsetsControlTarget target,
+ @NonNull InsetsControlTarget dcTarget) {
+ return target.getWindow() != null
+ && dcTarget.getWindow().getParentWindow() == target
+ && dcTarget.getWindow().mSubLayer > target.getWindow().mSubLayer;
+ }
+
+ private boolean isImeFallbackTarget(InsetsControlTarget target) {
+ return target == mDisplayContent.getImeFallback();
+ }
+
+ private boolean isImeInputTarget(InsetsControlTarget target) {
+ return target == mDisplayContent.getImeTarget(IME_TARGET_INPUT);
+ }
+
+ private boolean sameAsImeControlTarget() {
+ final InsetsControlTarget target = mDisplayContent.getImeTarget(IME_TARGET_CONTROL);
+ return target == mImeRequester
+ && (mImeRequester.getWindow() == null
+ || !mImeRequester.getWindow().isClosing());
+ }
+
+ private boolean isTargetChangedWithinActivity(InsetsControlTarget target) {
+ // We don't consider the target out of the activity.
+ if (target == null || target.getWindow() == null) {
+ return false;
+ }
+ return mImeRequester != target
+ && mImeRequester != null && mShowImeRunner != null
+ && mImeRequester.getWindow() != null
+ && mImeRequester.getWindow().mActivityRecord
+ == target.getWindow().mActivityRecord;
+ }
+ // ---------------------------------------------------------------------------------------
+
@Override
public void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);
pw.print(prefix);
pw.print("mImeShowing=");
pw.print(mImeShowing);
- if (mImeTargetFromIme != null) {
- pw.print(" showImePostLayout pending for mImeTargetFromIme=");
- pw.print(mImeTargetFromIme);
+ if (mImeRequester != null) {
+ pw.print(prefix);
+ pw.print("showImePostLayout pending for mImeRequester=");
+ pw.print(mImeRequester);
+ pw.println();
}
pw.println();
}
@@ -171,8 +210,8 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
void dumpDebug(ProtoOutputStream proto, long fieldId, @WindowTraceLogLevel int logLevel) {
final long token = proto.start(fieldId);
super.dumpDebug(proto, INSETS_SOURCE_PROVIDER, logLevel);
- if (mImeTargetFromIme != null) {
- mImeTargetFromIme.getWindow().dumpDebug(proto, IME_TARGET_FROM_IME, logLevel);
+ if (mImeRequester != null) {
+ mImeRequester.getWindow().dumpDebug(proto, IME_TARGET_FROM_IME, logLevel);
}
proto.write(IS_IME_LAYOUT_DRAWN, mIsImeLayoutDrawn);
proto.end(token);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 40315f98a98f..edd01ebee42f 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -57,7 +57,9 @@ import android.view.WindowInsets.Type;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.util.LatencyTracker;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -84,6 +86,11 @@ import java.util.stream.Collectors;
public class RecentsAnimationController implements DeathRecipient {
private static final String TAG = RecentsAnimationController.class.getSimpleName();
private static final long FAILSAFE_DELAY = 1000;
+ /**
+ * If the recents animation is canceled before the delay since the window drawn, do not log the
+ * action because the duration is too small that may be just a mistouch,
+ */
+ private static final long LATENCY_TRACKER_LOG_DELAY_MS = 300;
public static final int REORDER_KEEP_IN_PLACE = 0;
public static final int REORDER_MOVE_TO_TOP = 1;
@@ -123,7 +130,7 @@ public class RecentsAnimationController implements DeathRecipient {
private boolean mPendingStart = true;
// Set when the animation has been canceled
- private boolean mCanceled;
+ private volatile boolean mCanceled;
// Whether or not the input consumer is enabled. The input consumer must be both registered and
// enabled for it to start intercepting touch events.
@@ -364,6 +371,9 @@ public class RecentsAnimationController implements DeathRecipient {
Binder.restoreCallingIdentity(token);
}
}
+
+ @Override
+ public void detachNavigationBarFromApp() {}
};
/**
@@ -592,6 +602,15 @@ public class RecentsAnimationController implements DeathRecipient {
return adapter.createRemoteAnimationTarget();
}
+ void logRecentsAnimationStartTime(int durationMs) {
+ BackgroundThread.getHandler().postDelayed(() -> {
+ if (!mCanceled) {
+ mService.mLatencyTracker.logAction(LatencyTracker.ACTION_START_RECENTS_ANIMATION,
+ durationMs);
+ }
+ }, LATENCY_TRACKER_LOG_DELAY_MS);
+ }
+
private boolean removeTaskInternal(int taskId) {
boolean result = false;
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 378638f82c37..69723ff99d06 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -514,16 +514,6 @@ class Task extends WindowContainer<WindowContainer> {
// {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag of the root activity.
boolean mSupportsPictureInPicture;
- // Activity bounds if this task or its top activity is presented in letterbox mode and
- // {@code null} otherwise.
- @Nullable
- private Rect mLetterboxActivityBounds;
-
- // Activity insets if this task or its top activity is presented in letterbox mode and
- // {@code null} otherwise.
- @Nullable
- private Rect mLetterboxActivityInsets;
-
// Whether the task is currently being drag-resized
private boolean mDragResizing;
private int mDragResizeMode;
@@ -4116,16 +4106,10 @@ class Task extends WindowContainer<WindowContainer> {
info.resizeMode = top != null ? top.mResizeMode : mResizeMode;
info.topActivityType = top.getActivityType();
info.isResizeable = isResizeable();
- // Don't query getTopNonFinishingActivity().getBounds() directly because when fillTaskInfo
- // is triggered for the first time after activities change, getBounds() may return non final
- // bounds, e.g. fullscreen bounds instead of letterboxed bounds. To work around this,
- // assigning bounds from ActivityRecord#layoutLetterbox when they are ready.
- info.letterboxActivityBounds = Rect.copyOrNull(mLetterboxActivityBounds);
- info.letterboxActivityInsets = Rect.copyOrNull(mLetterboxActivityInsets);
+
info.positionInParent = getRelativePosition();
- info.parentBounds = getParentBounds();
- info.pictureInPictureParams = getPictureInPictureParams();
+ info.pictureInPictureParams = getPictureInPictureParams(top);
info.topActivityInfo = mReuseActivitiesReport.top != null
? mReuseActivitiesReport.top.info
: null;
@@ -4142,34 +4126,16 @@ class Task extends WindowContainer<WindowContainer> {
}
@Nullable PictureInPictureParams getPictureInPictureParams() {
- final Task top = getTopMostTask();
+ return getPictureInPictureParams(getTopMostTask());
+ }
+
+ private @Nullable PictureInPictureParams getPictureInPictureParams(Task top) {
if (top == null) return null;
final ActivityRecord rootActivity = top.getRootActivity();
return (rootActivity == null || rootActivity.pictureInPictureArgs.empty())
? null : new PictureInPictureParams(rootActivity.pictureInPictureArgs);
}
- void maybeUpdateLetterboxInTaskOrganizer(
- ActivityRecord activityRecord,
- @Nullable Rect activityBounds,
- @Nullable Rect activityInsets) {
- if (isOrganized()
- && mReuseActivitiesReport.top == activityRecord
- // Want to force update only if letterbox bounds have changed.
- && (!Objects.equals(mLetterboxActivityBounds, activityBounds)
- || !Objects.equals(mLetterboxActivityInsets, activityInsets))) {
- mLetterboxActivityBounds = Rect.copyOrNull(activityBounds);
- mLetterboxActivityInsets = Rect.copyOrNull(activityInsets);
- // Forcing update to reduce visual jank during the transition.
- dispatchTaskInfoChangedIfNeeded(true /* force */);
- }
- }
-
- private Rect getParentBounds() {
- final WindowContainer parent = getParent();
- return parent != null ? new Rect(parent.getBounds()) : new Rect();
- }
-
/**
* Returns a {@link TaskInfo} with information from this task.
*/
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 5522eeb6d900..7fed84015e8b 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -33,7 +33,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
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;
@@ -610,34 +609,6 @@ final class TaskDisplayArea extends DisplayArea<Task> {
return false;
}
- void setExitingTokensHasVisible(boolean hasVisible) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final ArrayList<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
- for (int j = activities.size() - 1; j >= 0; --j) {
- activities.get(j).hasVisible = hasVisible;
- }
- }
- }
-
- void removeExistingAppTokensIfPossible() {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final ArrayList<ActivityRecord> activities = mChildren.get(i).mExitingActivities;
- for (int j = activities.size() - 1; j >= 0; --j) {
- final ActivityRecord activity = activities.get(j);
- if (!activity.hasVisible && !mDisplayContent.mClosingApps.contains(activity)
- && (!activity.mIsExiting || activity.isEmpty())) {
- // Make sure there is no animation running on this activity, so any windows
- // associated with it will be removed as soon as their animations are
- // complete.
- cancelAnimation();
- ProtoLog.v(WM_DEBUG_ADD_REMOVE,
- "performLayout: Activity exiting now removed %s", activity);
- activity.removeIfPossible();
- }
- }
- }
- }
-
@Override
int getOrientation(int candidate) {
mLastOrientationSource = null;
@@ -894,11 +865,6 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
}
- @Nullable
- Task getRootTask(int rootTaskId) {
- return getRootTask(stack -> stack.getRootTaskId() == rootTaskId);
- }
-
/**
* Returns an existing stack compatible with the windowing mode and activity type or creates one
* if a compatible stack doesn't exist.
@@ -1296,69 +1262,6 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
}
- /**
- * Removes root tasks in the input windowing modes from the system if they are of activity type
- * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
- */
- void removeRootTasksInWindowingModes(int... windowingModes) {
- if (windowingModes == null || windowingModes.length == 0) {
- return;
- }
-
- // Collect the root tasks that are necessary to be removed instead of performing the removal
- // by looping the children, so that we don't miss any root tasks after the children size
- // changed or reordered.
- final ArrayList<Task> rootTasks = new ArrayList<>();
- for (int j = windowingModes.length - 1; j >= 0; --j) {
- final int windowingMode = windowingModes[j];
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final Task rootTask = mChildren.get(i);
- if (rootTask.mCreatedByOrganizer
- || !rootTask.isActivityTypeStandardOrUndefined()
- || rootTask.getWindowingMode() != windowingMode) {
- continue;
- }
- rootTasks.add(rootTask);
- }
- }
-
- for (int i = rootTasks.size() - 1; i >= 0; --i) {
- mRootWindowContainer.mTaskSupervisor.removeRootTask(rootTasks.get(i));
- }
- }
-
- void removeRootTasksWithActivityTypes(int... activityTypes) {
- if (activityTypes == null || activityTypes.length == 0) {
- return;
- }
-
- // Collect the root tasks that are necessary to be removed instead of performing the removal
- // by looping the children, so that we don't miss any root tasks after the children size
- // changed or reordered.
- final ArrayList<Task> rootTasks = new ArrayList<>();
- for (int j = activityTypes.length - 1; j >= 0; --j) {
- final int activityType = activityTypes[j];
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final Task rootTask = mChildren.get(i);
- // Collect the root tasks that are currently being organized.
- if (rootTask.mCreatedByOrganizer) {
- for (int k = rootTask.getChildCount() - 1; k >= 0; --k) {
- final Task task = (Task) rootTask.getChildAt(k);
- if (task.getActivityType() == activityType) {
- rootTasks.add(task);
- }
- }
- } else if (rootTask.getActivityType() == activityType) {
- rootTasks.add(rootTask);
- }
- }
- }
-
- for (int i = rootTasks.size() - 1; i >= 0; --i) {
- mRootWindowContainer.mTaskSupervisor.removeRootTask(rootTasks.get(i));
- }
- }
-
void onSplitScreenModeDismissed() {
// 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
@@ -1842,13 +1745,6 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
}
- void prepareFreezingTaskBounds() {
- for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final Task stack = getChildAt(stackNdx);
- stack.prepareFreezingTaskBounds();
- }
- }
-
/**
* Removes the stacks in the node applying the content removal node from the display.
*
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index ca44f0d60226..58aca20af926 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
+import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_CONFIGS;
import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_WINDOW_CONFIGS;
@@ -580,11 +581,11 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
synchronized (mGlobalLock) {
DisplayContent dc = mService.mWindowManager.mRoot
.getDisplayContent(displayId);
- if (dc == null || dc.mInputMethodTarget == null) {
+ if (dc == null || dc.getImeTarget(IME_TARGET_LAYERING) == null) {
return null;
}
// Avoid WindowState#getRootTask() so we don't attribute system windows to a task.
- final Task task = dc.mInputMethodTarget.getTask();
+ final Task task = dc.getImeTarget(IME_TARGET_LAYERING).getWindow().getTask();
if (task == null) {
return null;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f23319936536..6f10edfc59e5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -105,6 +105,9 @@ import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN;
import static com.android.server.LockGuard.INDEX_WINDOW;
import static com.android.server.LockGuard.installLock;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL;
+import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
+import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -1037,7 +1040,7 @@ public class WindowManagerService extends IWindowManager.Stub
private WindowContentFrameStats mTempWindowRenderStats;
- private final LatencyTracker mLatencyTracker;
+ final LatencyTracker mLatencyTracker;
/**
* Whether the UI is currently running in touch mode (not showing
@@ -1121,18 +1124,16 @@ public class WindowManagerService extends IWindowManager.Stub
// While running a recents animation, this will get called early because we show the
// recents animation target activity immediately when the animation starts. Defer the
// mLaunchTaskBehind updates until recents animation finishes.
- final boolean isRecentsAnimationTarget = getRecentsAnimationController() != null
- && getRecentsAnimationController().isTargetApp(atoken);
- if (atoken.mLaunchTaskBehind && !isRecentsAnimationTarget) {
+ if (atoken.mLaunchTaskBehind && !isRecentsAnimationTarget(atoken)) {
mAtmService.mTaskSupervisor.scheduleLaunchTaskBehindComplete(atoken.token);
atoken.mLaunchTaskBehind = false;
} else {
atoken.updateReportedVisibilityLocked();
// We should also defer sending the finished callback until the recents animation
// successfully finishes.
- if (atoken.mEnteringAnimation && !isRecentsAnimationTarget) {
+ if (atoken.mEnteringAnimation && !isRecentsAnimationTarget(atoken)) {
atoken.mEnteringAnimation = false;
- if (atoken != null && atoken.attachedToProcess()) {
+ if (atoken.attachedToProcess()) {
try {
atoken.app.getThread().scheduleEnterAnimationComplete(atoken.appToken);
} catch (RemoteException e) {
@@ -2969,6 +2970,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ boolean isRecentsAnimationTarget(ActivityRecord r) {
+ return mRecentsAnimationController != null && mRecentsAnimationController.isTargetApp(r);
+ }
+
void setWindowOpaqueLocked(IBinder token, boolean isOpaque) {
final ActivityRecord wtoken = mRoot.getActivityRecord(token);
if (wtoken != null) {
@@ -6322,20 +6327,20 @@ public class WindowManagerService extends IWindowManager.Stub
mRoot.dumpTopFocusedDisplayId(pw);
mRoot.forAllDisplays(dc -> {
final int displayId = dc.getDisplayId();
- final WindowState inputMethodTarget = dc.mInputMethodTarget;
- final WindowState inputMethodInputTarget = dc.mInputMethodInputTarget;
- final InsetsControlTarget inputMethodControlTarget = dc.mInputMethodControlTarget;
- if (inputMethodTarget != null) {
- pw.print(" mInputMethodTarget in display# "); pw.print(displayId);
- pw.print(' '); pw.println(inputMethodTarget);
+ final InsetsControlTarget imeLayeringTarget = dc.getImeTarget(IME_TARGET_LAYERING);
+ final InsetsControlTarget imeInputTarget = dc.getImeTarget(IME_TARGET_INPUT);
+ final InsetsControlTarget imeControlTarget = dc.getImeTarget(IME_TARGET_CONTROL);
+ if (imeLayeringTarget != null) {
+ pw.print(" imeLayeringTarget in display# "); pw.print(displayId);
+ pw.print(' '); pw.println(imeLayeringTarget);
}
- if (inputMethodInputTarget != null) {
- pw.print(" mInputMethodInputTarget in display# "); pw.print(displayId);
- pw.print(' '); pw.println(inputMethodInputTarget);
+ if (imeInputTarget != null) {
+ pw.print(" imeInputTarget in display# "); pw.print(displayId);
+ pw.print(' '); pw.println(imeInputTarget);
}
- if (inputMethodControlTarget != null) {
- pw.print(" inputMethodControlTarget in display# "); pw.print(displayId);
- pw.print(' '); pw.println(inputMethodControlTarget);
+ if (imeControlTarget != null) {
+ pw.print(" imeControlTarget in display# "); pw.print(displayId);
+ pw.print(' '); pw.println(imeControlTarget);
}
});
pw.print(" mInTouchMode="); pw.println(mInTouchMode);
@@ -7630,7 +7635,7 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mGlobalLock) {
final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
if (imeTarget != null) {
- imeTarget.getDisplayContent().setInputMethodInputTarget(imeTarget);
+ imeTarget.getDisplayContent().updateImeInputAndControlTarget(imeTarget);
}
}
}
@@ -7773,10 +7778,10 @@ public class WindowManagerService extends IWindowManager.Stub
// requested to be hidden.
dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout();
}
- if (dc != null && dc.mInputMethodControlTarget != null) {
+ if (dc != null && dc.getImeTarget(IME_TARGET_CONTROL) != null) {
ProtoLog.d(WM_DEBUG_IME, "hideIme Control target: %s ",
- dc.mInputMethodControlTarget);
- dc.mInputMethodControlTarget.hideInsets(
+ dc.getImeTarget(IME_TARGET_CONTROL));
+ dc.getImeTarget(IME_TARGET_CONTROL).hideInsets(
WindowInsets.Type.ime(), true /* fromIme */);
}
if (dc != null) {
@@ -7900,7 +7905,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (dc == null) {
return null;
}
- final InsetsControlTarget target = dc.mInputMethodControlTarget;
+ final InsetsControlTarget target = dc.getImeTarget(IME_TARGET_CONTROL);
if (target == null) {
return null;
}
@@ -7913,10 +7918,10 @@ public class WindowManagerService extends IWindowManager.Stub
public String getImeTargetNameForLogging(int displayId) {
synchronized (mGlobalLock) {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
- if (dc == null) {
+ if (dc == null || dc.getImeTarget(IME_TARGET_LAYERING) == null) {
return null;
}
- return dc.mInputMethodTarget != null ? dc.mInputMethodTarget.getName() : null;
+ return dc.getImeTarget(IME_TARGET_LAYERING).getWindow().getName();
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 3bbdcb8dfedd..32b84a8d0a2c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -119,6 +119,8 @@ import static com.android.server.policy.WindowManagerPolicy.TRANSIT_ENTER;
import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT;
import static com.android.server.policy.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
import static com.android.server.wm.AnimationSpecProto.MOVE;
+import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
+import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.DisplayContent.logsGestureExclusionRestrictions;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
@@ -1112,9 +1114,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
final int layoutXDiff;
final int layoutYDiff;
final WindowState imeWin = mWmService.mRoot.getCurrentInputMethodWindow();
+ final InsetsControlTarget imeTarget = dc.getImeTarget(IME_TARGET_LAYERING);
final boolean isInputMethodAdjustTarget = windowsAreFloating
- ? dc.mInputMethodTarget != null && task == dc.mInputMethodTarget.getTask()
- : isInputMethodTarget();
+ ? imeTarget != null && task == imeTarget.getWindow().getTask()
+ : isImeLayeringTarget();
final boolean isImeTarget =
imeWin != null && imeWin.isVisibleNow() && isInputMethodAdjustTarget;
if (isFullscreenAndFillsDisplay || layoutInParentFrame()) {
@@ -1451,9 +1454,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
void onDisplayChanged(DisplayContent dc) {
if (dc != null && mDisplayContent != null && dc != mDisplayContent
- && mDisplayContent.mInputMethodInputTarget == this) {
- dc.setInputMethodInputTarget(mDisplayContent.mInputMethodInputTarget);
- mDisplayContent.mInputMethodInputTarget = null;
+ && getImeInputTarget() == this) {
+ dc.updateImeInputAndControlTarget(getImeInputTarget());
+ mDisplayContent.setImeInputTarget(null);
}
super.onDisplayChanged(dc);
// Window was not laid out for this display yet, so make sure mLayoutSeq does not match.
@@ -2158,14 +2161,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
final DisplayContent dc = getDisplayContent();
- if (isInputMethodTarget()) {
- // Make sure to set mInputMethodTarget as null when the removed window is the IME
- // target, in case computeImeTarget may use the outdated target.
- dc.mInputMethodTarget = null;
+ if (isImeLayeringTarget()) {
+ // Make sure to set mImeLayeringTarget as null when the removed window is the
+ // IME target, in case computeImeTarget may use the outdated target.
+ dc.setImeLayeringTarget(null);
dc.computeImeTarget(true /* updateImeTarget */);
}
- if (dc.mInputMethodInputTarget == this) {
- dc.setInputMethodInputTarget(null);
+ if (dc.getImeTarget(IME_TARGET_INPUT) == this) {
+ dc.updateImeInputAndControlTarget(null);
}
final int type = mAttrs.type;
@@ -4615,7 +4618,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// directly above it. The exception is if we are in split screen
// in which case we process the IME at the DisplayContent level to
// ensure it is above the docked divider.
- if (isInputMethodTarget() && !inSplitScreenWindowingMode()) {
+ if (isImeLayeringTarget() && !inSplitScreenWindowingMode()) {
if (getDisplayContent().forAllImeWindows(callback, traverseTopToBottom)) {
return true;
}
@@ -5211,9 +5214,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
boolean needsZBoost() {
- final WindowState inputMethodTarget = getDisplayContent().mInputMethodTarget;
- if (mIsImWindow && inputMethodTarget != null) {
- final ActivityRecord activity = inputMethodTarget.mActivityRecord;
+ final InsetsControlTarget target = getDisplayContent().getImeTarget(IME_TARGET_LAYERING);
+ if (mIsImWindow && target != null) {
+ final ActivityRecord activity = target.getWindow().mActivityRecord;
if (activity != null) {
return activity.needsZBoost();
}
@@ -5365,14 +5368,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (isChildWindow()) {
// If we are a child of the input method target we need this promotion.
- if (getParentWindow().isInputMethodTarget()) {
+ if (getParentWindow().isImeLayeringTarget()) {
return true;
}
} else if (mActivityRecord != null) {
// Likewise if we share a token with the Input method target and are ordered
// above it but not necessarily a child (e.g. a Dialog) then we also need
// this promotion.
- final WindowState imeTarget = getDisplayContent().mInputMethodTarget;
+ final WindowState imeTarget = getImeLayeringTarget();
boolean inTokenWithAndAboveImeTarget = imeTarget != null && imeTarget != this
&& imeTarget.mToken == mToken
&& mAttrs.type != TYPE_APPLICATION_STARTING
@@ -5499,8 +5502,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return !mTapExcludeRegion.isEmpty();
}
- boolean isInputMethodTarget() {
- return getDisplayContent().mInputMethodTarget == this;
+ boolean isImeLayeringTarget() {
+ return getDisplayContent().getImeTarget(IME_TARGET_LAYERING) == this;
+ }
+
+ WindowState getImeLayeringTarget() {
+ final InsetsControlTarget target = getDisplayContent().getImeTarget(IME_TARGET_LAYERING);
+ return target != null ? target.getWindow() : null;
+ }
+
+ WindowState getImeInputTarget() {
+ final InsetsControlTarget target = mDisplayContent.getImeTarget(IME_TARGET_INPUT);
+ return target != null ? target.getWindow() : null;
}
long getFrameNumber() {
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index 4ca5b9e4b14f..1ecf850adb1f 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -47,7 +47,6 @@ android_test {
"testables",
"ub-uiautomator",
"hamcrest-library",
- "compatibility-device-util-axt",
],
libs: [
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 2053bfb45884..b451d9f4aaf0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -62,6 +62,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.same;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
+import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_FIXED_TRANSFORM;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
@@ -168,7 +170,7 @@ public class DisplayContentTests extends WindowTestsBase {
final WindowState imeAppTarget =
createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
- mDisplayContent.mInputMethodTarget = imeAppTarget;
+ mDisplayContent.setImeLayeringTarget(imeAppTarget);
assertForAllWindowsOrder(Arrays.asList(
mWallpaperWindow,
@@ -187,7 +189,7 @@ public class DisplayContentTests extends WindowTestsBase {
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
- mDisplayContent.mInputMethodTarget = mChildAppWindowAbove;
+ mDisplayContent.setImeLayeringTarget(mChildAppWindowAbove);
assertForAllWindowsOrder(Arrays.asList(
mWallpaperWindow,
@@ -205,7 +207,7 @@ public class DisplayContentTests extends WindowTestsBase {
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
- mDisplayContent.mInputMethodTarget = mStatusBarWindow;
+ mDisplayContent.setImeLayeringTarget(mStatusBarWindow);
assertForAllWindowsOrder(Arrays.asList(
mWallpaperWindow,
@@ -223,7 +225,7 @@ public class DisplayContentTests extends WindowTestsBase {
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testForAllWindows_WithNotificationShadeImeTarget() throws Exception {
- mDisplayContent.mInputMethodTarget = mNotificationShadeWindow;
+ mDisplayContent.setImeLayeringTarget(mNotificationShadeWindow);
assertForAllWindowsOrder(Arrays.asList(
mWallpaperWindow,
@@ -855,15 +857,17 @@ public class DisplayContentTests extends WindowTestsBase {
mDisplayContent.setInputMethodWindowLocked(mImeWindow);
newDisplay.setInputMethodWindowLocked(null);
assertEquals("appWin should be IME target window",
- appWin, mDisplayContent.mInputMethodTarget);
- assertNull("newDisplay Ime target: ", newDisplay.mInputMethodTarget);
+ appWin, mDisplayContent.getImeTarget(IME_TARGET_LAYERING));
+ assertNull("newDisplay Ime target: ", newDisplay.getImeTarget(IME_TARGET_LAYERING));
// Switch input method window on new display & make sure the input method target also
// switched as expected.
newDisplay.setInputMethodWindowLocked(mImeWindow);
mDisplayContent.setInputMethodWindowLocked(null);
- assertEquals("appWin1 should be IME target window", appWin1, newDisplay.mInputMethodTarget);
- assertNull("default display Ime target: ", mDisplayContent.mInputMethodTarget);
+ assertEquals("appWin1 should be IME target window", appWin1,
+ newDisplay.getImeTarget(IME_TARGET_LAYERING));
+ assertNull("default display Ime target: ",
+ mDisplayContent.getImeTarget(IME_TARGET_LAYERING));
}
@Test
@@ -937,17 +941,17 @@ public class DisplayContentTests extends WindowTestsBase {
@Test
public void testComputeImeParent_app() throws Exception {
final DisplayContent dc = createNewDisplay();
- dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
- dc.mInputMethodInputTarget = dc.mInputMethodTarget;
- assertEquals(dc.mInputMethodTarget.mActivityRecord.getSurfaceControl(),
- dc.computeImeParent());
+ dc.setImeLayeringTarget(createWindow(null, TYPE_BASE_APPLICATION, "app"));
+ dc.setImeInputTarget(dc.getImeTarget(IME_TARGET_LAYERING).getWindow());
+ assertEquals(dc.getImeTarget(IME_TARGET_LAYERING).getWindow()
+ .mActivityRecord.getSurfaceControl(), dc.computeImeParent());
}
@Test
public void testComputeImeParent_app_notFullscreen() throws Exception {
final DisplayContent dc = createNewDisplay();
- dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app");
- dc.mInputMethodTarget.setWindowingMode(
+ dc.setImeLayeringTarget(createWindow(null, TYPE_STATUS_BAR, "app"));
+ dc.getImeTarget(IME_TARGET_LAYERING).getWindow().setWindowingMode(
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
}
@@ -957,7 +961,7 @@ public class DisplayContentTests extends WindowTestsBase {
public void testComputeImeParent_app_notMatchParentBounds() {
spyOn(mAppWindow.mActivityRecord);
doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds();
- mDisplayContent.mInputMethodTarget = mAppWindow;
+ mDisplayContent.setImeLayeringTarget(mAppWindow);
// The surface parent of IME should be the display instead of app window.
assertEquals(mDisplayContent.getImeContainer().getParentSurfaceControl(),
mDisplayContent.computeImeParent());
@@ -966,7 +970,7 @@ public class DisplayContentTests extends WindowTestsBase {
@Test
public void testComputeImeParent_noApp() throws Exception {
final DisplayContent dc = createNewDisplay();
- dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar");
+ dc.setImeLayeringTarget(createWindow(null, TYPE_STATUS_BAR, "statusBar"));
assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
}
@@ -976,12 +980,12 @@ public class DisplayContentTests extends WindowTestsBase {
WindowState app = createWindow(null, TYPE_BASE_APPLICATION, dc, "app");
- dc.mInputMethodInputTarget = app;
+ dc.setImeInputTarget(app);
assertEquals(app, dc.computeImeControlTarget());
app.removeImmediately();
- assertNull(dc.mInputMethodInputTarget);
+ assertNull(dc.getImeTarget(IME_TARGET_INPUT));
assertNull(dc.computeImeControlTarget());
}
@@ -989,20 +993,21 @@ public class DisplayContentTests extends WindowTestsBase {
public void testComputeImeControlTarget() throws Exception {
final DisplayContent dc = createNewDisplay();
dc.setRemoteInsetsController(createDisplayWindowInsetsController());
- dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
- dc.mInputMethodTarget = dc.mInputMethodInputTarget;
- assertEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget());
+ dc.setImeInputTarget(createWindow(null, TYPE_BASE_APPLICATION, "app"));
+ dc.setImeLayeringTarget(dc.getImeTarget(IME_TARGET_INPUT).getWindow());
+ assertEquals(dc.getImeTarget(IME_TARGET_INPUT).getWindow(), dc.computeImeControlTarget());
}
@Test
public void testComputeImeControlTarget_splitscreen() throws Exception {
final DisplayContent dc = createNewDisplay();
- dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
- dc.mInputMethodInputTarget.setWindowingMode(
+ dc.setImeInputTarget(createWindow(null, TYPE_BASE_APPLICATION, "app"));
+ dc.getImeTarget(IME_TARGET_INPUT).getWindow().setWindowingMode(
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
- dc.mInputMethodTarget = dc.mInputMethodInputTarget;
+ dc.setImeLayeringTarget(dc.getImeTarget(IME_TARGET_INPUT).getWindow());
dc.setRemoteInsetsController(createDisplayWindowInsetsController());
- assertNotEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget());
+ assertNotEquals(dc.getImeTarget(IME_TARGET_INPUT).getWindow(),
+ dc.computeImeControlTarget());
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@@ -1010,8 +1015,9 @@ public class DisplayContentTests extends WindowTestsBase {
public void testComputeImeControlTarget_notMatchParentBounds() throws Exception {
spyOn(mAppWindow.mActivityRecord);
doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds();
- mDisplayContent.mInputMethodInputTarget = mAppWindow;
- mDisplayContent.mInputMethodTarget = mDisplayContent.mInputMethodInputTarget;
+ mDisplayContent.setImeInputTarget(mAppWindow);
+ mDisplayContent.setImeLayeringTarget(
+ mDisplayContent.getImeTarget(IME_TARGET_INPUT).getWindow());
mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController());
assertEquals(mAppWindow, mDisplayContent.computeImeControlTarget());
}
@@ -1637,7 +1643,7 @@ public class DisplayContentTests extends WindowTestsBase {
TYPE_BASE_APPLICATION, "nextImeTargetApp");
spyOn(child1);
doReturn(true).when(child1).inSplitScreenWindowingMode();
- mDisplayContent.mInputMethodTarget = child1;
+ mDisplayContent.setImeLayeringTarget(child1);
spyOn(nextImeTargetApp);
spyOn(mAppWindow);
@@ -1648,7 +1654,7 @@ public class DisplayContentTests extends WindowTestsBase {
child1.removeImmediately();
verify(mDisplayContent).computeImeTarget(true);
- assertNull(mDisplayContent.mInputMethodInputTarget);
+ assertNull(mDisplayContent.getImeTarget(IME_TARGET_INPUT));
verify(child1, never()).needsRelativeLayeringToIme();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
index 59d195b670a8..5f9626711896 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
@@ -52,19 +52,19 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase {
public void testTransparentControlTargetWindowCanShowIme() {
final WindowState appWin = createWindow(null, TYPE_APPLICATION, "app");
final WindowState popup = createWindow(appWin, TYPE_APPLICATION, "popup");
- mDisplayContent.mInputMethodControlTarget = popup;
- mDisplayContent.mInputMethodTarget = appWin;
+ mDisplayContent.setImeControlTarget(popup);
+ mDisplayContent.setImeLayeringTarget(appWin);
popup.mAttrs.format = PixelFormat.TRANSPARENT;
mImeProvider.scheduleShowImePostLayout(appWin);
- assertTrue(mImeProvider.isImeTargetFromDisplayContentAndImeSame());
+ assertTrue(mImeProvider.isReadyToShowIme());
}
@Test
public void testInputMethodInputTargetCanShowIme() {
WindowState target = createWindow(null, TYPE_APPLICATION, "app");
- mDisplayContent.mInputMethodTarget = target;
+ mDisplayContent.setImeLayeringTarget(target);
mImeProvider.scheduleShowImePostLayout(target);
- assertTrue(mImeProvider.isImeTargetFromDisplayContentAndImeSame());
+ assertTrue(mImeProvider.isReadyToShowIme());
}
@Test
@@ -74,8 +74,8 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase {
mImeProvider.setWindow(ime, null, null);
WindowState target = createWindow(null, TYPE_APPLICATION, "app");
- mDisplayContent.mInputMethodTarget = target;
- mDisplayContent.mInputMethodControlTarget = target;
+ mDisplayContent.setImeLayeringTarget(target);
+ mDisplayContent.setImeControlTarget(target);
mImeProvider.scheduleShowImePostLayout(target);
assertFalse(mImeProvider.isImeShowing());
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 90caf35e2936..276643847712 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -31,6 +31,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -181,16 +182,18 @@ public class InsetsStateControllerTest extends WindowTestsBase {
// This can be the IME z-order target while app cannot be the IME z-order target.
// This is also the only IME control target in this test, so IME won't be invisible caused
// by the control-target change.
- mDisplayContent.mInputMethodInputTarget = createWindow(null, TYPE_APPLICATION, "base");
+ mDisplayContent.updateImeInputAndControlTarget(
+ createWindow(null, TYPE_APPLICATION, "base"));
// Make IME and stay visible during the test.
mImeWindow.setHasSurface(true);
getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
- getController().onImeControlTargetChanged(mDisplayContent.mInputMethodInputTarget);
+ getController().onImeControlTargetChanged(mDisplayContent.getImeTarget(IME_TARGET_INPUT));
final InsetsState requestedState = new InsetsState();
requestedState.getSource(ITYPE_IME).setVisible(true);
- mDisplayContent.mInputMethodInputTarget.updateRequestedVisibility(requestedState);
- getController().onInsetsModified(mDisplayContent.mInputMethodInputTarget);
+ mDisplayContent.getImeTarget(IME_TARGET_INPUT).getWindow()
+ .updateRequestedVisibility(requestedState);
+ getController().onInsetsModified(mDisplayContent.getImeTarget(IME_TARGET_INPUT));
// Send our spy window (app) into the system so that we can detect the invocation.
final WindowState win = createWindow(null, TYPE_APPLICATION, "app");
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index dd6e490b8282..c7175a0c424d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -30,6 +30,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.Task.ActivityState.STOPPED;
import static org.junit.Assert.assertEquals;
@@ -270,7 +271,7 @@ public class SizeCompatTests extends WindowTestsBase {
// The position should be horizontal centered.
assertEquals((displayWidth - bounds.width()) / 2, bounds.left);
- mActivity.mDisplayContent.mInputMethodTarget = addWindowToActivity(mActivity);
+ mActivity.mDisplayContent.setImeLayeringTarget(addWindowToActivity(mActivity));
// Make sure IME cannot attach to the app, otherwise IME window will also be shifted.
assertFalse(mActivity.mDisplayContent.isImeAttachedToApp());
@@ -290,9 +291,9 @@ public class SizeCompatTests extends WindowTestsBase {
assertFitted();
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
- mActivity.mDisplayContent.mInputMethodTarget = addWindowToActivity(mActivity);
- mActivity.mDisplayContent.mInputMethodInputTarget =
- mActivity.mDisplayContent.mInputMethodTarget;
+ mActivity.mDisplayContent.setImeLayeringTarget(addWindowToActivity(mActivity));
+ mActivity.mDisplayContent.setImeInputTarget(
+ mActivity.mDisplayContent.getImeTarget(IME_TARGET_LAYERING).getWindow());
// Because the aspect ratio of display doesn't exceed the max aspect ratio of activity.
// The activity should still fill its parent container and IME can attach to the activity.
assertTrue(mActivity.matchParentBounds());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 788ef5ad2ec4..6046c9b2c2b1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -20,20 +20,19 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static com.android.server.wm.utils.CommonUtils.runWithShellPermissionIdentity;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.app.Activity;
-import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.ActivityView;
-import android.app.IActivityManager;
import android.app.ITaskStackListener;
-import android.app.Instrumentation;
import android.app.Instrumentation.ActivityMonitor;
import android.app.TaskStackListener;
import android.content.ComponentName;
@@ -44,7 +43,6 @@ import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
-import android.support.test.uiautomator.UiDevice;
import android.text.TextUtils;
import android.view.Display;
import android.view.ViewGroup;
@@ -52,10 +50,7 @@ import android.view.ViewGroup;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.SystemUtil;
-
import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.ArrayBlockingQueue;
@@ -70,17 +65,11 @@ import java.util.function.Predicate;
@MediumTest
public class TaskStackChangedListenerTest {
- private IActivityManager mService;
private ITaskStackListener mTaskStackListener;
private static final int WAIT_TIMEOUT_MS = 5000;
private static final Object sLock = new Object();
- @Before
- public void setUp() throws Exception {
- mService = ActivityManager.getService();
- }
-
@After
public void tearDown() throws Exception {
ActivityTaskManager.getService().unregisterTaskStackListener(mTaskStackListener);
@@ -374,7 +363,7 @@ public class TaskStackChangedListenerTest {
final ActivityMonitor monitor = new ActivityMonitor(activityClass.getName(), null, false);
getInstrumentation().addMonitor(monitor);
final Context context = getInstrumentation().getContext();
- SystemUtil.runWithShellPermissionIdentity(() -> context.startActivity(
+ runWithShellPermissionIdentity(() -> context.startActivity(
new Intent(context, activityClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
options.toBundle()));
final TestActivity activity =
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
index 78e873e2b0a3..f13847559aa0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
@@ -56,7 +56,7 @@ public class WindowContainerTraversalTests extends WindowTestsBase {
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
TYPE_BASE_APPLICATION, mDisplayContent, "splitScreenSecondaryWindow");
- mDisplayContent.mInputMethodTarget = splitScreenWindow;
+ mDisplayContent.setImeLayeringTarget(splitScreenWindow);
Consumer<WindowState> c = mock(Consumer.class);
mDisplayContent.forAllWindows(c, false);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index d2be50d02ef3..4a6906b88710 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -292,7 +292,7 @@ public class WindowFrameTests extends WindowTestsBase {
// Make IME attach to the window and can produce insets.
final DisplayContent dc = mTestDisplayContent;
- dc.mInputMethodTarget = w;
+ dc.setImeLayeringTarget(w);
WindowState mockIme = mock(WindowState.class);
Mockito.doReturn(true).when(mockIme).isVisibleNow();
dc.mInputMethodWindow = mockIme;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index a57de094a210..76f8207b4ad8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -789,7 +789,7 @@ public class WindowStateTests extends WindowTestsBase {
public void testNeedsRelativeLayeringToIme_notAttached() {
WindowState sameTokenWindow = createWindow(null, TYPE_BASE_APPLICATION, mAppWindow.mToken,
"SameTokenWindow");
- mDisplayContent.mInputMethodTarget = mAppWindow;
+ mDisplayContent.setImeLayeringTarget(mAppWindow);
sameTokenWindow.mActivityRecord.getStack().setWindowingMode(
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
assertTrue(sameTokenWindow.needsRelativeLayeringToIme());
@@ -802,7 +802,7 @@ public class WindowStateTests extends WindowTestsBase {
public void testNeedsRelativeLayeringToIme_startingWindow() {
WindowState sameTokenWindow = createWindow(null, TYPE_APPLICATION_STARTING,
mAppWindow.mToken, "SameTokenWindow");
- mDisplayContent.mInputMethodTarget = mAppWindow;
+ mDisplayContent.setImeLayeringTarget(mAppWindow);
sameTokenWindow.mActivityRecord.getStack().setWindowingMode(
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index e44d47a59fe5..811a14666db9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -218,7 +218,7 @@ public class ZOrderingTests extends WindowTestsBase {
@Test
public void testAssignWindowLayers_ForImeWithNoTarget() {
- mDisplayContent.mInputMethodTarget = null;
+ mDisplayContent.setImeLayeringTarget(null);
mDisplayContent.assignChildLayers(mTransaction);
// The Ime has an higher base layer than app windows and lower base layer than system
@@ -236,7 +236,7 @@ public class ZOrderingTests extends WindowTestsBase {
@Test
public void testAssignWindowLayers_ForImeWithAppTarget() {
final WindowState imeAppTarget = createWindow("imeAppTarget");
- mDisplayContent.mInputMethodTarget = imeAppTarget;
+ mDisplayContent.setImeLayeringTarget(imeAppTarget);
mDisplayContent.assignChildLayers(mTransaction);
@@ -262,7 +262,7 @@ public class ZOrderingTests extends WindowTestsBase {
TYPE_APPLICATION_MEDIA_OVERLAY, imeAppTarget.mToken,
"imeAppTargetChildBelowWindow");
- mDisplayContent.mInputMethodTarget = imeAppTarget;
+ mDisplayContent.setImeLayeringTarget(imeAppTarget);
mDisplayContent.assignChildLayers(mTransaction);
// Ime should be above all app windows except for child windows that are z-ordered above it
@@ -284,7 +284,7 @@ public class ZOrderingTests extends WindowTestsBase {
final WindowState imeAppTarget = createWindow("imeAppTarget");
final WindowState appAboveImeTarget = createWindow("appAboveImeTarget");
- mDisplayContent.mInputMethodTarget = imeAppTarget;
+ mDisplayContent.setImeLayeringTarget(imeAppTarget);
mDisplayContent.assignChildLayers(mTransaction);
// Ime should be above all app windows except for non-fullscreen app window above it and
@@ -307,7 +307,7 @@ public class ZOrderingTests extends WindowTestsBase {
mDisplayContent, "imeSystemOverlayTarget",
true /* ownerCanAddInternalSystemWindow */);
- mDisplayContent.mInputMethodTarget = imeSystemOverlayTarget;
+ mDisplayContent.setImeLayeringTarget(imeSystemOverlayTarget);
mDisplayContent.assignChildLayers(mTransaction);
// The IME target base layer is higher than all window except for the nav bar window, so the
@@ -330,7 +330,7 @@ public class ZOrderingTests extends WindowTestsBase {
@Test
public void testAssignWindowLayers_ForStatusBarImeTarget() {
- mDisplayContent.mInputMethodTarget = mStatusBarWindow;
+ mDisplayContent.setImeLayeringTarget(mStatusBarWindow);
mDisplayContent.assignChildLayers(mTransaction);
assertWindowHigher(mImeWindow, mChildAppWindowAbove);
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/CommonUtils.java b/services/tests/wmtests/src/com/android/server/wm/utils/CommonUtils.java
new file mode 100644
index 000000000000..99d73cf5f7d3
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/CommonUtils.java
@@ -0,0 +1,37 @@
+/*
+ * 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.wm.utils;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.app.UiAutomation;
+
+/** Provides common utility functions. */
+public class CommonUtils {
+ public static UiAutomation getUiAutomation() {
+ return getInstrumentation().getUiAutomation();
+ }
+
+ public static void runWithShellPermissionIdentity(Runnable runnable) {
+ getUiAutomation().adoptShellPermissionIdentity();
+ try {
+ runnable.run();
+ } finally {
+ getUiAutomation().dropShellPermissionIdentity();
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index 8b7a243c30e6..d502da9fb9ec 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -916,6 +916,84 @@ public final class DataFailCause {
/** System preference change back to SRAT during handoff */
public static final int HANDOFF_PREFERENCE_CHANGED = 0x8CB;
+ //IKE error notifications message as specified in 3GPP TS 24.302 (Section 8.1.2.2).
+
+ /** The PDN connection corresponding to the requested APN has been rejected. */
+ public static final int IWLAN_PDN_CONNECTION_REJECTION = 0x2000;
+ /**
+ * The PDN connection has been rejected. No additional PDN connections can be established
+ * for the UE due to the network policies or capabilities.
+ */
+ public static final int IWLAN_MAX_CONNECTION_REACHED = 0x2001;
+ /**
+ * The PDN connection has been rejected due to a semantic error in TFT operation.
+ */
+ public static final int IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION = 0x2031;
+ /**
+ * The PDN connection has been rejected due to a syntactic error in TFT operation.
+ */
+ public static final int IWLAN_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION = 0x2032;
+ /**
+ * The PDN connection has been rejected due to sematic errors in the packet filter.
+ */
+ public static final int IWLAN_SEMANTIC_ERRORS_IN_PACKET_FILTERS = 0x2034;
+ /**
+ * The PDN connection has been rejected due to syntactic errors in the packet filter.
+ */
+ public static final int IWLAN_SYNTACTICAL_ERRORS_IN_PACKET_FILTERS = 0x2035;
+ /**
+ * No non-3GPP subscription is associated with the IMSI.
+ * The UE is not allowed to use non-3GPP access to EPC.
+ */
+ public static final int IWLAN_NON_3GPP_ACCESS_TO_EPC_NOT_ALLOWED = 0x2328;
+ /** The user identified by the IMSI is unknown. */
+ public static final int IWLAN_USER_UNKNOWN = 0x2329;
+ /**
+ * The requested APN is not included in the user's profile,
+ * and therefore is not authorized for that user.
+ */
+ public static final int IWLAN_NO_APN_SUBSCRIPTION = 0x232A;
+ /** The user is barred from using the non-3GPP access or the subscribed APN. */
+ public static final int IWLAN_AUTHORIZATION_REJECTED = 0x232B;
+ /** The Mobile Equipment used is not acceptable to the network */
+ public static final int IWLAN_ILLEGAL_ME = 0x232E;
+ /**
+ * The network has determined that the requested procedure cannot be completed successfully
+ * due to network failure.
+ */
+ public static final int IWLAN_NETWORK_FAILURE = 0x2904;
+ /** The access type is restricted to the user. */
+ public static final int IWLAN_RAT_TYPE_NOT_ALLOWED = 0x2AF9;
+ /** The network does not accept emergency PDN bringup request using an IMEI */
+ public static final int IWLAN_IMEI_NOT_ACCEPTED = 0x2AFD;
+ /**
+ * The ePDG performs PLMN filtering (based on roaming agreements) and rejects
+ * the request from the UE.
+ * The UE requests service in a PLMN where the UE is not allowed to operate.
+ */
+ public static final int IWLAN_PLMN_NOT_ALLOWED = 0x2B03;
+ /** The ePDG does not support un-authenticated IMSI based emergency PDN bringup **/
+ public static final int IWLAN_UNAUTHENTICATED_EMERGENCY_NOT_SUPPORTED = 0x2B2F;
+
+ // Device is unable to establish an IPSec tunnel with the ePDG for any reason
+ // e.g authentication fail or certificate validation or DNS Resolution and timeout failure.
+
+ /** IKE configuration error resulting in failure */
+ public static final int IWLAN_IKEV2_CONFIG_FAILURE = 0x4000;
+ /**
+ * Sent in the response to an IKE_AUTH message when, for some reason,
+ * the authentication failed.
+ */
+ public static final int IWLAN_IKEV2_AUTH_FAILURE = 0x4001;
+ /** IKE message timeout, tunnel setup failed due to no response from EPDG */
+ public static final int IWLAN_IKEV2_MSG_TIMEOUT = 0x4002;
+ /** IKE Certification validation failure */
+ public static final int IWLAN_IKEV2_CERT_INVALID = 0x4003;
+ /** Unable to resolve FQDN for the ePDG to an IP address */
+ public static final int IWLAN_DNS_RESOLUTION_NAME_FAILURE = 0x4004;
+ /** No response received from the DNS Server due to a timeout*/
+ public static final int IWLAN_DNS_RESOLUTION_TIMEOUT = 0x4005;
+
// OEM sepecific error codes. To be used by OEMs when they don't
// want to reveal error code which would be replaced by ERROR_UNSPECIFIED
public static final int OEM_DCFAILCAUSE_1 = 0x1001;
@@ -1341,6 +1419,34 @@ public final class DataFailCause {
sFailCauseMap.put(VSNCP_RECONNECT_NOT_ALLOWED, "VSNCP_RECONNECT_NOT_ALLOWED");
sFailCauseMap.put(IPV6_PREFIX_UNAVAILABLE, "IPV6_PREFIX_UNAVAILABLE");
sFailCauseMap.put(HANDOFF_PREFERENCE_CHANGED, "HANDOFF_PREFERENCE_CHANGED");
+ sFailCauseMap.put(IWLAN_PDN_CONNECTION_REJECTION, "IWLAN_PDN_CONNECTION_REJECTION");
+ sFailCauseMap.put(IWLAN_MAX_CONNECTION_REACHED, "IWLAN_MAX_CONNECTION_REACHED");
+ sFailCauseMap.put(IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION,
+ "IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION");
+ sFailCauseMap.put(IWLAN_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION,
+ "IWLAN_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION");
+ sFailCauseMap.put(IWLAN_SEMANTIC_ERRORS_IN_PACKET_FILTERS,
+ "IWLAN_SEMANTIC_ERRORS_IN_PACKET_FILTERS");
+ sFailCauseMap.put(IWLAN_SYNTACTICAL_ERRORS_IN_PACKET_FILTERS,
+ "IWLAN_SYNTACTICAL_ERRORS_IN_PACKET_FILTERS");
+ sFailCauseMap.put(IWLAN_NON_3GPP_ACCESS_TO_EPC_NOT_ALLOWED,
+ "IWLAN_NON_3GPP_ACCESS_TO_EPC_NOT_ALLOWED");
+ sFailCauseMap.put(IWLAN_USER_UNKNOWN, "IWLAN_USER_UNKNOWN");
+ sFailCauseMap.put(IWLAN_NO_APN_SUBSCRIPTION, "IWLAN_NO_APN_SUBSCRIPTION");
+ sFailCauseMap.put(IWLAN_AUTHORIZATION_REJECTED, "IWLAN_AUTHORIZATION_REJECTED");
+ sFailCauseMap.put(IWLAN_ILLEGAL_ME, "IWLAN_ILLEGAL_ME");
+ sFailCauseMap.put(IWLAN_NETWORK_FAILURE, "IWLAN_NETWORK_FAILURE");
+ sFailCauseMap.put(IWLAN_RAT_TYPE_NOT_ALLOWED, "IWLAN_RAT_TYPE_NOT_ALLOWED");
+ sFailCauseMap.put(IWLAN_IMEI_NOT_ACCEPTED, "IWLAN_IMEI_NOT_ACCEPTED");
+ sFailCauseMap.put(IWLAN_PLMN_NOT_ALLOWED, "IWLAN_PLMN_NOT_ALLOWED");
+ sFailCauseMap.put(IWLAN_UNAUTHENTICATED_EMERGENCY_NOT_SUPPORTED,
+ "IWLAN_UNAUTHENTICATED_EMERGENCY_NOT_SUPPORTED");
+ sFailCauseMap.put(IWLAN_IKEV2_CONFIG_FAILURE, "IWLAN_IKEV2_CONFIG_FAILURE");
+ sFailCauseMap.put(IWLAN_IKEV2_AUTH_FAILURE, "IWLAN_IKEV2_AUTH_FAILURE");
+ sFailCauseMap.put(IWLAN_IKEV2_MSG_TIMEOUT, "IWLAN_IKEV2_MSG_TIMEOUT");
+ sFailCauseMap.put(IWLAN_IKEV2_CERT_INVALID, "IWLAN_IKEV2_CERT_INVALID");
+ sFailCauseMap.put(IWLAN_DNS_RESOLUTION_NAME_FAILURE, "IWLAN_DNS_RESOLUTION_NAME_FAILURE");
+ sFailCauseMap.put(IWLAN_DNS_RESOLUTION_TIMEOUT, "IWLAN_DNS_RESOLUTION_TIMEOUT");
sFailCauseMap.put(OEM_DCFAILCAUSE_1, "OEM_DCFAILCAUSE_1");
sFailCauseMap.put(OEM_DCFAILCAUSE_2, "OEM_DCFAILCAUSE_2");
sFailCauseMap.put(OEM_DCFAILCAUSE_3, "OEM_DCFAILCAUSE_3");
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 3aed6019beb5..b3bdd6055c62 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -188,6 +188,7 @@ import android.net.RouteInfo;
import android.net.RouteInfoParcel;
import android.net.SocketKeepalive;
import android.net.UidRange;
+import android.net.UidRangeParcel;
import android.net.Uri;
import android.net.VpnManager;
import android.net.metrics.IpConnectivityLog;
@@ -1055,7 +1056,7 @@ public class ConnectivityServiceTest {
public MockVpn(int userId) {
super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService,
- userId, mock(KeyStore.class));
+ mMockNetd, userId, mock(KeyStore.class));
mConfig = new VpnConfig();
}
@@ -1094,10 +1095,11 @@ public class ConnectivityServiceTest {
mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp,
mNetworkCapabilities);
mMockNetworkAgent.waitForIdle(TIMEOUT_MS);
- verify(mNetworkManagementService, times(1))
- .addVpnUidRanges(eq(mMockVpn.getNetId()), eq(uids.toArray(new UidRange[0])));
- verify(mNetworkManagementService, never())
- .removeVpnUidRanges(eq(mMockVpn.getNetId()), any());
+
+ verify(mMockNetd, times(1)).networkAddUidRanges(eq(mMockVpn.getNetId()),
+ eq(toUidRangeStableParcels(uids)));
+ verify(mMockNetd, never())
+ .networkRemoveUidRanges(eq(mMockVpn.getNetId()), any());
mAgentRegistered = true;
mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities());
mNetworkAgent = mMockNetworkAgent.getNetworkAgent();
@@ -1169,6 +1171,11 @@ public class ConnectivityServiceTest {
}
}
+ private UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) {
+ return ranges.stream().map(
+ r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new);
+ }
+
private void mockVpn(int uid) {
synchronized (mService.mVpns) {
int userId = UserHandle.getUserId(uid);
@@ -4947,8 +4954,8 @@ public class ConnectivityServiceTest {
expectForceUpdateIfaces(onlyCell, MOBILE_IFNAME);
reset(mStatsService);
- // Captive portal change shouldn't update ifaces
- mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
+ // Temp metered change shouldn't update ifaces
+ mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
waitForIdle();
verify(mStatsService, never())
.forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
@@ -5464,6 +5471,7 @@ public class ConnectivityServiceTest {
final Network wifi = mWiFiNetworkAgent.getNetwork();
final NetworkCapabilities initialCaps = new NetworkCapabilities();
+ initialCaps.addTransportType(TRANSPORT_VPN);
initialCaps.addCapability(NET_CAPABILITY_INTERNET);
initialCaps.removeCapability(NET_CAPABILITY_NOT_VPN);
@@ -5495,44 +5503,45 @@ public class ConnectivityServiceTest {
withWifiAndMobileUnderlying.setLinkDownstreamBandwidthKbps(10);
withWifiAndMobileUnderlying.setLinkUpstreamBandwidthKbps(20);
+ final NetworkCapabilities initialCapsNotMetered = new NetworkCapabilities(initialCaps);
+ initialCapsNotMetered.addCapability(NET_CAPABILITY_NOT_METERED);
+
NetworkCapabilities caps = new NetworkCapabilities(initialCaps);
- final boolean notDeclaredMetered = false;
- mService.applyUnderlyingCapabilities(new Network[]{}, caps, notDeclaredMetered);
+ mService.applyUnderlyingCapabilities(new Network[]{}, initialCapsNotMetered, caps);
assertEquals(withNoUnderlying, caps);
caps = new NetworkCapabilities(initialCaps);
- mService.applyUnderlyingCapabilities(new Network[]{null}, caps, notDeclaredMetered);
+ mService.applyUnderlyingCapabilities(new Network[]{null}, initialCapsNotMetered, caps);
assertEquals(withNoUnderlying, caps);
caps = new NetworkCapabilities(initialCaps);
- mService.applyUnderlyingCapabilities(new Network[]{mobile}, caps, notDeclaredMetered);
+ mService.applyUnderlyingCapabilities(new Network[]{mobile}, initialCapsNotMetered, caps);
assertEquals(withMobileUnderlying, caps);
- mService.applyUnderlyingCapabilities(new Network[]{wifi}, caps, notDeclaredMetered);
+ mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCapsNotMetered, caps);
assertEquals(withWifiUnderlying, caps);
- final boolean isDeclaredMetered = true;
withWifiUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED);
caps = new NetworkCapabilities(initialCaps);
- mService.applyUnderlyingCapabilities(new Network[]{wifi}, caps, isDeclaredMetered);
+ mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCaps, caps);
assertEquals(withWifiUnderlying, caps);
caps = new NetworkCapabilities(initialCaps);
- mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, caps, isDeclaredMetered);
+ mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, initialCaps, caps);
assertEquals(withWifiAndMobileUnderlying, caps);
withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED);
caps = new NetworkCapabilities(initialCaps);
mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi},
- caps, notDeclaredMetered);
+ initialCapsNotMetered, caps);
assertEquals(withWifiAndMobileUnderlying, caps);
caps = new NetworkCapabilities(initialCaps);
mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi},
- caps, notDeclaredMetered);
+ initialCapsNotMetered, caps);
assertEquals(withWifiAndMobileUnderlying, caps);
- mService.applyUnderlyingCapabilities(null, caps, notDeclaredMetered);
+ mService.applyUnderlyingCapabilities(null, initialCapsNotMetered, caps);
assertEquals(withWifiUnderlying, caps);
}
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 337507ac1d46..6e380be6c583 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -58,6 +58,7 @@ import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.INetd;
import android.net.Ikev2VpnProfile;
import android.net.InetAddresses;
import android.net.IpPrefix;
@@ -70,6 +71,7 @@ import android.net.NetworkCapabilities;
import android.net.NetworkInfo.DetailedState;
import android.net.RouteInfo;
import android.net.UidRange;
+import android.net.UidRangeParcel;
import android.net.VpnManager;
import android.net.VpnService;
import android.net.ipsec.ike.IkeSessionCallback;
@@ -172,11 +174,13 @@ public class VpnTest {
mPackages.put(PKGS[i], PKG_UIDS[i]);
}
}
+ private static final UidRange PRI_USER_RANGE = UidRange.createForUser(primaryUser.id);
@Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
@Mock private UserManager mUserManager;
@Mock private PackageManager mPackageManager;
@Mock private INetworkManagementService mNetService;
+ @Mock private INetd mNetd;
@Mock private AppOpsManager mAppOps;
@Mock private NotificationManager mNotificationManager;
@Mock private Vpn.SystemServices mSystemServices;
@@ -256,8 +260,7 @@ public class VpnTest {
null, null);
assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
- UidRange.createForUser(primaryUser.id),
- UidRange.createForUser(restrictedProfileA.id)
+ PRI_USER_RANGE, UidRange.createForUser(restrictedProfileA.id)
})), ranges);
}
@@ -269,9 +272,7 @@ public class VpnTest {
final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
null, null);
- assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
- UidRange.createForUser(primaryUser.id)
- })), ranges);
+ assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { PRI_USER_RANGE })), ranges);
}
@Test
@@ -282,15 +283,13 @@ public class VpnTest {
final Set<UidRange> ranges = new ArraySet<>();
vpn.addUserToRanges(ranges, primaryUser.id, null, null);
- assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
- UidRange.createForUser(primaryUser.id)
- })), ranges);
+ assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { PRI_USER_RANGE })), ranges);
}
@Test
public void testUidAllowAndDenylist() throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
- final UidRange user = UidRange.createForUser(primaryUser.id);
+ final UidRange user = PRI_USER_RANGE;
final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
// Allowed list
@@ -339,62 +338,67 @@ public class VpnTest {
@Test
public void testLockdownChangingPackage() throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
- final UidRange user = UidRange.createForUser(primaryUser.id);
+ final UidRange user = PRI_USER_RANGE;
// Default state.
- assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
+ assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1],
+ user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
// Set always-on without lockdown.
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null, mKeyStore));
- assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
+ assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1],
+ user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
// Set always-on with lockdown.
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null, mKeyStore));
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
- new UidRange(user.start, user.start + PKG_UIDS[1] - 1),
- new UidRange(user.start + PKG_UIDS[1] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
}));
- assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
+
+ assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[2],
+ user.start + PKG_UIDS[3]);
assertUnblocked(vpn, user.start + PKG_UIDS[1]);
// Switch to another app.
assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null, mKeyStore));
- verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
- new UidRange(user.start, user.start + PKG_UIDS[1] - 1),
- new UidRange(user.start + PKG_UIDS[1] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
}));
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
- new UidRange(user.start, user.start + PKG_UIDS[3] - 1),
- new UidRange(user.start + PKG_UIDS[3] + 1, user.stop)
+
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start, user.start + PKG_UIDS[3] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
}));
- assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
+ assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1],
+ user.start + PKG_UIDS[2]);
assertUnblocked(vpn, user.start + PKG_UIDS[3]);
}
@Test
public void testLockdownAllowlist() throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
- final UidRange user = UidRange.createForUser(primaryUser.id);
+ final UidRange user = PRI_USER_RANGE;
// Set always-on with lockdown and allow app PKGS[2] from lockdown.
assertTrue(vpn.setAlwaysOnPackage(
PKGS[1], true, Collections.singletonList(PKGS[2]), mKeyStore));
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
- new UidRange(user.start, user.start + PKG_UIDS[1] - 1),
- new UidRange(user.start + PKG_UIDS[2] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
}));
assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[3]);
assertUnblocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
-
// Change allowed app list to PKGS[3].
assertTrue(vpn.setAlwaysOnPackage(
PKGS[1], true, Collections.singletonList(PKGS[3]), mKeyStore));
- verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
- new UidRange(user.start + PKG_UIDS[2] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
}));
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
- new UidRange(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1),
- new UidRange(user.start + PKG_UIDS[3] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
}));
assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[2]);
assertUnblocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[3]);
@@ -402,25 +406,25 @@ public class VpnTest {
// Change the VPN app.
assertTrue(vpn.setAlwaysOnPackage(
PKGS[0], true, Collections.singletonList(PKGS[3]), mKeyStore));
- verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
- new UidRange(user.start, user.start + PKG_UIDS[1] - 1),
- new UidRange(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1)
+ verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1)
}));
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
- new UidRange(user.start, user.start + PKG_UIDS[0] - 1),
- new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1)
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start, user.start + PKG_UIDS[0] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1)
}));
assertBlocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[3]);
// Remove the list of allowed packages.
assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null, mKeyStore));
- verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
- new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1),
- new UidRange(user.start + PKG_UIDS[3] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
}));
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
- new UidRange(user.start + PKG_UIDS[0] + 1, user.stop),
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop),
}));
assertBlocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[2],
user.start + PKG_UIDS[3]);
@@ -429,12 +433,12 @@ public class VpnTest {
// Add the list of allowed packages.
assertTrue(vpn.setAlwaysOnPackage(
PKGS[0], true, Collections.singletonList(PKGS[1]), mKeyStore));
- verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
- new UidRange(user.start + PKG_UIDS[0] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop)
}));
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
- new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
- new UidRange(user.start + PKG_UIDS[1] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
}));
assertBlocked(vpn, user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1]);
@@ -447,13 +451,13 @@ public class VpnTest {
// allowed package should change from PGKS[1] to PKGS[2].
assertTrue(vpn.setAlwaysOnPackage(
PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app"), mKeyStore));
- verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[]{
- new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
- new UidRange(user.start + PKG_UIDS[1] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[]{
+ new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
}));
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[]{
- new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[2] - 1),
- new UidRange(user.start + PKG_UIDS[2] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[]{
+ new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[2] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
}));
}
@@ -467,86 +471,86 @@ public class VpnTest {
restrictedProfileA.flags);
tempProfile.restrictedProfileParentId = primaryUser.id;
- final UidRange user = UidRange.createForUser(primaryUser.id);
+ final UidRange user = PRI_USER_RANGE;
final UidRange profile = UidRange.createForUser(tempProfile.id);
// Set lockdown.
assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null, mKeyStore));
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
- new UidRange(user.start, user.start + PKG_UIDS[3] - 1),
- new UidRange(user.start + PKG_UIDS[3] + 1, user.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(user.start, user.start + PKG_UIDS[3] - 1),
+ new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
}));
-
// Verify restricted user isn't affected at first.
assertUnblocked(vpn, profile.start + PKG_UIDS[0]);
// Add the restricted user.
setMockedUsers(primaryUser, tempProfile);
vpn.onUserAdded(tempProfile.id);
- verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
- new UidRange(profile.start, profile.start + PKG_UIDS[3] - 1),
- new UidRange(profile.start + PKG_UIDS[3] + 1, profile.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(profile.start, profile.start + PKG_UIDS[3] - 1),
+ new UidRangeParcel(profile.start + PKG_UIDS[3] + 1, profile.stop)
}));
// Remove the restricted user.
tempProfile.partial = true;
vpn.onUserRemoved(tempProfile.id);
- verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
- new UidRange(profile.start, profile.start + PKG_UIDS[3] - 1),
- new UidRange(profile.start + PKG_UIDS[3] + 1, profile.stop)
+ verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
+ new UidRangeParcel(profile.start, profile.start + PKG_UIDS[3] - 1),
+ new UidRangeParcel(profile.start + PKG_UIDS[3] + 1, profile.stop)
}));
}
@Test
public void testLockdownRuleRepeatability() throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
-
+ final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] {
+ new UidRangeParcel(PRI_USER_RANGE.start, PRI_USER_RANGE.stop)};
// Given legacy lockdown is already enabled,
vpn.setLockdown(true);
- verify(mNetService, times(1)).setAllowOnlyVpnForUids(
- eq(true), aryEq(new UidRange[] {UidRange.createForUser(primaryUser.id)}));
+
+ verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(primaryUserRangeParcel));
// Enabling legacy lockdown twice should do nothing.
vpn.setLockdown(true);
- verify(mNetService, times(1)).setAllowOnlyVpnForUids(anyBoolean(), any(UidRange[].class));
+ verify(mNetd, times(1))
+ .networkRejectNonSecureVpn(anyBoolean(), any(UidRangeParcel[].class));
// And disabling should remove the rules exactly once.
vpn.setLockdown(false);
- verify(mNetService, times(1)).setAllowOnlyVpnForUids(
- eq(false), aryEq(new UidRange[] {UidRange.createForUser(primaryUser.id)}));
+ verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(primaryUserRangeParcel));
// Removing the lockdown again should have no effect.
vpn.setLockdown(false);
- verify(mNetService, times(2)).setAllowOnlyVpnForUids(anyBoolean(), any(UidRange[].class));
+ verify(mNetd, times(2)).networkRejectNonSecureVpn(
+ anyBoolean(), any(UidRangeParcel[].class));
}
@Test
public void testLockdownRuleReversibility() throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
-
- final UidRange[] entireUser = {
- UidRange.createForUser(primaryUser.id)
+ final UidRangeParcel[] entireUser = {
+ new UidRangeParcel(PRI_USER_RANGE.start, PRI_USER_RANGE.stop)
};
- final UidRange[] exceptPkg0 = {
- new UidRange(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1),
- new UidRange(entireUser[0].start + PKG_UIDS[0] + 1, entireUser[0].stop)
+ final UidRangeParcel[] exceptPkg0 = {
+ new UidRangeParcel(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1),
+ new UidRangeParcel(entireUser[0].start + PKG_UIDS[0] + 1, entireUser[0].stop)
};
- final InOrder order = inOrder(mNetService);
+ final InOrder order = inOrder(mNetd);
// Given lockdown is enabled with no package (legacy VPN),
vpn.setLockdown(true);
- order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(entireUser));
+ order.verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(entireUser));
// When a new VPN package is set the rules should change to cover that package.
vpn.prepare(null, PKGS[0], VpnManager.TYPE_VPN_SERVICE);
- order.verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(entireUser));
- order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(exceptPkg0));
+ order.verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(entireUser));
+ order.verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(exceptPkg0));
// When that VPN package is unset, everything should be undone again in reverse.
vpn.prepare(null, VpnConfig.LEGACY_VPN, VpnManager.TYPE_VPN_SERVICE);
- order.verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(exceptPkg0));
- order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(entireUser));
+ order.verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(exceptPkg0));
+ order.verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(entireUser));
}
@Test
@@ -1186,7 +1190,7 @@ public class VpnTest {
.thenReturn(asUserContext);
final TestLooper testLooper = new TestLooper();
final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, new TestDeps(), mNetService,
- userId, mKeyStore, mSystemServices, mIkev2SessionCreator);
+ mNetd, userId, mKeyStore, mSystemServices, mIkev2SessionCreator);
verify(mConnectivityManager, times(1)).registerNetworkProvider(argThat(
provider -> provider.getName().contains("VpnNetworkProvider")
));
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
index e11b33efcc33..4b0d38df0260 100644
--- a/wifi/api/current.txt
+++ b/wifi/api/current.txt
@@ -35,6 +35,7 @@ package android.net.wifi {
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.ScanResult> CREATOR;
field public String SSID;
field public static final int WIFI_STANDARD_11AC = 5; // 0x5
+ field public static final int WIFI_STANDARD_11AD = 7; // 0x7
field public static final int WIFI_STANDARD_11AX = 6; // 0x6
field public static final int WIFI_STANDARD_11N = 4; // 0x4
field public static final int WIFI_STANDARD_LEGACY = 1; // 0x1
@@ -1156,7 +1157,11 @@ package android.net.wifi.rtt {
public final class RangingRequest implements android.os.Parcelable {
method public int describeContents();
+ method public static int getDefaultRttBurstSize();
method public static int getMaxPeers();
+ method public static int getMaxRttBurstSize();
+ method public static int getMinRttBurstSize();
+ method public int getRttBurstSize();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingRequest> CREATOR;
}
@@ -1168,6 +1173,7 @@ package android.net.wifi.rtt {
method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.MacAddress);
method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.wifi.aware.PeerHandle);
method public android.net.wifi.rtt.RangingRequest build();
+ method @NonNull public android.net.wifi.rtt.RangingRequest.Builder setRttBurstSize(int);
}
public final class RangingResult implements android.os.Parcelable {
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
index 15a55485c1d4..e15d0f132b87 100644
--- a/wifi/api/system-current.txt
+++ b/wifi/api/system-current.txt
@@ -277,6 +277,7 @@ package android.net.wifi {
method @Nullable public android.net.wifi.WifiConfiguration toWifiConfiguration();
field public static final int BAND_2GHZ = 1; // 0x1
field public static final int BAND_5GHZ = 2; // 0x2
+ field public static final int BAND_60GHZ = 8; // 0x8
field public static final int BAND_6GHZ = 4; // 0x4
field @Deprecated public static final int BAND_ANY = 7; // 0x7
field public static final int RANDOMIZATION_NONE = 0; // 0x0
@@ -314,9 +315,13 @@ package android.net.wifi {
field public static final int CHANNEL_WIDTH_160MHZ = 6; // 0x6
field public static final int CHANNEL_WIDTH_20MHZ = 2; // 0x2
field public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1; // 0x1
+ field public static final int CHANNEL_WIDTH_2160MHZ = 7; // 0x7
field public static final int CHANNEL_WIDTH_40MHZ = 3; // 0x3
+ field public static final int CHANNEL_WIDTH_4320MHZ = 8; // 0x8
+ field public static final int CHANNEL_WIDTH_6480MHZ = 9; // 0x9
field public static final int CHANNEL_WIDTH_80MHZ = 4; // 0x4
field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5; // 0x5
+ field public static final int CHANNEL_WIDTH_8640MHZ = 10; // 0xa
field public static final int CHANNEL_WIDTH_INVALID = 0; // 0x0
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApInfo> CREATOR;
}
@@ -959,6 +964,10 @@ package android.net.wifi.p2p {
package android.net.wifi.rtt {
+ public final class RangingRequest implements android.os.Parcelable {
+ method @NonNull public java.util.List<android.net.wifi.rtt.ResponderConfig> getRttPeers();
+ }
+
public static final class RangingRequest.Builder {
method public android.net.wifi.rtt.RangingRequest.Builder addResponder(@NonNull android.net.wifi.rtt.ResponderConfig);
}
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 4c23286258d8..9f8ecf14175d 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -320,6 +320,11 @@ public final class ScanResult implements Parcelable {
public static final int WIFI_STANDARD_11AX = 6;
/**
+ * Wi-Fi 802.11ad/ay
+ */
+ public static final int WIFI_STANDARD_11AD = 7;
+
+ /**
* AP wifi standard.
*/
private @WifiStandard int mWifiStandard;
@@ -352,6 +357,8 @@ public final class ScanResult implements Parcelable {
return "11ac";
case WIFI_STANDARD_11AX:
return "11ax";
+ case WIFI_STANDARD_11AD:
+ return "11ad";
case WIFI_STANDARD_UNKNOWN:
return "unknown";
}
@@ -705,6 +712,13 @@ public final class ScanResult implements Parcelable {
return UNSPECIFIED;
}
}
+ if (band == WifiScanner.WIFI_BAND_60_GHZ) {
+ if (channel >= BAND_60_GHZ_FIRST_CH_NUM && channel <= BAND_60_GHZ_LAST_CH_NUM) {
+ return ((channel - BAND_60_GHZ_FIRST_CH_NUM) * 2160) + BAND_60_GHZ_START_FREQ_MHZ;
+ } else {
+ return UNSPECIFIED;
+ }
+ }
return UNSPECIFIED;
}
diff --git a/wifi/java/android/net/wifi/SecurityParams.java b/wifi/java/android/net/wifi/SecurityParams.java
index 157d1c5748d0..0ab6f572fba3 100644
--- a/wifi/java/android/net/wifi/SecurityParams.java
+++ b/wifi/java/android/net/wifi/SecurityParams.java
@@ -16,6 +16,7 @@
package android.net.wifi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.GroupCipher;
@@ -27,6 +28,8 @@ import android.net.wifi.WifiConfiguration.SecurityType;
import android.net.wifi.WifiConfiguration.SuiteBCipher;
import android.os.Parcel;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.BitSet;
import java.util.Objects;
@@ -37,6 +40,23 @@ import java.util.Objects;
public class SecurityParams {
private static final String TAG = "SecurityParams";
+ /** Passpoint Release 1 */
+ public static final int PASSPOINT_R1 = 1;
+
+ /** Passpoint Release 2 */
+ public static final int PASSPOINT_R2 = 2;
+
+ /** Passpoint Release 3 */
+ public static final int PASSPOINT_R3 = 3;
+
+ @IntDef(prefix = { "PASSPOINT_" }, value = {
+ PASSPOINT_R1,
+ PASSPOINT_R2,
+ PASSPOINT_R3,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PasspointRelease {}
+
private @SecurityType int mSecurityType = WifiConfiguration.SECURITY_TYPE_PSK;
/**
@@ -99,6 +119,8 @@ public class SecurityParams {
*/
private boolean mRequirePmf = false;
+ private @PasspointRelease int mPasspointRelease = PASSPOINT_R2;
+
/** Indicate that this SAE security type only accepts H2E (Hash-to-Element) mode. */
private boolean mIsSaeH2eOnlyMode = false;
@@ -562,11 +584,22 @@ public class SecurityParams {
}
/**
- * Create EAP security params for Passpoint.
+ * Create Passpoint security params.
*/
- public static @NonNull SecurityParams createPasspointParams(boolean requirePmf) {
+ public static @NonNull SecurityParams createPasspointParams(@PasspointRelease int release) {
SecurityParams params = new SecurityParams();
- params.mSecurityType = WifiConfiguration.SECURITY_TYPE_EAP;
+ switch (release) {
+ case PASSPOINT_R1:
+ case PASSPOINT_R2:
+ params.mSecurityType = WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2;
+ break;
+ case PASSPOINT_R3:
+ params.mSecurityType = WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3;
+ params.mRequirePmf = true;
+ break;
+ default:
+ throw new IllegalArgumentException("invalid passpoint release " + release);
+ }
params.mAllowedKeyManagement.set(KeyMgmt.WPA_EAP);
params.mAllowedKeyManagement.set(KeyMgmt.IEEE8021X);
@@ -574,12 +607,9 @@ public class SecurityParams {
params.mAllowedProtocols.set(Protocol.RSN);
params.mAllowedPairwiseCiphers.set(PairwiseCipher.CCMP);
- params.mAllowedPairwiseCiphers.set(PairwiseCipher.TKIP);
params.mAllowedGroupCiphers.set(GroupCipher.CCMP);
- params.mAllowedGroupCiphers.set(GroupCipher.TKIP);
- params.mRequirePmf = requirePmf;
return params;
}
diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java
index d570b7e8afa9..6f72f0b58b4b 100644
--- a/wifi/java/android/net/wifi/SoftApCapability.java
+++ b/wifi/java/android/net/wifi/SoftApCapability.java
@@ -116,6 +116,11 @@ public final class SoftApCapability implements Parcelable {
private int[] mSupportedChannelListIn6g = EMPTY_INT_ARRAY;
/**
+ * A list storing supported 60G channels.
+ */
+ private int[] mSupportedChannelListIn60g = EMPTY_INT_ARRAY;
+
+ /**
* Get the maximum supported client numbers which AP resides on.
*/
public int getMaxSupportedClients() {
@@ -147,8 +152,8 @@ public final class SoftApCapability implements Parcelable {
* Set supported channel list in target band type.
*
* @param band One of the following band types:
- * {@link SoftApConfiguation#BAND_2GHZ}, {@link SoftApConfiguation#BAND_5GHZ} or
- * {@link SoftApConfiguation#BAND_6GHZ}.
+ * {@link SoftApConfiguation#BAND_2GHZ}, {@link SoftApConfiguation#BAND_5GHZ},
+ * {@link SoftApConfiguation#BAND_6GHZ}, or {@link SoftApConfiguation#BAND_60GHZ}.
* @param supportedChannelList supported channel list in target band
* @return true if band and supportedChannelList are valid, otherwise false.
*
@@ -168,6 +173,9 @@ public final class SoftApCapability implements Parcelable {
case SoftApConfiguration.BAND_6GHZ:
mSupportedChannelListIn6g = supportedChannelList;
break;
+ case SoftApConfiguration.BAND_60GHZ:
+ mSupportedChannelListIn60g = supportedChannelList;
+ break;
default:
throw new IllegalArgumentException("Invalid band: " + band);
}
@@ -181,8 +189,8 @@ public final class SoftApCapability implements Parcelable {
* {@link SoftapConfiguration.Builder#setChannel(int, int)} API.
*
* @param band One of the following band types:
- * {@link SoftApConfiguation#BAND_2GHZ}, {@link SoftApConfiguation#BAND_5GHZ} or
- * {@link SoftApConfiguation#BAND_6GHZ}.
+ * {@link SoftApConfiguation#BAND_2GHZ}, {@link SoftApConfiguation#BAND_5GHZ},
+ * {@link SoftApConfiguation#BAND_6GHZ}, {@link SoftApConfiguation#BAND_60GHZ}.
* @return List of supported channels for the band.
*
* @throws IllegalArgumentException when band type is invalid.
@@ -199,6 +207,8 @@ public final class SoftApCapability implements Parcelable {
return mSupportedChannelListIn5g;
case SoftApConfiguration.BAND_6GHZ:
return mSupportedChannelListIn6g;
+ case SoftApConfiguration.BAND_60GHZ:
+ return mSupportedChannelListIn60g;
default:
throw new IllegalArgumentException("Invalid band: " + band);
}
@@ -214,6 +224,7 @@ public final class SoftApCapability implements Parcelable {
mSupportedChannelListIn24g = source.mSupportedChannelListIn24g;
mSupportedChannelListIn5g = source.mSupportedChannelListIn5g;
mSupportedChannelListIn6g = source.mSupportedChannelListIn6g;
+ mSupportedChannelListIn60g = source.mSupportedChannelListIn60g;
}
}
@@ -244,6 +255,7 @@ public final class SoftApCapability implements Parcelable {
dest.writeIntArray(mSupportedChannelListIn24g);
dest.writeIntArray(mSupportedChannelListIn5g);
dest.writeIntArray(mSupportedChannelListIn6g);
+ dest.writeIntArray(mSupportedChannelListIn60g);
}
@NonNull
@@ -255,6 +267,7 @@ public final class SoftApCapability implements Parcelable {
capability.setSupportedChannelList(SoftApConfiguration.BAND_2GHZ, in.createIntArray());
capability.setSupportedChannelList(SoftApConfiguration.BAND_5GHZ, in.createIntArray());
capability.setSupportedChannelList(SoftApConfiguration.BAND_6GHZ, in.createIntArray());
+ capability.setSupportedChannelList(SoftApConfiguration.BAND_60GHZ, in.createIntArray());
return capability;
}
@@ -273,6 +286,8 @@ public final class SoftApCapability implements Parcelable {
.append(Arrays.toString(mSupportedChannelListIn24g));
sbuf.append("SupportedChannelListIn5g").append(Arrays.toString(mSupportedChannelListIn5g));
sbuf.append("SupportedChannelListIn6g").append(Arrays.toString(mSupportedChannelListIn6g));
+ sbuf.append("SupportedChannelListIn60g")
+ .append(Arrays.toString(mSupportedChannelListIn60g));
return sbuf.toString();
}
@@ -285,7 +300,8 @@ public final class SoftApCapability implements Parcelable {
&& mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber
&& Arrays.equals(mSupportedChannelListIn24g, capability.mSupportedChannelListIn24g)
&& Arrays.equals(mSupportedChannelListIn5g, capability.mSupportedChannelListIn5g)
- && Arrays.equals(mSupportedChannelListIn6g, capability.mSupportedChannelListIn6g);
+ && Arrays.equals(mSupportedChannelListIn6g, capability.mSupportedChannelListIn6g)
+ && Arrays.equals(mSupportedChannelListIn60g, capability.mSupportedChannelListIn60g);
}
@Override
@@ -293,6 +309,7 @@ public final class SoftApCapability implements Parcelable {
return Objects.hash(mSupportedFeatures, mMaximumSupportedClientNumber,
Arrays.hashCode(mSupportedChannelListIn24g),
Arrays.hashCode(mSupportedChannelListIn5g),
- Arrays.hashCode(mSupportedChannelListIn6g));
+ Arrays.hashCode(mSupportedChannelListIn6g),
+ Arrays.hashCode(mSupportedChannelListIn60g));
}
}
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index 1bb9ebccb01a..d36acb72ff8a 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -88,6 +88,13 @@ public final class SoftApConfiguration implements Parcelable {
public static final int BAND_6GHZ = 1 << 2;
/**
+ * 60GHz band.
+ * @hide
+ */
+ @SystemApi
+ public static final int BAND_60GHZ = 1 << 3;
+
+ /**
* Device is allowed to choose the optimal band (2Ghz, 5Ghz, 6Ghz) based on device capability,
* operating country code and current radio conditions.
* @hide
@@ -104,11 +111,13 @@ public final class SoftApConfiguration implements Parcelable {
BAND_2GHZ,
BAND_5GHZ,
BAND_6GHZ,
+ BAND_60GHZ,
})
public @interface BandType {}
private static boolean isBandValid(@BandType int band) {
- return ((band != 0) && ((band & ~BAND_ANY) == 0));
+ int bandAny = BAND_2GHZ | BAND_5GHZ | BAND_6GHZ | BAND_60GHZ;
+ return ((band != 0) && ((band & ~bandAny) == 0));
}
private static final int MIN_CH_2G_BAND = 1;
@@ -117,6 +126,8 @@ public final class SoftApConfiguration implements Parcelable {
private static final int MAX_CH_5G_BAND = 196;
private static final int MIN_CH_6G_BAND = 1;
private static final int MAX_CH_6G_BAND = 253;
+ private static final int MIN_CH_60G_BAND = 1;
+ private static final int MAX_CH_60G_BAND = 6;
@@ -139,6 +150,13 @@ public final class SoftApConfiguration implements Parcelable {
return false;
}
break;
+
+ case BAND_60GHZ:
+ if (channel < MIN_CH_60G_BAND || channel > MAX_CH_60G_BAND) {
+ return false;
+ }
+ break;
+
default:
return false;
}
diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java
index c681ba9fd44f..e42e7868e944 100644
--- a/wifi/java/android/net/wifi/SoftApInfo.java
+++ b/wifi/java/android/net/wifi/SoftApInfo.java
@@ -86,6 +86,34 @@ public final class SoftApInfo implements Parcelable {
*/
public static final int CHANNEL_WIDTH_160MHZ = 6;
+ /**
+ * AP Channel bandwidth is 2160 MHZ.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_2160MHZ = 7;
+
+ /**
+ * AP Channel bandwidth is 4320 MHZ.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_4320MHZ = 8;
+
+ /**
+ * AP Channel bandwidth is 6480 MHZ.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_6480MHZ = 9;
+
+ /**
+ * AP Channel bandwidth is 8640 MHZ.
+ *
+ * @see #getBandwidth()
+ */
+ public static final int CHANNEL_WIDTH_8640MHZ = 10;
+
/** The frequency which AP resides on. */
private int mFrequency = 0;
@@ -125,7 +153,9 @@ public final class SoftApInfo implements Parcelable {
*
* @return One of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
* {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ},
- * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_INVALID}.
+ * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}, {@link #CHANNEL_WIDTH_2160MHZ},
+ * {@link #CHANNEL_WIDTH_4320MHZ}, {@link #CHANNEL_WIDTH_6480MHZ},
+ * {@link #CHANNEL_WIDTH_8640MHZ}, or {@link #CHANNEL_WIDTH_INVALID}.
*/
@WifiAnnotations.Bandwidth
public int getBandwidth() {
diff --git a/wifi/java/android/net/wifi/WifiAnnotations.java b/wifi/java/android/net/wifi/WifiAnnotations.java
index acda7e06c95d..807b40b5722c 100644
--- a/wifi/java/android/net/wifi/WifiAnnotations.java
+++ b/wifi/java/android/net/wifi/WifiAnnotations.java
@@ -57,6 +57,10 @@ public final class WifiAnnotations {
SoftApInfo.CHANNEL_WIDTH_80MHZ,
SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
SoftApInfo.CHANNEL_WIDTH_160MHZ,
+ SoftApInfo.CHANNEL_WIDTH_2160MHZ,
+ SoftApInfo.CHANNEL_WIDTH_4320MHZ,
+ SoftApInfo.CHANNEL_WIDTH_6480MHZ,
+ SoftApInfo.CHANNEL_WIDTH_8640MHZ,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Bandwidth {}
@@ -77,6 +81,7 @@ public final class WifiAnnotations {
ScanResult.WIFI_STANDARD_11N,
ScanResult.WIFI_STANDARD_11AC,
ScanResult.WIFI_STANDARD_11AX,
+ ScanResult.WIFI_STANDARD_11AD,
})
@Retention(RetentionPolicy.SOURCE)
public @interface WifiStandard{}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index f8b824ca01bd..2a98977fc08e 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -502,6 +502,20 @@ public class WifiConfiguration implements Parcelable {
* @hide
*/
public static final int SECURITY_TYPE_OSEN = 10;
+ /**
+ * Security type for a Passpoint R1/R2 network.
+ * Passpoint R1/R2 uses Enterprise security, where TKIP and WEP are not allowed.
+ * @hide
+ */
+ public static final int SECURITY_TYPE_PASSPOINT_R1_R2 = 11;
+
+ /**
+ * Security type for a Passpoint R3 network.
+ * Passpoint R3 uses Enterprise security, where TKIP and WEP are not allowed,
+ * and PMF must be set to Required.
+ * @hide
+ */
+ public static final int SECURITY_TYPE_PASSPOINT_R3 = 12;
/**
* Security types we support.
@@ -520,6 +534,8 @@ public class WifiConfiguration implements Parcelable {
SECURITY_TYPE_WAPI_CERT,
SECURITY_TYPE_EAP_WPA3_ENTERPRISE,
SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT,
+ SECURITY_TYPE_PASSPOINT_R1_R2,
+ SECURITY_TYPE_PASSPOINT_R3,
})
public @interface SecurityType {}
@@ -546,7 +562,7 @@ public class WifiConfiguration implements Parcelable {
* {@link #SECURITY_TYPE_WAPI_PSK},
* {@link #SECURITY_TYPE_WAPI_CERT},
* {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE},
- * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}
+ * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT},
*/
public void setSecurityParams(@SecurityType int securityType) {
// Clear existing data.
@@ -580,7 +596,7 @@ public class WifiConfiguration implements Parcelable {
* {@link #SECURITY_TYPE_WAPI_PSK},
* {@link #SECURITY_TYPE_WAPI_CERT},
* {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE},
- * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}
+ * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT},
*
* @hide
*/
@@ -627,6 +643,12 @@ public class WifiConfiguration implements Parcelable {
case SECURITY_TYPE_OSEN:
params = SecurityParams.createOsenParams();
break;
+ case SECURITY_TYPE_PASSPOINT_R1_R2:
+ params = SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R2);
+ break;
+ case SECURITY_TYPE_PASSPOINT_R3:
+ params = SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R3);
+ break;
default:
throw new IllegalArgumentException("unknown security type " + securityType);
}
@@ -719,7 +741,7 @@ public class WifiConfiguration implements Parcelable {
* {@link #SECURITY_TYPE_WAPI_PSK},
* {@link #SECURITY_TYPE_WAPI_CERT},
* {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE},
- * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}
+ * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT},
*
* @hide
*/
@@ -743,7 +765,7 @@ public class WifiConfiguration implements Parcelable {
* {@link #SECURITY_TYPE_WAPI_PSK},
* {@link #SECURITY_TYPE_WAPI_CERT},
* {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE},
- * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}
+ * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT},
*
* @return the copy of specific security params if found; otherwise null.
* @hide
@@ -769,7 +791,7 @@ public class WifiConfiguration implements Parcelable {
* {@link #SECURITY_TYPE_WAPI_PSK},
* {@link #SECURITY_TYPE_WAPI_CERT},
* {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE},
- * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}
+ * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT},
*
* @return true if there is a security params matches the type.
* @hide
diff --git a/wifi/java/android/net/wifi/rtt/RangingRequest.java b/wifi/java/android/net/wifi/rtt/RangingRequest.java
index 318efa61a110..04dfcf2f9cad 100644
--- a/wifi/java/android/net/wifi/rtt/RangingRequest.java
+++ b/wifi/java/android/net/wifi/rtt/RangingRequest.java
@@ -30,8 +30,11 @@ import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.modules.utils.build.SdkLevel;
+
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.StringJoiner;
/**
@@ -46,6 +49,9 @@ import java.util.StringJoiner;
*/
public final class RangingRequest implements Parcelable {
private static final int MAX_PEERS = 10;
+ private static final int DEFAULT_RTT_BURST_SIZE = 8;
+ private static final int MIN_RTT_BURST_SIZE = 2;
+ private static final int MAX_RTT_BURST_SIZE = 17;
/**
* Returns the maximum number of peers to range which can be specified in a single {@code
@@ -59,12 +65,80 @@ public final class RangingRequest implements Parcelable {
return MAX_PEERS;
}
+ /**
+ * Returns the default RTT burst size used to determine the average range.
+ *
+ * @return the RTT burst size used by default
+ */
+ public static int getDefaultRttBurstSize() {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ return DEFAULT_RTT_BURST_SIZE;
+ }
+
+ /**
+ * Returns the minimum RTT burst size that can be used to determine a average range.
+ *
+ * @return the minimum RTT burst size that can be used
+ */
+ public static int getMinRttBurstSize() {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ return MIN_RTT_BURST_SIZE;
+ }
+
+ /**
+ * Returns the minimum RTT burst size that can be used to determine a average range.
+ *
+ * @return the maximum RTT burst size that can be used
+ */
+ public static int getMaxRttBurstSize() {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ return MAX_RTT_BURST_SIZE;
+ }
+
/** @hide */
public final List<ResponderConfig> mRttPeers;
/** @hide */
- private RangingRequest(List<ResponderConfig> rttPeers) {
+ public final int mRttBurstSize;
+
+ /** @hide */
+ private RangingRequest(List<ResponderConfig> rttPeers, int rttBurstSize) {
mRttPeers = rttPeers;
+ mRttBurstSize = rttBurstSize;
+ }
+
+ /**
+ * Returns the list of RTT capable peers.
+ *
+ * @return the list of RTT capable peers in a common system representation
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public List<ResponderConfig> getRttPeers() {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ return mRttPeers;
+ }
+
+ /**
+ * Returns the RTT burst size used to determine the average range.
+ *
+ * @return the RTT burst size used
+ */
+ public int getRttBurstSize() {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ return mRttBurstSize;
}
@Override
@@ -75,6 +149,7 @@ public final class RangingRequest implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(mRttPeers);
+ dest.writeInt(mRttBurstSize);
}
public static final @android.annotation.NonNull Creator<RangingRequest> CREATOR = new Creator<RangingRequest>() {
@@ -85,7 +160,7 @@ public final class RangingRequest implements Parcelable {
@Override
public RangingRequest createFromParcel(Parcel in) {
- return new RangingRequest(in.readArrayList(null));
+ return new RangingRequest(in.readArrayList(null), in.readInt());
}
};
@@ -105,12 +180,20 @@ public final class RangingRequest implements Parcelable {
throw new IllegalArgumentException(
"Ranging to too many peers requested. Use getMaxPeers() API to get limit.");
}
-
for (ResponderConfig peer: mRttPeers) {
if (!peer.isValid(awareSupported)) {
throw new IllegalArgumentException("Invalid Responder specification");
}
}
+ if (SdkLevel.isAtLeastS()) {
+ if (mRttBurstSize < getMinRttBurstSize() || mRttBurstSize > getMaxRttBurstSize()) {
+ throw new IllegalArgumentException("RTT burst size is out of range");
+ }
+ } else {
+ if (mRttBurstSize != DEFAULT_RTT_BURST_SIZE) {
+ throw new IllegalArgumentException("RTT burst size is not the default value");
+ }
+ }
}
/**
@@ -118,6 +201,32 @@ public final class RangingRequest implements Parcelable {
*/
public static final class Builder {
private List<ResponderConfig> mRttPeers = new ArrayList<>();
+ private int mRttBurstSize = DEFAULT_RTT_BURST_SIZE;
+
+ /**
+ * Set the RTT Burst size for the ranging request.
+ * <p>
+ * If not set, the default RTT burst size given by
+ * {@link #getDefaultRttBurstSize()} is used to determine the default value.
+ * If set, the value must be in the range {@link #getMinRttBurstSize()} and
+ * {@link #getMaxRttBurstSize()} inclusively, or a
+ * {@link java.lang.IllegalArgumentException} will be thrown.
+ *
+ * @param rttBurstSize The number of FTM packets used to estimate a range.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ @NonNull
+ public Builder setRttBurstSize(int rttBurstSize) {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ if (rttBurstSize < MIN_RTT_BURST_SIZE || rttBurstSize > MAX_RTT_BURST_SIZE) {
+ throw new IllegalArgumentException("RTT burst size out of range.");
+ }
+ mRttBurstSize = rttBurstSize;
+ return this;
+ }
/**
* Add the device specified by the {@link ScanResult} to the list of devices with
@@ -241,7 +350,7 @@ public final class RangingRequest implements Parcelable {
* builder.
*/
public RangingRequest build() {
- return new RangingRequest(mRttPeers);
+ return new RangingRequest(mRttPeers, mRttBurstSize);
}
}
@@ -257,11 +366,13 @@ public final class RangingRequest implements Parcelable {
RangingRequest lhs = (RangingRequest) o;
- return mRttPeers.size() == lhs.mRttPeers.size() && mRttPeers.containsAll(lhs.mRttPeers);
+ return mRttPeers.size() == lhs.mRttPeers.size()
+ && mRttPeers.containsAll(lhs.mRttPeers)
+ && mRttBurstSize == lhs.mRttBurstSize;
}
@Override
public int hashCode() {
- return mRttPeers.hashCode();
+ return Objects.hash(mRttPeers, mRttBurstSize);
}
}
diff --git a/wifi/tests/src/android/net/wifi/SecurityParamsTest.java b/wifi/tests/src/android/net/wifi/SecurityParamsTest.java
index e581b77c14ad..2f6b7245795f 100644
--- a/wifi/tests/src/android/net/wifi/SecurityParamsTest.java
+++ b/wifi/tests/src/android/net/wifi/SecurityParamsTest.java
@@ -85,11 +85,28 @@ public class SecurityParamsTest {
expectedAllowedGroupCiphers, expectedRequirePmf);
}
- /** Verify EAP Passpoint params creator. */
+ /** Verify Passpoint R1 params creator. */
@Test
- public void testEapPasspointCreator() throws Exception {
- SecurityParams p = SecurityParams.createPasspointParams(false);
- int expectedSecurityType = WifiConfiguration.SECURITY_TYPE_EAP;
+ public void testEapPasspointR1Creator() throws Exception {
+ SecurityParams p = SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R1);
+ int expectedSecurityType = WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2;
+ int[] expectedAllowedKeyManagement = new int[] {KeyMgmt.WPA_EAP, KeyMgmt.IEEE8021X};
+ int[] expectedAllowedProtocols = new int[] {};
+ int[] expectedAllowedAuthAlgorithms = new int[] {};
+ int[] expectedAllowedPairwiseCiphers = new int[] {};
+ int[] expectedAllowedGroupCiphers = new int[] {};
+ boolean expectedRequirePmf = false;
+ verifySecurityParams(p, expectedSecurityType,
+ expectedAllowedKeyManagement, expectedAllowedProtocols,
+ expectedAllowedAuthAlgorithms, expectedAllowedPairwiseCiphers,
+ expectedAllowedGroupCiphers, expectedRequirePmf);
+ }
+
+ /** Verify Passpoint R2 params creator. */
+ @Test
+ public void testEapPasspointR2Creator() throws Exception {
+ SecurityParams p = SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R2);
+ int expectedSecurityType = WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2;
int[] expectedAllowedKeyManagement = new int[] {KeyMgmt.WPA_EAP, KeyMgmt.IEEE8021X};
int[] expectedAllowedProtocols = new int[] {};
int[] expectedAllowedAuthAlgorithms = new int[] {};
@@ -100,9 +117,19 @@ public class SecurityParamsTest {
expectedAllowedKeyManagement, expectedAllowedProtocols,
expectedAllowedAuthAlgorithms, expectedAllowedPairwiseCiphers,
expectedAllowedGroupCiphers, expectedRequirePmf);
+ }
- p = SecurityParams.createPasspointParams(true);
- expectedRequirePmf = true;
+ /** Verify Passpoint R3 params creator. */
+ @Test
+ public void testEapPasspointR3Creator() throws Exception {
+ SecurityParams p = SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R3);
+ int expectedSecurityType = WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3;
+ int[] expectedAllowedKeyManagement = new int[] {KeyMgmt.WPA_EAP, KeyMgmt.IEEE8021X};
+ int[] expectedAllowedProtocols = new int[] {};
+ int[] expectedAllowedAuthAlgorithms = new int[] {};
+ int[] expectedAllowedPairwiseCiphers = new int[] {};
+ int[] expectedAllowedGroupCiphers = new int[] {};
+ boolean expectedRequirePmf = true;
verifySecurityParams(p, expectedSecurityType,
expectedAllowedKeyManagement, expectedAllowedProtocols,
expectedAllowedAuthAlgorithms, expectedAllowedPairwiseCiphers,
@@ -408,7 +435,9 @@ public class SecurityParamsTest {
SecurityParams[] nonOpenSecurityParams = new SecurityParams[] {
SecurityParams.createWpaWpa2EnterpriseParams(),
- SecurityParams.createPasspointParams(false),
+ SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R1),
+ SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R2),
+ SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R3),
SecurityParams.createOsenParams(),
SecurityParams.createWapiCertParams(),
SecurityParams.createWapiPskParams(),
@@ -428,7 +457,9 @@ public class SecurityParamsTest {
public void testIsEnterpriseNetwork() {
SecurityParams[] enterpriseSecurityParams = new SecurityParams[] {
SecurityParams.createWpaWpa2EnterpriseParams(),
- SecurityParams.createPasspointParams(false),
+ SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R1),
+ SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R2),
+ SecurityParams.createPasspointParams(SecurityParams.PASSPOINT_R3),
SecurityParams.createWapiCertParams(),
SecurityParams.createWpa3Enterprise192BitParams(),
SecurityParams.createWpa3EnterpriseParams(),
diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java
index 702212b324f6..9e3b02266de1 100644
--- a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java
+++ b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java
@@ -42,10 +42,12 @@ public class SoftApCapabilityTest {
| SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD;
int[] testSupported2Glist = {1, 2, 3, 4};
int[] testSupported5Glist = {36, 149};
+ int[] testSupported60Glist = {1, 2};
SoftApCapability capability = new SoftApCapability(testSoftApFeature);
capability.setMaxSupportedClients(10);
capability.setSupportedChannelList(SoftApConfiguration.BAND_2GHZ, testSupported2Glist);
capability.setSupportedChannelList(SoftApConfiguration.BAND_5GHZ, testSupported5Glist);
+ capability.setSupportedChannelList(SoftApConfiguration.BAND_60GHZ, testSupported60Glist);
SoftApCapability copiedCapability = new SoftApCapability(capability);
@@ -64,9 +66,11 @@ public class SoftApCapabilityTest {
capability.setMaxSupportedClients(10);
int[] testSupported2Glist = {1, 2, 3, 4};
int[] testSupported5Glist = {36, 149};
+ int[] testSupported60Glist = {1, 2};
capability.setSupportedChannelList(SoftApConfiguration.BAND_2GHZ, testSupported2Glist);
capability.setSupportedChannelList(SoftApConfiguration.BAND_5GHZ, testSupported5Glist);
+ capability.setSupportedChannelList(SoftApConfiguration.BAND_60GHZ, testSupported60Glist);
Parcel parcelW = Parcel.obtain();
capability.writeToParcel(parcelW, 0);
diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
index bcfdf7d80061..a609a120b61f 100644
--- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
@@ -519,4 +519,14 @@ public class SoftApConfigurationTest {
}
assertTrue(isIllegalArgumentExceptionHappened);
}
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidConfigWhenSet60GhzChannels() throws Exception {
+ SparseIntArray invalid_channels = new SparseIntArray();
+ invalid_channels.put(SoftApConfiguration.BAND_60GHZ, 99);
+ SoftApConfiguration config = new SoftApConfiguration.Builder()
+ .setSsid("ssid")
+ .setChannels(invalid_channels)
+ .build();
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
index e6eae416ba78..c8006fead55b 100644
--- a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
@@ -16,6 +16,8 @@
package android.net.wifi.rtt;
+import static junit.framework.Assert.fail;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -143,6 +145,7 @@ public class WifiRttManagerTest {
PeerHandle peerHandle1 = new PeerHandle(12);
RangingRequest.Builder builder = new RangingRequest.Builder();
+ builder.setRttBurstSize(4);
builder.addAccessPoint(scanResult1);
builder.addAccessPoints(scanResults2and3);
builder.addWifiAwarePeer(mac1);
@@ -163,6 +166,60 @@ public class WifiRttManagerTest {
}
/**
+ * Validate the rtt burst size is set correctly when in range.
+ */
+ @Test
+ public void testRangingRequestSetBurstSize() {
+ ScanResult scanResult = new ScanResult();
+ scanResult.BSSID = "AA:BB:CC:DD:EE:FF";
+
+ // create request
+ RangingRequest.Builder builder = new RangingRequest.Builder();
+ builder.setRttBurstSize(4);
+ builder.addAccessPoint(scanResult);
+ RangingRequest request = builder.build();
+
+ // confirm rtt burst size is set correctly to default value
+ assertEquals(request.getRttBurstSize(), 4);
+ }
+
+ /**
+ * Validate the rtt burst size cannot be smaller than the minimum.
+ */
+ @Test
+ public void testRangingRequestMinBurstSizeIsEnforced() {
+ ScanResult scanResult = new ScanResult();
+ scanResult.BSSID = "AA:BB:CC:DD:EE:FF";
+
+ // create request
+ try {
+ RangingRequest.Builder builder = new RangingRequest.Builder();
+ builder.setRttBurstSize(RangingRequest.getMinRttBurstSize() - 1);
+ fail("RTT burst size was smaller than min value.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Validate the rtt burst size cannot exceed the maximum.
+ */
+ @Test
+ public void testRangingRequestMaxBurstSizeIsEnforced() {
+ ScanResult scanResult = new ScanResult();
+ scanResult.BSSID = "AA:BB:CC:DD:EE:FF";
+
+ // create request
+ try {
+ RangingRequest.Builder builder = new RangingRequest.Builder();
+ builder.setRttBurstSize(RangingRequest.getMaxRttBurstSize() + 1);
+ fail("RTT Burst size exceeded max value.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ /**
* Validate that can request as many range operation as the upper limit on number of requests.
*/
@Test
@@ -175,7 +232,7 @@ public class WifiRttManagerTest {
}
MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
- // create request
+ // create request using max RTT Peers
RangingRequest.Builder builder = new RangingRequest.Builder();
builder.addAccessPoint(scanResult);
builder.addAccessPoints(scanResultList);
@@ -185,6 +242,18 @@ public class WifiRttManagerTest {
// verify request
request.enforceValidity(true);
+ // confirm rtt burst size is set correctly to default value
+ assertEquals(request.getRttBurstSize(), RangingRequest.getDefaultRttBurstSize());
+ // confirm the number of peers in the request is the max number of peers
+ List<ResponderConfig> rttPeers = request.getRttPeers();
+ int numRttPeers = rttPeers.size();
+ assertEquals(RangingRequest.getMaxPeers(), numRttPeers);
+ // confirm each peer has the correct mac address
+ for (int i = 0; i < numRttPeers - 1; ++i) {
+ assertEquals("AA:BB:CC:DD:EE:FF", rttPeers.get(i).macAddress.toString().toUpperCase());
+ }
+ assertEquals("00:01:02:03:04:05",
+ rttPeers.get(numRttPeers - 1).macAddress.toString().toUpperCase());
}
/**