diff options
309 files changed, 7468 insertions, 3015 deletions
diff --git a/Android.bp b/Android.bp index 5af77562de85..4121b8a7f9e1 100644 --- a/Android.bp +++ b/Android.bp @@ -598,6 +598,12 @@ java_library { "//frameworks/base/apex/jobscheduler/framework", "//frameworks/base/packages/Tethering/tests/unit", ], + errorprone: { + javacflags: [ + "-Xep:AndroidFrameworkCompatChange:ERROR", + "-Xep:AndroidFrameworkUid:ERROR", + ], + }, } // This "framework" module is NOT installed to the device. It's diff --git a/StubLibraries.bp b/StubLibraries.bp index a3a209458679..53053ce87bbe 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -58,7 +58,24 @@ stubs_defaults { "media/aidl", ], }, - libs: ["framework-internal-utils"], + // These are libs from framework-internal-utils that are required (i.e. being referenced) + // from framework-non-updatable-sources. Add more here when there's a need. + // DO NOT add the entire framework-internal-utils. It might cause unnecessary circular + // dependencies gets bigger. + libs: [ + "android.hardware.cas-V1.2-java", + "android.hardware.health-V1.0-java-constants", + "android.hardware.radio-V1.5-java", + "android.hardware.thermal-V1.0-java-constants", + "android.hardware.thermal-V2.0-java", + "android.hardware.tv.input-V1.0-java-constants", + "android.hardware.tv.tuner-V1.0-java-constants", + "android.hardware.usb-V1.0-java-constants", + "android.hardware.usb-V1.1-java-constants", + "android.hardware.usb.gadget-V1.0-java", + "android.hardware.vibrator-V1.3-java", + "framework-protos", + ], installable: false, annotations_enabled: true, previous_api: ":android.api.public.latest", @@ -143,6 +160,11 @@ droidstubs { api_file: "non-updatable-api/current.txt", removed_api_file: "non-updatable-api/removed.txt", }, + last_released: { + api_file: ":android-non-updatable.api.public.latest", + removed_api_file: ":android-non-updatable-removed.api.public.latest", + baseline_file: ":public-api-incompatibilities-with-last-released", + }, api_lint: { enabled: true, new_since: ":android-non-updatable.api.public.latest", @@ -205,6 +227,11 @@ droidstubs { api_file: "non-updatable-api/system-current.txt", removed_api_file: "non-updatable-api/system-removed.txt", }, + last_released: { + api_file: ":android-non-updatable.api.system.latest", + removed_api_file: ":android-non-updatable-removed.api.system.latest", + baseline_file: ":system-api-incompatibilities-with-last-released" + }, api_lint: { enabled: true, new_since: ":android-non-updatable.api.system.latest", diff --git a/apct-tests/perftests/core/src/android/text/CanvasDrawTextTest.java b/apct-tests/perftests/core/src/android/text/CanvasDrawTextTest.java index bb6b691226d6..66b2b0ecb21d 100644 --- a/apct-tests/perftests/core/src/android/text/CanvasDrawTextTest.java +++ b/apct-tests/perftests/core/src/android/text/CanvasDrawTextTest.java @@ -53,19 +53,19 @@ public class CanvasDrawTextTest { final String text = mTextUtil.nextRandomParagraph( WORD_LENGTH, 4 * 1024 * 1024 /* 4mb text */).toString(); final RenderNode node = RenderNode.create("benchmark", null); - final RenderNode child = RenderNode.create("child", null); - child.setLeftTopRightBottom(50, 50, 100, 100); - - RecordingCanvas canvas = node.start(100, 100); - node.end(canvas); - canvas = child.start(50, 50); - child.end(canvas); final Random r = new Random(0); - while (state.keepRunning()) { + state.pauseTiming(); + RecordingCanvas canvas = node.beginRecording(); int start = r.nextInt(text.length() - 100); + state.resumeTiming(); + canvas.drawText(text, start, start + 100, 0, 0, PAINT); + + state.pauseTiming(); + node.endRecording(); + state.resumeTiming(); } } } diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java index efcabd817109..833cc0ff37a0 100644 --- a/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java +++ b/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java @@ -226,7 +226,7 @@ public class RecentsAnimationPerfTest extends WindowManagerPerfTestBase mMeasuredTimeNs = 0; final long startTime = SystemClock.elapsedRealtimeNanos(); - atm.startRecentsActivity(sRecentsIntent, null /* unused */, anim); + atm.startRecentsActivity(sRecentsIntent, 0 /* eventTime */, anim); final long elapsedTimeNsOfStart = SystemClock.elapsedRealtimeNanos() - startTime; mMeasuredTimeNs += elapsedTimeNsOfStart; state.addExtraResult("start", elapsedTimeNsOfStart); diff --git a/apex/media/framework/api/module-lib-current.txt b/apex/media/framework/api/module-lib-current.txt index d2826d01664c..2b69863675a5 100644 --- a/apex/media/framework/api/module-lib-current.txt +++ b/apex/media/framework/api/module-lib-current.txt @@ -1,14 +1,14 @@ // Signature format: 2.0 package android.media { - public final class MediaParceledListSlice<T extends android.os.Parcelable> implements android.os.Parcelable { - ctor public MediaParceledListSlice(@NonNull java.util.List<T>); - method public int describeContents(); - method @NonNull public static <T extends android.os.Parcelable> android.media.MediaParceledListSlice<T> emptyList(); - method public java.util.List<T> getList(); - method public void setInlineCountLimit(int); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.ClassLoaderCreator<android.media.MediaParceledListSlice> CREATOR; + @Deprecated public final class MediaParceledListSlice<T extends android.os.Parcelable> implements android.os.Parcelable { + ctor @Deprecated public MediaParceledListSlice(@NonNull java.util.List<T>); + method @Deprecated public int describeContents(); + method @Deprecated @NonNull public static <T extends android.os.Parcelable> android.media.MediaParceledListSlice<T> emptyList(); + method @Deprecated public java.util.List<T> getList(); + method @Deprecated public void setInlineCountLimit(int); + method @Deprecated public void writeToParcel(android.os.Parcel, int); + field @Deprecated @NonNull public static final android.os.Parcelable.ClassLoaderCreator<android.media.MediaParceledListSlice> CREATOR; } } diff --git a/apex/media/framework/java/android/media/MediaParceledListSlice.java b/apex/media/framework/java/android/media/MediaParceledListSlice.java index e1223f6a6bed..47ac193231a0 100644 --- a/apex/media/framework/java/android/media/MediaParceledListSlice.java +++ b/apex/media/framework/java/android/media/MediaParceledListSlice.java @@ -17,7 +17,6 @@ package android.media; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -32,13 +31,16 @@ import java.util.List; * Transfer a large list of Parcelable objects across an IPC. Splits into * multiple transactions if needed. * - * @see BaseMediaParceledListSlice - * * TODO: Remove this from @SystemApi once all the MediaSession related classes are moved * to apex (or ParceledListSlice moved to apex). This class is temporaily added to system API * for moving classes step by step. + * + * @param <T> The type of the elements in the list. + * @see BaseMediaParceledListSlice + * @deprecated This is temporary marked as @SystemApi. Should be removed from the API surface. * @hide */ +@Deprecated @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public final class MediaParceledListSlice<T extends Parcelable> extends BaseMediaParceledListSlice<T> { diff --git a/api/Android.bp b/api/Android.bp index 490c980cb7cb..e403082b1fb2 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -64,6 +64,24 @@ genrule { } genrule { + name: "frameworks-base-api-removed-merged.txt", + srcs: [ + ":conscrypt.module.public.api{.public.removed-api.txt}", + ":framework-media{.public.removed-api.txt}", + ":framework-mediaprovider{.public.removed-api.txt}", + ":framework-permission{.public.removed-api.txt}", + ":framework-sdkextensions{.public.removed-api.txt}", + ":framework-statsd{.public.removed-api.txt}", + ":framework-tethering{.public.removed-api.txt}", + ":framework-wifi{.public.removed-api.txt}", + ":non-updatable-removed.txt", + ], + out: ["removed.txt"], + tools: ["metalava"], + cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", +} + +genrule { name: "frameworks-base-api-system-current-merged.txt", srcs: [ ":framework-graphics{.system.api.txt}", @@ -82,6 +100,23 @@ genrule { } genrule { + name: "frameworks-base-api-system-removed-merged.txt", + srcs: [ + ":framework-media{.system.removed-api.txt}", + ":framework-mediaprovider{.system.removed-api.txt}", + ":framework-permission{.system.removed-api.txt}", + ":framework-sdkextensions{.system.removed-api.txt}", + ":framework-statsd{.system.removed-api.txt}", + ":framework-tethering{.system.removed-api.txt}", + ":framework-wifi{.system.removed-api.txt}", + ":non-updatable-system-removed.txt", + ], + out: ["system-removed.txt"], + tools: ["metalava"], + cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", +} + +genrule { name: "frameworks-base-api-module-lib-current-merged.txt", srcs: [ ":framework-graphics{.module-lib.api.txt}", @@ -98,3 +133,20 @@ genrule { tools: ["metalava"], cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", } + +genrule { + name: "frameworks-base-api-module-lib-removed-merged.txt", + srcs: [ + ":framework-media{.module-lib.removed-api.txt}", + ":framework-mediaprovider{.module-lib.removed-api.txt}", + ":framework-permission{.module-lib.removed-api.txt}", + ":framework-sdkextensions{.module-lib.removed-api.txt}", + ":framework-statsd{.module-lib.removed-api.txt}", + ":framework-tethering{.module-lib.removed-api.txt}", + ":framework-wifi{.module-lib.removed-api.txt}", + ":non-updatable-module-lib-removed.txt", + ], + out: ["module-lib-removed.txt"], + tools: ["metalava"], + cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", +} diff --git a/api/current.txt b/api/current.txt index ecdbcd2e56b5..94e90a75f644 100644 --- a/api/current.txt +++ b/api/current.txt @@ -36675,7 +36675,7 @@ package android.os { method public int dataCapacity(); method public int dataPosition(); method public int dataSize(); - method public void enforceInterface(String); + method public void enforceInterface(@NonNull String); method public boolean hasFileDescriptors(); method public byte[] marshall(); method @NonNull public static android.os.Parcel obtain(); @@ -36746,7 +36746,7 @@ package android.os { method public void writeFloatArray(@Nullable float[]); method public void writeInt(int); method public void writeIntArray(@Nullable int[]); - method public void writeInterfaceToken(String); + method public void writeInterfaceToken(@NonNull String); method public void writeList(@Nullable java.util.List); method public void writeLong(long); method public void writeLongArray(@Nullable long[]); diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index 3801e1d34b06..19f348c84062 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -53,14 +53,14 @@ package android.media { field public static final int FLAG_FROM_KEY = 4096; // 0x1000 } - public final class MediaParceledListSlice<T extends android.os.Parcelable> implements android.os.Parcelable { - ctor public MediaParceledListSlice(@NonNull java.util.List<T>); - method public int describeContents(); - method @NonNull public static <T extends android.os.Parcelable> android.media.MediaParceledListSlice<T> emptyList(); - method public java.util.List<T> getList(); - method public void setInlineCountLimit(int); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.ClassLoaderCreator<android.media.MediaParceledListSlice> CREATOR; + @Deprecated public final class MediaParceledListSlice<T extends android.os.Parcelable> implements android.os.Parcelable { + ctor @Deprecated public MediaParceledListSlice(@NonNull java.util.List<T>); + method @Deprecated public int describeContents(); + method @Deprecated @NonNull public static <T extends android.os.Parcelable> android.media.MediaParceledListSlice<T> emptyList(); + method @Deprecated public java.util.List<T> getList(); + method @Deprecated public void setInlineCountLimit(int); + method @Deprecated public void writeToParcel(android.os.Parcel, int); + field @Deprecated @NonNull public static final android.os.Parcelable.ClassLoaderCreator<android.media.MediaParceledListSlice> CREATOR; } } diff --git a/api/system-current.txt b/api/system-current.txt index e077ae40fc4e..f2ec2970f9ce 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -95,6 +95,7 @@ package android { field public static final String INJECT_EVENTS = "android.permission.INJECT_EVENTS"; field public static final String INSTALL_DYNAMIC_SYSTEM = "android.permission.INSTALL_DYNAMIC_SYSTEM"; field public static final String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"; + field public static final String INSTALL_LOCATION_TIME_ZONE_PROVIDER = "android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER"; field public static final String INSTALL_PACKAGE_UPDATES = "android.permission.INSTALL_PACKAGE_UPDATES"; field public static final String INSTALL_SELF_UPDATES = "android.permission.INSTALL_SELF_UPDATES"; field public static final String INTENT_FILTER_VERIFICATION_AGENT = "android.permission.INTENT_FILTER_VERIFICATION_AGENT"; @@ -125,6 +126,7 @@ package android { field public static final String MANAGE_SENSOR_PRIVACY = "android.permission.MANAGE_SENSOR_PRIVACY"; field public static final String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER"; field public static final String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS"; + field public static final String MANAGE_TIME_AND_ZONE_DETECTION = "android.permission.MANAGE_TIME_AND_ZONE_DETECTION"; field public static final String MANAGE_USB = "android.permission.MANAGE_USB"; field public static final String MANAGE_USERS = "android.permission.MANAGE_USERS"; field public static final String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE"; @@ -305,6 +307,7 @@ package android { field public static final int config_helpPackageNameValue = 17039388; // 0x104001c field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028 field public static final int config_systemGallery = 17039399; // 0x1040027 + field public static final int config_systemVideoCall = 17039401; // 0x1040029 } public static final class R.style { @@ -1389,6 +1392,57 @@ package android.app.role { } +package android.app.time { + + public final class TimeManager { + method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public void addTimeZoneDetectorListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.time.TimeManager.TimeZoneDetectorListener); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public android.app.time.TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig(); + method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public void removeTimeZoneDetectorListener(@NonNull android.app.time.TimeManager.TimeZoneDetectorListener); + method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public boolean updateTimeZoneConfiguration(@NonNull android.app.time.TimeZoneConfiguration); + } + + @java.lang.FunctionalInterface public static interface TimeManager.TimeZoneDetectorListener { + method public void onChange(); + } + + public final class TimeZoneCapabilities implements android.os.Parcelable { + method public int describeContents(); + method public int getConfigureAutoDetectionEnabledCapability(); + method public int getConfigureGeoDetectionEnabledCapability(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int CAPABILITY_NOT_ALLOWED = 20; // 0x14 + field public static final int CAPABILITY_NOT_APPLICABLE = 30; // 0x1e + field public static final int CAPABILITY_NOT_SUPPORTED = 10; // 0xa + field public static final int CAPABILITY_POSSESSED = 40; // 0x28 + field @NonNull public static final android.os.Parcelable.Creator<android.app.time.TimeZoneCapabilities> CREATOR; + } + + public final class TimeZoneCapabilitiesAndConfig implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.app.time.TimeZoneCapabilities getCapabilities(); + method @NonNull public android.app.time.TimeZoneConfiguration getConfiguration(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.app.time.TimeZoneCapabilitiesAndConfig> CREATOR; + } + + public final class TimeZoneConfiguration implements android.os.Parcelable { + method public int describeContents(); + method public boolean isAutoDetectionEnabled(); + method public boolean isGeoDetectionEnabled(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.app.time.TimeZoneConfiguration> CREATOR; + } + + public static final class TimeZoneConfiguration.Builder { + ctor public TimeZoneConfiguration.Builder(); + ctor public TimeZoneConfiguration.Builder(@NonNull android.app.time.TimeZoneConfiguration); + method @NonNull public android.app.time.TimeZoneConfiguration build(); + method @NonNull public android.app.time.TimeZoneConfiguration.Builder setAutoDetectionEnabled(boolean); + method @NonNull public android.app.time.TimeZoneConfiguration.Builder setGeoDetectionEnabled(boolean); + } + +} + package android.app.usage { public final class CacheQuotaHint implements android.os.Parcelable { diff --git a/api/test-current.txt b/api/test-current.txt index 68d28233ade0..576cbacb1290 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -45,6 +45,7 @@ package android { field public static final int config_defaultDialer = 17039395; // 0x1040023 field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028 field public static final int config_systemGallery = 17039399; // 0x1040027 + field public static final int config_systemVideoCall = 17039401; // 0x1040029 } } diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 42b560d87dd0..bda9e24d31fb 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -3777,6 +3777,7 @@ message AppStartOccurred { LAUNCHER = 1; NOTIFICATION = 2; LOCKSCREEN = 3; + RECENTS_ANIMATION = 4; } // The type of the startup source. optional SourceType source_type = 16; diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index a61159a23c2c..85cb120ecb69 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -1910,6 +1910,8 @@ public class ActivityOptions { public static final int TYPE_NOTIFICATION = 2; /** Launched from lockscreen, including notification while the device is locked. */ public static final int TYPE_LOCKSCREEN = 3; + /** Launched from recents gesture handler. */ + public static final int TYPE_RECENTS_ANIMATION = 4; @IntDef(flag = true, prefix = { "TYPE_" }, value = { TYPE_LAUNCHER, diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 1a4db4e541cc..19951288c01f 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -25,7 +25,6 @@ import android.app.GrantedUriPermission; import android.app.IApplicationThread; import android.app.IActivityController; import android.app.IAppTask; -import android.app.IAssistDataReceiver; import android.app.IInstrumentationWatcher; import android.app.IProcessObserver; import android.app.IServiceConnection; @@ -70,7 +69,6 @@ import android.os.RemoteCallback; import android.os.StrictMode; import android.os.WorkSource; import android.service.voice.IVoiceInteractionSession; -import android.view.IRecentsAnimationRunner; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationAdapter; import com.android.internal.app.IVoiceInteractor; @@ -470,11 +468,6 @@ interface IActivityManager { @UnsupportedAppUsage boolean isInLockTaskMode(); @UnsupportedAppUsage - void startRecentsActivity(in Intent intent, in IAssistDataReceiver assistDataReceiver, - in IRecentsAnimationRunner recentsAnimationRunner); - @UnsupportedAppUsage - void cancelRecentsAnimation(boolean restoreHomeStackPosition); - @UnsupportedAppUsage int startActivityFromRecents(int taskId, in Bundle options); @UnsupportedAppUsage void startSystemLockTaskMode(int taskId); diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index e21ef8ee23ad..ddf2dc50b9c3 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -123,7 +123,7 @@ interface IActivityTaskManager { in ProfilerInfo profilerInfo, in Bundle options, int userId); int startAssistantActivity(in String callingPackage, in String callingFeatureId, int callingPid, int callingUid, in Intent intent, in String resolvedType, in Bundle options, int userId); - void startRecentsActivity(in Intent intent, in IAssistDataReceiver assistDataReceiver, + void startRecentsActivity(in Intent intent, in long eventTime, in IRecentsAnimationRunner recentsAnimationRunner); int startActivityFromRecents(int taskId, in Bundle options); int startActivityAsCaller(in IApplicationThread caller, in String callingPackage, diff --git a/core/java/android/app/time/TimeManager.java b/core/java/android/app/time/TimeManager.java index 9864afba534a..4796d8db3e96 100644 --- a/core/java/android/app/time/TimeManager.java +++ b/core/java/android/app/time/TimeManager.java @@ -18,6 +18,7 @@ package android.app.time; import android.annotation.NonNull; import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.timezonedetector.ITimeZoneDetectorService; import android.content.Context; @@ -36,7 +37,7 @@ import java.util.concurrent.Executor; * * @hide */ -// @SystemApi +@SystemApi @SystemService(Context.TIME_MANAGER) public final class TimeManager { private static final String TAG = "time.TimeManager"; diff --git a/core/java/android/app/time/TimeZoneCapabilities.java b/core/java/android/app/time/TimeZoneCapabilities.java index c62c2b34f35d..df89c285d5bd 100644 --- a/core/java/android/app/time/TimeZoneCapabilities.java +++ b/core/java/android/app/time/TimeZoneCapabilities.java @@ -19,6 +19,7 @@ package android.app.time; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.app.timezonedetector.ManualTimeZoneSuggestion; import android.app.timezonedetector.TimeZoneDetector; import android.os.Parcel; @@ -50,7 +51,7 @@ import java.util.Objects; * * @hide */ -// @SystemApi +@SystemApi public final class TimeZoneCapabilities implements Parcelable { /** @hide */ diff --git a/core/java/android/app/time/TimeZoneCapabilitiesAndConfig.java b/core/java/android/app/time/TimeZoneCapabilitiesAndConfig.java index 6a04f3f277ed..b339e53b8be3 100644 --- a/core/java/android/app/time/TimeZoneCapabilitiesAndConfig.java +++ b/core/java/android/app/time/TimeZoneCapabilitiesAndConfig.java @@ -17,6 +17,7 @@ package android.app.time; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -27,7 +28,7 @@ import java.util.Objects; * * @hide */ -// @SystemApi +@SystemApi public final class TimeZoneCapabilitiesAndConfig implements Parcelable { public static final @NonNull Creator<TimeZoneCapabilitiesAndConfig> CREATOR = diff --git a/core/java/android/app/time/TimeZoneConfiguration.java b/core/java/android/app/time/TimeZoneConfiguration.java index 488818a528ef..c0a0c21b546d 100644 --- a/core/java/android/app/time/TimeZoneConfiguration.java +++ b/core/java/android/app/time/TimeZoneConfiguration.java @@ -18,6 +18,7 @@ package android.app.time; import android.annotation.NonNull; import android.annotation.StringDef; +import android.annotation.SystemApi; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -41,7 +42,7 @@ import java.util.Objects; * * @hide */ -// @SystemApi +@SystemApi public final class TimeZoneConfiguration implements Parcelable { public static final @NonNull Creator<TimeZoneConfiguration> CREATOR = @@ -188,7 +189,7 @@ public final class TimeZoneConfiguration implements Parcelable { * * @hide */ - // @SystemApi + @SystemApi public static final class Builder { private final Bundle mBundle = new Bundle(); diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 6a6879626c9c..573892bcf014 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -2563,7 +2563,7 @@ public final class BluetoothAdapter { * Create a listening, insecure RFCOMM Bluetooth socket with Service Record. * <p>The link key is not required to be authenticated, i.e the communication may be * vulnerable to Person In the Middle attacks. For Bluetooth 2.1 devices, - * the link will be encrypted, as encryption is mandartory. + * the link will be encrypted, as encryption is mandatory. * For legacy devices (pre Bluetooth 2.1 devices) the link will not * be encrypted. Use {@link #listenUsingRfcommWithServiceRecord}, if an * encrypted and authenticated communication channel is desired. @@ -2602,7 +2602,7 @@ public final class BluetoothAdapter { * an input and output capability or just has the ability to display a numeric key, * a secure socket connection is not possible and this socket can be used. * Use {@link #listenUsingInsecureRfcommWithServiceRecord}, if encryption is not required. - * For Bluetooth 2.1 devices, the link will be encrypted, as encryption is mandartory. + * For Bluetooth 2.1 devices, the link will be encrypted, as encryption is mandatory. * For more details, refer to the Security Model section 5.2 (vol 3) of * Bluetooth Core Specification version 2.1 + EDR. * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 35c7b968c892..9a9f165030b0 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2732,6 +2732,54 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_MY_PACKAGE_UNSUSPENDED = "android.intent.action.MY_PACKAGE_UNSUSPENDED"; /** + * Broadcast Action: Sent to indicate that the package becomes startable. + * The intent will have the following extra values: + * <ul> + * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package. </li> + * <li> {@link #EXTRA_PACKAGE_NAME} containing the package name. </li> + * </li> + * </ul> + * + * <p class="note">This is a protected intent that can only be sent by the system. + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PACKAGE_STARTABLE = "android.intent.action.PACKAGE_STARTABLE"; + + /** + * Broadcast Action: Sent to indicate that the package becomes unstartable. + * The intent will have the following extra values: + * <ul> + * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package. </li> + * <li> {@link #EXTRA_PACKAGE_NAME} containing the package name. </li> + * <li> {@link #EXTRA_REASON} containing the integer indicating the reason for the state change, + * @see PackageManager.UnstartableReason + * </li> + * </ul> + * + * <p class="note">This is a protected intent that can only be sent by the system. + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PACKAGE_UNSTARTABLE = + "android.intent.action.PACKAGE_UNSTARTABLE"; + + /** + * Broadcast Action: Sent to indicate that the package is fully loaded. + * <ul> + * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package. </li> + * <li> {@link #EXTRA_PACKAGE_NAME} containing the package name. </li> + * </li> + * </ul> + * + * <p class="note">This is a protected intent that can only be sent by the system. + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PACKAGE_FULLY_LOADED = + "android.intent.action.PACKAGE_FULLY_LOADED"; + + /** * Broadcast Action: A user ID has been removed from the system. The user * ID number is stored in the extra data under {@link #EXTRA_UID}. * diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index c2beab507da0..ea4b76257ab7 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -1109,6 +1109,34 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { } /** + * Returns the reversed orientation. + * @hide + */ + @ActivityInfo.ScreenOrientation + public static int reverseOrientation(@ActivityInfo.ScreenOrientation int orientation) { + switch (orientation) { + case SCREEN_ORIENTATION_LANDSCAPE: + return SCREEN_ORIENTATION_PORTRAIT; + case SCREEN_ORIENTATION_PORTRAIT: + return SCREEN_ORIENTATION_LANDSCAPE; + case SCREEN_ORIENTATION_SENSOR_LANDSCAPE: + return SCREEN_ORIENTATION_SENSOR_PORTRAIT; + case SCREEN_ORIENTATION_SENSOR_PORTRAIT: + return SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + case SCREEN_ORIENTATION_REVERSE_LANDSCAPE: + return SCREEN_ORIENTATION_REVERSE_PORTRAIT; + case SCREEN_ORIENTATION_REVERSE_PORTRAIT: + return SCREEN_ORIENTATION_REVERSE_LANDSCAPE; + case SCREEN_ORIENTATION_USER_LANDSCAPE: + return SCREEN_ORIENTATION_USER_PORTRAIT; + case SCREEN_ORIENTATION_USER_PORTRAIT: + return SCREEN_ORIENTATION_USER_LANDSCAPE; + default: + return orientation; + } + } + + /** * Returns true if the activity supports picture-in-picture. * @hide */ diff --git a/core/java/android/content/pm/IDataLoaderStatusListener.aidl b/core/java/android/content/pm/IDataLoaderStatusListener.aidl index efb00a016da5..745c39b460fa 100644 --- a/core/java/android/content/pm/IDataLoaderStatusListener.aidl +++ b/core/java/android/content/pm/IDataLoaderStatusListener.aidl @@ -50,7 +50,30 @@ oneway interface IDataLoaderStatusListener { * fail and all retry limits are exceeded. */ const int DATA_LOADER_UNRECOVERABLE = 8; + /** There are no known issues with the data stream. */ + const int STREAM_HEALTHY = 0; + + /** There are issues with the current transport layer (network, adb connection, etc.) that may + * recover automatically or could eventually require user intervention. */ + const int STREAM_TRANSPORT_ERROR = 1; + + /** Integrity failures in the data stream, this could be due to file corruption, decompression + * issues or similar. This indicates a likely unrecoverable error. */ + const int STREAM_INTEGRITY_ERROR = 2; + + /** There are issues with the source of the data, e.g., backend availability issues, account + * issues. This indicates a potentially recoverable error, but one that may take a long time to + * resolve. */ + const int STREAM_SOURCE_ERROR = 3; + + /** The device or app is low on storage and cannot complete the stream as a result. + * A subsequent page miss resulting in app failure will transition app to unstartable state. */ + const int STREAM_STORAGE_ERROR = 4; + /** Data loader status callback */ void onStatusChanged(in int dataLoaderId, in int status); + + /** Callback to report streaming health status of a specific data loader */ + void reportStreamHealth(in int dataLoaderId, in int streamStatus); } diff --git a/core/java/android/content/pm/IncrementalStatesInfo.aidl b/core/java/android/content/pm/IncrementalStatesInfo.aidl new file mode 100644 index 000000000000..7064fbfa8b6a --- /dev/null +++ b/core/java/android/content/pm/IncrementalStatesInfo.aidl @@ -0,0 +1,20 @@ +/* +** +** 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. +*/ + +package android.content.pm; + +parcelable IncrementalStatesInfo; diff --git a/core/java/android/content/pm/IncrementalStatesInfo.java b/core/java/android/content/pm/IncrementalStatesInfo.java new file mode 100644 index 000000000000..6e91c19affc2 --- /dev/null +++ b/core/java/android/content/pm/IncrementalStatesInfo.java @@ -0,0 +1,76 @@ +/* + * 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.content.pm; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Info about a package's states in Parcelable format. + * @hide + */ +public class IncrementalStatesInfo implements Parcelable { + private boolean mIsStartable; + private boolean mIsLoading; + private float mProgress; + + public IncrementalStatesInfo(boolean isStartable, boolean isLoading, float progress) { + mIsStartable = isStartable; + mIsLoading = isLoading; + mProgress = progress; + } + + private IncrementalStatesInfo(Parcel source) { + mIsStartable = source.readBoolean(); + mIsLoading = source.readBoolean(); + mProgress = source.readFloat(); + } + + public boolean isStartable() { + return mIsStartable; + } + + public boolean isLoading() { + return mIsLoading; + } + + public float getProgress() { + return mProgress; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeBoolean(mIsStartable); + dest.writeBoolean(mIsLoading); + dest.writeFloat(mProgress); + } + + public static final @android.annotation.NonNull Creator<IncrementalStatesInfo> CREATOR = + new Creator<IncrementalStatesInfo>() { + public IncrementalStatesInfo createFromParcel(Parcel source) { + return new IncrementalStatesInfo(source); + } + public IncrementalStatesInfo[] newArray(int size) { + return new IncrementalStatesInfo[size]; + } + }; +} diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index a600d6c8a236..c293e4ad6821 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -3786,6 +3786,39 @@ public abstract class PackageManager { */ public static final int SYSTEM_APP_STATE_UNINSTALLED = 3; + /** + * Reasons for why a package is unstartable. + * @hide + */ + @IntDef({UNSTARTABLE_REASON_UNKNOWN, + UNSTARTABLE_REASON_DATALOADER_TRANSPORT, + UNSTARTABLE_REASON_DATALOADER_STORAGE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface UnstartableReason {} + + /** + * Unstartable state with no root cause specified. E.g., data loader seeing missing pages but + * unclear about the cause. This corresponds to a generic alert window shown to the user when + * the user attempts to launch the app. + * @hide + */ + public static final int UNSTARTABLE_REASON_UNKNOWN = 0; + + /** + * Unstartable state after hint from dataloader of issues with the transport layer. + * This corresponds to an alert window shown to the user indicating network errors. + * @hide + */ + public static final int UNSTARTABLE_REASON_DATALOADER_TRANSPORT = 1; + + /** + * Unstartable state after encountering storage limitations. + * This corresponds to an alert window indicating limited storage. + * @hide + */ + public static final int UNSTARTABLE_REASON_DATALOADER_STORAGE = 2; + /** {@hide} */ public int getUserId() { return UserHandle.myUserId(); diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java index 327d1b8beeb1..3ed21b087972 100644 --- a/core/java/android/content/pm/PackageUserState.java +++ b/core/java/android/content/pm/PackageUserState.java @@ -44,7 +44,6 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.CollectionUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index cad103e9f082..651494d1c99c 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -21,14 +21,13 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.LinkPropertiesUtils; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; -import com.android.net.module.util.LinkPropertiesUtils; -import com.android.net.module.util.LinkPropertiesUtils.CompareResult; - import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java index 51c5a50dcafb..0eb3c1e8ad01 100644 --- a/core/java/android/net/MacAddress.java +++ b/core/java/android/net/MacAddress.java @@ -20,12 +20,12 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.MacAddressUtils; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.util.Preconditions; -import com.android.net.module.util.MacAddressUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index a8b45e9d128b..98760761736d 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -22,12 +22,11 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.NetUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; -import com.android.net.module.util.NetUtils; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.Inet4Address; diff --git a/core/java/android/os/FileBridge.java b/core/java/android/os/FileBridge.java index 21fd819f3d94..ab5637cbb878 100644 --- a/core/java/android/os/FileBridge.java +++ b/core/java/android/os/FileBridge.java @@ -16,7 +16,6 @@ package android.os; -import static android.system.OsConstants.AF_UNIX; import static android.system.OsConstants.SOCK_STREAM; import android.system.ErrnoException; @@ -58,17 +57,19 @@ public class FileBridge extends Thread { /** CMD_CLOSE */ private static final int CMD_CLOSE = 3; - private FileDescriptor mTarget; + private ParcelFileDescriptor mTarget; - private final FileDescriptor mServer = new FileDescriptor(); - private final FileDescriptor mClient = new FileDescriptor(); + private ParcelFileDescriptor mServer; + private ParcelFileDescriptor mClient; private volatile boolean mClosed; public FileBridge() { try { - Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mServer, mClient); - } catch (ErrnoException e) { + ParcelFileDescriptor[] fds = ParcelFileDescriptor.createSocketPair(SOCK_STREAM); + mServer = fds[0]; + mClient = fds[1]; + } catch (IOException e) { throw new RuntimeException("Failed to create bridge"); } } @@ -80,15 +81,14 @@ public class FileBridge extends Thread { public void forceClose() { IoUtils.closeQuietly(mTarget); IoUtils.closeQuietly(mServer); - IoUtils.closeQuietly(mClient); mClosed = true; } - public void setTargetFile(FileDescriptor target) { + public void setTargetFile(ParcelFileDescriptor target) { mTarget = target; } - public FileDescriptor getClientSocket() { + public ParcelFileDescriptor getClientSocket() { return mClient; } @@ -96,32 +96,33 @@ public class FileBridge extends Thread { public void run() { final byte[] temp = new byte[8192]; try { - while (IoBridge.read(mServer, temp, 0, MSG_LENGTH) == MSG_LENGTH) { + while (IoBridge.read(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH) == MSG_LENGTH) { final int cmd = Memory.peekInt(temp, 0, ByteOrder.BIG_ENDIAN); if (cmd == CMD_WRITE) { // Shuttle data into local file int len = Memory.peekInt(temp, 4, ByteOrder.BIG_ENDIAN); while (len > 0) { - int n = IoBridge.read(mServer, temp, 0, Math.min(temp.length, len)); + int n = IoBridge.read(mServer.getFileDescriptor(), temp, 0, + Math.min(temp.length, len)); if (n == -1) { throw new IOException( "Unexpected EOF; still expected " + len + " bytes"); } - IoBridge.write(mTarget, temp, 0, n); + IoBridge.write(mTarget.getFileDescriptor(), temp, 0, n); len -= n; } } else if (cmd == CMD_FSYNC) { // Sync and echo back to confirm - Os.fsync(mTarget); - IoBridge.write(mServer, temp, 0, MSG_LENGTH); + Os.fsync(mTarget.getFileDescriptor()); + IoBridge.write(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH); } else if (cmd == CMD_CLOSE) { // Close and echo back to confirm - Os.fsync(mTarget); - Os.close(mTarget); + Os.fsync(mTarget.getFileDescriptor()); + mTarget.close(); mClosed = true; - IoBridge.write(mServer, temp, 0, MSG_LENGTH); + IoBridge.write(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH); break; } } @@ -143,17 +144,11 @@ public class FileBridge extends Thread { mClient = clientPfd.getFileDescriptor(); } - public FileBridgeOutputStream(FileDescriptor client) { - mClientPfd = null; - mClient = client; - } - @Override public void close() throws IOException { try { writeCommandAndBlock(CMD_CLOSE, "close()"); } finally { - IoBridge.closeAndSignalBlockedThreads(mClient); IoUtils.closeQuietly(mClientPfd); } } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 1bddc49f839c..13d5f6a9c9d7 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -673,11 +673,11 @@ public final class Parcel { * {@link #dataPosition}. This is used to validate that the marshalled * transaction is intended for the target interface. */ - public final void writeInterfaceToken(String interfaceName) { + public final void writeInterfaceToken(@NonNull String interfaceName) { nativeWriteInterfaceToken(mNativePtr, interfaceName); } - public final void enforceInterface(String interfaceName) { + public final void enforceInterface(@NonNull String interfaceName) { nativeEnforceInterface(mNativePtr, interfaceName); } diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index ca0981b46182..e62ad1fa9052 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -852,12 +852,11 @@ public class Process { /** * Set the priority of a thread, based on Linux priorities. - * - * @param tid The identifier of the thread/process to change. It should be - * the native thread id but not the managed id of {@link java.lang.Thread}. + * + * @param tid The identifier of the thread/process to change. * @param priority A Linux priority level, from -20 for highest scheduling * priority to 19 for lowest scheduling priority. - * + * * @throws IllegalArgumentException Throws IllegalArgumentException if * <var>tid</var> does not exist. * @throws SecurityException Throws SecurityException if your process does diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 9e332e9b0456..06203ff15094 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -657,16 +657,8 @@ public class ZygoteProcess { argsForZygote.add("--runtime-flags=" + runtimeFlags); if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) { argsForZygote.add("--mount-external-default"); - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) { - argsForZygote.add("--mount-external-read"); - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) { - argsForZygote.add("--mount-external-write"); - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) { - argsForZygote.add("--mount-external-full"); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) { argsForZygote.add("--mount-external-installer"); - } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) { - argsForZygote.add("--mount-external-legacy"); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) { argsForZygote.add("--mount-external-pass-through"); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) { diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java index a79a1cfcd64f..4379ce1055ef 100644 --- a/core/java/android/os/storage/StorageManagerInternal.java +++ b/core/java/android/os/storage/StorageManagerInternal.java @@ -70,13 +70,6 @@ public abstract class StorageManagerInternal { public abstract void addExternalStoragePolicy(ExternalStorageMountPolicy policy); /** - * Notify the mount service that the mount policy for a UID changed. - * @param uid The UID for which policy changed. - * @param packageName The package in the UID for making the call. - */ - public abstract void onExternalStoragePolicyChanged(int uid, String packageName); - - /** * Gets the mount mode to use for a given UID as determined by consultin all * policies. * diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1dbf95f7db86..97acd2f95612 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3567,6 +3567,9 @@ public final class Settings { if (outConfig.fontScale < 0) { outConfig.fontScale = DEFAULT_FONT_SCALE; } + outConfig.forceBoldText = Settings.Secure.getIntForUser( + cr, Settings.Secure.FORCE_BOLD_TEXT, Configuration.FORCE_BOLD_TEXT_NO, + userHandle); final String localeValue = Settings.System.getStringForUser(cr, SYSTEM_LOCALES, userHandle); @@ -3597,6 +3600,7 @@ public final class Settings { if (!inoutConfig.userSetLocale && !inoutConfig.getLocales().isEmpty()) { inoutConfig.clearLocales(); } + inoutConfig.forceBoldText = Configuration.FORCE_BOLD_TEXT_UNDEFINED; } /** @@ -3620,7 +3624,11 @@ public final class Settings { DEFAULT_OVERRIDEABLE_BY_RESTORE); } - /** @hide */ + /** + * Convenience function for checking if settings should be overwritten with config changes. + * @see #putConfigurationForUser(ContentResolver, Configuration, int) + * @hide + */ public static boolean hasInterestingConfigurationChanges(int changes) { return (changes & ActivityInfo.CONFIG_FONT_SCALE) != 0 || (changes & ActivityInfo.CONFIG_LOCALE) != 0; @@ -13407,15 +13415,6 @@ public final class Settings { "power_button_very_long_press"; /** - * Global settings that shouldn't be persisted. - * - * @hide - */ - public static final String[] TRANSIENT_SETTINGS = { - LOCATION_GLOBAL_KILL_SWITCH, - }; - - /** * Keys we no longer back up under the current schema, but want to continue to * process when restoring historical backup datasets. * diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 70224f94d556..e520d7ccaa7a 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -673,8 +673,6 @@ public final class Choreographer { ThreadedRenderer.setFPSDivisor(divisor); } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@link " - + "#postFrameCallback} instead") void doFrame(long frameTimeNanos, int frame, long frameTimelineVsyncId) { final long startNanos; synchronized (mLock) { diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 430e2cf2bf21..51474d3c39c8 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -17,7 +17,6 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; @@ -158,8 +157,6 @@ public abstract class DisplayEventReceiver { * @param frameTimelineVsyncId The frame timeline vsync id, used to correlate a frame * produced by HWUI with the timeline data stored in Surface Flinger. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@link " - + "Choreographer#postFrameCallback} instead") public void onVsync(long timestampNanos, long physicalDisplayId, int frame, long frameTimelineVsyncId) { } @@ -203,8 +200,6 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@link " - + "Choreographer#postFrameCallback} instead") private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, long frameTimelineVsyncId) { onVsync(timestampNanos, physicalDisplayId, frame, frameTimelineVsyncId); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 44e603ea4900..0c64eeac2ec7 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -182,9 +182,6 @@ public final class SurfaceControl implements Parcelable { IBinder displayToken, int mode); private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject, long barrierObject, long frame); - private static native void nativeDeferTransactionUntilSurface(long transactionObj, - long nativeObject, - long surfaceObject, long frame); private static native void nativeReparentChildren(long transactionObj, long nativeObject, long newParentObject); private static native void nativeReparent(long transactionObj, long nativeObject, @@ -2947,22 +2944,6 @@ public final class SurfaceControl implements Parcelable { /** * @hide */ - @Deprecated - @UnsupportedAppUsage - public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface, - long frameNumber) { - if (frameNumber < 0) { - return this; - } - checkPreconditions(sc); - nativeDeferTransactionUntilSurface(mNativeObject, sc.mNativeObject, - barrierSurface.mNativeObject, frameNumber); - return this; - } - - /** - * @hide - */ public Transaction reparentChildren(SurfaceControl sc, SurfaceControl newParent) { checkPreconditions(sc); nativeReparentChildren(mNativeObject, sc.mNativeObject, newParent.mNativeObject); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index b653d219b90a..e00ff7e00888 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -78,6 +78,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; +import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.IME_FOCUS_CONTROLLER; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.INSETS_CONTROLLER; @@ -2707,7 +2708,13 @@ public final class ViewRootImpl implements ViewParent, updateColorModeIfNeeded(lp.getColorMode()); surfaceCreated = !hadSurface && mSurface.isValid(); surfaceDestroyed = hadSurface && !mSurface.isValid(); - surfaceReplaced = (surfaceGenerationId != mSurface.getGenerationId()) + // When using Blast, the surface generation id may not change when there's a new + // SurfaceControl. In that case, we also check relayout flag + // RELAYOUT_RES_SURFACE_CHANGED since it should indicate that WMS created a new + // SurfaceControl. + surfaceReplaced = (surfaceGenerationId != mSurface.getGenerationId() + || (relayoutResult & RELAYOUT_RES_SURFACE_CHANGED) + == RELAYOUT_RES_SURFACE_CHANGED) && mSurface.isValid(); if (cutoutChanged) { diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index d8f2bb248fd1..a7cb642b83f9 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -39,13 +39,14 @@ public class TaskOrganizer extends WindowOrganizer { private ITaskOrganizerController mTaskOrganizerController; public TaskOrganizer() { - mTaskOrganizerController = getController(); + this(null); } /** @hide */ @VisibleForTesting public TaskOrganizer(ITaskOrganizerController taskOrganizerController) { - mTaskOrganizerController = taskOrganizerController; + mTaskOrganizerController = taskOrganizerController != null + ? taskOrganizerController : getController(); } /** diff --git a/core/java/com/android/ims/internal/uce/presence/PresCmdId.aidl b/core/java/com/android/ims/internal/uce/presence/PresCmdID.aidl index 6ece045ffcf7..6ece045ffcf7 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCmdId.aidl +++ b/core/java/com/android/ims/internal/uce/presence/PresCmdID.aidl diff --git a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java index 900e18d468bb..28a96013e1c0 100644 --- a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java +++ b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java @@ -166,7 +166,7 @@ public final class SelectableTargetInfo implements ChooserTargetInfo { // Now fetch app icon and raster with no badging even in work profile Bitmap appIcon = mSelectableTargetInfoCommunicator.makePresentationGetter(info) - .getIconBitmap(UserHandle.getUserHandleForUid(UserHandle.myUserId())); + .getIconBitmap(android.os.Process.myUserHandle()); // Raster target drawable with appIcon as a badge SimpleIconFactory sif = SimpleIconFactory.obtain(mContext); diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index e60f7fc70757..dd4409c23437 100644 --- a/core/java/com/android/internal/jank/InteractionJankMonitor.java +++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java @@ -44,26 +44,37 @@ public class InteractionJankMonitor { private static final long DEFAULT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5L); // Every value must have a corresponding entry in CUJ_STATSD_INTERACTION_TYPE. - public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE = 1; - public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE_LOCK = 0; - public static final int CUJ_NOTIFICATION_SHADE_SCROLL_FLING = 0; - public static final int CUJ_NOTIFICATION_SHADE_ROW_EXPAND = 0; - public static final int CUJ_NOTIFICATION_SHADE_ROW_SWIPE = 0; - public static final int CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE = 0; - public static final int CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE = 0; - public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS = 0; - public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON = 0; - public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME = 0; - public static final int CUJ_LAUNCHER_APP_CLOSE_TO_PIP = 0; - public static final int CUJ_LAUNCHER_QUICK_SWITCH = 0; + public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE = 0; + public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE_LOCK = 1; + public static final int CUJ_NOTIFICATION_SHADE_SCROLL_FLING = 2; + public static final int CUJ_NOTIFICATION_SHADE_ROW_EXPAND = 3; + public static final int CUJ_NOTIFICATION_SHADE_ROW_SWIPE = 4; + public static final int CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE = 5; + public static final int CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE = 6; + public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS = 7; + public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON = 8; + public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME = 9; + public static final int CUJ_LAUNCHER_APP_CLOSE_TO_PIP = 10; + public static final int CUJ_LAUNCHER_QUICK_SWITCH = 11; private static final int NO_STATSD_LOGGING = -1; // Used to convert CujType to InteractionType enum value for statsd logging. // Use NO_STATSD_LOGGING in case the measurement for a given CUJ should not be logged to statsd. - private static final int[] CUJ_TO_STATSD_INTERACTION_TYPE = { - NO_STATSD_LOGGING, + @VisibleForTesting + public static final int[] CUJ_TO_STATSD_INTERACTION_TYPE = { UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__NOTIFICATION_SHADE_SWIPE, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, + NO_STATSD_LOGGING, }; private static volatile InteractionJankMonitor sInstance; diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index 095882ebe669..60f1b4438f54 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -36,7 +36,6 @@ import com.android.internal.logging.AndroidConfig; import com.android.server.NetworkManagementSocketTagger; import dalvik.system.RuntimeHooks; -import dalvik.system.ThreadPrioritySetter; import dalvik.system.VMRuntime; import libcore.content.type.MimeMap; @@ -208,7 +207,6 @@ public class RuntimeInit { */ public static void preForkInit() { if (DEBUG) Slog.d(TAG, "Entered preForkInit."); - RuntimeHooks.setThreadPrioritySetter(new RuntimeThreadPrioritySetter()); RuntimeInit.enableDdms(); // TODO(b/142019040#comment13): Decide whether to load the default instance eagerly, i.e. // MimeMap.setDefault(DefaultMimeMapFactory.create()); @@ -221,35 +219,6 @@ public class RuntimeInit { MimeMap.setDefaultSupplier(DefaultMimeMapFactory::create); } - private static class RuntimeThreadPrioritySetter implements ThreadPrioritySetter { - // Should remain consistent with kNiceValues[] in system/libartpalette/palette_android.cc - private static final int[] NICE_VALUES = { - Process.THREAD_PRIORITY_LOWEST, // 1 (MIN_PRIORITY) - Process.THREAD_PRIORITY_BACKGROUND + 6, - Process.THREAD_PRIORITY_BACKGROUND + 3, - Process.THREAD_PRIORITY_BACKGROUND, - Process.THREAD_PRIORITY_DEFAULT, // 5 (NORM_PRIORITY) - Process.THREAD_PRIORITY_DEFAULT - 2, - Process.THREAD_PRIORITY_DEFAULT - 4, - Process.THREAD_PRIORITY_URGENT_DISPLAY + 3, - Process.THREAD_PRIORITY_URGENT_DISPLAY + 2, - Process.THREAD_PRIORITY_URGENT_DISPLAY // 10 (MAX_PRIORITY) - }; - - @Override - public void setPriority(int nativeTid, int priority) { - // Check NICE_VALUES[] length first. - if (NICE_VALUES.length != (1 + Thread.MAX_PRIORITY - Thread.MIN_PRIORITY)) { - throw new AssertionError("Unexpected NICE_VALUES.length=" + NICE_VALUES.length); - } - // Priority should be in the range of MIN_PRIORITY (1) to MAX_PRIORITY (10). - if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) { - throw new IllegalArgumentException("Priority out of range: " + priority); - } - Process.setThreadPriority(nativeTid, NICE_VALUES[priority - Thread.MIN_PRIORITY]); - } - } - @UnsupportedAppUsage protected static final void commonInit() { if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!"); diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index a985965afe17..5e20cd067589 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -172,23 +172,11 @@ public final class Zygote { public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE; /** Default external storage should be mounted. */ public static final int MOUNT_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT; - /** Read-only external storage should be mounted. */ - public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ; - /** Read-write external storage should be mounted. */ - public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE; - /** - * Mount mode for apps that are already installed on the device before the isolated_storage - * feature is enabled. - */ - public static final int MOUNT_EXTERNAL_LEGACY = IVold.REMOUNT_MODE_LEGACY; /** * Mount mode for package installers which should give them access to * all obb dirs in addition to their package sandboxes */ public static final int MOUNT_EXTERNAL_INSTALLER = IVold.REMOUNT_MODE_INSTALLER; - /** Read-write external storage should be mounted instead of package sandbox */ - public static final int MOUNT_EXTERNAL_FULL = IVold.REMOUNT_MODE_FULL; - /** The lower file system should be bind mounted directly on external storage */ public static final int MOUNT_EXTERNAL_PASS_THROUGH = IVold.REMOUNT_MODE_PASS_THROUGH; diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java index ed074327c3c5..32b808ab2528 100644 --- a/core/java/com/android/internal/os/ZygoteArguments.java +++ b/core/java/com/android/internal/os/ZygoteArguments.java @@ -380,16 +380,8 @@ class ZygoteArguments { mNiceName = getAssignmentValue(arg); } else if (arg.equals("--mount-external-default")) { mMountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT; - } else if (arg.equals("--mount-external-read")) { - mMountExternal = Zygote.MOUNT_EXTERNAL_READ; - } else if (arg.equals("--mount-external-write")) { - mMountExternal = Zygote.MOUNT_EXTERNAL_WRITE; - } else if (arg.equals("--mount-external-full")) { - mMountExternal = Zygote.MOUNT_EXTERNAL_FULL; - } else if (arg.equals("--mount-external-installer")) { + } else if (arg.equals("--mount-external-installer")) { mMountExternal = Zygote.MOUNT_EXTERNAL_INSTALLER; - } else if (arg.equals("--mount-external-legacy")) { - mMountExternal = Zygote.MOUNT_EXTERNAL_LEGACY; } else if (arg.equals("--mount-external-pass-through")) { mMountExternal = Zygote.MOUNT_EXTERNAL_PASS_THROUGH; } else if (arg.equals("--mount-external-android-writable")) { diff --git a/core/java/com/android/internal/protolog/ProtoLogGroup.java b/core/java/com/android/internal/protolog/ProtoLogGroup.java index 50ba42fdae2f..ce3efd35ee48 100644 --- a/core/java/com/android/internal/protolog/ProtoLogGroup.java +++ b/core/java/com/android/internal/protolog/ProtoLogGroup.java @@ -48,6 +48,10 @@ public enum ProtoLogGroup implements IProtoLogGroup { Consts.TAG_WM), WM_DEBUG_LOCKTASK(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM), + WM_DEBUG_STATES(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), + WM_DEBUG_TASKS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM), WM_DEBUG_STARTING_WINDOW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM), WM_SHOW_TRANSACTIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index 0892b70b9651..355ef0cd6b3f 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -612,50 +612,77 @@ static jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr) return ret; } +// String tries to allocate itself on the stack, within a known size, but will +// make a heap allocation if not. +template <size_t StackReserve> +class StackString { +public: + StackString(JNIEnv* env, jstring str) : mEnv(env), mJStr(str) { + LOG_ALWAYS_FATAL_IF(str == nullptr); + mSize = env->GetStringLength(str); + if (mSize > StackReserve) { + mStr = new jchar[mSize]; + } else { + mStr = &mBuffer[0]; + } + mEnv->GetStringRegion(str, 0, mSize, mStr); + } + ~StackString() { + if (mStr != &mBuffer[0]) { + delete[] mStr; + } + } + const jchar* str() { return mStr; } + jsize size() { return mSize; } + +private: + JNIEnv* mEnv; + jstring mJStr; + + jchar mBuffer[StackReserve]; + // pointer to &mBuffer[0] if string fits in mBuffer, otherwise owned + jchar* mStr; + jsize mSize; +}; + +// This size is chosen to be longer than most interface descriptors. +// Ones longer than this will be allocated on the heap. +typedef StackString<64> InterfaceDescriptorString; + static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); - if (parcel != NULL) { - // In the current implementation, the token is just the serialized interface name that - // the caller expects to be invoking - const jchar* str = env->GetStringCritical(name, 0); - if (str != NULL) { - parcel->writeInterfaceToken(String16( - reinterpret_cast<const char16_t*>(str), - env->GetStringLength(name))); - env->ReleaseStringCritical(name, str); - } + if (parcel != nullptr) { + InterfaceDescriptorString descriptor(env, name); + parcel->writeInterfaceToken(reinterpret_cast<const char16_t*>(descriptor.str()), + descriptor.size()); } } static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); - if (parcel != NULL) { - const jchar* str = env->GetStringCritical(name, 0); - if (str) { - IPCThreadState* threadState = IPCThreadState::self(); - const int32_t oldPolicy = threadState->getStrictModePolicy(); - const bool isValid = parcel->enforceInterface( - reinterpret_cast<const char16_t*>(str), - env->GetStringLength(name), - threadState); - env->ReleaseStringCritical(name, str); - if (isValid) { - const int32_t newPolicy = threadState->getStrictModePolicy(); - if (oldPolicy != newPolicy) { - // Need to keep the Java-level thread-local strict - // mode policy in sync for the libcore - // enforcements, which involves an upcall back - // into Java. (We can't modify the - // Parcel.enforceInterface signature, as it's - // pseudo-public, and used via AIDL - // auto-generation...) - set_dalvik_blockguard_policy(env, newPolicy); - } - return; // everything was correct -> return silently + if (parcel != nullptr) { + InterfaceDescriptorString descriptor(env, name); + IPCThreadState* threadState = IPCThreadState::self(); + const int32_t oldPolicy = threadState->getStrictModePolicy(); + const bool isValid = + parcel->enforceInterface(reinterpret_cast<const char16_t*>(descriptor.str()), + descriptor.size(), threadState); + if (isValid) { + const int32_t newPolicy = threadState->getStrictModePolicy(); + if (oldPolicy != newPolicy) { + // Need to keep the Java-level thread-local strict + // mode policy in sync for the libcore + // enforcements, which involves an upcall back + // into Java. (We can't modify the + // Parcel.enforceInterface signature, as it's + // pseudo-public, and used via AIDL + // auto-generation...) + set_dalvik_blockguard_policy(env, newPolicy); } + return; // everything was correct -> return silently } } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 372a5b39147e..14198559ef9c 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -481,7 +481,7 @@ static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong transactionO auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); auto relative = reinterpret_cast<SurfaceControl *>(relativeToObject); auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); - transaction->setRelativeLayer(ctrl, relative->getHandle(), zorder); + transaction->setRelativeLayer(ctrl, relative, zorder); } static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj, @@ -1327,20 +1327,9 @@ static jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, jlong barrierObject, jlong frameNumber) { - auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); - auto barrier = reinterpret_cast<SurfaceControl *>(barrierObject); - auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); - transaction->deferTransactionUntil_legacy(ctrl, barrier->getHandle(), frameNumber); -} - -static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong transactionObj, - jlong nativeObject, - jlong surfaceObject, jlong frameNumber) { + sp<SurfaceControl> ctrl = reinterpret_cast<SurfaceControl*>(nativeObject); + sp<SurfaceControl> barrier = reinterpret_cast<SurfaceControl*>(barrierObject); auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); - - auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); - sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject); - transaction->deferTransactionUntil_legacy(ctrl, barrier, frameNumber); } @@ -1351,7 +1340,7 @@ static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionO auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject); auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); - transaction->reparentChildren(ctrl, newParent->getHandle()); + transaction->reparentChildren(ctrl, newParent); } static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj, @@ -1360,7 +1349,7 @@ static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj, auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject); auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); - transaction->reparent(ctrl, newParent != NULL ? newParent->getHandle() : NULL); + transaction->reparent(ctrl, newParent); } static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong transactionObj, @@ -1699,8 +1688,6 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeGetProtectedContentSupport }, {"nativeDeferTransactionUntil", "(JJJJ)V", (void*)nativeDeferTransactionUntil }, - {"nativeDeferTransactionUntilSurface", "(JJJJ)V", - (void*)nativeDeferTransactionUntilSurface }, {"nativeReparentChildren", "(JJJ)V", (void*)nativeReparentChildren } , {"nativeReparent", "(JJJ)V", diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index e6bfeccfa8ae..42aab6ad6918 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -326,31 +326,15 @@ static std::array<UsapTableEntry, USAP_POOL_SIZE_MAX_LIMIT> gUsapTable; static FileDescriptorTable* gOpenFdTable = nullptr; // Must match values in com.android.internal.os.Zygote. -// The order of entries here must be kept in sync with ExternalStorageViews array values. +// Note that there are gaps in the constants: +// This is to further keep the values consistent with IVold.aidl enum MountExternalKind { - MOUNT_EXTERNAL_NONE = 0, - MOUNT_EXTERNAL_DEFAULT = 1, - MOUNT_EXTERNAL_READ = 2, - MOUNT_EXTERNAL_WRITE = 3, - MOUNT_EXTERNAL_LEGACY = 4, - MOUNT_EXTERNAL_INSTALLER = 5, - MOUNT_EXTERNAL_FULL = 6, - MOUNT_EXTERNAL_PASS_THROUGH = 7, - MOUNT_EXTERNAL_ANDROID_WRITABLE = 8, - MOUNT_EXTERNAL_COUNT = 9 -}; - -// The order of entries here must be kept in sync with MountExternalKind enum values. -static const std::array<const std::string, MOUNT_EXTERNAL_COUNT> ExternalStorageViews = { - "", // MOUNT_EXTERNAL_NONE - "/mnt/runtime/default", // MOUNT_EXTERNAL_DEFAULT - "/mnt/runtime/read", // MOUNT_EXTERNAL_READ - "/mnt/runtime/write", // MOUNT_EXTERNAL_WRITE - "/mnt/runtime/write", // MOUNT_EXTERNAL_LEGACY - "/mnt/runtime/write", // MOUNT_EXTERNAL_INSTALLER - "/mnt/runtime/full", // MOUNT_EXTERNAL_FULL - "/mnt/runtime/full", // MOUNT_EXTERNAL_PASS_THROUGH (only used w/ FUSE) - "/mnt/runtime/full", // MOUNT_EXTERNAL_ANDROID_WRITABLE (only used w/ FUSE) + MOUNT_EXTERNAL_NONE = 0, + MOUNT_EXTERNAL_DEFAULT = 1, + MOUNT_EXTERNAL_INSTALLER = 5, + MOUNT_EXTERNAL_PASS_THROUGH = 7, + MOUNT_EXTERNAL_ANDROID_WRITABLE = 8, + MOUNT_EXTERNAL_COUNT = 9 }; // Must match values in com.android.internal.os.Zygote. diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto index d4d8772f3f81..d315ff27ef9a 100644 --- a/core/proto/android/server/windowmanagerservice.proto +++ b/core/proto/android/server/windowmanagerservice.proto @@ -205,9 +205,8 @@ message DisplayContentProto { optional WindowStateProto input_method_input_target = 28; optional WindowStateProto input_method_control_target = 29; optional WindowStateProto current_focus = 30; - optional InsetsSourceProviderProto insets_source_provider = 31; - optional ImeInsetsSourceProviderProto ime_insets_source_provider = 32; - optional bool can_show_ime = 33; + optional ImeInsetsSourceProviderProto ime_insets_source_provider = 31; + optional bool can_show_ime = 32; } /* represents DisplayArea object */ @@ -527,6 +526,7 @@ message InsetsSourceProviderProto { message ImeInsetsSourceProviderProto { option (.android.msg_privacy).dest = DEST_AUTOMATIC; - optional WindowStateProto ime_target_from_ime = 1; - optional bool is_ime_layout_drawn = 2; + optional InsetsSourceProviderProto insets_source_provider = 1; + optional WindowStateProto ime_target_from_ime = 2; + optional bool is_ime_layout_drawn = 3; }
\ No newline at end of file diff --git a/core/proto/android/service/package.proto b/core/proto/android/service/package.proto index 004b096496db..d289e00d3467 100644 --- a/core/proto/android/service/package.proto +++ b/core/proto/android/service/package.proto @@ -124,6 +124,11 @@ message PackageProto { optional string originating_package_name = 2; } + message StatesProto { + optional bool is_startable = 1; + optional bool is_loading = 2; + } + // Name of package. e.g. "com.android.providers.telephony". optional string name = 1; // UID for this package as assigned by Android OS. @@ -145,4 +150,6 @@ message PackageProto { repeated UserInfoProto users = 9; // Where the request to install this package came from, optional InstallSourceProto install_source = 10; + // Whether the package is startable or is still loading + optional StatesProto states = 11; } diff --git a/core/proto/android/view/inputmethod/inputmethodeditortrace.proto b/core/proto/android/view/inputmethod/inputmethodeditortrace.proto index 2729e82768c3..856d8da1a1ea 100644 --- a/core/proto/android/view/inputmethod/inputmethodeditortrace.proto +++ b/core/proto/android/view/inputmethod/inputmethodeditortrace.proto @@ -65,8 +65,6 @@ message InputMethodEditorProto { repeated ClientSideProto client = 1; } - /* todo: extract as a separate message to allow other dumps to use this as their client side - proto */ /* groups together the dump from ime related client side classes */ message ClientSideProto { optional int32 display_id = 1; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 7247e4fd3311..c8b8ef252c2e 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -42,6 +42,9 @@ <protected-broadcast android:name="android.intent.action.PACKAGE_REMOVED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_FULLY_REMOVED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_CHANGED" /> + <protected-broadcast android:name="android.intent.action.PACKAGE_STARTABLE" /> + <protected-broadcast android:name="android.intent.action.PACKAGE_UNSTARTABLE" /> + <protected-broadcast android:name="android.intent.action.PACKAGE_FULLY_LOADED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_ENABLE_ROLLBACK" /> <protected-broadcast android:name="android.intent.action.CANCEL_ENABLE_ROLLBACK" /> <protected-broadcast android:name="android.intent.action.ROLLBACK_COMMITTED" /> @@ -1575,6 +1578,13 @@ <permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi @hide Allows an application to install a LocationTimeZoneProvider into the + LocationTimeZoneProviderManager. + <p>Not for use by third-party applications. + --> + <permission android:name="android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER" + android:protectionLevel="signature|privileged" /> + <!-- @SystemApi @hide Allows HDMI-CEC service to access device and configuration files. This should only be used by HDMI-CEC service. --> @@ -2712,7 +2722,7 @@ <!-- Allows applications like settings to manage configuration associated with automatic time and time zone detection. <p>Not for use by third-party applications. - @hide + @SystemApi @hide --> <permission android:name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" android:protectionLevel="signature|privileged" /> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 60f7a0993b92..fac2f2223c99 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -432,23 +432,17 @@ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string> <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string> <string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string> - <!-- no translation found for permdesc_recordAudio (5857246765327514062) --> - <skip /> - <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) --> - <skip /> - <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) --> - <skip /> + <string name="permdesc_recordAudio" msgid="5857246765327514062">"This app can record audio using the microphone while the app is in use."</string> + <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"record audio in the background"</string> + <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"This app can record audio using the microphone at any time."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"send commands to the SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Allows the app to send commands to the SIM. This is very dangerous."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"recognise physical activity"</string> <string name="permdesc_activityRecognition" msgid="8667484762991357519">"This app can recognise your physical activity."</string> <string name="permlab_camera" msgid="6320282492904119413">"take pictures and videos"</string> - <!-- no translation found for permdesc_camera (5240801376168647151) --> - <skip /> - <!-- no translation found for permlab_backgroundCamera (7549917926079731681) --> - <skip /> - <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) --> - <skip /> + <string name="permdesc_camera" msgid="5240801376168647151">"This app can take pictures and record videos using the camera while the app is in use."</string> + <string name="permlab_backgroundCamera" msgid="7549917926079731681">"take pictures and videos in the background"</string> + <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"This app can take pictures and record videos using the camera at any time."</string> <string name="permlab_systemCamera" msgid="3642917457796210580">"Grant an application or service access to system cameras to take pictures and videos"</string> <string name="permdesc_systemCamera" msgid="5938360914419175986">"This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string> <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Allow an application or service to receive callbacks about camera devices being opened or closed."</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index ae3aaab89de2..8497658c52bb 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -432,23 +432,17 @@ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string> <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string> <string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string> - <!-- no translation found for permdesc_recordAudio (5857246765327514062) --> - <skip /> - <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) --> - <skip /> - <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) --> - <skip /> + <string name="permdesc_recordAudio" msgid="5857246765327514062">"This app can record audio using the microphone while the app is in use."</string> + <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"record audio in the background"</string> + <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"This app can record audio using the microphone at any time."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"send commands to the SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Allows the app to send commands to the SIM. This is very dangerous."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"recognise physical activity"</string> <string name="permdesc_activityRecognition" msgid="8667484762991357519">"This app can recognise your physical activity."</string> <string name="permlab_camera" msgid="6320282492904119413">"take pictures and videos"</string> - <!-- no translation found for permdesc_camera (5240801376168647151) --> - <skip /> - <!-- no translation found for permlab_backgroundCamera (7549917926079731681) --> - <skip /> - <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) --> - <skip /> + <string name="permdesc_camera" msgid="5240801376168647151">"This app can take pictures and record videos using the camera while the app is in use."</string> + <string name="permlab_backgroundCamera" msgid="7549917926079731681">"take pictures and videos in the background"</string> + <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"This app can take pictures and record videos using the camera at any time."</string> <string name="permlab_systemCamera" msgid="3642917457796210580">"Grant an application or service access to system cameras to take pictures and videos"</string> <string name="permdesc_systemCamera" msgid="5938360914419175986">"This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string> <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Allow an application or service to receive callbacks about camera devices being opened or closed."</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 52dcf979a45f..12881e7e70f1 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -432,23 +432,17 @@ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string> <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string> <string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string> - <!-- no translation found for permdesc_recordAudio (5857246765327514062) --> - <skip /> - <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) --> - <skip /> - <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) --> - <skip /> + <string name="permdesc_recordAudio" msgid="5857246765327514062">"This app can record audio using the microphone while the app is in use."</string> + <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"record audio in the background"</string> + <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"This app can record audio using the microphone at any time."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"send commands to the SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Allows the app to send commands to the SIM. This is very dangerous."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"recognise physical activity"</string> <string name="permdesc_activityRecognition" msgid="8667484762991357519">"This app can recognise your physical activity."</string> <string name="permlab_camera" msgid="6320282492904119413">"take pictures and videos"</string> - <!-- no translation found for permdesc_camera (5240801376168647151) --> - <skip /> - <!-- no translation found for permlab_backgroundCamera (7549917926079731681) --> - <skip /> - <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) --> - <skip /> + <string name="permdesc_camera" msgid="5240801376168647151">"This app can take pictures and record videos using the camera while the app is in use."</string> + <string name="permlab_backgroundCamera" msgid="7549917926079731681">"take pictures and videos in the background"</string> + <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"This app can take pictures and record videos using the camera at any time."</string> <string name="permlab_systemCamera" msgid="3642917457796210580">"Grant an application or service access to system cameras to take pictures and videos"</string> <string name="permdesc_systemCamera" msgid="5938360914419175986">"This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string> <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Allow an application or service to receive callbacks about camera devices being opened or closed."</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 2f7f271678e9..cb2eb7ab17ca 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -432,23 +432,17 @@ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string> <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string> <string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string> - <!-- no translation found for permdesc_recordAudio (5857246765327514062) --> - <skip /> - <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) --> - <skip /> - <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) --> - <skip /> + <string name="permdesc_recordAudio" msgid="5857246765327514062">"This app can record audio using the microphone while the app is in use."</string> + <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"record audio in the background"</string> + <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"This app can record audio using the microphone at any time."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"send commands to the SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Allows the app to send commands to the SIM. This is very dangerous."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"recognise physical activity"</string> <string name="permdesc_activityRecognition" msgid="8667484762991357519">"This app can recognise your physical activity."</string> <string name="permlab_camera" msgid="6320282492904119413">"take pictures and videos"</string> - <!-- no translation found for permdesc_camera (5240801376168647151) --> - <skip /> - <!-- no translation found for permlab_backgroundCamera (7549917926079731681) --> - <skip /> - <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) --> - <skip /> + <string name="permdesc_camera" msgid="5240801376168647151">"This app can take pictures and record videos using the camera while the app is in use."</string> + <string name="permlab_backgroundCamera" msgid="7549917926079731681">"take pictures and videos in the background"</string> + <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"This app can take pictures and record videos using the camera at any time."</string> <string name="permlab_systemCamera" msgid="3642917457796210580">"Grant an application or service access to system cameras to take pictures and videos"</string> <string name="permdesc_systemCamera" msgid="5938360914419175986">"This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string> <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Allow an application or service to receive callbacks about camera devices being opened or closed."</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 8f017f911b73..5750e50476b8 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -432,23 +432,17 @@ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string> <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string> <string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string> - <!-- no translation found for permdesc_recordAudio (5857246765327514062) --> - <skip /> - <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) --> - <skip /> - <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) --> - <skip /> + <string name="permdesc_recordAudio" msgid="5857246765327514062">"This app can record audio using the microphone while the app is in use."</string> + <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"record audio in the background"</string> + <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"This app can record audio using the microphone at any time."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"send commands to the SIM"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Allows the app to send commands to the SIM. This is very dangerous."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"recognize physical activity"</string> <string name="permdesc_activityRecognition" msgid="8667484762991357519">"This app can recognize your physical activity."</string> <string name="permlab_camera" msgid="6320282492904119413">"take pictures and videos"</string> - <!-- no translation found for permdesc_camera (5240801376168647151) --> - <skip /> - <!-- no translation found for permlab_backgroundCamera (7549917926079731681) --> - <skip /> - <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) --> - <skip /> + <string name="permdesc_camera" msgid="5240801376168647151">"This app can take pictures and record videos using the camera while the app is in use."</string> + <string name="permlab_backgroundCamera" msgid="7549917926079731681">"take pictures and videos in the background"</string> + <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"This app can take pictures and record videos using the camera at any time."</string> <string name="permlab_systemCamera" msgid="3642917457796210580">"Allow an application or service access to system cameras to take pictures and videos"</string> <string name="permdesc_systemCamera" msgid="5938360914419175986">"This privileged or system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string> <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Allow an application or service to receive callbacks about camera devices being opened or closed."</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index b327342ab0d5..7b376ff2b32f 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1632,12 +1632,10 @@ <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"सिफारिस तहभन्दा आवाज ठुलो गर्नुहुन्छ?\n\nलामो समय सम्म उच्च आवाजमा सुन्दा तपाईँको सुन्ने शक्तिलाई हानी गर्न सक्छ।"</string> <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"पहुँच सम्बन्धी सर्टकट प्रयोग गर्ने हो?"</string> <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"यो सर्टकट सक्रिय हुँदा, ३ सेकेन्डसम्म दुवै भोल्युम बटन थिच्नुले पहुँचसम्बन्धी कुनै सुविधा सुरु गर्ने छ।"</string> - <!-- no translation found for accessibility_shortcut_multiple_service_warning_title (3135860819356676426) --> - <skip /> + <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"सर्वसुलभता कायम गर्ने सुविधाहरू प्रयोग गर्न सर्टकट अन गर्ने हो?"</string> <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुभयो भने पहुँचसम्बन्धी सुविधाहरू सक्रिय हुन्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nहालका सुविधाहरू:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nतपाईं सेटिङ > पहुँचमा गएर चयन गरिएका सुविधाहरू परिवर्तन गर्न सक्नुहुन्छ।"</string> <string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string> - <!-- no translation found for accessibility_shortcut_single_service_warning_title (1909518473488345266) --> - <skip /> + <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"<xliff:g id="SERVICE">%1$s</xliff:g> प्रयोग गर्न सर्टकट अन गर्ने हो?"</string> <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुले <xliff:g id="SERVICE">%1$s</xliff:g> नामक पहुँचसम्बन्धी सुविधा सक्रिय गर्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nतपाईं सेटिङ > पहुँचमा गई यो सर्टकटमार्फत अर्को सुविधा खुल्ने बनाउन सक्नुहुन्छ।"</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"सक्रिय गरियोस्"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"सक्रिय नगरियोस्"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index f09e7b04bd44..450fddb025e2 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -432,23 +432,17 @@ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"alterar as suas configurações de áudio"</string> <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite que o app modifique configurações de áudio globais como volume e alto-falantes de saída."</string> <string name="permlab_recordAudio" msgid="1208457423054219147">"gravar áudio"</string> - <!-- no translation found for permdesc_recordAudio (5857246765327514062) --> - <skip /> - <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) --> - <skip /> - <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) --> - <skip /> + <string name="permdesc_recordAudio" msgid="5857246765327514062">"Enquanto está sendo usado, este app pode gravar áudio usando o microfone."</string> + <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"gravar áudio em segundo plano"</string> + <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Este app pode gravar áudio usando o microfone a qualquer momento."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"enviar comandos para o chip"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permite que o app envie comandos ao chip. Muito perigoso."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconhecer atividade física"</string> <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Este app pode reconhecer sua atividade física."</string> <string name="permlab_camera" msgid="6320282492904119413">"tirar fotos e gravar vídeos"</string> - <!-- no translation found for permdesc_camera (5240801376168647151) --> - <skip /> - <!-- no translation found for permlab_backgroundCamera (7549917926079731681) --> - <skip /> - <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) --> - <skip /> + <string name="permdesc_camera" msgid="5240801376168647151">"Enquanto está sendo usado, este app pode tirar fotos e gravar vídeos usando a câmera."</string> + <string name="permlab_backgroundCamera" msgid="7549917926079731681">"tirar fotos e gravar vídeos em segundo plano"</string> + <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Este app pode tirar fotos e gravar vídeos usando a câmera a qualquer momento."</string> <string name="permlab_systemCamera" msgid="3642917457796210580">"Permitir que um aplicativo ou serviço acesse as câmeras do sistema para tirar fotos e gravar vídeos"</string> <string name="permdesc_systemCamera" msgid="5938360914419175986">"Esse app do sistema ou com privilégios pode tirar fotos e gravar vídeos a qualquer momento usando a câmera do sistema. É necessário que o app tenha também a permissão android.permission.CAMERA"</string> <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Permitir que um aplicativo ou serviço receba callbacks sobre dispositivos de câmera sendo abertos ou fechados."</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index f09e7b04bd44..450fddb025e2 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -432,23 +432,17 @@ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"alterar as suas configurações de áudio"</string> <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite que o app modifique configurações de áudio globais como volume e alto-falantes de saída."</string> <string name="permlab_recordAudio" msgid="1208457423054219147">"gravar áudio"</string> - <!-- no translation found for permdesc_recordAudio (5857246765327514062) --> - <skip /> - <!-- no translation found for permlab_recordBackgroundAudio (5891032812308878254) --> - <skip /> - <!-- no translation found for permdesc_recordBackgroundAudio (1992623135737407516) --> - <skip /> + <string name="permdesc_recordAudio" msgid="5857246765327514062">"Enquanto está sendo usado, este app pode gravar áudio usando o microfone."</string> + <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"gravar áudio em segundo plano"</string> + <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Este app pode gravar áudio usando o microfone a qualquer momento."</string> <string name="permlab_sim_communication" msgid="176788115994050692">"enviar comandos para o chip"</string> <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permite que o app envie comandos ao chip. Muito perigoso."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconhecer atividade física"</string> <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Este app pode reconhecer sua atividade física."</string> <string name="permlab_camera" msgid="6320282492904119413">"tirar fotos e gravar vídeos"</string> - <!-- no translation found for permdesc_camera (5240801376168647151) --> - <skip /> - <!-- no translation found for permlab_backgroundCamera (7549917926079731681) --> - <skip /> - <!-- no translation found for permdesc_backgroundCamera (1615291686191138250) --> - <skip /> + <string name="permdesc_camera" msgid="5240801376168647151">"Enquanto está sendo usado, este app pode tirar fotos e gravar vídeos usando a câmera."</string> + <string name="permlab_backgroundCamera" msgid="7549917926079731681">"tirar fotos e gravar vídeos em segundo plano"</string> + <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Este app pode tirar fotos e gravar vídeos usando a câmera a qualquer momento."</string> <string name="permlab_systemCamera" msgid="3642917457796210580">"Permitir que um aplicativo ou serviço acesse as câmeras do sistema para tirar fotos e gravar vídeos"</string> <string name="permdesc_systemCamera" msgid="5938360914419175986">"Esse app do sistema ou com privilégios pode tirar fotos e gravar vídeos a qualquer momento usando a câmera do sistema. É necessário que o app tenha também a permissão android.permission.CAMERA"</string> <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Permitir que um aplicativo ou serviço receba callbacks sobre dispositivos de câmera sendo abertos ou fechados."</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index fc2fd35ace52..d0749601d697 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1325,7 +1325,7 @@ <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Отмена"</string> <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Запомнить выбор"</string> <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Это можно изменить позже в разделе настроек \"Приложения\"."</string> - <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Всегда разрешать"</string> + <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Разрешать всегда"</string> <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Не разрешать"</string> <string name="sim_removed_title" msgid="5387212933992546283">"SIM-карта удалена"</string> <string name="sim_removed_message" msgid="9051174064474904617">"Пока вы не вставите действующую SIM-карту, мобильная сеть будет недоступна."</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 89e348ab57b3..f55114c94eed 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -271,11 +271,6 @@ when there's no network connection. If the scan doesn't timeout, use zero --> <integer name="config_radioScanningTimeout">0</integer> - <!-- When true, Android uses the PAC implementation included in WebView to handle - networks with PAC scripts. - When false, Android's own implementation of libpac is used.--> - <bool name ="config_useWebViewPacProcessor">true</bool> - <!-- XXXXX NOTE THE FOLLOWING RESOURCES USE THE WRONG NAMING CONVENTION. Please don't copy them, copy anything else. --> @@ -1583,6 +1578,16 @@ config_timeZoneRulesUpdateTrackingEnabled are true.] --> <integer name="config_timeZoneRulesCheckRetryCount">5</integer> + <!-- Whether to enable primary location time zone provider overlay which allows the primary + location time zone provider to be replaced by an app at run-time. When disabled, only the + config_primaryLocationTimeZoneProviderPackageName package will be searched for the primary + location time zone provider, otherwise any system package is eligible. Anyone who wants to + disable the overlay mechanism can set it to false. --> + <bool name="config_enablePrimaryLocationTimeZoneOverlay" translatable="false">false</bool> + <!-- Package name providing the primary location time zone provider. Used only when + config_enablePrimaryLocationTimeZoneOverlay is false. --> + <string name="config_primaryLocationTimeZoneProviderPackageName" translatable="false">@null</string> + <!-- Whether to enable network location overlay which allows network location provider to be replaced by an app at run-time. When disabled, only the config_networkLocationProviderPackageName package will be searched for network location @@ -1826,6 +1831,8 @@ <string name="config_systemGallery" translatable="false">com.android.gallery3d</string> <!-- The name of the package that will hold the system cluster service role. --> <string name="config_systemAutomotiveCluster" translatable="false"></string> + <!-- The name of the package that will hold the system video call role. --> + <string name="config_systemVideoCall" translatable="false"></string> <!-- The name of the package that will be allowed to change its components' label/icon. --> <string name="config_overrideComponentUiPackage" translatable="false"></string> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 1e2d554a088b..fe17eca35545 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3071,6 +3071,8 @@ <public-group type="string" first-id="0x01040028"> <!-- @hide @SystemApi @TestApi --> <public name="config_systemAutomotiveCluster" /> + <!-- @hide @SystemApi @TestApi --> + <public name="config_systemVideoCall" /> </public-group> <public-group type="id" first-id="0x01020055"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 996e1f9fde9a..3e595493d07d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -287,7 +287,6 @@ <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" /> <java-symbol type="bool" name="config_disableTransitionAnimation" /> <java-symbol type="bool" name="config_enableAutoPowerModes" /> - <java-symbol type="bool" name="config_useWebViewPacProcessor" /> <java-symbol type="integer" name="config_autoPowerModeThresholdAngle" /> <java-symbol type="integer" name="config_autoPowerModeAnyMotionSensor" /> <java-symbol type="bool" name="config_autoPowerModePreferWristTilt" /> @@ -2159,6 +2158,8 @@ <java-symbol type="string" name="config_defaultNetworkScorerPackageName" /> <java-symbol type="string" name="config_persistentDataPackageName" /> <java-symbol type="string" name="config_deviceConfiguratorPackageName" /> + <java-symbol type="bool" name="config_enablePrimaryLocationTimeZoneOverlay" /> + <java-symbol type="string" name="config_primaryLocationTimeZoneProviderPackageName" /> <java-symbol type="layout" name="resolver_list" /> <java-symbol type="id" name="resolver_list" /> diff --git a/core/tests/coretests/src/android/os/FileBridgeTest.java b/core/tests/coretests/src/android/os/FileBridgeTest.java index d4f6b1fcec4e..708bfa6ece2e 100644 --- a/core/tests/coretests/src/android/os/FileBridgeTest.java +++ b/core/tests/coretests/src/android/os/FileBridgeTest.java @@ -16,6 +16,9 @@ package android.os; +import static android.os.ParcelFileDescriptor.MODE_CREATE; +import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; + import android.os.FileBridge.FileBridgeOutputStream; import android.test.AndroidTestCase; import android.test.MoreAsserts; @@ -25,7 +28,6 @@ import libcore.io.Streams; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Random; @@ -33,7 +35,7 @@ import java.util.Random; public class FileBridgeTest extends AndroidTestCase { private File file; - private FileOutputStream fileOs; + private ParcelFileDescriptor outputFile; private FileBridge bridge; private FileBridgeOutputStream client; @@ -44,17 +46,17 @@ public class FileBridgeTest extends AndroidTestCase { file = getContext().getFileStreamPath("meow.dat"); file.delete(); - fileOs = new FileOutputStream(file); + outputFile = ParcelFileDescriptor.open(file, MODE_CREATE | MODE_READ_WRITE); bridge = new FileBridge(); - bridge.setTargetFile(fileOs.getFD()); + bridge.setTargetFile(outputFile); bridge.start(); client = new FileBridgeOutputStream(bridge.getClientSocket()); } @Override protected void tearDown() throws Exception { - fileOs.close(); + outputFile.close(); file.delete(); } diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java index b669cc609baf..a9cfd286688b 100644 --- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java +++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java @@ -17,8 +17,10 @@ package com.android.internal.jank; import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_TO_STATSD_INTERACTION_TYPE; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; @@ -45,6 +47,13 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + @SmallTest public class InteractionJankMonitorTest { private ViewAttachTestActivity mActivity; @@ -138,4 +147,27 @@ public class InteractionJankMonitorTest { verify(tracker).cancel(); } + @Test + public void testCujTypeEnumCorrectlyDefined() throws Exception { + List<Field> cujEnumFields = + Arrays.stream(InteractionJankMonitor.class.getDeclaredFields()) + .filter(field -> field.getName().startsWith("CUJ_") + && Modifier.isStatic(field.getModifiers()) + && field.getType() == int.class) + .collect(Collectors.toList()); + + HashSet<Integer> allValues = new HashSet<>(); + for (Field field : cujEnumFields) { + int fieldValue = field.getInt(null); + assertWithMessage( + "Field %s must have a mapping to a value in CUJ_TO_STATSD_INTERACTION_TYPE", + field.getName()) + .that(fieldValue < CUJ_TO_STATSD_INTERACTION_TYPE.length) + .isTrue(); + assertWithMessage("All CujType values must be unique. Field %s repeats existing value.", + field.getName()) + .that(allValues.add(fieldValue)) + .isTrue(); + } + } } diff --git a/core/xsd/vts/Android.bp b/core/xsd/vts/Android.bp index 4b43b4136076..ca655f18149c 100644 --- a/core/xsd/vts/Android.bp +++ b/core/xsd/vts/Android.bp @@ -40,7 +40,3 @@ cc_test { ], test_config: "vts_permission_validate_test.xml", } - -vts_config { - name: "VtsValidatePermission", -} diff --git a/core/xsd/vts/AndroidTest.xml b/core/xsd/vts/AndroidTest.xml deleted file mode 100644 index e5cc9a0f74ee..000000000000 --- a/core/xsd/vts/AndroidTest.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Config for VTS VtsValidatePermission."> - <option name="config-descriptor:metadata" key="plan" value="vts-treble" /> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher"> - <option name="abort-on-push-failure" value="false"/> - <option name="push-group" value="HostDrivenTest.push"/> - <option name="push" value="DATA/etc/permission.xsd->/data/local/tmp/permission.xsd"/> - </target_preparer> - <test class="com.android.tradefed.testtype.VtsMultiDeviceTest"> - <option name="test-module-name" value="VtsValidatePermission"/> - <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_permission_validate_test/vts_permission_validate_test" /> - <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_permission_validate_test/vts_permission_validate_test" /> - <option name="binary-test-type" value="gtest"/> - <option name="test-timeout" value="30s"/> - </test> -</configuration> diff --git a/data/etc/com.android.storagemanager.xml b/data/etc/com.android.storagemanager.xml index e85a82c983df..a1635fe5548b 100644 --- a/data/etc/com.android.storagemanager.xml +++ b/data/etc/com.android.storagemanager.xml @@ -22,5 +22,6 @@ <permission name="android.permission.PACKAGE_USAGE_STATS"/> <permission name="android.permission.USE_RESERVED_DISK"/> <permission name="android.permission.WRITE_SECURE_SETTINGS"/> + <permission name="android.permission.MANAGE_EXTERNAL_STORAGE"/> </privapp-permissions> </permissions> diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index c53ea8789c8b..29c8de63fc31 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -49,6 +49,18 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-2062338592": { + "message": "Looking for task of %s", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "-2054442123": { + "message": "Setting Intent of %s to %s", + "level": "VERBOSE", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/Task.java" + }, "-2049725903": { "message": "Task back pressed on root taskId=%d", "level": "VERBOSE", @@ -103,6 +115,12 @@ "group": "WM_DEBUG_WINDOW_ORGANIZER", "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java" }, + "-1977793524": { + "message": "moveStackToDisplay: moving stackId=%d to displayId=%d", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" + }, "-1976930686": { "message": "Attempted to add Accessibility overlay window with bad token %s. Aborting.", "level": "WARN", @@ -163,6 +181,12 @@ "group": "WM_DEBUG_WINDOW_ORGANIZER", "at": "com\/android\/server\/wm\/TaskOrganizerController.java" }, + "-1890326172": { + "message": "no-history finish of %s on new resume", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-1884933373": { "message": "enableScreenAfterBoot: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s", "level": "INFO", @@ -199,6 +223,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/AppTransition.java" }, + "-1861864501": { + "message": "resumeTopActivityLocked: Going to sleep and all paused", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-1847087163": { "message": "TRANSIT_TASK_OPEN_BEHIND, adding %s to mOpeningApps", "level": "DEBUG", @@ -259,6 +289,12 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimationController.java" }, + "-1768090656": { + "message": "Re-launching after pause: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-1750206390": { "message": "Exception thrown when creating surface for client %s (%s). %s", "level": "WARN", @@ -295,6 +331,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayContent.java" }, + "-1704402370": { + "message": "resetTaskIntendedTask: calling finishActivity on %s", + "level": "WARN", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java" + }, "-1699018375": { "message": "Adding activity %s to task %s callers: %s", "level": "INFO", @@ -307,6 +349,12 @@ "group": "WM_DEBUG_ADD_REMOVE", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "-1679411993": { + "message": "setVr2dDisplayId called for: %d", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" + }, "-1670695197": { "message": "Attempted to add presentation window to a non-suitable display. Aborting.", "level": "WARN", @@ -319,6 +367,18 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-1655805455": { + "message": "Enqueue pending stop if needed: %s wasStopping=%b visibleRequested=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, + "-1647332198": { + "message": "remove RecentTask %s when finishing user %d", + "level": "INFO", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RecentTasks.java" + }, "-1638958146": { "message": "Removing activity %s from task=%s adding to task=%s Callers=%s", "level": "INFO", @@ -337,6 +397,24 @@ "group": "WM_DEBUG_LOCKTASK", "at": "com\/android\/server\/wm\/LockTaskController.java" }, + "-1613096551": { + "message": "Top resumed state released %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, + "-1607026519": { + "message": "Ready to stop: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, + "-1601745126": { + "message": "Launch on display check: allow launch for owner of the display", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "-1598452494": { "message": "activityDestroyedLocked: r=%s", "level": "DEBUG", @@ -355,6 +433,18 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, + "-1585311008": { + "message": "Bring to front target: %s from %s", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStarter.java" + }, + "-1575977269": { + "message": "Skipping %s: mismatch root %s", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "-1568331821": { "message": "Enabling listeners", "level": "VERBOSE", @@ -367,6 +457,12 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, + "-1558137010": { + "message": "Config is relaunching invisible activity %s called by %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-1554521902": { "message": "showInsets(ime) was requested by different window: %s ", "level": "WARN", @@ -433,6 +529,18 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityStarter.java" }, + "-1492696222": { + "message": "App died during pause, not stopping: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, + "-1474292612": { + "message": "Could not find task for id: %d", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" + }, "-1471946192": { "message": "Marking app token %s with replacing child windows.", "level": "DEBUG", @@ -463,6 +571,12 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimationController.java" }, + "-1432963966": { + "message": "Moving to DESTROYING: %s (destroy requested)", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-1427184084": { "message": "addWindow: New client %s: window=%s Callers=%s", "level": "VERBOSE", @@ -499,6 +613,12 @@ "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, + "-1376035390": { + "message": "No task found", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "-1375751630": { "message": " --- Start combine pass ---", "level": "VERBOSE", @@ -541,12 +661,36 @@ "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/WindowState.java" }, + "-1305966693": { + "message": "Sending position change to %s, onTop: %b", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, + "-1305791032": { + "message": "Moving to STOPPED: %s (stop complete)", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-1305755880": { "message": "Initial config: %s", "level": "VERBOSE", "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" }, + "-1304806505": { + "message": "Starting new activity %s in new task %s", + "level": "VERBOSE", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStarter.java" + }, + "-1295684101": { + "message": "Launch on display check: no caller info, skip check", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "-1292329638": { "message": "Added starting %s: startingWindow=%s startingView=%s", "level": "VERBOSE", @@ -601,12 +745,30 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimationController.java" }, + "-1198579104": { + "message": "Pushing next activity %s out to target's task %s", + "level": "VERBOSE", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java" + }, + "-1193946201": { + "message": "Can't report activity position update - client not running, activityRecord=%s", + "level": "WARN", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-1176488860": { "message": "SURFACE isSecure=%b: %s", "level": "INFO", "group": "WM_SHOW_TRANSACTIONS", "at": "com\/android\/server\/wm\/WindowSurfaceController.java" }, + "-1164930508": { + "message": "Moving to RESUMED: %s (starting new instance) callers=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-1156118957": { "message": "Updated config=%s", "level": "DEBUG", @@ -631,6 +793,12 @@ "group": "WM_DEBUG_FOCUS", "at": "com\/android\/server\/wm\/DisplayContent.java" }, + "-1136139407": { + "message": "no-history finish of %s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-1130891072": { "message": "Orientation continue waiting for draw in %s", "level": "VERBOSE", @@ -697,12 +865,24 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "-1084548141": { + "message": "Launch on display check: allow launch any on display", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "-1076978367": { "message": "thawRotation: mRotation=%d", "level": "VERBOSE", "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-1066383762": { + "message": "Sleep still waiting to pause %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-1060365734": { "message": "Attempted to add QS dialog window with bad token %s. Aborting.", "level": "WARN", @@ -727,12 +907,30 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-1022146708": { + "message": "Skipping %s: mismatch activity type", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "-1016578046": { + "message": "Moving to %s Relaunching %s callers=%s", + "level": "INFO", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-1009117329": { "message": "isFetchingAppTransitionSpecs=true", "level": "VERBOSE", "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/AppTransitionController.java" }, + "-1003060523": { + "message": "Finish needs to pause: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-993378225": { "message": "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", "level": "VERBOSE", @@ -751,6 +949,12 @@ "group": "WM_DEBUG_WINDOW_ORGANIZER", "at": "com\/android\/server\/wm\/TaskOrganizerController.java" }, + "-937498525": { + "message": "Executing finish of failed to pause activity: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-930893991": { "message": "Set sync ready, syncId=%d", "level": "VERBOSE", @@ -775,6 +979,18 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" }, + "-926231510": { + "message": "State unchanged from:%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, + "-917215012": { + "message": "%s: caller %d is using old GET_TASKS but privileged; allowing", + "level": "WARN", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" + }, "-916108501": { "message": "Adding %s to %s", "level": "VERBOSE", @@ -787,18 +1003,36 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-903853754": { + "message": "pauseBackStacks: stack=%s mResumedActivity=%s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/TaskDisplayArea.java" + }, "-883738232": { "message": "Adding more than one toast window for UID at a time.", "level": "WARN", "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-877494781": { + "message": "Start pushing activity %s out to bottom task %s", + "level": "VERBOSE", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java" + }, "-874446906": { "message": "showBootMessage: msg=%s always=%b mAllowBootMessages=%b mShowingBootMessages=%b mSystemBooted=%b. %s", "level": "INFO", "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-866966979": { + "message": "Moving to PAUSED: %s (starting in paused state)", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "-861859917": { "message": "Attempted to add window to a display that does not exist: %d. Aborting.", "level": "WARN", @@ -841,6 +1075,12 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "-814760297": { + "message": "Looking for task of %s in %s", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "-809771899": { "message": "findFocusedWindow: Reached focused app=%s", "level": "VERBOSE", @@ -871,6 +1111,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-775004869": { + "message": "Not a match: %s", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "-771177730": { "message": "Removing focused app token:%s displayId=%d", "level": "VERBOSE", @@ -901,12 +1147,24 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "-729530161": { + "message": "Moving to DESTROYED: %s (no app)", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-716565534": { "message": "moveActivityStackToFront: unfocusable activity=%s", "level": "DEBUG", "group": "WM_DEBUG_FOCUS", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "-705939410": { + "message": "Waiting for pause to complete...", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-703543418": { "message": " check sibling %s", "level": "VERBOSE", @@ -925,6 +1183,12 @@ "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, + "-672228342": { + "message": "resumeTopActivityLocked: Top activity resumed %s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-668956537": { "message": " THUMBNAIL %s: CREATE", "level": "INFO", @@ -943,6 +1207,12 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, + "-650261962": { + "message": "Sleep needs to pause %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-639305784": { "message": "Could not report config changes to the window token client.", "level": "WARN", @@ -979,6 +1249,18 @@ "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-606328116": { + "message": "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) %s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, + "-596163537": { + "message": "Waiting for top state to be released by %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "-593535526": { "message": "Binding proc %s with config %s", "level": "VERBOSE", @@ -997,6 +1279,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayRotation.java" }, + "-571686216": { + "message": "Launch on display check: disallow launch on virtual display for not-embedded activity.", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "-561092364": { "message": "onPointerDownOutsideFocusLocked called on %s", "level": "INFO", @@ -1027,12 +1315,24 @@ "group": "WM_SHOW_TRANSACTIONS", "at": "com\/android\/server\/wm\/WindowAnimator.java" }, + "-533690126": { + "message": "resumeTopActivityLocked: Resumed %s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-532081937": { "message": " Commit activity becoming invisible: %s", "level": "VERBOSE", "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, + "-527683022": { + "message": "resumeTopActivityLocked: Skip resume: some activity pausing.", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-519504830": { "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s isEntrance=%b Callers=%s", "level": "VERBOSE", @@ -1117,6 +1417,18 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayRotation.java" }, + "-427457280": { + "message": "App died while pausing: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, + "-417514857": { + "message": "Key dispatch not paused for screen off", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-415865166": { "message": "findFocusedWindow: Found new focus @ %s", "level": "VERBOSE", @@ -1135,6 +1447,18 @@ "group": "WM_DEBUG_CONTAINERS", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "-401029526": { + "message": "%s: caller %d does not hold REAL_GET_TASKS; limiting output", + "level": "WARN", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" + }, + "-399343789": { + "message": "Skipping %s: different user", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "-395922585": { "message": "InsetsSource setWin %s", "level": "DEBUG", @@ -1183,6 +1507,12 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/WindowStateAnimator.java" }, + "-332679827": { + "message": "resumeNextFocusableActivityWhenStackIsEmpty: %s, go home", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-324085783": { "message": "SURFACE CROP %s: %s", "level": "INFO", @@ -1225,12 +1555,30 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, + "-300896109": { + "message": "moveTaskToStack: moving task=%d to stackId=%d toTop=%b", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" + }, + "-279436615": { + "message": "Moving to PAUSING: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-272719931": { "message": "startLockTaskModeLocked: %s", "level": "WARN", "group": "WM_DEBUG_LOCKTASK", "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" }, + "-262984451": { + "message": "Relaunch failed %s", + "level": "INFO", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-260960989": { "message": "Removing and adding activity %s to stack at top callers=%s", "level": "INFO", @@ -1249,6 +1597,12 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "-234244777": { + "message": "Activity config changed during resume: %s, new next: %s", + "level": "INFO", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-198463978": { "message": "updateRotationUnchecked: alwaysSendConfiguration=%b forceRelayout=%b", "level": "VERBOSE", @@ -1273,6 +1627,12 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimationController.java" }, + "-172326720": { + "message": "Saving icicle of %s: %s", + "level": "INFO", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-168799453": { "message": "Allowing features %d:0x%s", "level": "WARN", @@ -1291,6 +1651,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/AppTransitionController.java" }, + "-118786523": { + "message": "Resume failed; resetting state to %s: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "-116086365": { "message": "******************** ENABLING SCREEN!", "level": "INFO", @@ -1351,6 +1717,12 @@ "group": "WM_SHOW_TRANSACTIONS", "at": "com\/android\/server\/wm\/WindowSurfaceController.java" }, + "-21399771": { + "message": "activity %s already destroying, skipping request with reason:%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "-7343917": { "message": "onAnimationFinished(): targetStack=%s targetActivity=%s mRestoreTargetBehindStack=%s", "level": "DEBUG", @@ -1411,6 +1783,12 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "51927339": { + "message": "Skipping %s: voice session", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "73987756": { "message": "ControlAdapter onAnimationCancelled mSource: %s mControlTarget: %s", "level": "INFO", @@ -1429,12 +1807,24 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimationController.java" }, + "86989930": { + "message": "setTaskWindowingMode: moving task=%d to windowingMode=%d toTop=%b", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.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", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "95216706": { "message": "hideIme target: %s ", "level": "DEBUG", @@ -1537,6 +1927,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/AppTransitionController.java" }, + "189628502": { + "message": "Moving to STOPPING: %s (stop requested)", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "194124419": { "message": "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d", "level": "DEBUG", @@ -1657,6 +2053,12 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimationController.java" }, + "306524472": { + "message": "Stop failed; moving to STOPPED: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "309039362": { "message": "SURFACE MATRIX [%f,%f,%f,%f]: %s", "level": "INFO", @@ -1729,6 +2131,12 @@ "group": "WM_DEBUG_FOCUS", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "397382873": { + "message": "Moving to PAUSED: %s %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "399841913": { "message": "SURFACE RECOVER DESTROY: %s", "level": "INFO", @@ -1783,6 +2191,12 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimation.java" }, + "485170982": { + "message": "Not finishing noHistory %s on stop because we're just sleeping", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "487621047": { "message": "DisplayArea vanished name=%s", "level": "VERBOSE", @@ -1849,6 +2263,12 @@ "group": "WM_SHOW_TRANSACTIONS", "at": "com\/android\/server\/wm\/WindowSurfaceController.java" }, + "579298675": { + "message": "Moving to DESTROYED: %s (removed from history)", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "585096182": { "message": "SURFACE isColorSpaceAgnostic=%b: %s", "level": "INFO", @@ -1969,6 +2389,12 @@ "group": "WM_DEBUG_SCREEN_ON", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "674932310": { + "message": "Setting Intent of %s to target %s", + "level": "VERBOSE", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/Task.java" + }, "685047360": { "message": "Resizing window %s", "level": "VERBOSE", @@ -1993,12 +2419,24 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "709500946": { + "message": "resumeTopActivityLocked: Skip resume: need to start pausing", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "715749922": { "message": "Allowlisting %d:%s", "level": "WARN", "group": "WM_DEBUG_LOCKTASK", "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" }, + "726205185": { + "message": "Moving to DESTROYED: %s (destroy skipped)", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "736692676": { "message": "Config is relaunching %s", "level": "VERBOSE", @@ -2083,6 +2521,12 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimation.java" }, + "864551564": { + "message": "Launch on display check: disallow activity embedding without permission.", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "869266572": { "message": "Removing activity %s from stack, reason= %s callers=%s", "level": "INFO", @@ -2101,12 +2545,30 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, + "875196661": { + "message": "Skipping stack: (mismatch activity\/stack) %s", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/TaskDisplayArea.java" + }, "892244061": { "message": "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d", "level": "INFO", "group": "WM_DEBUG_SCREEN_ON", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "895158150": { + "message": "allPausedActivitiesComplete: r=%s state=%s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, + "897964776": { + "message": "Complete pause: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "898863925": { "message": "Attempted to add QS dialog window with unknown token %s. Aborting.", "level": "WARN", @@ -2161,6 +2623,12 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, + "988389910": { + "message": "resumeTopActivityLocked: Pausing %s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "996960396": { "message": "Starting Transition %d", "level": "VERBOSE", @@ -2173,12 +2641,30 @@ "group": "WM_DEBUG_SYNC_ENGINE", "at": "com\/android\/server\/wm\/BLASTSyncEngine.java" }, + "1001509841": { + "message": "Auto-PIP allowed, entering PIP mode directly: %s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "1001904964": { "message": "***** BOOT TIMEOUT: forcing display enabled", "level": "WARN", "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "1015542198": { + "message": "Launch on display check: displayId=%d callingPid=%d callingUid=%d", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, + "1023413388": { + "message": "Finish waiting for pause of: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "1040675582": { "message": "Can't report activity configuration update - client not running, activityRecord=%s", "level": "WARN", @@ -2191,6 +2677,12 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "1047769218": { + "message": "Finishing activity r=%s, result=%d, data=%s, reason=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "1049367566": { "message": "Sending to proc %s new config %s", "level": "VERBOSE", @@ -2203,6 +2695,12 @@ "group": "WM_DEBUG_ADD_REMOVE", "at": "com\/android\/server\/wm\/WindowState.java" }, + "1068803972": { + "message": "Activity paused: token=%s, timeout=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "1073230342": { "message": "startAnimation", "level": "DEBUG", @@ -2221,6 +2719,12 @@ "group": "WM_SHOW_SURFACE_ALLOC", "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java" }, + "1098891625": { + "message": "realStartActivityLocked: Skipping start of r=%s some activities pausing...", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "1112047265": { "message": "finishDrawingWindow: %s mDrawState=%s", "level": "DEBUG", @@ -2239,6 +2743,12 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "1126328412": { + "message": "Scheduling idle now: forceIdle=%b immediate=%b", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "1140424002": { "message": "Finished screen turning on...", "level": "INFO", @@ -2263,12 +2773,24 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, + "1192413464": { + "message": "Comparing existing cls=%s \/aff=%s to new cls=%s \/aff=%s", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "1208313423": { "message": "addWindowToken: Attempted to add token: %s for non-exiting displayId=%d", "level": "WARN", "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "1217926207": { + "message": "Activity not running, resuming next.", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "1219600119": { "message": "addWindow: win=%s Callers=%s", "level": "DEBUG", @@ -2305,12 +2827,24 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "1270792394": { + "message": "Resumed after relaunch %s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "1288731814": { "message": "WindowState.hideLw: setting mFocusMayChange true", "level": "INFO", "group": "WM_DEBUG_FOCUS_LIGHT", "at": "com\/android\/server\/wm\/WindowState.java" }, + "1316533291": { + "message": "State movement: %s from:%s to:%s reason:%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "1325649102": { "message": "Bad requesting window %s", "level": "WARN", @@ -2353,6 +2887,12 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" }, + "1364126018": { + "message": "Resumed activity; dropping state of: %s", + "level": "INFO", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "1364498663": { "message": "notifyAppResumed: wasStopped=%b %s", "level": "VERBOSE", @@ -2503,6 +3043,12 @@ "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/WindowState.java" }, + "1557732761": { + "message": "For Intent %s bringing to top: %s", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "1563755163": { "message": "Permission Denial: %s from pid=%d, uid=%d requires %s", "level": "WARN", @@ -2527,12 +3073,24 @@ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/WindowContainer.java" }, + "1585450696": { + "message": "resumeTopActivityLocked: Restarting %s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "1589610525": { "message": "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: anim=%s transit=%s isEntrance=true Callers=%s", "level": "VERBOSE", "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/AppTransition.java" }, + "1610646518": { + "message": "Enqueueing pending finish: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "1628345525": { "message": "Now opening app %s", "level": "VERBOSE", @@ -2593,6 +3151,18 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "1696210756": { + "message": "Launch on display check: allow launch on public display", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, + "1706082525": { + "message": "Stopping %s: nowVisible=%b animating=%b finishing=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "1720229827": { "message": "Creating animation bounds layer", "level": "INFO", @@ -2659,6 +3229,12 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/TransitionController.java" }, + "1804435108": { + "message": "allResumedActivitiesIdle: stack=%d %s not idle", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "1822843721": { "message": "Aborted starting %s: startingData=%s", "level": "VERBOSE", @@ -2695,6 +3271,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "1837992242": { + "message": "Executing finish of activity: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "1853793312": { "message": "Notify removed startingWindow %s", "level": "VERBOSE", @@ -2713,12 +3295,24 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "1884961873": { + "message": "Sleep still need to stop %d activities", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "1891501279": { "message": "cancelAnimation(): reason=%s", "level": "DEBUG", "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, + "1894239744": { + "message": "Enqueueing pending pause: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/Task.java" + }, "1903353011": { "message": "notifyAppStopped: %s", "level": "VERBOSE", @@ -2749,6 +3343,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayRotation.java" }, + "1947936538": { + "message": "Found matching class!", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "1964565370": { "message": "Starting remote animation", "level": "INFO", @@ -2827,12 +3427,24 @@ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/AppTransition.java" }, + "2034714267": { + "message": "Launch on display check: allow launch for caller present on the display", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityStackSupervisor.java" + }, "2034780299": { "message": "CHECK_IF_BOOT_ANIMATION_FINISHED:", "level": "INFO", "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "2039056415": { + "message": "Found matching affinity candidate!", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/RootWindowContainer.java" + }, "2045641491": { "message": "Checking %d opening apps (frozen=%b timeout=%b)...", "level": "VERBOSE", @@ -2881,6 +3493,12 @@ "group": "WM_DEBUG_ADD_REMOVE", "at": "com\/android\/server\/wm\/WindowState.java" }, + "2117696413": { + "message": "moveTaskToFront: moving taskId=%d", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" + }, "2119122320": { "message": "setInputMethodTarget %s", "level": "INFO", @@ -2964,12 +3582,18 @@ "WM_DEBUG_STARTING_WINDOW": { "tag": "WindowManager" }, + "WM_DEBUG_STATES": { + "tag": "WindowManager" + }, "WM_DEBUG_SWITCH": { "tag": "WindowManager" }, "WM_DEBUG_SYNC_ENGINE": { "tag": "WindowManager" }, + "WM_DEBUG_TASKS": { + "tag": "WindowManager" + }, "WM_DEBUG_WINDOW_MOVEMENT": { "tag": "WindowManager" }, diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/CompatChangeChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/CompatChangeChecker.java new file mode 100644 index 000000000000..9c84f50b76bb --- /dev/null +++ b/errorprone/java/com/google/errorprone/bugpatterns/android/CompatChangeChecker.java @@ -0,0 +1,125 @@ +/* + * 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.google.errorprone.bugpatterns.android; + +import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; +import static com.google.errorprone.bugpatterns.android.TargetSdkChecker.binaryTreeExact; +import static com.google.errorprone.matchers.FieldMatchers.anyFieldInClass; +import static com.google.errorprone.matchers.FieldMatchers.staticField; +import static com.google.errorprone.matchers.Matchers.allOf; +import static com.google.errorprone.matchers.Matchers.anyOf; +import static com.google.errorprone.matchers.Matchers.anything; +import static com.google.errorprone.matchers.Matchers.kindIs; +import static com.google.errorprone.matchers.Matchers.not; + +import com.google.auto.service.AutoService; +import com.google.errorprone.BugPattern; +import com.google.errorprone.VisitorState; +import com.google.errorprone.bugpatterns.BugChecker; +import com.google.errorprone.bugpatterns.BugChecker.BinaryTreeMatcher; +import com.google.errorprone.matchers.Description; +import com.google.errorprone.matchers.Matcher; +import com.sun.source.tree.BinaryTree; +import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.Tree.Kind; + +/** + * Each SDK level often has dozens of different behavior changes, which can be + * difficult for large app developers to adjust to during preview or beta + * releases. For this reason, {@code android.app.compat.CompatChanges} was + * introduced as a new best-practice for adding behavior changes. + * <p> + * During a preview or beta release, developers can temporarily opt-out of each + * individual change to aid debugging. This opt-out is only available during + * preview of beta releases, and cannot be adjusted on finalized builds. + */ +@AutoService(BugChecker.class) +@BugPattern( + name = "AndroidFrameworkCompatChange", + summary = "Verifies that behavior changes use the modern compatibility framework", + severity = WARNING) +public final class CompatChangeChecker extends BugChecker implements BinaryTreeMatcher { + private static final Matcher<ExpressionTree> VERSION_CODE = + anyFieldInClass("android.os.Build.VERSION_CODES"); + + // Ship has already sailed on these SDK levels; not worth fixing + private static final Matcher<ExpressionTree> LEGACY_VERSION_CODE = anyOf( + staticField("android.os.Build.VERSION_CODES", "BASE"), + staticField("android.os.Build.VERSION_CODES", "BASE_1_1"), + staticField("android.os.Build.VERSION_CODES", "CUPCAKE"), + staticField("android.os.Build.VERSION_CODES", "DONUT"), + staticField("android.os.Build.VERSION_CODES", "ECLAIR"), + staticField("android.os.Build.VERSION_CODES", "ECLAIR_0_1"), + staticField("android.os.Build.VERSION_CODES", "ECLAIR_MR1"), + staticField("android.os.Build.VERSION_CODES", "FROYO"), + staticField("android.os.Build.VERSION_CODES", "GINGERBREAD"), + staticField("android.os.Build.VERSION_CODES", "GINGERBREAD_MR1"), + staticField("android.os.Build.VERSION_CODES", "HONEYCOMB"), + staticField("android.os.Build.VERSION_CODES", "HONEYCOMB_MR1"), + staticField("android.os.Build.VERSION_CODES", "HONEYCOMB_MR2"), + staticField("android.os.Build.VERSION_CODES", "ICE_CREAM_SANDWICH"), + staticField("android.os.Build.VERSION_CODES", "ICE_CREAM_SANDWICH_MR1"), + staticField("android.os.Build.VERSION_CODES", "JELLY_BEAN"), + staticField("android.os.Build.VERSION_CODES", "JELLY_BEAN_MR1"), + staticField("android.os.Build.VERSION_CODES", "JELLY_BEAN_MR2"), + staticField("android.os.Build.VERSION_CODES", "KITKAT"), + staticField("android.os.Build.VERSION_CODES", "KITKAT_WATCH"), + staticField("android.os.Build.VERSION_CODES", "L"), + staticField("android.os.Build.VERSION_CODES", "LOLLIPOP"), + staticField("android.os.Build.VERSION_CODES", "LOLLIPOP_MR1"), + staticField("android.os.Build.VERSION_CODES", "M"), + staticField("android.os.Build.VERSION_CODES", "N"), + staticField("android.os.Build.VERSION_CODES", "N_MR1"), + staticField("android.os.Build.VERSION_CODES", "O"), + staticField("android.os.Build.VERSION_CODES", "O_MR1"), + staticField("android.os.Build.VERSION_CODES", "P"), + staticField("android.os.Build.VERSION_CODES", "Q"), + staticField("android.os.Build.VERSION_CODES", "R")); + + private static final Matcher<ExpressionTree> R_VERSION_CODE = + staticField("android.os.Build.VERSION_CODES", "R"); + + private static final Matcher<ExpressionTree> CUR_DEVELOPMENT_VERSION_CODE = + staticField("android.os.Build.VERSION_CODES", "CUR_DEVELOPMENT"); + + private static final Matcher<ExpressionTree> MODERN_VERSION_CODE = + allOf(VERSION_CODE, not(LEGACY_VERSION_CODE), not(CUR_DEVELOPMENT_VERSION_CODE)); + + private static final Matcher<ExpressionTree> BOOLEAN_OPERATOR = anyOf( + kindIs(Kind.LESS_THAN), kindIs(Kind.LESS_THAN_EQUAL), + kindIs(Kind.GREATER_THAN), kindIs(Kind.GREATER_THAN_EQUAL), + kindIs(Kind.EQUAL_TO), kindIs(Kind.NOT_EQUAL_TO)); + + private static final Matcher<BinaryTree> INVALID = anyOf( + allOf(BOOLEAN_OPERATOR, binaryTreeExact(MODERN_VERSION_CODE, anything())), + allOf(BOOLEAN_OPERATOR, binaryTreeExact(anything(), MODERN_VERSION_CODE)), + allOf(kindIs(Kind.GREATER_THAN), binaryTreeExact(anything(), R_VERSION_CODE)), + allOf(kindIs(Kind.LESS_THAN), binaryTreeExact(R_VERSION_CODE, anything()))); + + @Override + public Description matchBinary(BinaryTree tree, VisitorState state) { + if (INVALID.matches(tree, state)) { + return buildDescription(tree) + .setMessage("Behavior changes should use CompatChanges.isChangeEnabled() " + + "instead of direct SDK checks to ease developer transitions; " + + "see go/compat-framework for more details") + .build(); + + } + return Description.NO_MATCH; + } +} diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java index 4f1af3e9bea2..3a1bc1eeb9ae 100644 --- a/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java +++ b/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java @@ -18,6 +18,7 @@ package com.google.errorprone.bugpatterns.android; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.bugpatterns.android.UidChecker.getFlavor; +import static com.google.errorprone.matchers.Matchers.anyOf; import static com.google.errorprone.matchers.Matchers.enclosingClass; import static com.google.errorprone.matchers.Matchers.hasAnnotation; import static com.google.errorprone.matchers.Matchers.instanceMethod; @@ -60,8 +61,13 @@ public final class ContextUserIdChecker extends BugChecker implements MethodInvo private static final Matcher<ExpressionTree> BINDER_CALL = methodInvocation( instanceMethod().onDescendantOf("android.os.IInterface").withAnyName()); - private static final Matcher<ExpressionTree> GET_USER_ID_CALL = methodInvocation( - instanceMethod().onDescendantOf("android.content.Context").named("getUserId")); + private static final Matcher<ExpressionTree> GET_USER_ID_CALL = methodInvocation(anyOf( + instanceMethod().onExactClass("android.app.admin.DevicePolicyManager") + .named("myUserId"), + instanceMethod().onExactClass("android.content.pm.ShortcutManager") + .named("injectMyUserId"), + instanceMethod().onDescendantOf("android.content.Context") + .named("getUserId"))); private static final Matcher<ExpressionTree> USER_ID_FIELD = new Matcher<ExpressionTree>() { @Override diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemChecker.java index 48123abd26cb..130b256e6622 100644 --- a/errorprone/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemChecker.java +++ b/errorprone/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemChecker.java @@ -17,11 +17,14 @@ package com.google.errorprone.bugpatterns.android; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; +import static com.google.errorprone.matchers.Matchers.allOf; +import static com.google.errorprone.matchers.Matchers.contains; import static com.google.errorprone.matchers.Matchers.enclosingClass; import static com.google.errorprone.matchers.Matchers.hasAnnotation; import static com.google.errorprone.matchers.Matchers.instanceMethod; import static com.google.errorprone.matchers.Matchers.isSameType; import static com.google.errorprone.matchers.Matchers.methodInvocation; +import static com.google.errorprone.matchers.Matchers.not; import static com.google.errorprone.matchers.Matchers.throwStatement; import static com.google.errorprone.matchers.Matchers.variableType; @@ -29,13 +32,17 @@ import com.google.auto.service.AutoService; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; import com.google.errorprone.bugpatterns.BugChecker; -import com.google.errorprone.bugpatterns.BugChecker.CatchTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.TryTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.matchers.Matcher; +import com.google.errorprone.predicates.TypePredicate; import com.sun.source.tree.CatchTree; +import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.StatementTree; import com.sun.source.tree.Tree; +import com.sun.source.tree.TryTree; import com.sun.source.tree.VariableTree; +import com.sun.tools.javac.code.Type; import java.util.List; @@ -54,9 +61,17 @@ import java.util.List; name = "AndroidFrameworkRethrowFromSystem", summary = "Verifies that system_server calls use rethrowFromSystemServer()", severity = WARNING) -public final class RethrowFromSystemChecker extends BugChecker implements CatchTreeMatcher { +public final class RethrowFromSystemChecker extends BugChecker implements TryTreeMatcher { private static final Matcher<Tree> INSIDE_MANAGER = enclosingClass(hasAnnotation("android.annotation.SystemService")); + + // Purposefully exclude telephony Binder interfaces, since we know they + // always run under the separate AID_RADIO + private static final Matcher<ExpressionTree> SYSTEM_BINDER_CALL = methodInvocation(allOf( + instanceMethod().onDescendantOf("android.os.IInterface").withAnyName(), + not(instanceMethod().onClass(inPackage("com.android.internal.telephony"))), + not(instanceMethod().onClass(inPackage("com.android.internal.telecom"))))); + private static final Matcher<VariableTree> REMOTE_EXCEPTION = variableType( isSameType("android.os.RemoteException")); private static final Matcher<StatementTree> RETHROW_FROM_SYSTEM = throwStatement( @@ -64,17 +79,33 @@ public final class RethrowFromSystemChecker extends BugChecker implements CatchT .named("rethrowFromSystemServer"))); @Override - public Description matchCatch(CatchTree tree, VisitorState state) { + public Description matchTry(TryTree tree, VisitorState state) { if (INSIDE_MANAGER.matches(tree, state) - && REMOTE_EXCEPTION.matches(tree.getParameter(), state)) { - final List<? extends StatementTree> statements = tree.getBlock().getStatements(); - if (statements.size() != 1 || !RETHROW_FROM_SYSTEM.matches(statements.get(0), state)) { - return buildDescription(tree) - .setMessage("Must contain single " - + "'throw e.rethrowFromSystemServer()' statement") - .build(); + && contains(ExpressionTree.class, SYSTEM_BINDER_CALL) + .matches(tree.getBlock(), state)) { + for (CatchTree catchTree : tree.getCatches()) { + if (REMOTE_EXCEPTION.matches(catchTree.getParameter(), state)) { + final List<? extends StatementTree> statements = catchTree.getBlock() + .getStatements(); + if (statements.size() != 1 + || !RETHROW_FROM_SYSTEM.matches(statements.get(0), state)) { + return buildDescription(catchTree) + .setMessage("Must contain single " + + "'throw e.rethrowFromSystemServer()' statement") + .build(); + } + } } } return Description.NO_MATCH; } + + private static TypePredicate inPackage(final String filter) { + return new TypePredicate() { + @Override + public boolean apply(Type type, VisitorState state) { + return type.tsym.packge().fullname.toString().startsWith(filter); + } + }; + } } diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/TargetSdkChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/TargetSdkChecker.java index 232cf3f0d677..e1ebf42fec19 100644 --- a/errorprone/java/com/google/errorprone/bugpatterns/android/TargetSdkChecker.java +++ b/errorprone/java/com/google/errorprone/bugpatterns/android/TargetSdkChecker.java @@ -89,7 +89,7 @@ public final class TargetSdkChecker extends BugChecker implements BinaryTreeMatc return Description.NO_MATCH; } - private static Matcher<BinaryTree> binaryTreeExact(Matcher<ExpressionTree> left, + static Matcher<BinaryTree> binaryTreeExact(Matcher<ExpressionTree> left, Matcher<ExpressionTree> right) { return new Matcher<BinaryTree>() { @Override diff --git a/errorprone/java/com/google/errorprone/matchers/FieldMatchers.java b/errorprone/java/com/google/errorprone/matchers/FieldMatchers.java index 46f0fb2e534c..08969d60671a 100644 --- a/errorprone/java/com/google/errorprone/matchers/FieldMatchers.java +++ b/errorprone/java/com/google/errorprone/matchers/FieldMatchers.java @@ -36,7 +36,8 @@ public final class FieldMatchers { return new FieldReferenceMatcher() { @Override boolean classIsAppropriate(ClassSymbol classSymbol) { - return classSymbol.getQualifiedName().contentEquals(className); + return classSymbol != null + && classSymbol.getQualifiedName().contentEquals(className); } @Override @@ -50,12 +51,14 @@ public final class FieldMatchers { return new FieldReferenceMatcher() { @Override boolean classIsAppropriate(ClassSymbol classSymbol) { - return classSymbol.getQualifiedName().contentEquals(className); + return classSymbol != null + && classSymbol.getQualifiedName().contentEquals(className); } @Override boolean fieldSymbolIsAppropriate(Symbol symbol) { - return symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName); + return symbol != null + && symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName); } }; } @@ -64,12 +67,14 @@ public final class FieldMatchers { return new FieldReferenceMatcher() { @Override boolean classIsAppropriate(ClassSymbol classSymbol) { - return classSymbol.getQualifiedName().contentEquals(className); + return classSymbol != null + && classSymbol.getQualifiedName().contentEquals(className); } @Override boolean fieldSymbolIsAppropriate(Symbol symbol) { - return !symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName); + return symbol != null + && !symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName); } }; } diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/CompatChangeCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/CompatChangeCheckerTest.java new file mode 100644 index 000000000000..4625d43a1648 --- /dev/null +++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/CompatChangeCheckerTest.java @@ -0,0 +1,102 @@ +/* + * 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.google.errorprone.bugpatterns.android; + +import com.google.errorprone.CompilationTestHelper; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class CompatChangeCheckerTest { + private CompilationTestHelper compilationHelper; + + @Before + public void setUp() { + compilationHelper = CompilationTestHelper.newInstance( + CompatChangeChecker.class, getClass()); + } + + @Test + public void testSimple() { + compilationHelper + .addSourceFile("/android/os/Build.java") + .addSourceLines("Example.java", + "import android.os.Build;", + "public class Example {", + " void test(int targetSdkVersion) {", + " // BUG: Diagnostic contains:", + " if (targetSdkVersion < Build.VERSION_CODES.S) { }", + " // BUG: Diagnostic contains:", + " if (targetSdkVersion <= Build.VERSION_CODES.S) { }", + " // BUG: Diagnostic contains:", + " if (targetSdkVersion > Build.VERSION_CODES.S) { }", + " // BUG: Diagnostic contains:", + " if (targetSdkVersion >= Build.VERSION_CODES.S) { }", + " // BUG: Diagnostic contains:", + " if (targetSdkVersion == Build.VERSION_CODES.S) { }", + " // BUG: Diagnostic contains:", + " if (targetSdkVersion != Build.VERSION_CODES.S) { }", + " }", + "}") + .doTest(); + } + + @Test + public void testObscure() { + compilationHelper + .addSourceFile("/android/os/Build.java") + .addSourceLines("Example.java", + "import android.os.Build;", + "import static android.os.Build.VERSION_CODES.S;", + "public class Example {", + " void test(int targetSdkVersion) {", + " // BUG: Diagnostic contains:", + " boolean indirect = S >= targetSdkVersion;", + " // BUG: Diagnostic contains:", + " if (targetSdkVersion > Build.VERSION_CODES.R) { }", + " if (targetSdkVersion >= Build.VERSION_CODES.R) { }", + " if (targetSdkVersion < Build.VERSION_CODES.R) { }", + " if (targetSdkVersion <= Build.VERSION_CODES.R) { }", + " // BUG: Diagnostic contains:", + " if (Build.VERSION_CODES.R < targetSdkVersion) { }", + " if (Build.VERSION_CODES.R <= targetSdkVersion) { }", + " if (Build.VERSION_CODES.R > targetSdkVersion) { }", + " if (Build.VERSION_CODES.R >= targetSdkVersion) { }", + " }", + "}") + .doTest(); + } + + @Test + public void testIgnored() { + compilationHelper + .addSourceFile("/android/os/Build.java") + .addSourceLines("Example.java", + "import android.os.Build;", + "public class Example {", + " void test(int targetSdkVersion) {", + " if (targetSdkVersion < Build.VERSION_CODES.DONUT) { }", + " String result = \"test\" + Build.VERSION_CODES.S;", + " if (targetSdkVersion != Build.VERSION_CODES.CUR_DEVELOPMENT) { }", + " }", + "}") + .doTest(); + } +} diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java index c0b8cd745afc..c8772306a59b 100644 --- a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java +++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java @@ -92,4 +92,56 @@ public class ContextUserIdCheckerTest { "}") .doTest(); } + + @Test + public void testDevicePolicyManager() { + compilationHelper + .addSourceFile("/android/annotation/SystemService.java") + .addSourceFile("/android/content/Context.java") + .addSourceFile("/android/foo/IFooService.java") + .addSourceFile("/android/os/IInterface.java") + .addSourceFile("/android/os/UserHandle.java") + .addSourceFile("/android/os/RemoteException.java") + .addSourceLines("DevicePolicyManager.java", + "package android.app.admin;", + "import android.annotation.SystemService;", + "import android.content.Context;", + "import android.foo.IFooService;", + "import android.os.UserHandle;", + "import android.os.RemoteException;", + "@SystemService(\"dp\") public class DevicePolicyManager {", + " IFooService mService;", + " int myUserId() { return 0; }", + " void bar() throws RemoteException {", + " mService.baz(null, myUserId());", + " }", + "}") + .doTest(); + } + + @Test + public void testShortcutManager() { + compilationHelper + .addSourceFile("/android/annotation/SystemService.java") + .addSourceFile("/android/content/Context.java") + .addSourceFile("/android/foo/IFooService.java") + .addSourceFile("/android/os/IInterface.java") + .addSourceFile("/android/os/UserHandle.java") + .addSourceFile("/android/os/RemoteException.java") + .addSourceLines("ShortcutManager.java", + "package android.content.pm;", + "import android.annotation.SystemService;", + "import android.content.Context;", + "import android.foo.IFooService;", + "import android.os.UserHandle;", + "import android.os.RemoteException;", + "@SystemService(\"shortcut\") public class ShortcutManager {", + " IFooService mService;", + " int injectMyUserId() { return 0; }", + " void bar() throws RemoteException {", + " mService.baz(null, injectMyUserId());", + " }", + "}") + .doTest(); + } } diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemCheckerTest.java index 32efbf206a45..0943bd65c06f 100644 --- a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemCheckerTest.java +++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemCheckerTest.java @@ -105,4 +105,27 @@ public class RethrowFromSystemCheckerTest { "}") .doTest(); } + + @Test + public void testTelephony() { + compilationHelper + .addSourceFile("/android/annotation/SystemService.java") + .addSourceFile("/com/android/internal/telephony/ITelephony.java") + .addSourceFile("/android/os/IInterface.java") + .addSourceFile("/android/os/RemoteException.java") + .addSourceLines("TelephonyManager.java", + "import android.annotation.SystemService;", + "import com.android.internal.telephony.ITelephony;", + "import android.os.RemoteException;", + "@SystemService(\"telephony\") public class TelephonyManager {", + " ITelephony mService;", + " void bar() {", + " try {", + " mService.bar();", + " } catch (RemoteException ignored) {", + " }", + " }", + "}") + .doTest(); + } } diff --git a/errorprone/tests/res/android/os/Build.java b/errorprone/tests/res/android/os/Build.java index bbf7ef2172b5..2d354e2ac370 100644 --- a/errorprone/tests/res/android/os/Build.java +++ b/errorprone/tests/res/android/os/Build.java @@ -18,6 +18,9 @@ package android.os; public class Build { public static class VERSION_CODES { + public static final int CUR_DEVELOPMENT = 10000; public static final int DONUT = 4; + public static final int R = 30; + public static final int S = CUR_DEVELOPMENT; } } diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/LibpacInterface.java b/errorprone/tests/res/com/android/internal/telephony/ITelephony.java index 103ef7811ff0..61c4dd561b0b 100644 --- a/packages/services/PacProcessor/src/com/android/pacprocessor/LibpacInterface.java +++ b/errorprone/tests/res/com/android/internal/telephony/ITelephony.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,22 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.pacprocessor; -/** - * Common interface for both Android's and WebView's implementation of PAC processor. - * - * @hide - */ -interface LibpacInterface { - default boolean startPacSupport() { - return true; - } +package com.android.internal.telephony; - default boolean stopPacSupport() { - return true; - } +import android.os.RemoteException; - boolean setCurrentProxyScript(String script); - String makeProxyRequest(String url, String host); +public interface ITelephony extends android.os.IInterface { + public void bar() throws RemoteException; } diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java index e1a17957ebd7..21b8fc6f1c80 100644 --- a/graphics/java/android/graphics/fonts/Font.java +++ b/graphics/java/android/graphics/fonts/Font.java @@ -516,7 +516,7 @@ public final class Font { mLocaleList = localeList; synchronized (MAP_LOCK) { - FONT_PTR_MAP.append(mNativePtr, new WeakReference<>(this)); + FONT_PTR_MAP.append(nGetNativeFontPtr(mNativePtr), new WeakReference<>(this)); } } @@ -716,4 +716,7 @@ public final class Font { @FastNative private static native float nGetFontMetrics(long font, long paint, Paint.FontMetrics metrics); + + @CriticalNative + private static native long nGetNativeFontPtr(long ptr); } 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 8f496d01c83b..f6edc073ac4f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -66,10 +66,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { public ShellTaskOrganizer(SyncTransactionQueue syncQueue, TransactionPool transactionPool, ShellExecutor mainExecutor, ShellExecutor animExecutor) { - super(); - addListener(new FullscreenTaskListener(syncQueue), WINDOWING_MODE_FULLSCREEN); - mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor); - if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions); + this(null, syncQueue, transactionPool, mainExecutor, animExecutor); } @VisibleForTesting diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index bb501fb050e6..e236d24334b3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -88,7 +88,7 @@ import java.util.function.Consumer; * This class is also responsible for general resize/offset PiP operations within SysUI component, * see also {@link PipMotionHelper}. */ -public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganizer.TaskListener, +public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, DisplayController.OnDisplaysChangedListener { private static final String TAG = PipTaskOrganizer.class.getSimpleName(); private static final boolean DEBUG = false; diff --git a/libs/hwui/hwui/MinikinSkia.h b/libs/hwui/hwui/MinikinSkia.h index 298967689cd9..77a21428f36a 100644 --- a/libs/hwui/hwui/MinikinSkia.h +++ b/libs/hwui/hwui/MinikinSkia.h @@ -49,6 +49,8 @@ public: void GetFontExtent(minikin::MinikinExtent* extent, const minikin::MinikinPaint& paint, const minikin::FontFakery& fakery) const override; + const std::string& GetFontPath() const override { return mFilePath; } + SkTypeface* GetSkTypeface() const; sk_sp<SkTypeface> RefSkTypeface() const; diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp index ccc328c702db..03f1d62625f1 100644 --- a/libs/hwui/hwui/Typeface.cpp +++ b/libs/hwui/hwui/Typeface.cpp @@ -188,7 +188,7 @@ void Typeface::setRobotoTypefaceForTest() { std::shared_ptr<minikin::MinikinFont> font = std::make_shared<MinikinFontSkia>( std::move(typeface), data, st.st_size, kRobotoFont, 0, std::vector<minikin::FontVariation>()); - std::vector<minikin::Font> fonts; + std::vector<std::shared_ptr<minikin::Font>> fonts; fonts.push_back(minikin::Font::Builder(font).build()); std::shared_ptr<minikin::FontCollection> collection = std::make_shared<minikin::FontCollection>( diff --git a/libs/hwui/jni/FontFamily.cpp b/libs/hwui/jni/FontFamily.cpp index 68eaa0a3ca54..2e85840cad99 100644 --- a/libs/hwui/jni/FontFamily.cpp +++ b/libs/hwui/jni/FontFamily.cpp @@ -42,7 +42,7 @@ struct NativeFamilyBuilder { : langId(langId), variant(static_cast<minikin::FamilyVariant>(variant)) {} uint32_t langId; minikin::FamilyVariant variant; - std::vector<minikin::Font> fonts; + std::vector<std::shared_ptr<minikin::Font>> fonts; std::vector<minikin::FontVariation> axes; }; diff --git a/libs/hwui/jni/FontUtils.h b/libs/hwui/jni/FontUtils.h index f93a0daaf748..ba4e56e4c7f7 100644 --- a/libs/hwui/jni/FontUtils.h +++ b/libs/hwui/jni/FontUtils.h @@ -19,6 +19,7 @@ #include <jni.h> #include <memory> +#include <utility> #include <minikin/Font.h> @@ -34,18 +35,10 @@ struct FontFamilyWrapper { }; struct FontWrapper { - FontWrapper(minikin::Font&& font) : font(std::move(font)) {} - minikin::Font font; + explicit FontWrapper(std::shared_ptr<minikin::Font>&& font) : font(font) {} + std::shared_ptr<minikin::Font> font; }; -// We assume FontWrapper's address is the same as underlying Font's address. -// This assumption is used for looking up Java font object from native address. -// The Font object can be created without Java's Font object but all Java's Font objects point to -// the native FontWrapper. So when looking up Java object from minikin::Layout which gives us Font -// address, we lookup Font Java object from Font address with assumption that it is the same as -// FontWrapper address. -static_assert(offsetof(FontWrapper, font) == 0); - // Utility wrapper for java.util.List class ListHelper { public: diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp index 0eb409557718..6bc318db1049 100644 --- a/libs/hwui/jni/fonts/Font.cpp +++ b/libs/hwui/jni/fonts/Font.cpp @@ -118,7 +118,7 @@ static jlong Font_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jo std::make_shared<MinikinFontSkia>(std::move(face), fontPtr, fontSize, std::string_view(fontPath.c_str(), fontPath.size()), ttcIndex, builder->axes); - minikin::Font font = minikin::Font::Builder(minikinFont).setWeight(weight) + std::shared_ptr<minikin::Font> font = minikin::Font::Builder(minikinFont).setWeight(weight) .setSlant(static_cast<minikin::FontStyle::Slant>(italic)).build(); return reinterpret_cast<jlong>(new FontWrapper(std::move(font))); } @@ -127,7 +127,7 @@ static jlong Font_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jo static jlong Font_Builder_clone(JNIEnv* env, jobject clazz, jlong fontPtr, jlong builderPtr, jint weight, jboolean italic, jint ttcIndex) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr); - MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font.typeface().get()); + MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get()); std::unique_ptr<NativeFontBuilder> builder(toBuilder(builderPtr)); // Reconstruct SkTypeface with different arguments from existing SkTypeface. @@ -148,8 +148,10 @@ static jlong Font_Builder_clone(JNIEnv* env, jobject clazz, jlong fontPtr, jlong minikinSkia->getFilePath(), minikinSkia->GetFontIndex(), builder->axes); - minikin::Font newFont = minikin::Font::Builder(newMinikinFont).setWeight(weight) - .setSlant(static_cast<minikin::FontStyle::Slant>(italic)).build(); + std::shared_ptr<minikin::Font> newFont = minikin::Font::Builder(newMinikinFont) + .setWeight(weight) + .setSlant(static_cast<minikin::FontStyle::Slant>(italic)) + .build(); return reinterpret_cast<jlong>(new FontWrapper(std::move(newFont))); } @@ -164,7 +166,7 @@ static jlong Font_Builder_getReleaseNativeFont(CRITICAL_JNI_PARAMS) { static jfloat Font_getGlyphBounds(JNIEnv* env, jobject, jlong fontHandle, jint glyphId, jlong paintHandle, jobject rect) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle); - MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font.typeface().get()); + MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get()); Paint* paint = reinterpret_cast<Paint*>(paintHandle); SkFont* skFont = &paint->getSkFont(); @@ -184,7 +186,7 @@ static jfloat Font_getGlyphBounds(JNIEnv* env, jobject, jlong fontHandle, jint g static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong paintHandle, jobject metricsObj) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle); - MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font.typeface().get()); + MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get()); Paint* paint = reinterpret_cast<Paint*>(paintHandle); SkFont* skFont = &paint->getSkFont(); @@ -200,11 +202,11 @@ static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong // Critical Native static jlong Font_getFontInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) { - FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle); - MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font.typeface().get()); + const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle); + MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get()); - uint64_t result = font->font.style().weight(); - result |= font->font.style().slant() == minikin::FontStyle::Slant::ITALIC ? 0x10000 : 0x00000; + uint64_t result = font->style().weight(); + result |= font->style().slant() == minikin::FontStyle::Slant::ITALIC ? 0x10000 : 0x00000; result |= ((static_cast<uint64_t>(minikinSkia->GetFontIndex())) << 32); result |= ((static_cast<uint64_t>(minikinSkia->GetAxes().size())) << 48); return result; @@ -212,13 +214,19 @@ static jlong Font_getFontInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) { // Critical Native static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle, jint index) { - FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle); - MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font.typeface().get()); + const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle); + MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get()); const minikin::FontVariation& var = minikinSkia->GetAxes().at(index); uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value); return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary); } +// Critical Native +static jlong Font_getNativeFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) { + FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle); + return reinterpret_cast<jlong>(font->font.get()); +} + /////////////////////////////////////////////////////////////////////////////// struct FontBufferWrapper { @@ -234,8 +242,8 @@ static void unrefBuffer(jlong nativePtr) { // Critical Native static jlong FontBufferHelper_refFontBuffer(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) { - FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle); - return reinterpret_cast<jlong>(new FontBufferWrapper(font->font.typeface())); + const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle); + return reinterpret_cast<jlong>(new FontBufferWrapper(font->typeface())); } // Fast Native @@ -266,6 +274,7 @@ static const JNINativeMethod gFontMethods[] = { { "nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F", (void*) Font_getFontMetrics }, { "nGetFontInfo", "(J)J", (void*) Font_getFontInfo }, { "nGetAxisInfo", "(JI)J", (void*) Font_getAxisInfo }, + { "nGetNativeFontPtr", "(J)J", (void*) Font_getNativeFontPtr }, }; static const JNINativeMethod gFontBufferHelperMethods[] = { diff --git a/libs/hwui/jni/fonts/FontFamily.cpp b/libs/hwui/jni/fonts/FontFamily.cpp index df619d9f1406..37e52766f2ef 100644 --- a/libs/hwui/jni/fonts/FontFamily.cpp +++ b/libs/hwui/jni/fonts/FontFamily.cpp @@ -30,7 +30,7 @@ namespace android { struct NativeFamilyBuilder { - std::vector<minikin::Font> fonts; + std::vector<std::shared_ptr<minikin::Font>> fonts; }; static inline NativeFamilyBuilder* toBuilder(jlong ptr) { diff --git a/libs/hwui/tests/unit/TypefaceTests.cpp b/libs/hwui/tests/unit/TypefaceTests.cpp index b5baafd3c2dc..5d2aa2ff83c9 100644 --- a/libs/hwui/tests/unit/TypefaceTests.cpp +++ b/libs/hwui/tests/unit/TypefaceTests.cpp @@ -59,7 +59,7 @@ std::shared_ptr<minikin::FontFamily> buildFamily(const char* fileName) { std::shared_ptr<minikin::MinikinFont> font = std::make_shared<MinikinFontSkia>(std::move(typeface), data, st.st_size, fileName, 0, std::vector<minikin::FontVariation>()); - std::vector<minikin::Font> fonts; + std::vector<std::shared_ptr<minikin::Font>> fonts; fonts.push_back(minikin::Font::Builder(font).build()); return std::make_shared<minikin::FontFamily>(std::move(fonts)); } diff --git a/location/java/android/location/util/identity/CallerIdentity.java b/location/java/android/location/util/identity/CallerIdentity.java index c32970f1bb04..e023aa1dcd22 100644 --- a/location/java/android/location/util/identity/CallerIdentity.java +++ b/location/java/android/location/util/identity/CallerIdentity.java @@ -150,6 +150,11 @@ public final class CallerIdentity { return mListenerId; } + /** Returns true if this represents a system identity. */ + public boolean isSystem() { + return mUid == Process.SYSTEM_UID; + } + /** * Adds this identity to the worksource supplied, or if not worksource is supplied, creates a * new worksource representing this identity. diff --git a/media/java/android/media/tv/TvChannelInfo.java b/media/java/android/media/tv/TvChannelInfo.java index 635b13045921..11cb1f7cd0bd 100644 --- a/media/java/android/media/tv/TvChannelInfo.java +++ b/media/java/android/media/tv/TvChannelInfo.java @@ -22,19 +22,44 @@ import android.annotation.Nullable; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + /** + * This class is used to specify information of a TV channel. * @hide */ public final class TvChannelInfo implements Parcelable { static final String TAG = "TvChannelInfo"; + + /** + * App tag for {@link #getAppTag()}: the corresponding application of the channel is the same as + * the caller. + * <p>{@link #getAppType()} returns {@link #APP_TYPE_SELF} if and only if the app tag is + * {@link #APP_TAG_SELF}. + */ public static final int APP_TAG_SELF = 0; + /** + * App tag for {@link #getAppType()}: the corresponding application of the channel is the same + * as the caller. + * <p>{@link #getAppType()} returns {@link #APP_TYPE_SELF} if and only if the app tag is + * {@link #APP_TAG_SELF}. + */ public static final int APP_TYPE_SELF = 1; + /** + * App tag for {@link #getAppType()}: the corresponding app of the channel is a system + * application. + */ public static final int APP_TYPE_SYSTEM = 2; + /** + * App tag for {@link #getAppType()}: the corresponding app of the channel is not a system + * application. + */ public static final int APP_TYPE_NON_SYSTEM = 3; /** @hide */ @@ -68,6 +93,7 @@ public final class TvChannelInfo implements Parcelable { @AppType private final int mAppType; private final int mAppTag; + /** @hide */ public TvChannelInfo( String inputId, @Nullable Uri channelUri, boolean isRecordingSession, boolean isForeground, @AppType int appType, int appTag) { @@ -90,24 +116,41 @@ public final class TvChannelInfo implements Parcelable { mAppTag = source.readInt(); } + /** + * Returns the TV input ID of the channel. + */ + @NonNull public String getInputId() { return mInputId; } + /** + * Returns the channel URI of the channel. + * <p>Returns {@code null} if it's a passthrough input or the permission is not granted. + */ + @Nullable public Uri getChannelUri() { return mChannelUri; } + /** + * Returns {@code true} if the channel session is a recording session. + * @see TvInputService.RecordingSession + */ public boolean isRecordingSession() { return mIsRecordingSession; } + /** + * Returns {@code true} if the application is a foreground application. + * @see android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND + */ public boolean isForeground() { return mIsForeground; } /** - * Gets app tag. + * Returns the app tag. * <p>App tag is used to differentiate one app from another. * {@link #APP_TAG_SELF} is for current app. */ @@ -115,6 +158,9 @@ public final class TvChannelInfo implements Parcelable { return mAppTag; } + /** + * Returns the app type. + */ @AppType public int getAppType() { return mAppType; @@ -126,7 +172,7 @@ public final class TvChannelInfo implements Parcelable { } @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(mInputId); String uriString = mChannelUri == null ? null : mChannelUri.toString(); dest.writeString(uriString); @@ -145,4 +191,26 @@ public final class TvChannelInfo implements Parcelable { + ";appType=" + mAppType + ";appTag=" + mAppTag; } + + @Override + public boolean equals(Object o) { + if (!(o instanceof TvChannelInfo)) { + return false; + } + + TvChannelInfo other = (TvChannelInfo) o; + + return TextUtils.equals(mInputId, other.getInputId()) + && Objects.equals(mChannelUri, other.mChannelUri) + && mIsRecordingSession == other.mIsRecordingSession + && mIsForeground == other.mIsForeground + && mAppType == other.mAppType + && mAppTag == other.mAppTag; + } + + @Override + public int hashCode() { + return Objects.hash( + mInputId, mChannelUri, mIsRecordingSession, mIsForeground, mAppType, mAppTag); + } } diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index d38369fea2b8..c80f3c6a0b39 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -900,8 +900,13 @@ public final class TvInputManager { public void onTvInputInfoUpdated(TvInputInfo inputInfo) { } - /** @hide */ - public void onCurrentTvChannelInfosUpdated(List<TvChannelInfo> tvChannelInfos) { + /** + * This is called when the information about current TV channels has been updated. + * + * @param tvChannelInfos a list of {@link TvChannelInfo} objects of new current channels. + * @hide + */ + public void onCurrentTvChannelInfosUpdated(@NonNull List<TvChannelInfo> tvChannelInfos) { } } @@ -1976,8 +1981,15 @@ public final class TvInputManager { } /** + * Returns the list of TV channel information for {@link TvInputService.Session} that are + * currently in use. + * <p> Permission com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS is required to get + * the channel URIs. If the permission is not granted, {@link TvChannelInfo#getChannelUri()} + * returns {@code null}. * @hide */ + @RequiresPermission("com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS") + @NonNull public List<TvChannelInfo> getCurrentTvChannelInfos() { try { return mService.getCurrentTvChannelInfos(mUserId); diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 0af6cbf3cb40..0a466f424cec 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -317,10 +317,9 @@ void ASurfaceTransaction_reparent(ASurfaceTransaction* aSurfaceTransaction, sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl); sp<SurfaceControl> newParentSurfaceControl = ASurfaceControl_to_SurfaceControl( newParentASurfaceControl); - sp<IBinder> newParentHandle = (newParentSurfaceControl)? newParentSurfaceControl->getHandle() : nullptr; Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction); - transaction->reparent(surfaceControl, newParentHandle); + transaction->reparent(surfaceControl, newParentSurfaceControl); } void ASurfaceTransaction_setVisibility(ASurfaceTransaction* aSurfaceTransaction, diff --git a/non-updatable-api/Android.bp b/non-updatable-api/Android.bp index 4037781c1844..00b901992b90 100644 --- a/non-updatable-api/Android.bp +++ b/non-updatable-api/Android.bp @@ -23,13 +23,31 @@ filegroup { } filegroup { + name: "non-updatable-removed.txt", + srcs: ["removed.txt"], + visibility: ["//frameworks/base/api"], +} + +filegroup { name: "non-updatable-system-current.txt", srcs: ["system-current.txt"], visibility: ["//frameworks/base/api"], } filegroup { + name: "non-updatable-system-removed.txt", + srcs: ["system-removed.txt"], + visibility: ["//frameworks/base/api"], +} + +filegroup { name: "non-updatable-module-lib-current.txt", srcs: ["module-lib-current.txt"], visibility: ["//frameworks/base/api"], } + +filegroup { + name: "non-updatable-module-lib-removed.txt", + srcs: ["module-lib-removed.txt"], + visibility: ["//frameworks/base/api"], +} diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index 008f74f9cf68..983f20aad2e3 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -35210,7 +35210,7 @@ package android.os { method public int dataCapacity(); method public int dataPosition(); method public int dataSize(); - method public void enforceInterface(String); + method public void enforceInterface(@NonNull String); method public boolean hasFileDescriptors(); method public byte[] marshall(); method @NonNull public static android.os.Parcel obtain(); @@ -35281,7 +35281,7 @@ package android.os { method public void writeFloatArray(@Nullable float[]); method public void writeInt(int); method public void writeIntArray(@Nullable int[]); - method public void writeInterfaceToken(String); + method public void writeInterfaceToken(@NonNull String); method public void writeList(@Nullable java.util.List); method public void writeLong(long); method public void writeLongArray(@Nullable long[]); diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index f116c80e85d6..04847d5fec35 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -95,6 +95,7 @@ package android { field public static final String INJECT_EVENTS = "android.permission.INJECT_EVENTS"; field public static final String INSTALL_DYNAMIC_SYSTEM = "android.permission.INSTALL_DYNAMIC_SYSTEM"; field public static final String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"; + field public static final String INSTALL_LOCATION_TIME_ZONE_PROVIDER = "android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER"; field public static final String INSTALL_PACKAGE_UPDATES = "android.permission.INSTALL_PACKAGE_UPDATES"; field public static final String INSTALL_SELF_UPDATES = "android.permission.INSTALL_SELF_UPDATES"; field public static final String INTENT_FILTER_VERIFICATION_AGENT = "android.permission.INTENT_FILTER_VERIFICATION_AGENT"; @@ -125,6 +126,7 @@ package android { field public static final String MANAGE_SENSOR_PRIVACY = "android.permission.MANAGE_SENSOR_PRIVACY"; field public static final String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER"; field public static final String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS"; + field public static final String MANAGE_TIME_AND_ZONE_DETECTION = "android.permission.MANAGE_TIME_AND_ZONE_DETECTION"; field public static final String MANAGE_USB = "android.permission.MANAGE_USB"; field public static final String MANAGE_USERS = "android.permission.MANAGE_USERS"; field public static final String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE"; @@ -305,6 +307,7 @@ package android { field public static final int config_helpPackageNameValue = 17039388; // 0x104001c field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028 field public static final int config_systemGallery = 17039399; // 0x1040027 + field public static final int config_systemVideoCall = 17039401; // 0x1040029 } public static final class R.style { @@ -1329,6 +1332,57 @@ package android.app.role { } +package android.app.time { + + public final class TimeManager { + method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public void addTimeZoneDetectorListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.time.TimeManager.TimeZoneDetectorListener); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public android.app.time.TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig(); + method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public void removeTimeZoneDetectorListener(@NonNull android.app.time.TimeManager.TimeZoneDetectorListener); + method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public boolean updateTimeZoneConfiguration(@NonNull android.app.time.TimeZoneConfiguration); + } + + @java.lang.FunctionalInterface public static interface TimeManager.TimeZoneDetectorListener { + method public void onChange(); + } + + public final class TimeZoneCapabilities implements android.os.Parcelable { + method public int describeContents(); + method public int getConfigureAutoDetectionEnabledCapability(); + method public int getConfigureGeoDetectionEnabledCapability(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int CAPABILITY_NOT_ALLOWED = 20; // 0x14 + field public static final int CAPABILITY_NOT_APPLICABLE = 30; // 0x1e + field public static final int CAPABILITY_NOT_SUPPORTED = 10; // 0xa + field public static final int CAPABILITY_POSSESSED = 40; // 0x28 + field @NonNull public static final android.os.Parcelable.Creator<android.app.time.TimeZoneCapabilities> CREATOR; + } + + public final class TimeZoneCapabilitiesAndConfig implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.app.time.TimeZoneCapabilities getCapabilities(); + method @NonNull public android.app.time.TimeZoneConfiguration getConfiguration(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.app.time.TimeZoneCapabilitiesAndConfig> CREATOR; + } + + public final class TimeZoneConfiguration implements android.os.Parcelable { + method public int describeContents(); + method public boolean isAutoDetectionEnabled(); + method public boolean isGeoDetectionEnabled(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.app.time.TimeZoneConfiguration> CREATOR; + } + + public static final class TimeZoneConfiguration.Builder { + ctor public TimeZoneConfiguration.Builder(); + ctor public TimeZoneConfiguration.Builder(@NonNull android.app.time.TimeZoneConfiguration); + method @NonNull public android.app.time.TimeZoneConfiguration build(); + method @NonNull public android.app.time.TimeZoneConfiguration.Builder setAutoDetectionEnabled(boolean); + method @NonNull public android.app.time.TimeZoneConfiguration.Builder setGeoDetectionEnabled(boolean); + } + +} + package android.app.usage { public final class CacheQuotaHint implements android.os.Parcelable { diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index d2485cc49b6e..506b6085131b 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -892,9 +892,6 @@ class SettingsProtoDumpUtil { Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED, GlobalSettingsProto.Location.SETTINGS_LINK_TO_PERMISSIONS_ENABLED); dumpSetting(s, p, - Settings.Global.LOCATION_GLOBAL_KILL_SWITCH, - GlobalSettingsProto.Location.GLOBAL_KILL_SWITCH); - dumpSetting(s, p, Settings.Global.GNSS_SATELLITE_BLACKLIST, GlobalSettingsProto.Location.GNSS_SATELLITE_BLACKLIST); dumpSetting(s, p, diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 3ccb1f4483b1..710c016d594c 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -328,10 +328,6 @@ public class SettingsProvider extends ContentProvider { return SettingsState.getUserIdFromKey(key); } - public static String settingTypeToString(int type) { - return SettingsState.settingTypeToString(type); - } - public static String keyToString(int key) { return SettingsState.keyToString(key); } @@ -373,8 +369,7 @@ public class SettingsProvider extends ContentProvider { } case Settings.CALL_METHOD_GET_SECURE: { - Setting setting = getSecureSetting(name, requestingUserId, - /*enableOverride=*/ true); + Setting setting = getSecureSetting(name, requestingUserId); return packageValueForCallResult(setting, isTrackingGeneration(args)); } @@ -581,7 +576,7 @@ public class SettingsProvider extends ContentProvider { } private ArrayList<String> buildSettingsList(Cursor cursor) { - final ArrayList<String> lines = new ArrayList<String>(); + final ArrayList<String> lines = new ArrayList<>(); try { while (cursor != null && cursor.moveToNext()) { lines.add(cursor.getString(1) + "=" + cursor.getString(2)); @@ -1381,10 +1376,6 @@ public class SettingsProvider extends ContentProvider { } private Setting getSecureSetting(String name, int requestingUserId) { - return getSecureSetting(name, requestingUserId, /*enableOverride=*/ false); - } - - private Setting getSecureSetting(String name, int requestingUserId, boolean enableOverride) { if (DEBUG) { Slog.v(LOG_TAG, "getSecureSetting(" + name + ", " + requestingUserId + ")"); } @@ -1414,14 +1405,6 @@ public class SettingsProvider extends ContentProvider { return getSsaidSettingLocked(callingPkg, owningUserId); } } - if (enableOverride) { - if (Secure.LOCATION_MODE.equals(name)) { - final Setting overridden = getLocationModeSetting(owningUserId); - if (overridden != null) { - return overridden; - } - } - } // Not the SSAID; do a straight lookup synchronized (mLock) { @@ -1511,35 +1494,6 @@ public class SettingsProvider extends ContentProvider { return null; } - private Setting getLocationModeSetting(int owningUserId) { - synchronized (mLock) { - final Setting setting = getGlobalSetting( - Global.LOCATION_GLOBAL_KILL_SWITCH); - if (!"1".equals(setting.getValue())) { - return null; - } - // Global kill-switch is enabled. Return an empty value. - final SettingsState settingsState = mSettingsRegistry.getSettingsLocked( - SETTINGS_TYPE_SECURE, owningUserId); - return settingsState.new Setting( - Secure.LOCATION_MODE, - "", // value - "", // tag - "", // default value - "", // package name - false, // from system - "0" // id - ) { - @Override - public boolean update(String value, boolean setDefault, String packageName, - String tag, boolean forceNonSystemPackage, boolean overrideableByRestore) { - Slog.wtf(LOG_TAG, "update shouldn't be called on this instance."); - return false; - } - }; - } - } - private boolean insertSecureSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, boolean forceNotify, boolean overrideableByRestore) { @@ -1808,12 +1762,8 @@ public class SettingsProvider extends ContentProvider { private boolean hasWriteSecureSettingsPermission() { // Write secure settings is a more protected permission. If caller has it we are good. - if (getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) - == PackageManager.PERMISSION_GRANTED) { - return true; - } - - return false; + return getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + == PackageManager.PERMISSION_GRANTED; } private void validateSystemSettingValue(String name, String value) { @@ -3174,12 +3124,6 @@ public class SettingsProvider extends ContentProvider { if (isGlobalSettingsKey(key) || isConfigSettingsKey(key)) { final long token = Binder.clearCallingIdentity(); try { - if (Global.LOCATION_GLOBAL_KILL_SWITCH.equals(name) - && isGlobalSettingsKey(key)) { - // When the global kill switch is updated, send the - // change notification for the location setting. - notifyLocationChangeForRunningUsers(); - } notifySettingChangeForRunningUsers(key, name); } finally { Binder.restoreCallingIdentity(token); @@ -3257,26 +3201,6 @@ public class SettingsProvider extends ContentProvider { } } - private void notifyLocationChangeForRunningUsers() { - final List<UserInfo> users = mUserManager.getAliveUsers(); - - for (int i = 0; i < users.size(); i++) { - final int userId = users.get(i).id; - - if (!mUserManager.isUserRunning(UserHandle.of(userId))) { - continue; - } - - // Increment the generation first, so observers always see the new value - final int key = makeKey(SETTINGS_TYPE_SECURE, userId); - mGenerationRegistry.incrementGeneration(key); - - final Uri uri = getNotificationUriFor(key, Secure.LOCATION_MODE); - mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, - userId, 0, uri).sendToTarget(); - } - } - private boolean isConfigSettingsKey(int key) { return getTypeFromKey(key) == SETTINGS_TYPE_CONFIG; } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index 6678cf6f1033..b061df1423ba 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -34,7 +34,6 @@ import android.os.Message; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; -import android.provider.Settings.Global; import android.providers.settings.SettingsOperationProto; import android.text.TextUtils; import android.util.ArrayMap; @@ -47,7 +46,6 @@ import android.util.Xml; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; import libcore.io.IoUtils; @@ -817,13 +815,6 @@ final class SettingsState { for (int i = 0; i < settingCount; i++) { Setting setting = settings.valueAt(i); - if (setting.isTransient()) { - if (DEBUG_PERSISTENCE) { - Slog.i(LOG_TAG, "[SKIPPED PERSISTING]" + setting.getName()); - } - continue; - } - writeSingleSetting(mVersion, serializer, setting.getId(), setting.getName(), setting.getValue(), setting.getDefaultValue(), setting.getPackageName(), setting.getTag(), setting.isDefaultFromSystem(), @@ -1109,8 +1100,7 @@ final class SettingsState { ATTR_DEFAULT_VALUE_BASE64); String isPreservedInRestoreString = parser.getAttributeValue(null, ATTR_PRESERVE_IN_RESTORE); - boolean isPreservedInRestore = isPreservedInRestoreString != null - && Boolean.parseBoolean(isPreservedInRestoreString); + boolean isPreservedInRestore = Boolean.parseBoolean(isPreservedInRestoreString); String tag = null; boolean fromSystem = false; if (defaultValue != null) { @@ -1308,14 +1298,6 @@ final class SettingsState { /* resetToDefault */ true); } - public boolean isTransient() { - switch (getTypeFromKey(getKey())) { - case SETTINGS_TYPE_GLOBAL: - return ArrayUtils.contains(Global.TRANSIENT_SETTINGS, getName()); - } - return false; - } - public boolean update(String value, boolean setDefault, String packageName, String tag, boolean forceNonSystemPackage, boolean overrideableByRestore) { return update(value, setDefault, packageName, tag, forceNonSystemPackage, @@ -1444,7 +1426,7 @@ final class SettingsState { } private static String fromBytes(byte[] bytes) { - final StringBuffer sb = new StringBuffer(bytes.length / 2); + final StringBuilder sb = new StringBuilder(bytes.length / 2); final int last = bytes.length - 1; diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 72dfe74b2fde..7d3390ddac85 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Instellings"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Vergrotingvenster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Vergrotingvensterkontroles"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Toestelkontroles"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Voeg kontroles vir jou gekoppelde toestelle by"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Stel toestelkontroles op"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ontkoppel)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Kon nie koppel nie. Probeer weer."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bind nuwe toestel saam"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 0ec236de8867..a91182e2380e 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ቅንብሮች"</string> <string name="magnification_window_title" msgid="4863914360847258333">"የማጉያ መስኮት"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"የማጉያ መስኮት መቆጣጠሪያዎች"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"የመሣሪያ መቆጣጠሪያዎች"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"ለእርስዎ የተገናኙ መሣሪያዎች መቆጣጠሪያዎችን ያክሉ"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"የመሣሪያ መቆጣጠሪያዎችን ያቀናብሩ"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ግንኙነት ተቋርጧል)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"ማገናኘት አልተቻለም። እንደገና ይሞክሩ።"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"አዲስ መሣሪያ ያጣምሩ"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index b09e5b9b30a3..74a9b648f60e 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -1032,6 +1032,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"الإعدادات"</string> <string name="magnification_window_title" msgid="4863914360847258333">"نافذة التكبير"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"عناصر التحكم في نافذة التكبير"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"أدوات التحكم بالأجهزة"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"إضافة عناصر تحكّم لأجهزتك المتصلة"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"إعداد أدوات التحكم بالجهاز"</string> @@ -1049,7 +1061,7 @@ <string name="accessibility_control_favorite" msgid="8694362691985545985">"تمت الإضافة إلى المفضّلة"</string> <string name="accessibility_control_favorite_position" msgid="54220258048929221">"تمت الإضافة إلى المفضّلة، الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"تمت الإزالة من المفضّلة"</string> - <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"إضافة إلى المُفضلة"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"إضافة إلى المحتوى المفضّل"</string> <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"إزالة من المفضّلة"</string> <string name="accessibility_control_move" msgid="8980344493796647792">"نقل إلى الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"عناصر التحكّم"</string> @@ -1099,4 +1111,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (غير متّصل)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"تعذّر الاتصال. يُرجى إعادة المحاولة."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"إقران جهاز جديد"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 61ba6dc1265c..297d7746b25f 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ছেটিংসমূহ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"বিবৰ্ধন ৱিণ্ড’"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"বিবৰ্ধন ৱিণ্ড’ৰ নিয়ন্ত্ৰণসমূহ"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ডিভাইচৰ নিয়ন্ত্ৰণসমূহ"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"আপোনাৰ সংযোজিত ডিভাইচসমূহৰ বাবে নিয়ন্ত্ৰণসমূহ যোগ কৰক"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"ডিভাইচৰ নিয়ন্ত্ৰণসমূহ ছেট আপ কৰক"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (সংযোগ বিচ্ছিন্ন হৈছে)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"সংযোগ কৰিব পৰা নগ’ল। পুনৰ চেষ্টা কৰক।"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইচ পেয়াৰ কৰক"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index bee0e5fdca54..debad02f3586 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Ayarlar"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Böyütmə Pəncərəsi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Böyütmə Pəncərəsi Kontrolları"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz idarəetmələri"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Qoşulmuş cihazlarınız üçün nizamlayıcılar əlavə edin"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz idarəetmələrini ayarlayın"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (bağlantı kəsilib)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Qoşulmaq alınmadı. Yenə cəhd edin."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihazı qoşalaşdırın"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 5966356d1e66..be31c2d95a79 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -1017,6 +1017,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Podešavanja"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećanje"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećanje"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodajte kontrole za povezane uređaje"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Podesite kontrole uređaja"</string> @@ -1081,4 +1093,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (veza je prekinuta)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Povezivanje nije uspelo. Probajte ponovo."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index cedc3753da42..e3831a858bbc 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -1022,6 +1022,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Налады"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Акно павелічэння"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Налады акна павелічэння"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Элементы кіравання прыладай"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Дадайце элементы кіравання для падключаных прылад"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Наладзіць элементы кіравання прыладай"</string> @@ -1087,4 +1099,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (адключана)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Не ўдалося падключыцца. Паўтарыце спробу."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спалучыць з новай прыладай"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 14088404e81b..d9591782d58c 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Настройки"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за ниво на мащаба"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли за прозореца за ниво на мащаба"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Контроли за устройството"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Добавяне на контроли за свързаните ви устройства"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Настройване на контролите за устройството"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (връзката е прекратена)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Неуспешно свързване. Опитайте отново."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Сдвояване на ново устройство"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index aed9522ced21..fffa555f8d33 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"সেটিংস"</string> <string name="magnification_window_title" msgid="4863914360847258333">"উইন্ডো বড় করে দেখা"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"উইন্ডো কন্ট্রোল বড় করে দেখা"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ডিভাইস কন্ট্রোল"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"আপনার কানেক্ট করা ডিভাইসের জন্য কন্ট্রোল যোগ করুন"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"ডিভাইস কন্ট্রোল সেট-আপ করুন"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (কানেক্ট করা নেই)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"কানেক্ট করা যায়নি। আবার চেষ্টা করুন।"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইস পেয়ার করুন"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 41a2671466df..f5410cf2d321 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -1017,6 +1017,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Postavke"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećavanje"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećavanje"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodajte kontrole za povezane uređaje"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Postavite kontrole uređaja"</string> @@ -1081,4 +1093,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (veza je prekinuta)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Povezivanje nije uspjelo. Pokušajte ponovo."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 0a0368042d5f..28bf3bb42fb0 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Configuració"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Finestra d\'ampliació"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Finestra de controls d\'ampliació"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Controls de dispositius"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Afegeix controls per als teus dispositius connectats"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura els controls de dispositius"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (desconnectat)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"No s\'ha pogut connectar. Torna-ho a provar."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincula un dispositiu nou"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 419e62510d50..c66f200f8935 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -1022,6 +1022,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Nastavení"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Zvětšovací okno"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ovládací prvky zvětšovacího okna"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Ovládání zařízení"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Přidejte ovládací prvky pro připojená zařízení"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavení ovládání zařízení"</string> @@ -1087,4 +1099,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (odpojeno)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Spojení se nezdařilo. Zkuste to znovu."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovat nové zařízení"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index f2e8a3f908f3..5b0566d097e0 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Indstillinger"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Vindue med forstørrelse"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Vindue med forstørrelsesstyring"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Enhedsstyring"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Tilføj styring af dine tilsluttede enheder"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer enhedsstyring"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ingen forbindelse)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Der kunne ikke oprettes forbindelse. Prøv igen."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Par ny enhed"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 4dbd74ae4f48..0ab1f0e66399 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Einstellungen"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Vergrößerungsfenster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Einstellungen für Vergrößerungsfenster"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Gerätesteuerung"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Steuerelemente für verbundene Geräte hinzufügen"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Gerätesteuerung einrichten"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (nicht verbunden)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Verbindung nicht möglich. Versuch es noch einmal."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Neues Gerät koppeln"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 1b912c7a6ed9..6d86e91f3cd3 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Ρυθμίσεις"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Παράθυρο μεγέθυνσης"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Στοιχεία ελέγχου παραθύρου μεγέθυνσης"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Στοιχεία ελέγχου συσκευής"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Προσθήκη στοιχείων ελέγχου για τις συνδεδεμένες συσκευές σας."</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Ρύθμιση στοιχείων ελέγχου συσκευής"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (αποσυνδέθηκε)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Δεν ήταν δυνατή η σύνδεση. Δοκιμάστε ξανά."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Σύζευξη νέας συσκευής"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 065c17bec41a..cb03d40dd579 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -1012,6 +1012,12 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Settings"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string> + <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> + <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Zoom out"</string> + <string name="accessibility_control_move_up" msgid="6622825494014720136">"Move up"</string> + <string name="accessibility_control_move_down" msgid="5390922476900974512">"Move down"</string> + <string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string> + <string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Add controls for your connected devices"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Set up device controls"</string> @@ -1075,4 +1081,6 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (disconnected)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Couldn\'t connect. Try again."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string> + <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> + <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> </resources> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 1cc662521645..8e5849e435f8 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -1012,6 +1012,12 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Settings"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string> + <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> + <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Zoom out"</string> + <string name="accessibility_control_move_up" msgid="6622825494014720136">"Move up"</string> + <string name="accessibility_control_move_down" msgid="5390922476900974512">"Move down"</string> + <string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string> + <string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Add controls for your connected devices"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Set up device controls"</string> @@ -1075,4 +1081,6 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (disconnected)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Couldn\'t connect. Try again."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string> + <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> + <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 065c17bec41a..cb03d40dd579 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -1012,6 +1012,12 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Settings"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string> + <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> + <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Zoom out"</string> + <string name="accessibility_control_move_up" msgid="6622825494014720136">"Move up"</string> + <string name="accessibility_control_move_down" msgid="5390922476900974512">"Move down"</string> + <string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string> + <string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Add controls for your connected devices"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Set up device controls"</string> @@ -1075,4 +1081,6 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (disconnected)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Couldn\'t connect. Try again."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string> + <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> + <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 065c17bec41a..cb03d40dd579 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -1012,6 +1012,12 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Settings"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string> + <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> + <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Zoom out"</string> + <string name="accessibility_control_move_up" msgid="6622825494014720136">"Move up"</string> + <string name="accessibility_control_move_down" msgid="5390922476900974512">"Move down"</string> + <string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string> + <string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Add controls for your connected devices"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Set up device controls"</string> @@ -1075,4 +1081,6 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (disconnected)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Couldn\'t connect. Try again."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string> + <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> + <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> </resources> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 7702337f080f..e107ed5ad3dc 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -1012,6 +1012,12 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Settings"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Magnification Window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification Window Controls"</string> + <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string> + <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Zoom out"</string> + <string name="accessibility_control_move_up" msgid="6622825494014720136">"Move up"</string> + <string name="accessibility_control_move_down" msgid="5390922476900974512">"Move down"</string> + <string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string> + <string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Add controls for your connected devices"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Set up device controls"</string> @@ -1075,4 +1081,6 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (disconnected)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Couldn\'t connect. Try again."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string> + <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> + <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 8a8f1e737741..be37623fa033 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Configuración"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controles de ampliación de la ventana"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Controles de dispositivos"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Agrega controles para los dispositivos conectados"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles de dispositivos"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (desconectado)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"No se pudo establecer la conexión. Vuelve a intentarlo."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo nuevo"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 20b50abd5b08..08b17cce4f6b 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Ajustes"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ventana de controles de ampliación"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Añade controles para tus dispositivos conectados"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar control de dispositivos"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (desconectado)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"No se ha podido conectar. Inténtalo de nuevo."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular nuevo dispositivo"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index ced06044f331..b33ad0138b91 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Seaded"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Suurendamisaken"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Suurendamisakna juhtelemendid"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Seadmete juhikud"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lisage juhtelemendid ühendatud seadmete jaoks"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Seadmete juhtimisvidinate seadistamine"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (pole ühendatud)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Ühenduse loomine ebaõnnestus. Proovige uuesti."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uue seadme sidumine"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index e8d2f4763348..3f1a53c9159f 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Ezarpenak"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Lupa-leihoa"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Lupa-leihoaren aukerak"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Gailuak kontrolatzeko widgetak"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Gehitu konektatutako gailuak kontrolatzeko widgetak"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfiguratu gailuak kontrolatzeko widgetak"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (deskonektatuta)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Ezin izan da konektatu. Saiatu berriro."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parekatu beste gailu batekin"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index f6cf179d7d00..e5606a249dae 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -246,7 +246,7 @@ <string name="accessibility_remove_notification" msgid="1641455251495815527">"پاک کردن اعلان"</string> <string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS فعال شد."</string> <string name="accessibility_gps_acquiring" msgid="896207402196024040">"دستیابی به GPS."</string> - <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter فعال شد."</string> + <string name="accessibility_tty_enabled" msgid="1123180388823381118">"تلهتایپ فعال شد."</string> <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"زنگ لرزشی."</string> <string name="accessibility_ringer_silent" msgid="8994620163934249882">"زنگ بیصدا."</string> <!-- no translation found for accessibility_casting (8708751252897282313) --> @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"تنظیمات"</string> <string name="magnification_window_title" msgid="4863914360847258333">"پنجره بزرگنمایی"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"کنترلهای پنجره بزرگنمایی"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"کنترلهای دستگاه"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"افزودن کنترلها برای دستگاههای متصل"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"تنظیم کنترلهای دستگاه"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (اتصال قطع شد)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"متصل نشد. دوباره امتحان کنید."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"مرتبط کردن دستگاه جدید"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 3d9a6dbee1f9..e00b50ee71aa 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Asetukset"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Suurennusikkuna"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Suurennusikkunan ohjaimet"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Laitteiden hallinta"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lisää ohjaimia yhdistettyjä laitteita varten"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Laitteiden hallinnan käyttöönotto"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (yhteys katkaistu)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Ei yhteyttä. Yritä uudelleen."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Muodosta uusi laitepari"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index ff89ce2dabcd..03e205d84a94 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Paramètres"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Fenêtre d\'agrandissement"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Commandes pour la fenêtre d\'agrandissement"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ajoutez des commandes pour vos appareils connectés"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes des appareils"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (déconnecté)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Impossible de se connecter. Réessayez."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un autre appareil"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index a126cfaadd65..82df63a01d25 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Paramètres"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Fenêtre d\'agrandissement"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Fenêtre des commandes d\'agrandissement"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ajouter des commandes pour vos appareils connectés"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes des appareils"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (déconnecté)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Impossible de se connecter. Réessayez."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un nouvel appareil"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 9075a69b2ed8..9be451d84c5a 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -246,7 +246,7 @@ <string name="accessibility_remove_notification" msgid="1641455251495815527">"Eliminar notificación."</string> <string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS activado"</string> <string name="accessibility_gps_acquiring" msgid="896207402196024040">"Obtendo GPS."</string> - <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter activado"</string> + <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletipo activado"</string> <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Timbre en vibración"</string> <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Timbre silenciado"</string> <!-- no translation found for accessibility_casting (8708751252897282313) --> @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Configuración"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Ventá de superposición"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controis de ampliación da ventá"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Engade controis para os dispositivos conectados"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar o control de dispositivos"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (dispositivo desconectado)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Non se puido establecer a conexión. Téntao de novo."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo novo"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index e8b446063922..864d05f5f61b 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"સેટિંગ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"વિસ્તૃતીકરણ વિંડો"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"વિસ્તૃતીકરણ વિંડોના નિયંત્રણો"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ડિવાઇસનાં નિયંત્રણો"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"તમારા કનેક્ટ કરેલા ડિવાઇસ માટે નિયંત્રણો ઉમેરો"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"ડિવાઇસનાં નિયંત્રણો સેટઅપ કરો"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ડિસ્કનેક્ટ થયેલું)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"કનેક્ટ કરી શકાયું નહીં. ફરી પ્રયાસ કરો."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"નવા ડિવાઇસ સાથે જોડાણ કરો"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 9a563d960cf3..e11055c47bfd 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -1014,6 +1014,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"सेटिंग"</string> <string name="magnification_window_title" msgid="4863914360847258333">"स्क्रीन को बड़ा करके दिखाने वाली विंडो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"स्क्रीन को बड़ा करके दिखाने वाली विंडो के नियंत्रण"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"डिवाइस कंट्रोल"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"कनेक्ट किए गए डिवाइस के लिए कंट्रोल जोड़ें"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"डिवाइस कंट्रोल सेट अप करें"</string> @@ -1077,4 +1089,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (डिसकनेक्ट किया गया)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"कनेक्ट नहीं किया जा सका. फिर से कोशिश करें."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नया डिवाइस जोड़ें"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 649299b1cd7d..d5033fa45b07 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -1017,6 +1017,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Postavke"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za povećavanje"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za povećavanje"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodavanje kontrola za povezane uređaje"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Postavljanje kontrola uređaja"</string> @@ -1081,4 +1093,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (nije povezano)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Povezivanje nije bilo moguće. Pokušajte ponovo."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index f658bb76c649..6d960e7c9491 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Beállítások"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Nagyítás ablaka"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Nagyítási vezérlők ablaka"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Eszközvezérlők"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Vezérlők hozzáadása a csatlakoztatott eszközökhöz"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Eszközvezérlők beállítása"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (leválasztva)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Sikertelen csatlakozás. Próbálja újra."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Új eszköz párosítása"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 171773c95aed..9e746fa9b439 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -246,7 +246,7 @@ <string name="accessibility_remove_notification" msgid="1641455251495815527">"Մաքրել ծանուցումը:"</string> <string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS-ը միացված է:"</string> <string name="accessibility_gps_acquiring" msgid="896207402196024040">"GPS-ի ստացում:"</string> - <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Հեռամուտքագրիչը միացված է:"</string> + <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Հեռատիպը միացված է:"</string> <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Թրթռազանգ:"</string> <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Զանգակը լռեցված է:"</string> <!-- no translation found for accessibility_casting (8708751252897282313) --> @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Կարգավորումներ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Խոշորացման պատուհան"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Խոշորացման պատուհանի կառավարման տարրեր"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Սարքերի կառավարման տարրեր"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ավելացրեք կառավարման տարրեր ձեր միացված սարքերի համար"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Սարքերի կառավարման տարրերի կարգավորում"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (անջատված է)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Չհաջողվեց միանալ։ Նորից փորձեք։"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Նոր սարքի զուգակցում"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 12f42e84c3db..380e94370ae6 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -597,7 +597,7 @@ <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Ringkasan untuk melepas pin."</string> <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Beranda untuk melepas pin."</string> <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Data pribadi dapat diakses (seperti kontak dan konten email)."</string> - <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Aplikasi yang dipasangi pin dapat membuka aplikasi lain."</string> + <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Aplikasi yang disematkan dapat membuka aplikasi lain."</string> <string name="screen_pinning_toast" msgid="8177286912533744328">"Untuk melepas pin aplikasi ini, sentuh & lama tombol Kembali dan Ringkasan"</string> <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Untuk melepas pin aplikasi ini, sentuh & lama tombol Kembali dan Layar utama"</string> <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Untuk melepas pin aplikasi ini, geser ke atas & tahan"</string> @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Setelan"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Jendela Pembesaran"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrol Jendela Pembesaran"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Kontrol perangkat"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Tambahkan kontrol untuk perangkat terhubung"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Siapkan kontrol perangkat"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (terputus)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Tidak dapat terhubung. Coba lagi."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sambungkan perangkat baru"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 4a750a594dad..dd12ed624807 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Stillingar"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Stækkunargluggi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Stækkunarstillingar glugga"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Tækjastjórnun"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Bæta við stýringum fyrir tengd tæki"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Setja upp tækjastjórnun"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (aftengt)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Tenging mistókst. Reyndu aftur."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Para nýtt tæki"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index eb76a4b58fcd..851228fedd2b 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Impostazioni"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Finestra ingrandimento"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Finestra controlli di ingrandimento"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Controllo dei dispositivi"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Aggiungi controlli per i dispositivi connessi"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura il controllo dei dispositivi"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (disconnesso)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Impossibile connettersi. Riprova."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Accoppia nuovo dispositivo"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index e6fbdb54a9de..d4ad45e38ab2 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -1022,6 +1022,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"הגדרות"</string> <string name="magnification_window_title" msgid="4863914360847258333">"חלון הגדלה"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"בקרות של חלון ההגדלה"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"פקדי מכשירים"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"יש להוסיף פקדים למכשירים המחוברים"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"הגדרה של פקדי מכשירים"</string> @@ -1087,4 +1099,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (מנותק)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"לא ניתן היה להתחבר. יש לנסות שוב."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"התאמה של מכשיר חדש"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index b358f3d866dc..7547853035f6 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"設定"</string> <string name="magnification_window_title" msgid="4863914360847258333">"拡大ウィンドウ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"拡大ウィンドウ コントロール"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"デバイス コントロール"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"接続済みデバイスのコントロールを追加します"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"デバイス コントロールの設定"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>(未接続)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"接続できませんでした。もう一度お試しください。"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"新しいデバイスとのペア設定"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 4e85d608a72b..69b1d14e1c01 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"პარამეტრები"</string> <string name="magnification_window_title" msgid="4863914360847258333">"გადიდების ფანჯარა"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"გადიდების კონტროლის ფანჯარა"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"მოწყობილ. მართვის საშუალებები"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"მართვის საშუალებების დამატება თქვენს დაკავშირებულ მოწყობილობებზე"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"მოწყობილობის მართვის საშუალებების დაყენება"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (კავშირი გაწყვეტილია)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"დაკავშირება ვერ მოხერხდა. ცადეთ ხელახლა."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ახალი მოწყობილობის დაწყვილება"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index f17210602b83..b86f32ed5fb7 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Параметрлер"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Ұлғайту терезесі"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ұлғайту терезесінің басқару элементтері"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Құрылғыны басқару элементтері"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Жалғанған құрылғылар үшін басқару виджеттерін қосу"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Құрылғыны басқару элементтерін реттеу"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ажыратылған)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Қосылмады. Қайта қосылып көріңіз."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңа құрылғыны жұптау"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index b126a11d1310..e89514007e8a 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ការកំណត់"</string> <string name="magnification_window_title" msgid="4863914360847258333">"វិនដូការពង្រីក"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"វិនដូគ្រប់គ្រងការពង្រីក"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"បញ្ចូលផ្ទាំងគ្រប់គ្រងសម្រាប់ឧបករណ៍ដែលអ្នកបានភ្ជាប់"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"រៀបចំផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (បានផ្ដាច់)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"មិនអាចភ្ជាប់បានទេ។ សូមព្យាយាមម្ដងទៀត។"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ផ្គូផ្គងឧបករណ៍ថ្មី"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 475677be3845..2a9f6490e691 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ವರ್ಧನೆಯ ವಿಂಡೋ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ವರ್ಧನೆಯ ವಿಂಡೋ ನಿಯಂತ್ರಣಗಳು"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ಸಾಧನ ನಿಯಂತ್ರಣಗಳು"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"ನಿಮ್ಮ ಸಂಪರ್ಕಿತ ಸಾಧನಗಳಿಗೆ ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಿ"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"ಸಾಧನ ನಿಯಂತ್ರಣಗಳನ್ನು ಸೆಟಪ್ ಮಾಡಿ"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index ac7f04e77586..559205c20a59 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"설정"</string> <string name="magnification_window_title" msgid="4863914360847258333">"확대 창"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"확대 창 컨트롤"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"기기 컨트롤"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"연결된 기기의 컨트롤을 추가하세요."</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"기기 컨트롤 설정"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>(연결 끊김)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"연결할 수 없습니다. 다시 시도하세요."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"새 기기와 페어링"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index b1fab0781b2a..a688150ac2a0 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Жөндөөлөр"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Чоңойтуу терезеси"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Чоңойтуу терезесин башкаруу каражаттары"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Түзмөктү башкаруу элементтери"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Байланышкан түзмөктөрүңүздү башкаруу элементтерин кошосуз"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Түзмөктү башкаруу элементтерин жөндөө"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ажыратылды)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Байланышпай койду. Кайталоо."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңы түзмөктү жупташтыруу"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 67642d3471f5..1a6c338ce9c8 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ການຕັ້ງຄ່າ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ໜ້າຈໍການຂະຫຍາຍ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ການຄວບຄຸມໜ້າຈໍການຂະຫຍາຍ"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ການຄວບຄຸມອຸປະກອນ"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"ເພີ່ມການຄວບຄຸມສຳລັບອຸປະກອນທີ່ເຊື່ອມຕໍ່ແລ້ວຂອງທ່ານ"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"ຕັ້ງຄ່າການຄວບຄຸມອຸປະກອນ"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ຕັດການເຊື່ອມຕໍ່ແລ້ວ)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"ບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້. ລອງໃໝ່."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ຈັບຄູ່ອຸປະກອນໃໝ່"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index e17f6e490373..6fb84dd89424 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -1022,6 +1022,12 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Nustatymai"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Didinimo langas"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Didinimo lango valdikliai"</string> + <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Artinti"</string> + <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Tolinti"</string> + <string name="accessibility_control_move_up" msgid="6622825494014720136">"Perkelti aukštyn"</string> + <string name="accessibility_control_move_down" msgid="5390922476900974512">"Perkelti žemyn"</string> + <string name="accessibility_control_move_left" msgid="8156206978511401995">"Perkelti kairėn"</string> + <string name="accessibility_control_move_right" msgid="8926821093629582888">"Perkelti dešinėn"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Įrenginio valdikliai"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Pridėkite prijungtų įrenginių valdiklių"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Įrenginio valdiklių nustatymas"</string> @@ -1087,4 +1093,6 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"„<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“ (atjungta)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Nepavyko prijungti. Bandykite dar kartą."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Naujo įrenginio susiejimas"</string> + <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string> + <string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 96d563c61a75..9864a61f2e26 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -1017,6 +1017,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Iestatījumi"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Palielināšanas logs"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Palielināšanas loga vadīklas"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Ierīču vadīklas"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Pievienojiet vadīklas pievienotajām ierīcēm"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Ierīču vadīklu iestatīšana"</string> @@ -1081,4 +1093,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (savienojums pārtraukts)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Nevarēja izveidot savienojumu. Mēģiniet vēlreiz."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Savienošana pārī ar jaunu ierīci"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index f53147e03c84..362cbdce38c6 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Поставки"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за зголемување"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли на прозорец за зголемување"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Контроли за уредите"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Додајте контроли за поврзаните уреди"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Поставете ги контролите за уредите"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (исклучен)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Не можеше да се поврзе. Обидете се повторно."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спарете нов уред"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 80f0106bbd20..95634b8e0542 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ക്രമീകരണം"</string> <string name="magnification_window_title" msgid="4863914360847258333">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ നിയന്ത്രണങ്ങൾ"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ഉപകരണ നിയന്ത്രണങ്ങൾ"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"കണക്റ്റ് ചെയ്ത ഉപകരണങ്ങൾക്ക് നിയന്ത്രണങ്ങൾ ചേർക്കുക"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"ഉപകരണ നിയന്ത്രണങ്ങൾ സജ്ജീകരിക്കുക"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (വിച്ഛേദിച്ചു)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"കണക്റ്റ് ചെയ്യാനായില്ല. വീണ്ടും ശ്രമിക്കുക."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"പുതിയ ഉപകരണവുമായി ജോടിയാക്കുക"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 1c82e48c9ad9..a2e174545b5c 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Тохиргоо"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Томруулалтын цонх"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Томруулалтын цонхны хяналт"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Төхөөрөмжийн хяналт"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Холбогдсон төхөөрөмжүүд дээрээ хяналт нэмэх"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Төхөөрөмжийн хяналтыг тохируулах"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (салсан)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Холбогдож чадсангүй. Дахин оролдоно уу."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Шинэ төхөөрөмж хослуулах"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index b26f89f63243..7a62c1763f3a 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"सेटिंग्ज"</string> <string name="magnification_window_title" msgid="4863914360847258333">"मॅग्निफिकेशन विंडो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"मॅग्निफिकेशन विंडो नियंत्रणे"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"डिव्हाइस नियंत्रणे"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"तुमच्या कनेक्ट केलेल्या डिव्हाइससाठी नियंत्रणे जोडा"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"डिव्हाइस नियंत्रणे सेट करा"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (डिस्कनेक्ट केले)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"कनेक्ट करू शकलो नाही. पुन्हा प्रयत्न करा."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नवीन डिव्हाइससोबत पेअर करा"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 92bc807e76cc..2b501bbc9354 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Tetapan"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Tetingkap Pembesaran"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kawalan Tetingkap Pembesaran"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Kawalan peranti"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Tambah kawalan untuk peranti yang disambungkan"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Sediakan kawalan peranti"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (diputuskan sambungan)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Tidak boleh menyambung. Cuba lagi."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Gandingkan peranti baharu"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 9cc9398979de..1cbf17fef105 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ဆက်တင်များ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ဝင်းဒိုး ချဲ့ခြင်း"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ဝင်းဒိုး ထိန်းချုပ်မှုများ ချဲ့ခြင်း"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"စက်ထိန်းစနစ်"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"ချိတ်ဆက်စက်များအတွက် ထိန်းချုပ်မှုများထည့်ပါ"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"စက်ထိန်းစနစ် ထည့်သွင်းခြင်း"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ချိတ်ဆက်မထားပါ)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"ချိတ်ဆက်၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"စက်အသစ် တွဲချိတ်ရန်"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 92ae68943352..6d6d66fee381 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Innstillinger"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Forstørringsvindu"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontroller for forstørringsvindu"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyring"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Legg til kontroller for de tilkoblede enhetene dine"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer enhetsstyring"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (frakoblet)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Kunne ikke koble til. Prøv på nytt."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Koble til en ny enhet"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 1346874ed08f..e1dd8c02000b 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"सेटिङ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"म्याग्निफिकेसन विन्डो"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"म्याग्निफिकेसन विन्डोका नियन्त्रणहरू"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"यन्त्र नियन्त्रण गर्ने विजेटहरू"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"आफ्ना जोडिएका यन्त्रहरूका लागि नियन्त्रण सुविधाहरू थप्नुहोस्"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"यन्त्र नियन्त्रण गर्ने विजेटहरू सेटअप गर्नुहोस्"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (डिस्कनेक्ट गरिएको)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"कनेक्ट गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नयाँ यन्त्रको जोडा बनाउनुहोस्"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 139b57b7c3bf..e2db22cb38f6 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Instellingen"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Vergrotingsvenster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Bediening van vergrotingsvenster"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Apparaatbediening"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Bedieningselementen voor je gekoppelde apparaten toevoegen"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Apparaatbediening instellen"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (verbinding verbroken)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Kan geen verbinding maken. Probeer het nog eens."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Nieuw apparaat koppelen"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 3973734f16d2..970e61c02ab3 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ସେଟିଂସ୍"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"ଆପଣଙ୍କ ସଂଯୁକ୍ତ ଡିଭାଇସଗୁଡ଼ିକ ପାଇଁ ନିୟନ୍ତ୍ରଣ ଯୋଗ କରନ୍ତୁ"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ବିଚ୍ଛିନ୍ନ କରାଯାଇଛି)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"ସଂଯୋଗ କରାଯାଇପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ନୂଆ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index e727f48a1a3e..690d6e5b3bb7 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ਸੈਟਿੰਗਾਂ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window ਦੇ ਕੰਟਰੋਲ"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ਡੀਵਾਈਸ ਕੰਟਰੋਲ"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"ਆਪਣੇ ਕਨੈਕਟ ਕੀਤੇ ਡੀਵਾਈਸਾਂ ਲਈ ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"ਡੀਵਾਈਸ ਕੰਟਰੋਲਾਂ ਦਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ਡਿਸਕਨੈਕਟ ਹੋਇਆ)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index f188aaa1ca76..9b31c527f33a 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -1022,6 +1022,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Ustawienia"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Okno powiększenia"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Elementy sterujące okna powiększenia"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Sterowanie urządzeniami"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodaj elementy sterujące połączonymi urządzeniami"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurowanie sterowania urządzeniami"</string> @@ -1087,4 +1099,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (rozłączono)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Nie udało się połączyć. Spróbuj ponownie."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sparuj nowe urządzenie"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 8c8adae62e82..b76ebda64705 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -1012,6 +1012,12 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Configurações"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controles da janela de ampliação"</string> + <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumentar zoom"</string> + <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Diminuir zoom"</string> + <string name="accessibility_control_move_up" msgid="6622825494014720136">"Mover para cima"</string> + <string name="accessibility_control_move_down" msgid="5390922476900974512">"Mover para baixo"</string> + <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover para a esquerda"</string> + <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover para a direita"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Adiciona controles aos dispositivos conectados"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles do dispositivo"</string> @@ -1075,4 +1081,6 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (desconectado)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Não foi possível conectar. Tente novamente."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string> + <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string> + <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 082e14ec6fc3..089bbd46db12 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Definições"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controlos da janela de ampliação"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Controlos de dispositivos"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Adicione controlos para os dispositivos associados."</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configure os controlos de dispositivos"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (desligado)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Não foi possível ligar. Tente novamente."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sincronize o novo dispositivo"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 8c8adae62e82..b76ebda64705 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -1012,6 +1012,12 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Configurações"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Controles da janela de ampliação"</string> + <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumentar zoom"</string> + <string name="accessibility_control_zoom_out" msgid="69578832020304084">"Diminuir zoom"</string> + <string name="accessibility_control_move_up" msgid="6622825494014720136">"Mover para cima"</string> + <string name="accessibility_control_move_down" msgid="5390922476900974512">"Mover para baixo"</string> + <string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover para a esquerda"</string> + <string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover para a direita"</string> <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Adiciona controles aos dispositivos conectados"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles do dispositivo"</string> @@ -1075,4 +1081,6 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (desconectado)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Não foi possível conectar. Tente novamente."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string> + <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string> + <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 4128c21eaa4e..3194b9f076c7 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -1017,6 +1017,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Setări"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Fereastra de mărire"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Comenzi pentru fereastra de mărire"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Comenzile dispozitivelor"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Adăugați comenzi pentru dispozitivele conectate"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurați comenzile dispozitivelor"</string> @@ -1081,4 +1093,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (s-a deconectat)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Nu s-a putut conecta. Reîncercați."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Asociați un nou dispozitiv"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 7584173d48c5..26e343325939 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -1022,6 +1022,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Настройки"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Окно увеличения"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Настройки окна увеличения"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Управление устройствами"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Добавьте виджеты для управления устройствами."</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Настройте виджеты управления устройствами"</string> @@ -1087,4 +1099,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (отключено)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Не удалось подключиться. Повторите попытку."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Подключить новое устройство"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 98e8d1fd9d63..8eea1edb6dcb 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"සැකසීම්"</string> <string name="magnification_window_title" msgid="4863914360847258333">"විශාලන කවුළුව"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"විශාලනය කිරීමේ කවුළු පාලන"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"උපාංග පාලන"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"ඔබේ සම්බන්ධිත උපාංග සඳහා පාලන එක් කරන්න"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"උපාංග පාලන පිහිටුවන්න"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (විසන්ධි විය)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"සම්බන්ධ වීමට නොහැකි විය. නැවත උත්සාහ කරන්න."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"නව උපාංගය යුගල කරන්න"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index d9c6279ec42e..47045d8f2116 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -1022,6 +1022,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Nastavenia"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Okno priblíženia"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Ovládacie prvky okna priblíženia"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Ovládanie zariadení"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Pridajte si ovládače pripojených zariadení"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavenie ovládania zariadení"</string> @@ -1087,4 +1099,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (odpojené)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Nepodarilo sa pripojiť. Skúste to znova."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovať nové zariadenie"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 778938c77374..7b68a3a2e68d 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -1022,6 +1022,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Nastavitve"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Povečevalno okno"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrolniki povečevalnega okna"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Kontrolniki naprave"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodajte kontrolnike za povezane naprave"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavitev kontrolnikov naprave"</string> @@ -1087,4 +1099,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (povezava prekinjena)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Povezave ni bilo mogoče vzpostaviti. Poskusite znova."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Seznanitev nove naprave"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 5172303032b7..b7ebb2a1ef0d 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -246,7 +246,7 @@ <string name="accessibility_remove_notification" msgid="1641455251495815527">"Pastro njoftimin."</string> <string name="accessibility_gps_enabled" msgid="4061313248217660858">"GPS-ja është e aktivizuar."</string> <string name="accessibility_gps_acquiring" msgid="896207402196024040">"Po siguron GPS-në."</string> - <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teleprinteri është i aktivizuar."</string> + <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletajpi është i aktivizuar."</string> <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zile me dridhje."</string> <string name="accessibility_ringer_silent" msgid="8994620163934249882">"Zilja është heshtur."</string> <!-- no translation found for accessibility_casting (8708751252897282313) --> @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Cilësimet"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Dritarja e zmadhimit"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrollet e dritares së zmadhimit"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Kontrollet e pajisjes"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Shto kontrolle për pajisjet e tua të lidhura"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfiguro kontrollet e pajisjes"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (e shkëputur)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Nuk mund të lidhej. Provo sërish."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Çifto pajisjen e re"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 90f1c5adf7be..b6a90cd0076b 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -1017,6 +1017,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Подешавања"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Прозор за увећање"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Контроле прозора за увећање"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Контроле уређаја"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Додајте контроле за повезане уређаје"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Подесите контроле уређаја"</string> @@ -1081,4 +1093,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (веза је прекинута)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Повезивање није успело. Пробајте поново."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Упари нови уређај"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 8918f519b020..890f5041f247 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Inställningar"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Förstoringsfönster"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Inställningar för förstoringsfönster"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyrning"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Lägg till snabbkontroller för anslutna enheter"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurera enhetsstyrning"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (frånkopplad)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Det gick inte att ansluta. Försök igen."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parkoppla en ny enhet"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 3949f2df6e40..34042ad59c64 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Mipangilio"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Dirisha la Ukuzaji"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Vidhibiti vya Dirisha la Ukuzaji"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Vidhibiti vya vifaa"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Weka vidhibiti vya vifaa ulivyounganisha"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Weka mipangilio ya vidhibiti vya vifaa"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (hakijaunganishwa)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Imeshindwa kuunganisha. Jaribu tena."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Oanisha kifaa kipya"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index d91f1fda3f0c..b30859fdc08e 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -879,12 +879,12 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"குறைந்த முன்னுரிமை உள்ள அறிவிப்பு ஐகான்களைக் காட்டு"</string> <string name="other" msgid="429768510980739978">"மற்றவை"</string> - <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"டைலை அகற்றும்"</string> - <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"கடைசியில் டைலைச் சேர்க்கும்"</string> - <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"டைலை நகர்த்து"</string> - <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"டைலைச் சேர்"</string> - <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> இடத்திற்கு நகர்த்தும்"</string> - <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> என்ற இடத்தில் சேர்க்கும்"</string> + <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"கட்டத்தை அகற்றும்"</string> + <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"கடைசியில் கட்டத்தைச் சேர்க்கும்"</string> + <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"கட்டத்தை நகர்த்து"</string> + <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"கட்டத்தைச் சேர்"</string> + <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>க்கு நகர்த்தும்"</string> + <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>ல் சேர்க்கும்"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"இடம்: <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"விரைவு அமைப்புகள் திருத்தி."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> அறிவிப்பு: <xliff:g id="ID_2">%2$s</xliff:g>"</string> @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"அமைப்புகள்"</string> <string name="magnification_window_title" msgid="4863914360847258333">"பெரிதாக்கல் சாளரம்"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"பெரிதாக்கல் சாளரக் கட்டுப்பாடுகள்"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"சாதனக் கட்டுப்பாடுகள்"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"இணைக்கப்பட்ட சாதனங்களில் கட்டுப்பாடுகளைச் சேர்க்கலாம்"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"சாதனக் கட்டுப்பாடுகளை அமைத்தல்"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (இணைப்பு துண்டிக்கப்பட்டது)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"இணைக்க முடியவில்லை. மீண்டும் முயலவும்."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"புதிய சாதனத்தை இணைத்தல்"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index d7a27b86a99a..cb134a10adc7 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"సెట్టింగ్లు"</string> <string name="magnification_window_title" msgid="4863914360847258333">"మాగ్నిఫికేషన్ విండో"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"మాగ్నిఫికేషన్ నియంత్రణల విండో"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"పరికరం నియంత్రణలు"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"మీ కనెక్ట్ అయిన పరికరాలకు నియంత్రణలను జోడించండి"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"పరికరం నియంత్రణలను సెటప్ చేయడం"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (డిస్కనెక్ట్ అయ్యింది)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"కనెక్ట్ చేయడం సాధ్యపడలేదు. మళ్లీ ట్రై చేయండి."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"కొత్త పరికరాన్ని పెయిర్ చేయండి"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index cb6089fa0344..d6783530721f 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"การตั้งค่า"</string> <string name="magnification_window_title" msgid="4863914360847258333">"หน้าต่างการขยาย"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"การควบคุมหน้าต่างการขยาย"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"ระบบควบคุมอุปกรณ์"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"เพิ่มตัวควบคุมของอุปกรณ์ที่เชื่อมต่อ"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"ตั้งค่าระบบควบคุมอุปกรณ์"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (ยกเลิกการเชื่อมต่อแล้ว)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"เชื่อมต่อไม่ได้ ลองใหม่"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"จับคู่อุปกรณ์ใหม่"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 7e6aa629ea63..21fdd3106f7e 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Mga Setting"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Window ng Pag-magnify"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Mga Kontrol sa Pag-magnify ng Window"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Mga kontrol ng device"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Magdagdag ng kontrol para sa mga nakakonektang device"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"I-set up ang mga kontrol ng device"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (nakadiskonekta)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Hindi makakonekta. Subukan ulit."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Magpares ng bagong device"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index dac352f79d8b..3e04d19c07e6 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Ayarlar"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Büyütme Penceresi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Büyütme Penceresi Kontrolleri"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz denetimleri"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Bağlı cihazlarınız için denetimler ekleyin"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz denetimlerini kur"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (bağlı değil)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Bağlanılamadı. Tekrar deneyin."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihaz eşle"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 26053af9936f..a7c6bef69349 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -1022,6 +1022,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Налаштування"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Вікно збільшення"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Елементи керування вікна збільшення"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Керування пристроями"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Додайте елементи керування для підключених пристроїв"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Налаштувати елементи керування пристроями"</string> @@ -1087,4 +1099,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (відключено)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Не вдалося підключитися. Повторіть спробу."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Підключити новий пристрій"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 4bd192fd63f0..f24492c21146 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"ترتیبات"</string> <string name="magnification_window_title" msgid="4863914360847258333">"میگنیفکیشن ونڈو"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"میگنیفکیشن ونڈو کنٹرولز"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"آلہ کے کنٹرولز"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"اپنے منسلک آلات کے لیے کنٹرولز شامل کریں"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"آلہ کے کنٹرولز سیٹ اپ کریں"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (غیر منسلک ہو گیا)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"منسلک نہیں ہو سکا۔ پھر کوشش کریں۔"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"نئے آلہ کا جوڑا بنائیں"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 7c3728abab78..32c24065dc83 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Sozlamalar"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Kattalashtirish oynasi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Kattalashtirish oynasi sozlamalari"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Qurilmalarni boshqarish"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Ulangan qurilmalar uchun boshqaruv elementlari"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Qurilma boshqaruv elementlarini sozlash"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (uzilgan)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Ulanmadi. Qayta urining."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yangi qurilmani ulash"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index f23f7424a073..d9c80dff925a 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Cài đặt"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Cửa sổ phóng to"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Các tùy chọn điều khiển cửa sổ phóng to"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Điều khiển thiết bị"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Thêm các tùy chọn điều khiển cho các thiết bị đã kết nối của bạn"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Thiết lập các tùy chọn điều khiển thiết bị"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (đã ngắt kết nối)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Không thể kết nối. Hãy thử lại."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Ghép nối thiết bị mới"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 9b81cb04db1a..9f9424d5bb8e 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"设置"</string> <string name="magnification_window_title" msgid="4863914360847258333">"放大窗口"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"放大窗口控件"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"设备控制器"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"为您所连接的设备添加控件"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"设置设备控件"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>(已断开连接)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"无法连接。请重试。"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"与新设备配对"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index dbb9e03ac279..2825a9efc5cb 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"設定"</string> <string name="magnification_window_title" msgid="4863914360847258333">"放大視窗"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"放大視窗控制項"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"為連接的裝置新增控制選項"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"設定裝置控制"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (已中斷連線)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"無法連線,請再試一次。"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 4e4db70ddd67..8acf2c687b2d 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"設定"</string> <string name="magnification_window_title" msgid="4863914360847258333">"放大視窗"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"放大視窗控制項"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"新增已連結裝置的控制項"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"設定裝置控制"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (已中斷連線)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"無法連線,請再試一次。"</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 65e9a1c6a5e0..493520632cc3 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -1012,6 +1012,18 @@ <string name="priority_onboarding_settings_button_title" msgid="6663601574303585927">"Amasethingi"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Iwindi Lesikhulisi"</string> <string name="magnification_controls_title" msgid="8421106606708891519">"Izilawuli Zewindi Lesikhulisi"</string> + <!-- no translation found for accessibility_control_zoom_in (1189272315480097417) --> + <skip /> + <!-- no translation found for accessibility_control_zoom_out (69578832020304084) --> + <skip /> + <!-- no translation found for accessibility_control_move_up (6622825494014720136) --> + <skip /> + <!-- no translation found for accessibility_control_move_down (5390922476900974512) --> + <skip /> + <!-- no translation found for accessibility_control_move_left (8156206978511401995) --> + <skip /> + <!-- no translation found for accessibility_control_move_right (8926821093629582888) --> + <skip /> <string name="quick_controls_title" msgid="6839108006171302273">"Izilawuli zezinsiza"</string> <string name="quick_controls_subtitle" msgid="1667408093326318053">"Engeza izilawuli zedivayisi yakho exhunyiwe"</string> <string name="quick_controls_setup_title" msgid="8901436655997849822">"Setha izilawuli zezinsiza"</string> @@ -1075,4 +1087,8 @@ <string name="media_output_dialog_disconnected" msgid="1834473104836986046">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> (inqamukile)"</string> <string name="media_output_dialog_connect_failed" msgid="3225190634236259010">"Ayikwazanga ukuxhumeka. Zama futhi."</string> <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhanqa idivayisi entsha"</string> + <!-- no translation found for build_number_clip_data_label (3623176728412560914) --> + <skip /> + <!-- no translation found for build_number_copy_toast (877720921605503046) --> + <skip /> </resources> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index ee05c6cf4c47..a98f6661cb06 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -34,7 +34,6 @@ import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.AppGlobals; -import android.app.IAssistDataReceiver; import android.app.WindowConfiguration; import android.content.ContentResolver; import android.content.Context; @@ -43,7 +42,6 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; -import android.graphics.Bitmap; import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; @@ -228,21 +226,10 @@ public class ActivityManagerWrapper { /** * Starts the recents activity. The caller should manage the thread on which this is called. */ - public void startRecentsActivity(Intent intent, final AssistDataReceiver assistDataReceiver, + public void startRecentsActivity(Intent intent, long eventTime, final RecentsAnimationListener animationHandler, final Consumer<Boolean> resultCallback, Handler resultCallbackHandler) { try { - IAssistDataReceiver receiver = null; - if (assistDataReceiver != null) { - receiver = new IAssistDataReceiver.Stub() { - public void onHandleAssistData(Bundle resultData) { - assistDataReceiver.onHandleAssistData(resultData); - } - public void onHandleAssistScreenshot(Bitmap screenshot) { - assistDataReceiver.onHandleAssistScreenshot(screenshot); - } - }; - } IRecentsAnimationRunner runner = null; if (animationHandler != null) { runner = new IRecentsAnimationRunner.Stub() { @@ -272,7 +259,7 @@ public class ActivityManagerWrapper { } }; } - ActivityTaskManager.getService().startRecentsActivity(intent, receiver, runner); + ActivityTaskManager.getService().startRecentsActivity(intent, eventTime, runner); if (resultCallback != null) { resultCallbackHandler.post(new Runnable() { @Override diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java index e5f2ad5b7586..5122f6cf31a1 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java @@ -27,6 +27,7 @@ import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.util.Log; +import android.view.InsetsState; import android.view.SurfaceControl; import android.view.WindowManager; import android.view.WindowManagerGlobal; @@ -81,12 +82,25 @@ public class WindowManagerWrapper { WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; public static final int WINDOWING_MODE_FREEFORM = WindowConfiguration.WINDOWING_MODE_FREEFORM; + public static final int ITYPE_EXTRA_NAVIGATION_BAR = InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; + private static final WindowManagerWrapper sInstance = new WindowManagerWrapper(); public static WindowManagerWrapper getInstance() { return sInstance; } + + /** + * Sets {@param providesInsetsTypes} as the inset types provided by {@param params}. + * @param params The window layout params. + * @param providesInsetsTypes The inset types we would like this layout params to provide. + */ + public void setProvidesInsetsTypes(WindowManager.LayoutParams params, + int[] providesInsetsTypes) { + params.providesInsetsTypes = providesInsetsTypes; + } + /** * @return the stable insets for the primary display. */ diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java index 911bf9ef757b..a705ec784c9a 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java @@ -37,6 +37,7 @@ import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.SystemUI; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.statusbar.CommandQueue; import javax.inject.Inject; @@ -66,7 +67,8 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall @Inject public WindowMagnification(Context context, @Main Handler mainHandler, - CommandQueue commandQueue, ModeSwitchesController modeSwitchesController) { + CommandQueue commandQueue, ModeSwitchesController modeSwitchesController, + NavigationModeController navigationModeController) { super(context); mHandler = mainHandler; mLastConfiguration = new Configuration(context.getResources().getConfiguration()); @@ -77,6 +79,9 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall final WindowMagnificationController controller = new WindowMagnificationController(mContext, mHandler, new SfVsyncFrameCallbackProvider(), null, new SurfaceControl.Transaction(), this); + final int navBarMode = navigationModeController.addListener( + controller::onNavigationModeChanged); + controller.onNavigationModeChanged(navBarMode); mWindowMagnificationAnimationController = new WindowMagnificationAnimationController( mContext, controller); } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java index 3832ff307d20..c3474bb7ca57 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java @@ -17,6 +17,8 @@ package com.android.systemui.accessibility; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import android.annotation.NonNull; import android.annotation.Nullable; @@ -117,6 +119,9 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold // The boundary of magnification frame. private final Rect mMagnificationFrameBoundary = new Rect(); + private int mNavBarMode; + private int mNavGestureHeight; + private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider; private Choreographer.FrameCallback mMirrorViewGeometryVsyncCallback; private Locale mLocale; @@ -195,6 +200,19 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold R.dimen.magnification_drag_view_size); mOuterBorderSize = mResources.getDimensionPixelSize( R.dimen.magnification_outer_border_margin); + updateNavigationBarDimensions(); + } + + private void updateNavigationBarDimensions() { + if (!supportsSwipeUpGesture()) { + mNavGestureHeight = 0; + return; + } + mNavGestureHeight = (mDisplaySize.x > mDisplaySize.y) + ? mResources.getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_height_landscape) + : mResources.getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_gesture_height); } /** @@ -239,6 +257,13 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold } } + /** Handles MirrorWindow position when the navigation bar mode changed. */ + public void onNavigationModeChanged(int mode) { + mNavBarMode = mode; + updateNavigationBarDimensions(); + updateMirrorViewLayout(); + } + /** Handles MirrorWindow position when the device rotation changed. */ private void onRotate() { final Display display = mContext.getDisplay(); @@ -246,6 +271,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold display.getRealSize(mDisplaySize); setMagnificationFrameBoundary(); mRotation = display.getRotation(); + updateNavigationBarDimensions(); if (!isWindowVisible()) { return; @@ -401,15 +427,23 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold * moved close to the screen edges. */ private void updateMirrorViewLayout() { + if (!isWindowVisible()) { + return; + } + final int maxMirrorViewX = mDisplaySize.x - mMirrorView.getWidth(); + final int maxMirrorViewY = mDisplaySize.y - mMirrorView.getHeight() - mNavGestureHeight; WindowManager.LayoutParams params = (WindowManager.LayoutParams) mMirrorView.getLayoutParams(); params.x = mMagnificationFrame.left - mMirrorSurfaceMargin; params.y = mMagnificationFrame.top - mMirrorSurfaceMargin; + // If nav bar mode supports swipe-up gesture, the Y position of mirror view should not + // overlap nav bar window to prevent window-dragging obscured. + if (supportsSwipeUpGesture()) { + params.y = Math.min(params.y, maxMirrorViewY); + } // Translates MirrorView position to make MirrorSurfaceView that is inside MirrorView // able to move close to the screen edges. - final int maxMirrorViewX = mDisplaySize.x - mMirrorView.getWidth(); - final int maxMirrorViewY = mDisplaySize.y - mMirrorView.getHeight(); final float translationX; final float translationY; if (params.x < 0) { @@ -621,6 +655,10 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold return mMirrorView != null; } + private boolean supportsSwipeUpGesture() { + return mNavBarMode == NAV_BAR_MODE_2BUTTON || mNavBarMode == NAV_BAR_MODE_GESTURAL; + } + private CharSequence formatStateDescription(float scale) { // Cache the locale-appropriate NumberFormat. Configuration locale is guaranteed // non-null, so the first time this is called we will always get the appropriate diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java index fa3328417bd6..1e239b1e9ec9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java @@ -17,30 +17,44 @@ package com.android.systemui.qs; import com.android.systemui.R; +import com.android.systemui.util.ViewController; import javax.inject.Inject; -public class QSContainerImplController { - private final QSContainerImpl mView; +class QSContainerImplController extends ViewController<QSContainerImpl> { private final QuickStatusBarHeaderController mQuickStatusBarHeaderController; private QSContainerImplController(QSContainerImpl view, QuickStatusBarHeaderController.Builder quickStatusBarHeaderControllerBuilder) { - mView = view; + super(view); mQuickStatusBarHeaderController = quickStatusBarHeaderControllerBuilder .setQuickStatusBarHeader(mView.findViewById(R.id.header)).build(); } + @Override + public void init() { + super.init(); + mQuickStatusBarHeaderController.init(); + } + public void setListening(boolean listening) { mQuickStatusBarHeaderController.setListening(listening); } - public static class Builder { + @Override + protected void onViewAttached() { + } + + @Override + protected void onViewDetached() { + } + + static class Builder { private final QuickStatusBarHeaderController.Builder mQuickStatusBarHeaderControllerBuilder; private QSContainerImpl mView; @Inject - public Builder( + Builder( QuickStatusBarHeaderController.Builder quickStatusBarHeaderControllerBuilder) { mQuickStatusBarHeaderControllerBuilder = quickStatusBarHeaderControllerBuilder; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index f1bb8996e181..3a783653a2d8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -142,7 +142,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca mQSContainerImplController = mQSContainerImplControllerBuilder .setQSContainerImpl((QSContainerImpl) view) .build(); - + mQSContainerImplController.init(); mQSDetail.setQsPanel(mQSPanel, mHeader, (View) mFooter); mQSAnimator = new QSAnimator(this, mHeader.findViewById(R.id.quick_qs_panel), mQSPanel); @@ -367,14 +367,13 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca if (DEBUG) Log.d(TAG, "setListening " + listening); mListening = listening; mQSContainerImplController.setListening(listening); - mHeader.setListening(listening); mFooter.setListening(listening); mQSPanel.setListening(mListening, mQsExpanded); } @Override public void setHeaderListening(boolean listening) { - mHeader.setListening(listening); + mQSContainerImplController.setListening(listening); mFooter.setListening(listening); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 544249a51b08..a9fbc744b38e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -17,27 +17,16 @@ package com.android.systemui.qs; import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT; - import android.annotation.ColorInt; -import android.app.AlarmManager; +import android.app.AlarmManager.AlarmClockInfo; import android.content.Context; -import android.content.Intent; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; import android.media.AudioManager; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.provider.AlarmClock; -import android.provider.Settings; -import android.service.notification.ZenModeConfig; -import android.text.format.DateUtils; import android.util.AttributeSet; -import android.util.Log; import android.util.MathUtils; import android.util.Pair; import android.view.ContextThemeWrapper; @@ -53,93 +42,48 @@ import android.widget.Space; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleRegistry; -import com.android.internal.logging.UiEventLogger; import com.android.settingslib.Utils; import com.android.systemui.BatteryMeterView; import com.android.systemui.DualToneHandler; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.demomode.DemoMode; -import com.android.systemui.demomode.DemoModeController; -import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.privacy.OngoingPrivacyChip; -import com.android.systemui.privacy.PrivacyChipEvent; -import com.android.systemui.privacy.PrivacyItem; -import com.android.systemui.privacy.PrivacyItemController; import com.android.systemui.qs.QSDetail.Callback; -import com.android.systemui.qs.carrier.QSCarrierGroup; -import com.android.systemui.settings.UserTracker; -import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager; import com.android.systemui.statusbar.phone.StatusBarWindowView; -import com.android.systemui.statusbar.phone.StatusIconContainer; import com.android.systemui.statusbar.policy.Clock; -import com.android.systemui.statusbar.policy.DateView; -import com.android.systemui.statusbar.policy.NextAlarmController; -import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.systemui.util.RingerModeTracker; -import java.util.ArrayList; -import java.util.List; import java.util.Locale; import java.util.Objects; -import javax.inject.Inject; -import javax.inject.Named; - /** * View that contains the top-most bits of the screen (primarily the status bar with date, time, and * battery) and also contains the {@link QuickQSPanel} along with some of the panel's inner * contents. */ -public class QuickStatusBarHeader extends RelativeLayout implements - View.OnClickListener, NextAlarmController.NextAlarmChangeCallback, - ZenModeController.Callback, LifecycleOwner { - private static final String TAG = "QuickStatusBarHeader"; - private static final boolean DEBUG = false; - - /** Delay for auto fading out the long press tooltip after it's fully visible (in ms). */ - private static final long AUTO_FADE_OUT_DELAY_MS = DateUtils.SECOND_IN_MILLIS * 6; - private static final int FADE_ANIMATION_DURATION_MS = 300; - private static final int TOOLTIP_NOT_YET_SHOWN_COUNT = 0; - public static final int MAX_TOOLTIP_SHOWN_COUNT = 2; +public class QuickStatusBarHeader extends RelativeLayout implements LifecycleOwner { - private final NextAlarmController mAlarmController; - private final ZenModeController mZenController; - private final StatusBarIconController mStatusBarIconController; - private final ActivityStarter mActivityStarter; - - private QSPanel mQsPanel; + public static final int MAX_TOOLTIP_SHOWN_COUNT = 2; private boolean mExpanded; - private boolean mListening; private boolean mQsDisabled; - private QSCarrierGroup mCarrierGroup; protected QuickQSPanel mHeaderQsPanel; - protected QSTileHost mHost; - private TintedIconManager mIconManager; private TouchAnimator mStatusIconsAlphaAnimator; private TouchAnimator mHeaderTextContainerAlphaAnimator; private TouchAnimator mPrivacyChipAlphaAnimator; private DualToneHandler mDualToneHandler; - private final CommandQueue mCommandQueue; private View mSystemIconsView; private View mQuickQsStatusIcons; private View mHeaderTextContainerView; - private int mRingerMode = AudioManager.RINGER_MODE_NORMAL; - private AlarmManager.AlarmClockInfo mNextAlarm; - private ImageView mNextAlarmIcon; /** {@link TextView} containing the actual text indicating when the next alarm will go off. */ private TextView mNextAlarmTextView; @@ -149,23 +93,13 @@ public class QuickStatusBarHeader extends RelativeLayout implements private TextView mRingerModeTextView; private View mRingerContainer; private Clock mClockView; - private DateView mDateView; private OngoingPrivacyChip mPrivacyChip; private Space mSpace; private BatteryMeterView mBatteryRemainingIcon; - private RingerModeTracker mRingerModeTracker; - private DemoModeController mDemoModeController; - private DemoMode mDemoModeReceiver; - private UserTracker mUserTracker; - private boolean mAllIndicatorsEnabled; - private boolean mMicCameraIndicatorsEnabled; - - private PrivacyItemController mPrivacyItemController; - private final UiEventLogger mUiEventLogger; + // Used for RingerModeTracker private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this); - private boolean mHasTopCutout = false; private int mStatusBarPaddingTop = 0; private int mRoundedCornerPadding = 0; private int mContentMarginStart; @@ -175,59 +109,11 @@ public class QuickStatusBarHeader extends RelativeLayout implements private int mCutOutPaddingRight; private float mExpandedHeaderAlpha = 1.0f; private float mKeyguardExpansionFraction; - private boolean mPrivacyChipLogged = false; - - private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() { - @Override - public void onPrivacyItemsChanged(List<PrivacyItem> privacyItems) { - mPrivacyChip.setPrivacyList(privacyItems); - setChipVisibility(!privacyItems.isEmpty()); - } - - @Override - public void onFlagAllChanged(boolean flag) { - if (mAllIndicatorsEnabled != flag) { - mAllIndicatorsEnabled = flag; - update(); - } - } - @Override - public void onFlagMicCameraChanged(boolean flag) { - if (mMicCameraIndicatorsEnabled != flag) { - mMicCameraIndicatorsEnabled = flag; - update(); - } - } - - private void update() { - StatusIconContainer iconContainer = requireViewById(R.id.statusIcons); - iconContainer.setIgnoredSlots(getIgnoredIconSlots()); - setChipVisibility(!mPrivacyChip.getPrivacyList().isEmpty()); - } - }; - - @Inject - public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, - NextAlarmController nextAlarmController, ZenModeController zenModeController, - StatusBarIconController statusBarIconController, - ActivityStarter activityStarter, PrivacyItemController privacyItemController, - CommandQueue commandQueue, RingerModeTracker ringerModeTracker, - UiEventLogger uiEventLogger, DemoModeController demoModeController, - UserTracker userTracker) { + public QuickStatusBarHeader(Context context, AttributeSet attrs) { super(context, attrs); - mAlarmController = nextAlarmController; - mZenController = zenModeController; - mStatusBarIconController = statusBarIconController; - mActivityStarter = activityStarter; - mPrivacyItemController = privacyItemController; mDualToneHandler = new DualToneHandler( new ContextThemeWrapper(context, R.style.QSHeaderTheme)); - mCommandQueue = commandQueue; - mRingerModeTracker = ringerModeTracker; - mUiEventLogger = uiEventLogger; - mDemoModeController = demoModeController; - mUserTracker = userTracker; } @Override @@ -237,11 +123,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements mHeaderQsPanel = findViewById(R.id.quick_qs_panel); mSystemIconsView = findViewById(R.id.quick_status_bar_system_icons); mQuickQsStatusIcons = findViewById(R.id.quick_qs_status_icons); - StatusIconContainer iconContainer = findViewById(R.id.statusIcons); - // Ignore privacy icons because they show in the space above QQS - iconContainer.addIgnoredSlots(getIgnoredIconSlots()); - iconContainer.setShouldRestrictIcons(false); - mIconManager = new TintedIconManager(iconContainer, mCommandQueue); // Views corresponding to the header info section (e.g. ringer and next alarm). mHeaderTextContainerView = findViewById(R.id.header_text_container); @@ -249,36 +130,18 @@ public class QuickStatusBarHeader extends RelativeLayout implements mNextAlarmIcon = findViewById(R.id.next_alarm_icon); mNextAlarmTextView = findViewById(R.id.next_alarm_text); mNextAlarmContainer = findViewById(R.id.alarm_container); - mNextAlarmContainer.setOnClickListener(this::onClick); mRingerModeIcon = findViewById(R.id.ringer_mode_icon); mRingerModeTextView = findViewById(R.id.ringer_mode_text); mRingerContainer = findViewById(R.id.ringer_container); - mRingerContainer.setOnClickListener(this::onClick); mPrivacyChip = findViewById(R.id.privacy_chip); - mPrivacyChip.setOnClickListener(this::onClick); - mCarrierGroup = findViewById(R.id.carrier_group); - updateResources(); Rect tintArea = new Rect(0, 0, 0, 0); - int colorForeground = Utils.getColorAttrDefaultColor(getContext(), - android.R.attr.colorForeground); - float intensity = getColorIntensity(colorForeground); - int fillColor = mDualToneHandler.getSingleColor(intensity); - // Set light text on the header icons because they will always be on a black background applyDarkness(R.id.clock, tintArea, 0, DarkIconDispatcher.DEFAULT_ICON_TINT); - // Set the correct tint for the status icons so they contrast - mIconManager.setTint(fillColor); - mNextAlarmIcon.setImageTintList(ColorStateList.valueOf(fillColor)); - mRingerModeIcon.setImageTintList(ColorStateList.valueOf(fillColor)); - mClockView = findViewById(R.id.clock); - mClockView.setOnClickListener(this); - mDemoModeReceiver = new ClockDemoModeReceiver(mClockView); - mDateView = findViewById(R.id.date); mSpace = findViewById(R.id.space); // Tint for the battery icons are handled in setupHost() @@ -290,33 +153,28 @@ public class QuickStatusBarHeader extends RelativeLayout implements mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE); mRingerModeTextView.setSelected(true); mNextAlarmTextView.setSelected(true); + } - mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable(); - mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable(); + void onAttach(TintedIconManager iconManager) { + int colorForeground = Utils.getColorAttrDefaultColor(getContext(), + android.R.attr.colorForeground); + float intensity = getColorIntensity(colorForeground); + int fillColor = mDualToneHandler.getSingleColor(intensity); + + // Set the correct tint for the status icons so they contrast + iconManager.setTint(fillColor); + mNextAlarmIcon.setImageTintList(ColorStateList.valueOf(fillColor)); + mRingerModeIcon.setImageTintList(ColorStateList.valueOf(fillColor)); } public QuickQSPanel getHeaderQsPanel() { return mHeaderQsPanel; } - private List<String> getIgnoredIconSlots() { - ArrayList<String> ignored = new ArrayList<>(); - if (getChipEnabled()) { - ignored.add(mContext.getResources().getString( - com.android.internal.R.string.status_bar_camera)); - ignored.add(mContext.getResources().getString( - com.android.internal.R.string.status_bar_microphone)); - if (mAllIndicatorsEnabled) { - ignored.add(mContext.getResources().getString( - com.android.internal.R.string.status_bar_location)); - } - } - - return ignored; - } - - private void updateStatusText() { - boolean changed = updateRingerStatus() || updateAlarmStatus(); + void updateStatusText(int ringerMode, AlarmClockInfo nextAlarm, boolean zenOverridingRinger, + boolean use24HourFormat) { + boolean changed = updateRingerStatus(ringerMode, zenOverridingRinger) + || updateAlarmStatus(nextAlarm, use24HourFormat); if (changed) { boolean alarmVisible = mNextAlarmTextView.getVisibility() == View.VISIBLE; @@ -326,32 +184,17 @@ public class QuickStatusBarHeader extends RelativeLayout implements } } - private void setChipVisibility(boolean chipVisible) { - if (chipVisible && getChipEnabled()) { - mPrivacyChip.setVisibility(View.VISIBLE); - // Makes sure that the chip is logged as viewed at most once each time QS is opened - // mListening makes sure that the callback didn't return after the user closed QS - if (!mPrivacyChipLogged && mListening) { - mPrivacyChipLogged = true; - mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_VIEW); - } - } else { - mPrivacyChip.setVisibility(View.GONE); - } - } - - private boolean updateRingerStatus() { + private boolean updateRingerStatus(int ringerMode, boolean zenOverridingRinger) { boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE; CharSequence originalRingerText = mRingerModeTextView.getText(); boolean ringerVisible = false; - if (!ZenModeConfig.isZenOverridingRinger(mZenController.getZen(), - mZenController.getConsolidatedPolicy())) { - if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { + if (!zenOverridingRinger) { + if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { mRingerModeIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate); mRingerModeTextView.setText(R.string.qs_status_phone_vibrate); ringerVisible = true; - } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT) { + } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) { mRingerModeIcon.setImageResource(R.drawable.ic_volume_ringer_mute); mRingerModeTextView.setText(R.string.qs_status_phone_muted); ringerVisible = true; @@ -365,14 +208,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements !Objects.equals(originalRingerText, mRingerModeTextView.getText()); } - private boolean updateAlarmStatus() { + private boolean updateAlarmStatus(AlarmClockInfo nextAlarm, boolean use24HourFormat) { boolean isOriginalVisible = mNextAlarmTextView.getVisibility() == View.VISIBLE; CharSequence originalAlarmText = mNextAlarmTextView.getText(); boolean alarmVisible = false; - if (mNextAlarm != null) { + if (nextAlarm != null) { alarmVisible = true; - mNextAlarmTextView.setText(formatNextAlarm(mNextAlarm)); + mNextAlarmTextView.setText(formatNextAlarm(nextAlarm, use24HourFormat)); } mNextAlarmIcon.setVisibility(alarmVisible ? View.VISIBLE : View.GONE); mNextAlarmTextView.setVisibility(alarmVisible ? View.VISIBLE : View.GONE); @@ -419,7 +262,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements setMinimumHeight(sbHeight + qqsHeight); } - private void updateResources() { + void updateResources() { Resources resources = mContext.getResources(); updateMinimumHeight(); @@ -529,18 +372,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements } @Override - public void onAttachedToWindow() { - super.onAttachedToWindow(); - mRingerModeTracker.getRingerModeInternal().observe(this, ringer -> { - mRingerMode = ringer; - updateStatusText(); - }); - mStatusBarIconController.addIconGroup(mIconManager); - mDemoModeController.addCallback(mDemoModeReceiver); - requestApplyInsets(); - } - - @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { // Handle padding of the clock DisplayCutout cutout = insets.getDisplayCutout(); @@ -563,17 +394,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements if (cutout != null) { Rect topCutout = cutout.getBoundingRectTop(); if (topCutout.isEmpty() || cornerCutout) { - mHasTopCutout = false; lp.width = 0; mSpace.setVisibility(View.GONE); } else { - mHasTopCutout = true; lp.width = topCutout.width(); mSpace.setVisibility(View.VISIBLE); } } mSpace.setLayoutParams(lp); - setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE); mCutOutPaddingLeft = padding.first; mCutOutPaddingRight = padding.second; mWaterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top; @@ -611,103 +439,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements 0); } - @Override - @VisibleForTesting - public void onDetachedFromWindow() { - setListening(false); - mRingerModeTracker.getRingerModeInternal().removeObservers(this); - mStatusBarIconController.removeIconGroup(mIconManager); - mDemoModeController.removeCallback(mDemoModeReceiver); - super.onDetachedFromWindow(); - } - - public void setListening(boolean listening) { - if (listening == mListening) { - return; - } - mHeaderQsPanel.setListening(listening); - if (mHeaderQsPanel.switchTileLayout()) { - updateResources(); - } - mListening = listening; - - if (listening) { - mZenController.addCallback(this); - mAlarmController.addCallback(this); - mLifecycle.setCurrentState(Lifecycle.State.RESUMED); - // Get the most up to date info - mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable(); - mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable(); - mPrivacyItemController.addCallback(mPICCallback); - } else { - mZenController.removeCallback(this); - mAlarmController.removeCallback(this); - mLifecycle.setCurrentState(Lifecycle.State.CREATED); - mPrivacyItemController.removeCallback(mPICCallback); - mPrivacyChipLogged = false; - } - } - - @Override - public void onClick(View v) { - if (v == mClockView) { - mActivityStarter.postStartActivityDismissingKeyguard(new Intent( - AlarmClock.ACTION_SHOW_ALARMS), 0); - } else if (v == mNextAlarmContainer && mNextAlarmContainer.isVisibleToUser()) { - if (mNextAlarm.getShowIntent() != null) { - mActivityStarter.postStartActivityDismissingKeyguard( - mNextAlarm.getShowIntent()); - } else { - Log.d(TAG, "No PendingIntent for next alarm. Using default intent"); - mActivityStarter.postStartActivityDismissingKeyguard(new Intent( - AlarmClock.ACTION_SHOW_ALARMS), 0); - } - } else if (v == mPrivacyChip) { - // If the privacy chip is visible, it means there were some indicators - Handler mUiHandler = new Handler(Looper.getMainLooper()); - mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_CLICK); - mUiHandler.post(() -> { - mActivityStarter.postStartActivityDismissingKeyguard( - new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0); - mHost.collapsePanels(); - }); - } else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) { - mActivityStarter.postStartActivityDismissingKeyguard(new Intent( - Settings.ACTION_SOUND_SETTINGS), 0); - } - } - - @Override - public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) { - mNextAlarm = nextAlarm; - updateStatusText(); - } - - @Override - public void onZenChanged(int zen) { - updateStatusText(); - } - - @Override - public void onConfigChanged(ZenModeConfig config) { - updateStatusText(); - } - public void updateEverything() { post(() -> setClickable(!mExpanded)); } public void setQSPanel(final QSPanel qsPanel) { - mQsPanel = qsPanel; - setupHost(qsPanel.getHost()); - } - - public void setupHost(final QSTileHost host) { - mHost = host; //host.setHeaderView(mExpandIndicator); - mHeaderQsPanel.setQSPanelAndHeader(mQsPanel, this); - mHeaderQsPanel.setHost(host, null /* No customization in header */); - + mHeaderQsPanel.setQSPanelAndHeader(qsPanel, this); + mHeaderQsPanel.setHost(qsPanel.getHost(), null /* No customization in header */); Rect tintArea = new Rect(0, 0, 0, 0); int colorForeground = Utils.getColorAttrDefaultColor(getContext(), @@ -721,12 +460,11 @@ public class QuickStatusBarHeader extends RelativeLayout implements mHeaderQsPanel.setCallback(qsPanelCallback); } - private String formatNextAlarm(AlarmManager.AlarmClockInfo info) { + private String formatNextAlarm(AlarmClockInfo info, boolean use24HourFormat) { if (info == null) { return ""; } - String skeleton = android.text.format.DateFormat - .is24HourFormat(mContext, mUserTracker.getUserId()) ? "EHm" : "Ehma"; + String skeleton = use24HourFormat ? "EHm" : "Ehma"; String pattern = android.text.format.DateFormat .getBestDateTimePattern(Locale.getDefault(), skeleton); return android.text.format.DateFormat.format(pattern, info.getTriggerTime()).toString(); @@ -777,37 +515,4 @@ public class QuickStatusBarHeader extends RelativeLayout implements updateHeaderTextContainerAlphaAnimator(); } } - - private boolean getChipEnabled() { - return mMicCameraIndicatorsEnabled || mAllIndicatorsEnabled; - } - - private static class ClockDemoModeReceiver implements DemoMode { - private Clock mClockView; - - @Override - public List<String> demoCommands() { - return List.of(COMMAND_CLOCK); - } - - ClockDemoModeReceiver(Clock clockView) { - mClockView = clockView; - } - - @Override - public void dispatchDemoCommand(String command, Bundle args) { - mClockView.dispatchDemoCommand(command, args); - } - - @Override - public void onDemoModeStarted() { - mClockView.onDemoModeStarted(); - } - - @Override - public void onDemoModeFinished() { - mClockView.onDemoModeFinished(); - } - } - } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java index d899acbade4a..676a300b0ff2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java @@ -16,36 +16,393 @@ package com.android.systemui.qs; +import android.app.AlarmManager.AlarmClockInfo; +import android.content.Intent; +import android.media.AudioManager; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.provider.AlarmClock; +import android.provider.Settings; +import android.service.notification.ZenModeConfig; +import android.util.Log; +import android.view.View; +import android.view.View.OnClickListener; + +import androidx.annotation.NonNull; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.LifecycleRegistry; + +import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; +import com.android.systemui.demomode.DemoMode; +import com.android.systemui.demomode.DemoModeController; +import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.privacy.OngoingPrivacyChip; +import com.android.systemui.privacy.PrivacyChipEvent; +import com.android.systemui.privacy.PrivacyItem; +import com.android.systemui.privacy.PrivacyItemController; import com.android.systemui.qs.carrier.QSCarrierGroupController; +import com.android.systemui.settings.UserTracker; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.statusbar.phone.StatusIconContainer; +import com.android.systemui.statusbar.policy.Clock; +import com.android.systemui.statusbar.policy.NextAlarmController; +import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback; +import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.statusbar.policy.ZenModeController.Callback; +import com.android.systemui.util.RingerModeTracker; +import com.android.systemui.util.ViewController; + +import java.util.ArrayList; +import java.util.List; import javax.inject.Inject; -public class QuickStatusBarHeaderController { - private final QuickStatusBarHeader mView; +/** + * Controller for {@link QuickStatusBarHeader}. + */ +class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader> { + private static final String TAG = "QuickStatusBarHeader"; + + private final ZenModeController mZenModeController; + private final NextAlarmController mNextAlarmController; + private final PrivacyItemController mPrivacyItemController; + private final RingerModeTracker mRingerModeTracker; + private final ActivityStarter mActivityStarter; + private final UiEventLogger mUiEventLogger; private final QSCarrierGroupController mQSCarrierGroupController; + private final QuickQSPanel mHeaderQsPanel; + private final LifecycleRegistry mLifecycle; + private final OngoingPrivacyChip mPrivacyChip; + private final Clock mClockView; + private final View mNextAlarmContainer; + private final View mRingerContainer; + private final QSTileHost mQSTileHost; + private final StatusBarIconController mStatusBarIconController; + private final CommandQueue mCommandQueue; + private final DemoModeController mDemoModeController; + private final UserTracker mUserTracker; + private final StatusIconContainer mIconContainer; + private final StatusBarIconController.TintedIconManager mIconManager; + private final DemoMode mDemoModeReceiver; + + private boolean mListening; + private AlarmClockInfo mNextAlarm; + private boolean mAllIndicatorsEnabled; + private boolean mMicCameraIndicatorsEnabled; + private boolean mPrivacyChipLogged; + private int mRingerMode = AudioManager.RINGER_MODE_NORMAL; + + private final ZenModeController.Callback mZenModeControllerCallback = new Callback() { + @Override + public void onZenChanged(int zen) { + mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(), + use24HourFormat()); + } + + @Override + public void onConfigChanged(ZenModeConfig config) { + mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(), + use24HourFormat()); + } + }; + + private boolean use24HourFormat() { + return android.text.format.DateFormat.is24HourFormat( + mView.getContext(), mUserTracker.getUserId()); + + } + + private final NextAlarmChangeCallback mNextAlarmChangeCallback = new NextAlarmChangeCallback() { + @Override + public void onNextAlarmChanged(AlarmClockInfo nextAlarm) { + mNextAlarm = nextAlarm; + mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(), + use24HourFormat()); + } + }; + + private final LifecycleOwner mLifecycleOwner = new LifecycleOwner() { + @NonNull + @Override + public Lifecycle getLifecycle() { + return mLifecycle; + } + }; + + private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() { + @Override + public void onPrivacyItemsChanged(@NonNull List<PrivacyItem> privacyItems) { + mPrivacyChip.setPrivacyList(privacyItems); + setChipVisibility(!privacyItems.isEmpty()); + } + + @Override + public void onFlagAllChanged(boolean flag) { + if (mAllIndicatorsEnabled != flag) { + mAllIndicatorsEnabled = flag; + update(); + } + } + + @Override + public void onFlagMicCameraChanged(boolean flag) { + if (mMicCameraIndicatorsEnabled != flag) { + mMicCameraIndicatorsEnabled = flag; + update(); + } + } + + private void update() { + StatusIconContainer iconContainer = mView.requireViewById(R.id.statusIcons); + iconContainer.setIgnoredSlots(getIgnoredIconSlots()); + setChipVisibility(!mPrivacyChip.getPrivacyList().isEmpty()); + } + }; + + private View.OnClickListener mOnClickListener = new OnClickListener() { + @Override + public void onClick(View v) { + if (v == mClockView) { + mActivityStarter.postStartActivityDismissingKeyguard(new Intent( + AlarmClock.ACTION_SHOW_ALARMS), 0); + } else if (v == mNextAlarmContainer && mNextAlarmContainer.isVisibleToUser()) { + if (mNextAlarm.getShowIntent() != null) { + mActivityStarter.postStartActivityDismissingKeyguard( + mNextAlarm.getShowIntent()); + } else { + Log.d(TAG, "No PendingIntent for next alarm. Using default intent"); + mActivityStarter.postStartActivityDismissingKeyguard(new Intent( + AlarmClock.ACTION_SHOW_ALARMS), 0); + } + } else if (v == mPrivacyChip) { + // If the privacy chip is visible, it means there were some indicators + Handler mUiHandler = new Handler(Looper.getMainLooper()); + mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_CLICK); + mUiHandler.post(() -> { + mActivityStarter.postStartActivityDismissingKeyguard( + new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0); + mQSTileHost.collapsePanels(); + }); + } else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) { + mActivityStarter.postStartActivityDismissingKeyguard(new Intent( + Settings.ACTION_SOUND_SETTINGS), 0); + } + } + }; private QuickStatusBarHeaderController(QuickStatusBarHeader view, + ZenModeController zenModeController, NextAlarmController nextAlarmController, + PrivacyItemController privacyItemController, RingerModeTracker ringerModeTracker, + ActivityStarter activityStarter, UiEventLogger uiEventLogger, + QSTileHost qsTileHost, StatusBarIconController statusBarIconController, + CommandQueue commandQueue, DemoModeController demoModeController, + UserTracker userTracker, QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder) { - mView = view; + super(view); + mZenModeController = zenModeController; + mNextAlarmController = nextAlarmController; + mPrivacyItemController = privacyItemController; + mRingerModeTracker = ringerModeTracker; + mActivityStarter = activityStarter; + mUiEventLogger = uiEventLogger; + mQSTileHost = qsTileHost; + mStatusBarIconController = statusBarIconController; + mCommandQueue = commandQueue; + mDemoModeController = demoModeController; + mUserTracker = userTracker; + mLifecycle = new LifecycleRegistry(mLifecycleOwner); + mQSCarrierGroupController = qsCarrierGroupControllerBuilder .setQSCarrierGroup(mView.findViewById(R.id.carrier_group)) .build(); + + + mPrivacyChip = mView.findViewById(R.id.privacy_chip); + mHeaderQsPanel = mView.findViewById(R.id.quick_qs_panel); + mNextAlarmContainer = mView.findViewById(R.id.alarm_container); + mClockView = mView.findViewById(R.id.clock); + mRingerContainer = mView.findViewById(R.id.ringer_container); + mIconContainer = mView.findViewById(R.id.statusIcons); + + mIconManager = new StatusBarIconController.TintedIconManager(mIconContainer, mCommandQueue); + mDemoModeReceiver = new ClockDemoModeReceiver(mClockView); + } + + @Override + protected void onViewAttached() { + mRingerModeTracker.getRingerModeInternal().observe(mLifecycleOwner, ringer -> { + mRingerMode = ringer; + mView.updateStatusText(mRingerMode, mNextAlarm, isZenOverridingRinger(), + use24HourFormat()); + }); + + mClockView.setOnClickListener(mOnClickListener); + mNextAlarmContainer.setOnClickListener(mOnClickListener); + mRingerContainer.setOnClickListener(mOnClickListener); + mPrivacyChip.setOnClickListener(mOnClickListener); + + // Ignore privacy icons because they show in the space above QQS + mIconContainer.addIgnoredSlots(getIgnoredIconSlots()); + mIconContainer.setShouldRestrictIcons(false); + mStatusBarIconController.addIconGroup(mIconManager); + + mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable(); + mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable(); + + setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE); + + mView.onAttach(mIconManager); + + mDemoModeController.addCallback(mDemoModeReceiver); + } + + @Override + protected void onViewDetached() { + mRingerModeTracker.getRingerModeInternal().removeObservers(mLifecycleOwner); + mClockView.setOnClickListener(null); + mNextAlarmContainer.setOnClickListener(null); + mRingerContainer.setOnClickListener(null); + mPrivacyChip.setOnClickListener(null); + mStatusBarIconController.removeIconGroup(mIconManager); + mDemoModeController.removeCallback(mDemoModeReceiver); + setListening(false); } public void setListening(boolean listening) { mQSCarrierGroupController.setListening(listening); - // TODO: move mView.setListening logic into here. - mView.setListening(listening); + + if (listening == mListening) { + return; + } + mListening = listening; + + mHeaderQsPanel.setListening(listening); + if (mHeaderQsPanel.switchTileLayout()) { + mView.updateResources(); + } + + if (listening) { + mZenModeController.addCallback(mZenModeControllerCallback); + mNextAlarmController.addCallback(mNextAlarmChangeCallback); + mLifecycle.setCurrentState(Lifecycle.State.RESUMED); + // Get the most up to date info + mAllIndicatorsEnabled = mPrivacyItemController.getAllIndicatorsAvailable(); + mMicCameraIndicatorsEnabled = mPrivacyItemController.getMicCameraAvailable(); + mPrivacyItemController.addCallback(mPICCallback); + } else { + mZenModeController.removeCallback(mZenModeControllerCallback); + mNextAlarmController.removeCallback(mNextAlarmChangeCallback); + mLifecycle.setCurrentState(Lifecycle.State.CREATED); + mPrivacyItemController.removeCallback(mPICCallback); + mPrivacyChipLogged = false; + } } + private void setChipVisibility(boolean chipVisible) { + if (chipVisible && getChipEnabled()) { + mPrivacyChip.setVisibility(View.VISIBLE); + // Makes sure that the chip is logged as viewed at most once each time QS is opened + // mListening makes sure that the callback didn't return after the user closed QS + if (!mPrivacyChipLogged && mListening) { + mPrivacyChipLogged = true; + mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_VIEW); + } + } else { + mPrivacyChip.setVisibility(View.GONE); + } + } - public static class Builder { + private List<String> getIgnoredIconSlots() { + ArrayList<String> ignored = new ArrayList<>(); + if (getChipEnabled()) { + ignored.add(mView.getResources().getString( + com.android.internal.R.string.status_bar_camera)); + ignored.add(mView.getResources().getString( + com.android.internal.R.string.status_bar_microphone)); + if (mAllIndicatorsEnabled) { + ignored.add(mView.getResources().getString( + com.android.internal.R.string.status_bar_location)); + } + } + + return ignored; + } + + private boolean getChipEnabled() { + return mMicCameraIndicatorsEnabled || mAllIndicatorsEnabled; + } + + private boolean isZenOverridingRinger() { + return ZenModeConfig.isZenOverridingRinger(mZenModeController.getZen(), + mZenModeController.getConsolidatedPolicy()); + } + + + private static class ClockDemoModeReceiver implements DemoMode { + private Clock mClockView; + + @Override + public List<String> demoCommands() { + return List.of(COMMAND_CLOCK); + } + + ClockDemoModeReceiver(Clock clockView) { + mClockView = clockView; + } + + @Override + public void dispatchDemoCommand(String command, Bundle args) { + mClockView.dispatchDemoCommand(command, args); + } + + @Override + public void onDemoModeStarted() { + mClockView.onDemoModeStarted(); + } + + @Override + public void onDemoModeFinished() { + mClockView.onDemoModeFinished(); + } + } + + static class Builder { + private final ZenModeController mZenModeController; + private final NextAlarmController mNextAlarmController; + private final PrivacyItemController mPrivacyItemController; + private final RingerModeTracker mRingerModeTracker; + private final ActivityStarter mActivityStarter; + private final UiEventLogger mUiEventLogger; + private final QSTileHost mQsTileHost; + private final StatusBarIconController mStatusBarIconController; + private final CommandQueue mCommandQueue; + private final DemoModeController mDemoModeController; + private final UserTracker mUserTracker; private final QSCarrierGroupController.Builder mQSCarrierGroupControllerBuilder; private QuickStatusBarHeader mView; @Inject - public Builder(QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder) { + Builder(ZenModeController zenModeController, NextAlarmController nextAlarmController, + PrivacyItemController privacyItemController, RingerModeTracker ringerModeTracker, + ActivityStarter activityStarter, UiEventLogger uiEventLogger, QSTileHost qsTileHost, + StatusBarIconController statusBarIconController, CommandQueue commandQueue, + DemoModeController demoModeController, UserTracker userTracker, + QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder) { + mZenModeController = zenModeController; + mNextAlarmController = nextAlarmController; + mPrivacyItemController = privacyItemController; + mRingerModeTracker = ringerModeTracker; + mActivityStarter = activityStarter; + mUiEventLogger = uiEventLogger; + mQsTileHost = qsTileHost; + mStatusBarIconController = statusBarIconController; + mCommandQueue = commandQueue; + mDemoModeController = demoModeController; + mUserTracker = userTracker; mQSCarrierGroupControllerBuilder = qsCarrierGroupControllerBuilder; } @@ -54,8 +411,13 @@ public class QuickStatusBarHeaderController { return this; } - public QuickStatusBarHeaderController build() { - return new QuickStatusBarHeaderController(mView, mQSCarrierGroupControllerBuilder); + + QuickStatusBarHeaderController build() { + return new QuickStatusBarHeaderController(mView, mZenModeController, + mNextAlarmController, mPrivacyItemController, mRingerModeTracker, + mActivityStarter, mUiEventLogger, mQsTileHost, mStatusBarIconController, + mCommandQueue, mDemoModeController, mUserTracker, + mQSCarrierGroupControllerBuilder); } } } diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java index df03c3e08f08..0aa9d4d662a5 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenInternalAudioRecorder.java @@ -48,6 +48,7 @@ public class ScreenInternalAudioRecorder { private long mTotalBytes; private MediaMuxer mMuxer; private boolean mMic; + private boolean mStarted; private int mTrackId = -1; @@ -263,10 +264,14 @@ public class ScreenInternalAudioRecorder { * start recording * @throws IllegalStateException if recording fails to initialize */ - public void start() throws IllegalStateException { - if (mThread != null) { - Log.e(TAG, "a recording is being done in parallel or stop is not called"); + public synchronized void start() throws IllegalStateException { + if (mStarted) { + if (mThread == null) { + throw new IllegalStateException("Recording stopped and can't restart (single use)"); + } + throw new IllegalStateException("Recording already started"); } + mStarted = true; mAudioRecord.startRecording(); if (mMic) mAudioRecordMic.startRecording(); Log.d(TAG, "channel count " + mAudioRecord.getChannelCount()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java index 7aeca64ba9e8..c9d1b71bca77 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java @@ -284,25 +284,28 @@ public class AudioRecordingDisclosureBar implements mAnimator.setTarget(mIndicatorView); mAnimator.setProperty(View.ALPHA); mAnimator.addListener(new AnimatorListenerAdapter() { + boolean mCancelled; + @Override public void onAnimationStart(Animator animation, boolean isReverse) { - if (DEBUG) Log.d(TAG, "onAnimationStart"); + if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationStart"); + mCancelled = false; } @Override public void onAnimationCancel(Animator animation) { - if (DEBUG) Log.d(TAG, "onAnimationCancel"); + if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationCancel"); + mCancelled = true; } @Override public void onAnimationEnd(Animator animation) { - if (DEBUG) Log.d(TAG, "onAnimationEnd"); - - if (mState == STATE_APPEARING) { - mState = STATE_SHOWN; - } else if (mState == STATE_DISAPPEARING) { - removeIndicatorView(); - mState = STATE_NOT_SHOWN; + if (DEBUG) Log.d(TAG, "AnimatorListenerAdapter#onAnimationEnd"); + // When ValueAnimator#cancel() is called it always calls onAnimationCancel(...) + // and then onAnimationEnd(...). We, however, only want to proceed here if the + // animation ended "naturally". + if (!mCancelled) { + onAnimationFinished(); } } }); @@ -319,6 +322,17 @@ public class AudioRecordingDisclosureBar implements mAnimator.start(); } + private void onAnimationFinished() { + if (DEBUG) Log.d(TAG, "onAnimationFinished"); + + if (mState == STATE_APPEARING) { + mState = STATE_SHOWN; + } else if (mState == STATE_DISAPPEARING) { + removeIndicatorView(); + mState = STATE_NOT_SHOWN; + } + } + private boolean hasActiveRecorders() { for (int index = mAudioActivityObservers.length - 1; index >= 0; index--) { for (String activePackage : mAudioActivityObservers[index].getActivePackages()) { @@ -330,6 +344,8 @@ public class AudioRecordingDisclosureBar implements } private void removeIndicatorView() { + if (DEBUG) Log.d(TAG, "removeIndicatorView"); + final WindowManager windowManager = (WindowManager) mContext.getSystemService( Context.WINDOW_SERVICE); windowManager.removeView(mIndicatorView); diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java index a6cd350b33ce..344f0d2f5506 100644 --- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java +++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java @@ -27,7 +27,6 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.qs.QSFooterImpl; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QuickQSPanel; -import com.android.systemui.qs.QuickStatusBarHeader; import com.android.systemui.qs.customize.QSCustomizer; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; @@ -93,10 +92,6 @@ public class InjectionInflationController { } /** - * Creates the QuickStatusBarHeader. - */ - QuickStatusBarHeader createQsHeader(); - /** * Creates the QSFooterImpl. */ QSFooterImpl createQsFooter(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java index 1e969c226ff1..fa78d1cc0191 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java @@ -36,6 +36,7 @@ import android.view.accessibility.IWindowMagnificationConnectionCallback; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.statusbar.CommandQueue; import org.junit.Before; @@ -65,6 +66,8 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase { @Mock private ModeSwitchesController mModeSwitchesController; @Mock + private NavigationModeController mNavigationModeController; + @Mock private IRemoteMagnificationAnimationCallback mAnimationCallback; private IWindowMagnificationConnection mIWindowMagnificationConnection; private WindowMagnification mWindowMagnification; @@ -79,7 +82,8 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase { }).when(mAccessibilityManager).setWindowMagnificationConnection( any(IWindowMagnificationConnection.class)); mWindowMagnification = new WindowMagnification(getContext(), - getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController); + getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController, + mNavigationModeController); mWindowMagnification.mWindowMagnificationAnimationController = mWindowMagnificationAnimationController; mWindowMagnification.requestWindowMagnificationConnection(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java index c6440f4290fd..5f2fd697b86d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java @@ -17,6 +17,7 @@ package com.android.systemui.accessibility; import static android.view.Choreographer.FrameCallback; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import static org.hamcrest.Matchers.containsString; @@ -28,6 +29,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.verify; @@ -294,4 +296,15 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { assertTrue( mMirrorView.performAccessibilityAction(R.id.accessibility_action_move_left, null)); } + + @Test + public void onNavigationModeChanged_updateMirrorViewLayout() { + mInstrumentation.runOnMainSync(() -> { + mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN, + Float.NaN); + mWindowMagnificationController.onNavigationModeChanged(NAV_BAR_MODE_GESTURAL); + }); + + verify(mWindowManager).updateViewLayout(eq(mMirrorView), any()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java index 936558bca2d2..4a0e216ae87e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java @@ -35,6 +35,7 @@ import android.view.accessibility.IWindowMagnificationConnectionCallback; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.statusbar.CommandQueue; import org.junit.Before; @@ -53,6 +54,8 @@ public class WindowMagnificationTest extends SysuiTestCase { private AccessibilityManager mAccessibilityManager; @Mock private ModeSwitchesController mModeSwitchesController; + @Mock + private NavigationModeController mNavigationModeController; private CommandQueue mCommandQueue; private WindowMagnification mWindowMagnification; @@ -63,7 +66,8 @@ public class WindowMagnificationTest extends SysuiTestCase { mCommandQueue = new CommandQueue(getContext()); mWindowMagnification = new WindowMagnification(getContext(), - getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController); + getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController, + mNavigationModeController); mWindowMagnification.start(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java index ca328fbe44fb..9ebb587d3d85 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java @@ -36,6 +36,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.phone.ShadeController; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -73,6 +74,11 @@ public class MediaOutputDialogTest extends SysuiTestCase { when(mMediaDevice.getFeatures()).thenReturn(mFeatures); } + @After + public void tearDown() { + mMediaOutputDialog.dismissDialog(); + } + @Test public void getStopButtonVisibility_remoteDevice_returnVisible() { mFeatures.add(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java index 1c2d08402e69..e472cb22ed6b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java @@ -37,7 +37,6 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.keyguard.CarrierText; import com.android.systemui.Dependency; -import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiBaseFragmentTest; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -116,11 +115,6 @@ public class QSFragmentTest extends SysuiBaseFragmentTest { qs.setListening(false); processAllMessages(); - - // Manually push header through detach so it can handle standard cleanup it does on - // removed from window. - ((QuickStatusBarHeader) qs.getView().findViewById(R.id.header)).onDetachedFromWindow(); - host.destroy(); processAllMessages(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java index f3cdbf7409c1..c0856892dc44 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java @@ -21,6 +21,7 @@ import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS; import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.app.KeyguardManager; @@ -167,6 +168,45 @@ public class VolumeDialogImplTest extends SysuiTestCase { AccessibilityManager.FLAG_CONTENT_CONTROLS); } + @Test + public void testVibrateOnRingerChangedToVibrate() { + final State initialSilentState = new State(); + initialSilentState.ringerModeInternal = AudioManager.RINGER_MODE_SILENT; + + final State vibrateState = new State(); + vibrateState.ringerModeInternal = AudioManager.RINGER_MODE_VIBRATE; + + // change ringer to silent + mDialog.onStateChangedH(initialSilentState); + + // expected: shouldn't call vibrate yet + verify(mController, never()).vibrate(any()); + + // changed ringer to vibrate + mDialog.onStateChangedH(vibrateState); + + // expected: vibrate device + verify(mController).vibrate(any()); + } + + @Test + public void testNoVibrateOnRingerInitialization() { + final State initialUnsetState = new State(); + initialUnsetState.ringerModeInternal = -1; + + // ringer not initialized yet: + mDialog.onStateChangedH(initialUnsetState); + + final State vibrateState = new State(); + vibrateState.ringerModeInternal = AudioManager.RINGER_MODE_VIBRATE; + + // changed ringer to vibrate + mDialog.onStateChangedH(vibrateState); + + // shouldn't call vibrate + verify(mController, never()).vibrate(any()); + } + /* @Test public void testContentDescriptions() { diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp index 915c2f6087b8..613d28b20b8e 100644 --- a/packages/Tethering/Android.bp +++ b/packages/Tethering/Android.bp @@ -102,6 +102,7 @@ java_defaults { ], libs: [ "framework-tethering", + "framework-wifi", ], jarjar_rules: "jarjar-rules.txt", optimize: { diff --git a/packages/Tethering/src/android/net/ip/NeighborPacketForwarder.java b/packages/Tethering/src/android/net/ip/NeighborPacketForwarder.java index 084743db03c4..73fc833fabf5 100644 --- a/packages/Tethering/src/android/net/ip/NeighborPacketForwarder.java +++ b/packages/Tethering/src/android/net/ip/NeighborPacketForwarder.java @@ -25,6 +25,7 @@ import static android.system.OsConstants.SOCK_NONBLOCK; import static android.system.OsConstants.SOCK_RAW; import android.net.util.InterfaceParams; +import android.net.util.PacketReader; import android.net.util.SocketUtils; import android.net.util.TetheringUtils; import android.os.Handler; @@ -32,8 +33,6 @@ import android.system.ErrnoException; import android.system.Os; import android.util.Log; -import com.android.net.module.util.PacketReader; - import java.io.FileDescriptor; import java.io.IOException; import java.net.Inet6Address; diff --git a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java index fd9e36080c80..b285849f9edf 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java @@ -15,6 +15,7 @@ */ package com.android.networkstack.tethering; +import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.TetheringManager.TETHERING_WIFI_P2P; import static java.util.Arrays.asList; @@ -23,7 +24,6 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.IpPrefix; import android.net.LinkAddress; -import android.net.LinkProperties; import android.net.Network; import android.net.ip.IpServer; import android.net.util.PrefixUtils; @@ -90,16 +90,24 @@ public class PrivateAddressCoordinator { /** * Record a new upstream IpPrefix which may conflict with tethering downstreams. - * The downstreams will be notified if a conflict is found. + * The downstreams will be notified if a conflict is found. When updateUpstreamPrefix is called, + * UpstreamNetworkState must have an already populated LinkProperties. */ - public void updateUpstreamPrefix(final Network network, final LinkProperties lp) { - final ArrayList<IpPrefix> ipv4Prefixes = getIpv4Prefixes(lp.getAllLinkAddresses()); + public void updateUpstreamPrefix(final UpstreamNetworkState ns) { + // Do not support VPN as upstream + if (ns.networkCapabilities != null && ns.networkCapabilities.hasTransport(TRANSPORT_VPN)) { + removeUpstreamPrefix(ns.network); + return; + } + + final ArrayList<IpPrefix> ipv4Prefixes = getIpv4Prefixes( + ns.linkProperties.getAllLinkAddresses()); if (ipv4Prefixes.isEmpty()) { - removeUpstreamPrefix(network); + removeUpstreamPrefix(ns.network); return; } - mUpstreamPrefixMap.put(network, ipv4Prefixes); + mUpstreamPrefixMap.put(ns.network, ipv4Prefixes); handleMaybePrefixConflict(ipv4Prefixes); } diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index 64d5025807e7..474f4e8b603a 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -1678,14 +1678,6 @@ public class Tethering { } } - private void addUpstreamPrefixes(final UpstreamNetworkState ns) { - mPrivateAddressCoordinator.updateUpstreamPrefix(ns.network, ns.linkProperties); - } - - private void removeUpstreamPrefixes(final UpstreamNetworkState ns) { - mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network); - } - @VisibleForTesting void handleUpstreamNetworkMonitorCallback(int arg1, Object o) { if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) { @@ -1696,10 +1688,10 @@ public class Tethering { final UpstreamNetworkState ns = (UpstreamNetworkState) o; switch (arg1) { case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES: - addUpstreamPrefixes(ns); + mPrivateAddressCoordinator.updateUpstreamPrefix(ns); break; case UpstreamNetworkMonitor.EVENT_ON_LOST: - removeUpstreamPrefixes(ns); + mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network); break; } diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java index 8e93c2e447b3..7b6632c36f24 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java @@ -15,6 +15,10 @@ */ package com.android.networkstack.tethering; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_VPN; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.TetheringManager.TETHERING_ETHERNET; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; @@ -30,13 +34,12 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.net.ConnectivityManager; -import android.net.InetAddresses; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; +import android.net.NetworkCapabilities; import android.net.ip.IpServer; -import android.net.util.NetworkConstants; import android.net.util.PrefixUtils; import androidx.test.filters.SmallTest; @@ -48,13 +51,10 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.util.List; - @RunWith(AndroidJUnit4.class) @SmallTest public final class PrivateAddressCoordinatorTest { - private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0"; - private static final String TEST_WIFI_IFNAME = "test_wlan0"; + private static final String TEST_IFNAME = "test0"; @Mock private IpServer mHotspotIpServer; @Mock private IpServer mUsbIpServer; @@ -69,7 +69,8 @@ public final class PrivateAddressCoordinatorTest { private final LinkAddress mLegacyWifiP2pAddress = new LinkAddress("192.168.49.1/24"); private final Network mWifiNetwork = new Network(1); private final Network mMobileNetwork = new Network(2); - private final Network[] mAllNetworks = {mMobileNetwork, mWifiNetwork}; + private final Network mVpnNetwork = new Network(3); + private final Network[] mAllNetworks = {mMobileNetwork, mWifiNetwork, mVpnNetwork}; private void setUpIpServers() throws Exception { when(mUsbIpServer.interfaceType()).thenReturn(TETHERING_USB); @@ -184,33 +185,25 @@ public final class PrivateAddressCoordinatorTest { assertEquals("Fail to reselect available prefix: ", predefinedPrefix, allowUseFreePrefix); } - private LinkProperties buildUpstreamLinkProperties(boolean withIPv4, boolean withIPv6, - boolean isMobile) { - final String testIface; - final String testIpv4Address; - if (isMobile) { - testIface = TEST_MOBILE_IFNAME; - testIpv4Address = "10.0.0.1"; - } else { - testIface = TEST_WIFI_IFNAME; - testIpv4Address = "192.168.43.5"; - } - + private UpstreamNetworkState buildUpstreamNetworkState(final Network network, + final LinkAddress v4Addr, final LinkAddress v6Addr, final NetworkCapabilities cap) { final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(testIface); + prop.setInterfaceName(TEST_IFNAME); + if (v4Addr != null) prop.addLinkAddress(v4Addr); - if (withIPv4) { - prop.addLinkAddress( - new LinkAddress(InetAddresses.parseNumericAddress(testIpv4Address), - NetworkConstants.IPV4_ADDR_BITS)); - } + if (v6Addr != null) prop.addLinkAddress(v6Addr); + + return new UpstreamNetworkState(prop, cap, network); + } - if (withIPv6) { - prop.addLinkAddress( - new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"), - NetworkConstants.RFC7421_PREFIX_LENGTH)); + private NetworkCapabilities makeNetworkCapabilities(final int transportType) { + final NetworkCapabilities cap = new NetworkCapabilities(); + cap.addTransportType(transportType); + if (transportType == TRANSPORT_VPN) { + cap.removeCapability(NET_CAPABILITY_NOT_VPN); } - return prop; + + return cap; } @Test @@ -220,53 +213,76 @@ public final class PrivateAddressCoordinatorTest { final IpPrefix predefinedPrefix = new IpPrefix("192.168.43.0/24"); // Force always get subAddress "43.5" for conflict testing. when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr); - // 1. Enable hotspot with prefix 192.168.43.0/24 + // - Enable hotspot with prefix 192.168.43.0/24 final LinkAddress hotspotAddr = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer); final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(hotspotAddr); assertEquals("Wrong wifi prefix: ", predefinedPrefix, hotspotPrefix); when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddr); - // 2. Update v6 only mobile network, hotspot prefix should not be removed. - List<String> testConflicts; - final LinkProperties v6OnlyMobileProp = buildUpstreamLinkProperties(false, true, true); - mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v6OnlyMobileProp); + // - test mobile network with null NetworkCapabilities. Ideally this should not happen, + // just make sure no crash in this case. + final UpstreamNetworkState noCapUpstream = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("10.0.0.8/24"), null, null); + mPrivateAddressCoordinator.updateUpstreamPrefix(noCapUpstream); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + // - test mobile upstream with no address. + final UpstreamNetworkState noAddress = buildUpstreamNetworkState(mMobileNetwork, + null, null, makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(noCapUpstream); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + // - Update v6 only mobile network, hotspot prefix should not be removed. + final UpstreamNetworkState v6OnlyMobile = buildUpstreamNetworkState(mMobileNetwork, + null, new LinkAddress("2001:db8::/64"), + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v6OnlyMobile); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); mPrivateAddressCoordinator.removeUpstreamPrefix(mMobileNetwork); - // 3. Update v4 only mobile network, hotspot prefix should not be removed. - final LinkProperties v4OnlyMobileProp = buildUpstreamLinkProperties(true, false, true); - mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v4OnlyMobileProp); + // - Update v4 only mobile network, hotspot prefix should not be removed. + final UpstreamNetworkState v4OnlyMobile = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("10.0.0.8/24"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyMobile); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); - // 4. Update v4v6 mobile network, hotspot prefix should not be removed. - final LinkProperties v4v6MobileProp = buildUpstreamLinkProperties(true, true, true); - mPrivateAddressCoordinator.updateUpstreamPrefix(mMobileNetwork, v4v6MobileProp); + // - Update v4v6 mobile network, hotspot prefix should not be removed. + final UpstreamNetworkState v4v6Mobile = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("10.0.0.8/24"), new LinkAddress("2001:db8::/64"), + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4v6Mobile); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); - // 5. Update v6 only wifi network, hotspot prefix should not be removed. - final LinkProperties v6OnlyWifiProp = buildUpstreamLinkProperties(false, true, false); - mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v6OnlyWifiProp); + // - Update v6 only wifi network, hotspot prefix should not be removed. + final UpstreamNetworkState v6OnlyWifi = buildUpstreamNetworkState(mWifiNetwork, + null, new LinkAddress("2001:db8::/64"), makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v6OnlyWifi); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); mPrivateAddressCoordinator.removeUpstreamPrefix(mWifiNetwork); - // 6. Update v4 only wifi network, it conflict with hotspot prefix. - final LinkProperties v4OnlyWifiProp = buildUpstreamLinkProperties(true, false, false); - mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v4OnlyWifiProp); + // - Update vpn network, it conflict with hotspot prefix but VPN networks are ignored. + final UpstreamNetworkState v4OnlyVpn = buildUpstreamNetworkState(mVpnNetwork, + new LinkAddress("192.168.43.5/24"), null, makeNetworkCapabilities(TRANSPORT_VPN)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyVpn); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + // - Update v4 only wifi network, it conflict with hotspot prefix. + final UpstreamNetworkState v4OnlyWifi = buildUpstreamNetworkState(mWifiNetwork, + new LinkAddress("192.168.43.5/24"), null, makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyWifi); verify(mHotspotIpServer).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); reset(mHotspotIpServer); - // 7. Restart hotspot again and its prefix is different previous. + // - Restart hotspot again and its prefix is different previous. mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); final LinkAddress hotspotAddr2 = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer); final IpPrefix hotspotPrefix2 = PrefixUtils.asIpPrefix(hotspotAddr2); assertNotEquals(hotspotPrefix, hotspotPrefix2); when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddr2); - mPrivateAddressCoordinator.updateUpstreamPrefix(mWifiNetwork, v4OnlyWifiProp); + mPrivateAddressCoordinator.updateUpstreamPrefix(v4OnlyWifi); verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); - // 7. Usb tethering can be enabled and its prefix is different with conflict one. + // - Usb tethering can be enabled and its prefix is different with conflict one. final LinkAddress usbAddr = mPrivateAddressCoordinator.requestDownstreamAddress( mUsbIpServer); final IpPrefix usbPrefix = PrefixUtils.asIpPrefix(usbAddr); assertNotEquals(predefinedPrefix, usbPrefix); assertNotEquals(hotspotPrefix2, usbPrefix); when(mUsbIpServer.getAddress()).thenReturn(usbAddr); - // 8. Disable wifi upstream, then wifi's prefix can be selected again. + // - Disable wifi upstream, then wifi's prefix can be selected again. mPrivateAddressCoordinator.removeUpstreamPrefix(mWifiNetwork); final LinkAddress ethAddr = mPrivateAddressCoordinator.requestDownstreamAddress( mEthernetIpServer); diff --git a/packages/services/PacProcessor/Android.bp b/packages/services/PacProcessor/Android.bp index 494a8187886d..1fd972ce4b3d 100644 --- a/packages/services/PacProcessor/Android.bp +++ b/packages/services/PacProcessor/Android.bp @@ -19,7 +19,6 @@ android_app { srcs: ["src/**/*.java"], platform_apis: true, certificate: "platform", - jni_libs: ["libjni_pacprocessor"], } filegroup { diff --git a/packages/services/PacProcessor/jni/Android.bp b/packages/services/PacProcessor/jni/Android.bp deleted file mode 100644 index 0e7e10152f81..000000000000 --- a/packages/services/PacProcessor/jni/Android.bp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (C) 2013 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. -// - -cc_library_shared { - name: "libjni_pacprocessor", - - srcs: [ - "jni_init.cpp", - "com_android_pacprocessor_PacNative.cpp", - ], - - shared_libs: [ - "libandroidfw", - "libandroid_runtime", - "liblog", - "libutils", - "libnativehelper", - "libpac", - ], - - cflags: [ - "-Wall", - "-Werror", - "-Wunused", - "-Wunreachable-code", - ], - sanitize: { - cfi: true, - }, -} diff --git a/packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp b/packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp deleted file mode 100644 index d969c69cfaf1..000000000000 --- a/packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -#define LOG_TAG "PacProcessor" - -#include <stdlib.h> -#include <string> - -#include <utils/Log.h> -#include <utils/Mutex.h> -#include "android_runtime/AndroidRuntime.h" - -#include "jni.h" -#include <nativehelper/JNIHelp.h> - -#include "proxy_resolver_v8_wrapper.h" - -namespace android { - -ProxyResolverV8Handle* proxyResolver = NULL; -bool pacSet = false; - -std::u16string jstringToString16(JNIEnv* env, jstring jstr) { - const jchar* str = env->GetStringCritical(jstr, 0); - std::u16string str16(reinterpret_cast<const char16_t*>(str), - env->GetStringLength(jstr)); - env->ReleaseStringCritical(jstr, str); - return str16; -} - -jstring string16ToJstring(JNIEnv* env, std::u16string string) { - const char16_t* str = string.data(); - size_t len = string.length(); - - return env->NewString(reinterpret_cast<const jchar*>(str), len); -} - -static jboolean com_android_pacprocessor_PacNative_createV8ParserNativeLocked(JNIEnv* /* env */, - jobject) { - if (proxyResolver == NULL) { - proxyResolver = ProxyResolverV8Handle_new(); - pacSet = false; - return JNI_FALSE; - } - return JNI_TRUE; -} - -static jboolean com_android_pacprocessor_PacNative_destroyV8ParserNativeLocked(JNIEnv* /* env */, - jobject) { - if (proxyResolver != NULL) { - ProxyResolverV8Handle_delete(proxyResolver); - proxyResolver = NULL; - return JNI_FALSE; - } - return JNI_TRUE; -} - -static jboolean com_android_pacprocessor_PacNative_setProxyScriptNativeLocked(JNIEnv* env, jobject, - jstring script) { - std::u16string script16 = jstringToString16(env, script); - - if (proxyResolver == NULL) { - ALOGE("V8 Parser not started when setting PAC script"); - return JNI_TRUE; - } - - if (ProxyResolverV8Handle_SetPacScript(proxyResolver, script16.data()) != OK) { - ALOGE("Unable to set PAC script"); - return JNI_TRUE; - } - pacSet = true; - - return JNI_FALSE; -} - -static jstring com_android_pacprocessor_PacNative_makeProxyRequestNativeLocked(JNIEnv* env, jobject, - jstring url, jstring host) { - std::u16string url16 = jstringToString16(env, url); - std::u16string host16 = jstringToString16(env, host); - - if (proxyResolver == NULL) { - ALOGE("V8 Parser not initialized when running PAC script"); - return NULL; - } - - if (!pacSet) { - ALOGW("Attempting to run PAC with no script set"); - return NULL; - } - - std::unique_ptr<char16_t, decltype(&free)> result = std::unique_ptr<char16_t, decltype(&free)>( - ProxyResolverV8Handle_GetProxyForURL(proxyResolver, url16.data(), host16.data()), &free); - if (result.get() == NULL) { - ALOGE("Error Running PAC"); - return NULL; - } - - std::u16string ret(result.get()); - jstring jret = string16ToJstring(env, ret); - - return jret; -} - -static const JNINativeMethod gMethods[] = { - { "createV8ParserNativeLocked", "()Z", - (void*)com_android_pacprocessor_PacNative_createV8ParserNativeLocked}, - { "destroyV8ParserNativeLocked", "()Z", - (void*)com_android_pacprocessor_PacNative_destroyV8ParserNativeLocked}, - { "setProxyScriptNativeLocked", "(Ljava/lang/String;)Z", - (void*)com_android_pacprocessor_PacNative_setProxyScriptNativeLocked}, - { "makeProxyRequestNativeLocked", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", - (void*)com_android_pacprocessor_PacNative_makeProxyRequestNativeLocked}, -}; - -int register_com_android_pacprocessor_PacNative(JNIEnv* env) { - return jniRegisterNativeMethods(env, "com/android/pacprocessor/PacNative", - gMethods, NELEM(gMethods)); -} - -} /* namespace android */ diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java deleted file mode 100644 index 9c0cfc27bd14..000000000000 --- a/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright (c) 2013, 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.pacprocessor; - -import android.util.Log; - -/** - * @hide - */ -public class PacNative implements LibpacInterface { - private static final String TAG = "PacProxy"; - - private static final PacNative sInstance = new PacNative(); - - private String mCurrentPac; - - private boolean mIsActive; - - // Only make native calls from inside synchronized blocks. - private native boolean createV8ParserNativeLocked(); - private native boolean destroyV8ParserNativeLocked(); - - private native boolean setProxyScriptNativeLocked(String script); - - private native String makeProxyRequestNativeLocked(String url, String host); - - static { - System.loadLibrary("jni_pacprocessor"); - } - - private PacNative() { - - } - - public static PacNative getInstance() { - return sInstance; - } - - @Override - public synchronized boolean startPacSupport() { - if (createV8ParserNativeLocked()) { - Log.e(TAG, "Unable to Create v8 Proxy Parser."); - return false; - } - mIsActive = true; - return true; - } - - @Override - public synchronized boolean stopPacSupport() { - if (mIsActive) { - if (destroyV8ParserNativeLocked()) { - Log.e(TAG, "Unable to Destroy v8 Proxy Parser."); - return false; - } - mIsActive = false; - } - return true; - } - - @Override - public synchronized boolean setCurrentProxyScript(String script) { - if (setProxyScriptNativeLocked(script)) { - Log.e(TAG, "Unable to parse proxy script."); - return false; - } - return true; - } - - @Override - public synchronized String makeProxyRequest(String url, String host) { - String ret = makeProxyRequestNativeLocked(url, host); - if ((ret == null) || (ret.length() == 0)) { - Log.e(TAG, "v8 Proxy request failed."); - ret = null; - } - return ret; - } - - public synchronized boolean isActive() { - return mIsActive; - } -} diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java index 5a7de9f70b49..46bda06d0e04 100644 --- a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java +++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java @@ -17,13 +17,14 @@ package com.android.pacprocessor; import android.app.Service; import android.content.Intent; -import android.content.res.Resources; import android.os.Binder; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.util.Log; +import android.webkit.PacProcessor; +import com.android.internal.annotations.GuardedBy; import com.android.net.IProxyService; import java.net.MalformedURLException; @@ -31,24 +32,21 @@ import java.net.URL; public class PacService extends Service { private static final String TAG = "PacService"; - private static final boolean sUseWebViewPacProcessor = Resources.getSystem().getBoolean( - com.android.internal.R.bool.config_useWebViewPacProcessor); - private final LibpacInterface mLibpac = sUseWebViewPacProcessor - ? PacWebView.getInstance() - : PacNative.getInstance(); + private Object mLock = new Object(); + + @GuardedBy("mLock") + private final PacProcessor mPacProcessor = PacProcessor.getInstance(); private ProxyServiceStub mStub = new ProxyServiceStub(); @Override public void onCreate() { super.onCreate(); - mLibpac.startPacSupport(); } @Override public void onDestroy() { - mLibpac.stopPacSupport(); super.onDestroy(); } @@ -74,7 +72,10 @@ public class PacService extends Service { throw new IllegalArgumentException("Invalid host was passed"); } } - return mLibpac.makeProxyRequest(url, host); + + synchronized (mLock) { + return mPacProcessor.findProxyForUrl(url); + } } catch (MalformedURLException e) { throw new IllegalArgumentException("Invalid URL was passed"); } @@ -86,7 +87,11 @@ public class PacService extends Service { Log.e(TAG, "Only system user is allowed to call setPacFile"); throw new SecurityException(); } - mLibpac.setCurrentProxyScript(script); + synchronized (mLock) { + if (!mPacProcessor.setProxyScript(script)) { + Log.e(TAG, "Unable to parse proxy script."); + } + } } } } diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacWebView.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacWebView.java deleted file mode 100644 index 4dd00f1ff01b..000000000000 --- a/packages/services/PacProcessor/src/com/android/pacprocessor/PacWebView.java +++ /dev/null @@ -1,48 +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.pacprocessor; - -import android.util.Log; -import android.webkit.PacProcessor; - -/** - * @hide - */ -public class PacWebView implements LibpacInterface { - private static final String TAG = "PacWebView"; - - private static final PacWebView sInstance = new PacWebView(); - private PacProcessor mProcessor = PacProcessor.getInstance(); - - public static PacWebView getInstance() { - return sInstance; - } - - @Override - public synchronized boolean setCurrentProxyScript(String script) { - if (!mProcessor.setProxyScript(script)) { - Log.e(TAG, "Unable to parse proxy script."); - return false; - } - return true; - } - - @Override - public synchronized String makeProxyRequest(String url, String host) { - return mProcessor.findProxyForUrl(url); - } -} diff --git a/services/Android.bp b/services/Android.bp index ef52c2aff002..25a0d7e06b22 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -3,6 +3,12 @@ java_defaults { plugins: [ "error_prone_android_framework", ], + errorprone: { + javacflags: [ + "-Xep:AndroidFrameworkCompatChange:ERROR", + "-Xep:AndroidFrameworkUid:ERROR", + ], + }, } filegroup { diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 6ca99d1a244b..40b171869cf2 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -317,7 +317,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind AndroidFuture<Association> future = new AndroidFuture<>(); service.startDiscovery(request, callingPackage, callback, future); return future; - }).whenComplete(uncheckExceptions((association, err) -> { + }).cancelTimeout().whenComplete(uncheckExceptions((association, err) -> { if (err == null) { addAssociation(association); } else { diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index da5d1c2aa61e..8a1baf25481b 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -136,6 +136,8 @@ import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; import android.net.shared.PrivateDnsConfig; +import android.net.util.LinkPropertiesUtils.CompareOrUpdateResult; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; import android.os.Binder; @@ -193,8 +195,6 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.LocationPermissionChecker; import com.android.internal.util.MessageUtils; import com.android.internal.util.XmlUtils; -import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult; -import com.android.net.module.util.LinkPropertiesUtils.CompareResult; import com.android.server.am.BatteryStatsService; import com.android.server.connectivity.AutodestructReference; import com.android.server.connectivity.DataConnectionStats; diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index d90750548114..4a1820a8e538 100644 --- a/services/core/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java @@ -25,6 +25,7 @@ import android.net.Uri; import android.net.nsd.INsdManager; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; +import android.net.util.nsd.DnsSdTxtRecord; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -41,7 +42,6 @@ import com.android.internal.util.AsyncChannel; import com.android.internal.util.DumpUtils; import com.android.internal.util.State; import com.android.internal.util.StateMachine; -import com.android.net.module.util.DnsSdTxtRecord; import java.io.FileDescriptor; import java.io.PrintWriter; diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 6d774869b391..7775354a8077 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -18,14 +18,10 @@ package com.android.server; import static android.Manifest.permission.ACCESS_MTP; import static android.Manifest.permission.INSTALL_PACKAGES; -import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; -import static android.Manifest.permission.WRITE_MEDIA_STORAGE; -import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.OP_LEGACY_STORAGE; import static android.app.AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE; -import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE; import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES; import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE; import static android.content.pm.PackageManager.MATCH_ANY_USER; @@ -137,7 +133,6 @@ import android.util.TimeUtils; import android.util.Xml; import com.android.internal.annotations.GuardedBy; -import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.content.PackageMonitor; import com.android.internal.os.AppFuseMount; @@ -153,7 +148,6 @@ import com.android.internal.util.HexDump; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; -import com.android.server.SystemService.TargetUser; import com.android.server.pm.Installer; import com.android.server.storage.AppFuseBridge; import com.android.server.storage.StorageSessionController; @@ -2523,19 +2517,6 @@ class StorageManagerService extends IStorageManager.Stub abortIdleMaint(null); } - private void remountUidExternalStorage(int uid, int mode) { - if (uid == Process.SYSTEM_UID) { - // No need to remount uid for system because it has all access anyways - return; - } - - try { - mVold.remountUid(uid, mode); - } catch (Exception e) { - Slog.wtf(TAG, e); - } - } - @Override public void setDebugFlags(int flags, int mask) { enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS); @@ -3847,21 +3828,6 @@ class StorageManagerService extends IStorageManager.Stub } } - private IAppOpsCallback.Stub mAppOpsCallback = new IAppOpsCallback.Stub() { - @Override - public void opChanged(int op, int uid, String packageName) throws RemoteException { - if (!ENABLE_ISOLATED_STORAGE) return; - - int mountMode = getMountMode(uid, packageName); - boolean isUidActive = LocalServices.getService(ActivityManagerInternal.class) - .getUidProcessState(uid) != PROCESS_STATE_NONEXISTENT; - - if (isUidActive) { - remountUidExternalStorage(uid, mountMode); - } - } - }; - private void addObbStateLocked(ObbState obbState) throws RemoteException { final IBinder binder = obbState.getBinder(); List<ObbState> obbStates = mObbMounts.get(binder); @@ -4236,19 +4202,9 @@ class StorageManagerService extends IStorageManager.Stub } // Determine if caller is holding runtime permission - final boolean hasRead = StorageManager.checkPermissionAndCheckOp(mContext, false, 0, - uid, packageName, READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE); final boolean hasWrite = StorageManager.checkPermissionAndCheckOp(mContext, false, 0, uid, packageName, WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE); - // We're only willing to give out broad access if they also hold - // runtime permission; this is a firm CDD requirement - final boolean hasFull = mIPackageManager.checkUidPermission(WRITE_MEDIA_STORAGE, - uid) == PERMISSION_GRANTED; - if (hasFull && hasWrite) { - return Zygote.MOUNT_EXTERNAL_FULL; - } - // We're only willing to give out installer access if they also hold // runtime permission; this is a firm CDD requirement final boolean hasInstall = mIPackageManager.checkUidPermission(INSTALL_PACKAGES, @@ -4268,19 +4224,7 @@ class StorageManagerService extends IStorageManager.Stub if ((hasInstall || hasInstallOp) && hasWrite) { return Zygote.MOUNT_EXTERNAL_INSTALLER; } - - // Otherwise we're willing to give out sandboxed or non-sandboxed if - // they hold the runtime permission - boolean hasLegacy = mIAppOpsService.checkOperation(OP_LEGACY_STORAGE, - uid, packageName) == MODE_ALLOWED; - - if (hasLegacy && hasWrite) { - return Zygote.MOUNT_EXTERNAL_WRITE; - } else if (hasLegacy && hasRead) { - return Zygote.MOUNT_EXTERNAL_READ; - } else { - return Zygote.MOUNT_EXTERNAL_DEFAULT; - } + return Zygote.MOUNT_EXTERNAL_DEFAULT; } catch (RemoteException e) { // Should not happen } @@ -4570,12 +4514,6 @@ class StorageManagerService extends IStorageManager.Stub } @Override - public void onExternalStoragePolicyChanged(int uid, String packageName) { - final int mountMode = getExternalStorageMountMode(uid, packageName); - remountUidExternalStorage(uid, mountMode); - } - - @Override public int getExternalStorageMountMode(int uid, String packageName) { if (ENABLE_ISOLATED_STORAGE) { return getMountMode(uid, packageName); @@ -4720,16 +4658,6 @@ class StorageManagerService extends IStorageManager.Stub updateLegacyStorageApps(packageName, uid, mode == MODE_ALLOWED); return; } - - if (mode == MODE_ALLOWED && (code == OP_READ_EXTERNAL_STORAGE - || code == OP_WRITE_EXTERNAL_STORAGE - || code == OP_REQUEST_INSTALL_PACKAGES)) { - final UserManagerInternal userManagerInternal = - LocalServices.getService(UserManagerInternal.class); - if (userManagerInternal.isUserInitialized(UserHandle.getUserId(uid))) { - onExternalStoragePolicyChanged(uid, packageName); - } - } } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ffdcd156122e..d3f4667fe448 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -153,7 +153,6 @@ import android.app.ContentProviderHolder; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IApplicationThread; -import android.app.IAssistDataReceiver; import android.app.IInstrumentationWatcher; import android.app.INotificationManager; import android.app.IProcessObserver; @@ -286,7 +285,6 @@ import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; import android.view.Display; import android.view.Gravity; -import android.view.IRecentsAnimationRunner; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; @@ -2840,18 +2838,6 @@ public class ActivityManagerService extends IActivityManager.Stub return mActivityTaskManager.startActivityFromRecents(taskId, bOptions); } - @Override - public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver, - IRecentsAnimationRunner recentsAnimationRunner) { - mActivityTaskManager.startRecentsActivity( - intent, assistDataReceiver, recentsAnimationRunner); - } - - @Override - public void cancelRecentsAnimation(boolean restoreHomeStackPosition) { - mActivityTaskManager.cancelRecentsAnimation(restoreHomeStackPosition); - } - /** * This is the internal entry point for handling Activity.finish(). * @@ -16492,7 +16478,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public int getStorageMountMode(int pid, int uid) { if (uid == SHELL_UID || uid == ROOT_UID) { - return Zygote.MOUNT_EXTERNAL_FULL; + return Zygote.MOUNT_EXTERNAL_DEFAULT; } synchronized (mPidsSelfLocked) { final ProcessRecord pr = mPidsSelfLocked.get(pid); diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java index 692b3f11a5f8..b6010d917ef8 100644 --- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java @@ -33,7 +33,6 @@ import android.telephony.ModemActivityInfo; import android.telephony.TelephonyManager; import android.util.IntArray; import android.util.Slog; -import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BatteryStatsImpl; @@ -607,49 +606,11 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } wasReset = true; } else { - final long totalActiveTimeMs = txTimeMs + rxTimeMs; - long maxExpectedIdleTimeMs; - if (totalActiveTimeMs > timePeriodMs) { - // Cap the max idle time at zero since the active time consumed the whole time - maxExpectedIdleTimeMs = 0; - if (totalActiveTimeMs > timePeriodMs + MAX_WIFI_STATS_SAMPLE_ERROR_MILLIS) { - StringBuilder sb = new StringBuilder(); - sb.append("Total Active time "); - TimeUtils.formatDuration(totalActiveTimeMs, sb); - sb.append(" is longer than sample period "); - TimeUtils.formatDuration(timePeriodMs, sb); - sb.append(".\n"); - sb.append("Previous WiFi snapshot: ").append("idle="); - TimeUtils.formatDuration(lastIdleMs, sb); - sb.append(" rx="); - TimeUtils.formatDuration(lastRxMs, sb); - sb.append(" tx="); - TimeUtils.formatDuration(lastTxMs, sb); - sb.append(" e=").append(lastEnergy); - sb.append("\n"); - sb.append("Current WiFi snapshot: ").append("idle="); - TimeUtils.formatDuration(latest.getControllerIdleDurationMillis(), sb); - sb.append(" rx="); - TimeUtils.formatDuration(latest.getControllerRxDurationMillis(), sb); - sb.append(" tx="); - TimeUtils.formatDuration(latest.getControllerTxDurationMillis(), sb); - sb.append(" e=").append(latest.getControllerEnergyUsedMicroJoules()); - Slog.wtf(TAG, sb.toString()); - } - } else { - maxExpectedIdleTimeMs = timePeriodMs - totalActiveTimeMs; - } // These times seem to be the most reliable. deltaControllerTxDurationMillis = txTimeMs; deltaControllerRxDurationMillis = rxTimeMs; deltaControllerScanDurationMillis = scanTimeMs; - // WiFi calculates the idle time as a difference from the on time and the various - // Rx + Tx times. There seems to be some missing time there because this sometimes - // becomes negative. Just cap it at 0 and ensure that it is less than the expected idle - // time from the difference in timestamps. - // b/21613534 - deltaControllerIdleDurationMillis = - Math.min(maxExpectedIdleTimeMs, Math.max(0, idleTimeMs)); + deltaControllerIdleDurationMillis = idleTimeMs; deltaControllerEnergyUsedMicroJoules = Math.max(0, latest.getControllerEnergyUsedMicroJoules() - lastEnergy); wasReset = false; diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java index dbf91ee64333..529c6516398e 100644 --- a/services/core/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java @@ -18,6 +18,7 @@ package com.android.server.am; import android.annotation.NonNull; import android.app.ActivityThread; +import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; @@ -223,16 +224,17 @@ final class CoreSettingsObserver extends ContentObserver { @VisibleForTesting void populateSettings(Bundle snapshot, Map<String, Class<?>> map) { - Context context = mActivityManagerService.mContext; + final Context context = mActivityManagerService.mContext; + final ContentResolver cr = context.getContentResolver(); for (Map.Entry<String, Class<?>> entry : map.entrySet()) { String setting = entry.getKey(); final String value; if (map == sSecureSettingToTypeMap) { - value = Settings.Secure.getString(context.getContentResolver(), setting); + value = Settings.Secure.getStringForUser(cr, setting, cr.getUserId()); } else if (map == sSystemSettingToTypeMap) { - value = Settings.System.getString(context.getContentResolver(), setting); + value = Settings.System.getStringForUser(cr, setting, cr.getUserId()); } else { - value = Settings.Global.getString(context.getContentResolver(), setting); + value = Settings.Global.getString(cr, setting); } if (value == null) { snapshot.remove(setting); diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 5e6556339b43..ed47616d92dc 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -92,7 +92,6 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; -import android.os.storage.StorageManager; import android.os.storage.StorageManagerInternal; import android.system.Os; import android.text.TextUtils; @@ -1780,14 +1779,10 @@ public final class ProcessList { final IPackageManager pm = AppGlobals.getPackageManager(); permGids = pm.getPackageGids(app.info.packageName, MATCH_DIRECT_BOOT_AUTO, app.userId); - if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) { - mountExternal = Zygote.MOUNT_EXTERNAL_FULL; - } else { - StorageManagerInternal storageManagerInternal = LocalServices.getService( - StorageManagerInternal.class); - mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, - app.info.packageName); - } + StorageManagerInternal storageManagerInternal = LocalServices.getService( + StorageManagerInternal.class); + mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, + app.info.packageName); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } @@ -1918,7 +1913,9 @@ public final class ProcessList { String instructionSet = null; if (app.info.primaryCpuAbi != null) { - instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); + // If ABI override is specified, use the isa derived from the value of ABI override. + // Otherwise, use the isa derived from primary ABI + instructionSet = VMRuntime.getInstructionSet(requiredAbi); } app.gids = gids; @@ -1927,7 +1924,7 @@ public final class ProcessList { // If instructionSet is non-null, this indicates that the system_server is spawning a // process with an ISA that may be different from its own. System (kernel and hardware) - // compatililty for these features is checked in the decideTaggingLevel in the + // compatibility for these features is checked in the decideTaggingLevel in the // system_server process (not the child process). As both MTE and TBI are only supported // in aarch64, we can simply ensure that the new process is also aarch64. This prevents // the mismatch where a 64-bit system server spawns a 32-bit child that thinks it should diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index c1777b847d9b..7dbb39e3cb39 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -1709,24 +1709,13 @@ public class AppOpsService extends IAppOpsService.Stub { if (Process.isIsolated(uid)) { return Zygote.MOUNT_EXTERNAL_NONE; } - if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid, - packageName, null, true, "External storage policy", true) - != AppOpsManager.MODE_ALLOWED) { - return Zygote.MOUNT_EXTERNAL_NONE; - } - if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid, - packageName, null, true, "External storage policy", true) - != AppOpsManager.MODE_ALLOWED) { - return Zygote.MOUNT_EXTERNAL_READ; - } - return Zygote.MOUNT_EXTERNAL_WRITE; + return Zygote.MOUNT_EXTERNAL_DEFAULT; } @Override public boolean hasExternalStorage(int uid, String packageName) { final int mountMode = getMountMode(uid, packageName); - return mountMode == Zygote.MOUNT_EXTERNAL_READ - || mountMode == Zygote.MOUNT_EXTERNAL_WRITE; + return mountMode != Zygote.MOUNT_EXTERNAL_NONE; } }); } diff --git a/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java index 92c498c55dbf..bac944fca1de 100644 --- a/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java @@ -27,8 +27,6 @@ public abstract class GenerateChallengeClient<T> extends ClientMonitor<T> { private static final String TAG = "GenerateChallengeClient"; - protected long mChallenge; - public GenerateChallengeClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, @NonNull String owner, int sensorId) { @@ -51,12 +49,5 @@ public abstract class GenerateChallengeClient<T> extends ClientMonitor<T> { super.start(callback); startHalOperation(); - try { - getListener().onChallengeGenerated(getSensorId(), mChallenge); - mCallback.onClientFinished(this, true /* success */); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - mCallback.onClientFinished(this, false /* success */); - } } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java index 49a4b7c4deb3..c2d4c152cba6 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java @@ -519,19 +519,17 @@ class Face10 implements IHwBinder.DeathRecipient { @NonNull String opPackageName) { mHandler.post(() -> { if (mCurrentChallengeOwner != null) { - Slog.w(TAG, "Current challenge owner: " + mCurrentChallengeOwner - + ", interrupted by: " + opPackageName); final ClientMonitorCallbackConverter listener = mCurrentChallengeOwner.getListener(); - if (listener == null) { - Slog.w(TAG, "Null listener, skip sending interruption callback"); - return; - } - - try { - listener.onChallengeInterrupted(mSensorId); - } catch (RemoteException e) { - Slog.e(TAG, "Unable to notify challenge interrupted", e); + Slog.w(TAG, "Current challenge owner: " + mCurrentChallengeOwner + + ", listener: " + listener + + ", interrupted by: " + opPackageName); + if (listener != null) { + try { + listener.onChallengeInterrupted(mSensorId); + } catch (RemoteException e) { + Slog.e(TAG, "Unable to notify challenge interrupted", e); + } } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java index ba401f255e43..406a7ccedc33 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java @@ -59,7 +59,14 @@ public class FaceGenerateChallengeClient extends GenerateChallengeClient<IBiomet @Override protected void startHalOperation() { try { - mChallenge = getFreshDaemon().generateChallenge(CHALLENGE_TIMEOUT_SEC).value; + final long challenge = getFreshDaemon().generateChallenge(CHALLENGE_TIMEOUT_SEC).value; + try { + getListener().onChallengeGenerated(getSensorId(), challenge); + mCallback.onClientFinished(this, true /* success */); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + mCallback.onClientFinished(this, false /* success */); + } } catch (RemoteException e) { Slog.e(TAG, "generateChallenge failed", e); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java index abaaac59fbef..5169c7de8cdd 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintGenerateChallengeClient.java @@ -45,7 +45,14 @@ public class FingerprintGenerateChallengeClient @Override protected void startHalOperation() { try { - mChallenge = getFreshDaemon().preEnroll(); + final long challenge = getFreshDaemon().preEnroll(); + try { + getListener().onChallengeGenerated(getSensorId(), challenge); + mCallback.onClientFinished(this, true /* success */); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + mCallback.onClientFinished(this, false /* success */); + } } catch (RemoteException e) { Slog.e(TAG, "preEnroll failed", e); } diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java index fa03e59f2f2e..626303001ba0 100644 --- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java +++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java @@ -60,12 +60,12 @@ import android.net.ipsec.ike.IkeTrafficSelector; import android.net.ipsec.ike.TunnelModeChildSessionParams; import android.net.ipsec.ike.exceptions.IkeException; import android.net.ipsec.ike.exceptions.IkeProtocolException; +import android.net.util.IpRange; import android.system.OsConstants; import android.util.Log; import com.android.internal.net.VpnProfile; import com.android.internal.util.HexDump; -import com.android.net.module.util.IpRange; import java.net.Inet4Address; import java.net.Inet6Address; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index bb6f14c0f6c4..96679c3ab767 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -16,6 +16,8 @@ package com.android.server.hdmi; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.hardware.hdmi.HdmiPortInfo; import android.hardware.tv.cec.V1_0.CecMessage; import android.hardware.tv.cec.V1_0.HotplugEvent; @@ -774,6 +776,7 @@ final class HdmiCecController { private IHdmiCec mHdmiCec; private final Object mLock = new Object(); private int mPhysicalAddress = INVALID_PHYSICAL_ADDRESS; + @Nullable private HdmiCecCallback mCallback; @Override public String nativeInit() { @@ -782,7 +785,7 @@ final class HdmiCecController { boolean connectToHal() { try { - mHdmiCec = IHdmiCec.getService(); + mHdmiCec = IHdmiCec.getService(true); try { mHdmiCec.linkToDeath(this, HDMI_CEC_HAL_DEATH_COOKIE); } catch (RemoteException e) { @@ -796,7 +799,8 @@ final class HdmiCecController { } @Override - public void setCallback(HdmiCecCallback callback) { + public void setCallback(@NonNull HdmiCecCallback callback) { + mCallback = callback; try { mHdmiCec.setCallback(callback); } catch (RemoteException e) { @@ -936,6 +940,10 @@ final class HdmiCecController { if (cookie == HDMI_CEC_HAL_DEATH_COOKIE) { HdmiLogger.error("Service died cookie : " + cookie + "; reconnecting"); connectToHal(); + // Reconnect the callback + if (mCallback != null) { + setCallback(mCallback); + } } } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index 68473c1830ae..29bdd6cb40c3 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -379,7 +379,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { assertRunOnServiceThread(); if (reason == mService.INITIATED_BY_ENABLE_CEC) { mService.setAndBroadcastActiveSource(mService.getPhysicalAddress(), - getDeviceInfo().getDeviceType(), Constants.ADDR_BROADCAST); + getDeviceInfo().getDeviceType(), Constants.ADDR_BROADCAST, + "HdmiCecLocalDeviceAudioSystem#onAddressAllocated()"); } mService.sendCecCommand( HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( @@ -1324,7 +1325,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { if (getRoutingPort() == Constants.CEC_SWITCH_HOME && mService.isPlaybackDevice()) { routeToInputFromPortId(Constants.CEC_SWITCH_HOME); mService.setAndBroadcastActiveSourceFromOneDeviceType( - message.getSource(), mService.getPhysicalAddress()); + message.getSource(), mService.getPhysicalAddress(), + "HdmiCecLocalDeviceAudioSystem#handleRoutingChangeAndInformationForSwitch()"); return; } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index 6e6d848c2acc..6257032cf709 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -16,6 +16,7 @@ package com.android.server.hdmi; +import android.annotation.CallSuper; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.IHdmiControlCallback; @@ -96,7 +97,8 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { assertRunOnServiceThread(); if (reason == mService.INITIATED_BY_ENABLE_CEC) { mService.setAndBroadcastActiveSource(mService.getPhysicalAddress(), - getDeviceInfo().getDeviceType(), Constants.ADDR_BROADCAST); + getDeviceInfo().getDeviceType(), Constants.ADDR_BROADCAST, + "HdmiCecLocalDevicePlayback#onAddressAllocated()"); } mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( mAddress, mService.getPhysicalAddress(), mDeviceType)); @@ -165,7 +167,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { void onHotplug(int portId, boolean connected) { assertRunOnServiceThread(); mCecMessageCache.flushAll(); - // We'll not clear mIsActiveSource on the hotplug event to pass CETC 11.2.2-2 ~ 3. + // We'll not invalidate the active source on the hotplug event to pass CETC 11.2.2-2 ~ 3. if (!connected) { getWakeLock().release(); } @@ -178,13 +180,12 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { if (!mService.isControlEnabled()) { return; } - if (mIsActiveSource) { + if (isActiveSource()) { mService.sendCecCommand(HdmiCecMessageBuilder.buildInactiveSource( mAddress, mService.getPhysicalAddress())); } - boolean wasActiveSource = mIsActiveSource; + boolean wasActiveSource = isActiveSource(); // Invalidate the internal active source record when goes to standby - // This set will also update mIsActiveSource mService.setActiveSource(Constants.ADDR_INVALID, Constants.INVALID_PHYSICAL_ADDRESS, "HdmiCecLocalDevicePlayback#onStandby()"); if (initiatedByCec || !mAutoTvOff || !wasActiveSource) { @@ -229,12 +230,13 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { } @Override + @CallSuper @ServiceThreadOnly @VisibleForTesting - void setIsActiveSource(boolean on) { + protected void setActiveSource(int logicalAddress, int physicalAddress, String caller) { assertRunOnServiceThread(); - super.setIsActiveSource(on); - if (on) { + super.setActiveSource(logicalAddress, physicalAddress, caller); + if (isActiveSource()) { getWakeLock().acquire(); } else { getWakeLock().release(); @@ -291,7 +293,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { @Override protected void wakeUpIfActiveSource() { - if (!mIsActiveSource) { + if (!isActiveSource()) { return; } // Wake up the device if the power is in standby mode, or its screen is off - @@ -399,9 +401,16 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()"); return; } + if (!isActiveSource()) { + // If routing is changed to the device while Active Source, don't invalidate the + // Active Source + setActiveSource(physicalAddress, + "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()"); + } switch (mPlaybackDeviceActionOnRoutingControl) { case WAKE_UP_AND_SEND_ACTIVE_SOURCE: - setAndBroadcastActiveSource(message, physicalAddress); + setAndBroadcastActiveSource(message, physicalAddress, + "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()"); break; case WAKE_UP_ONLY: mService.wakeUp(); @@ -436,7 +445,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { @Override protected void dump(final IndentingPrintWriter pw) { super.dump(pw); - pw.println("mIsActiveSource: " + mIsActiveSource); + pw.println("isActiveSource(): " + isActiveSource()); pw.println("mAutoTvOff:" + mAutoTvOff); } @@ -457,7 +466,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { @Override public void acquire() { mWakeLock.acquire(); - HdmiLogger.debug("active source: %b. Wake lock acquired", mIsActiveSource); + HdmiLogger.debug("active source: %b. Wake lock acquired", isActiveSource()); } @Override diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index 4ff36c4b65db..4325f797416e 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -16,6 +16,7 @@ package com.android.server.hdmi; +import android.annotation.CallSuper; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPortInfo; import android.hardware.hdmi.IHdmiControlCallback; @@ -36,10 +37,6 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { private static final String TAG = "HdmiCecLocalDeviceSource"; - // Indicate if current device is Active Source or not - @VisibleForTesting - protected boolean mIsActiveSource = false; - // Device has cec switch functionality or not. // Default is false. protected boolean mIsSwitchDevice = HdmiProperties.is_switch().orElse(false); @@ -78,7 +75,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { if (mService.getPortInfo(portId).getType() == HdmiPortInfo.PORT_OUTPUT) { mCecMessageCache.flushAll(); } - // We'll not clear mIsActiveSource on the hotplug event to pass CETC 11.2.2-2 ~ 3. + // We'll not invalidate the active source on the hotplug event to pass CETC 11.2.2-2 ~ 3. if (connected) { mService.wakeUp(); } @@ -118,10 +115,21 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { // Nothing to do. } + @Override + @CallSuper + @ServiceThreadOnly + void setActiveSource(int logicalAddress, int physicalAddress, String caller) { + boolean wasActiveSource = isActiveSource(); + super.setActiveSource(logicalAddress, physicalAddress, caller); + if (wasActiveSource && !isActiveSource()) { + onActiveSourceLost(); + } + } + @ServiceThreadOnly protected void setActiveSource(int physicalAddress, String caller) { assertRunOnServiceThread(); - // Invalidate the internal active source record. This will also update mIsActiveSource. + // Invalidate the internal active source record. ActiveSource activeSource = ActiveSource.of(Constants.ADDR_INVALID, physicalAddress); setActiveSource(activeSource, caller); } @@ -135,7 +143,6 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { if (!getActiveSource().equals(activeSource)) { setActiveSource(activeSource, "HdmiCecLocalDeviceSource#handleActiveSource()"); } - setIsActiveSource(physicalAddress == mService.getPhysicalAddress()); updateDevicePowerStatus(logicalAddress, HdmiControlManager.POWER_STATUS_ON); if (isRoutingControlFeatureEnabled()) { switchInputOnReceivingNewActivePath(physicalAddress); @@ -159,9 +166,11 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { // If current device is the target path, set to Active Source. // If the path is under the current device, should switch if (physicalAddress == mService.getPhysicalAddress() && mService.isPlaybackDevice()) { - setAndBroadcastActiveSource(message, physicalAddress); - } - if (physicalAddress != mService.getPhysicalAddress()) { + setAndBroadcastActiveSource(message, physicalAddress, + "HdmiCecLocalDeviceSource#handleSetStreamPath()"); + } else if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) { + // Invalidate the active source if stream path is set to other physical address or + // our physical address while not active source setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleSetStreamPath()"); } switchInputOnReceivingNewActivePath(physicalAddress); @@ -173,19 +182,15 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { protected boolean handleRoutingChange(HdmiCecMessage message) { assertRunOnServiceThread(); int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams(), 2); - if (physicalAddress != mService.getPhysicalAddress()) { + if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) { + // Invalidate the active source if routing is changed to other physical address or + // our physical address while not active source setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleRoutingChange()"); } if (!isRoutingControlFeatureEnabled()) { mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED); return true; } - // if the current device is a pure playback device - if (!mIsSwitchDevice - && physicalAddress == mService.getPhysicalAddress() - && mService.isPlaybackDevice()) { - setAndBroadcastActiveSource(message, physicalAddress); - } handleRoutingChangeAndInformation(physicalAddress, message); return true; } @@ -195,19 +200,15 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { protected boolean handleRoutingInformation(HdmiCecMessage message) { assertRunOnServiceThread(); int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); - if (physicalAddress != mService.getPhysicalAddress()) { + if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) { + // Invalidate the active source if routing is changed to other physical address or + // our physical address while not active source setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleRoutingInformation()"); } if (!isRoutingControlFeatureEnabled()) { mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED); return true; } - // if the current device is a pure playback device - if (!mIsSwitchDevice - && physicalAddress == mService.getPhysicalAddress() - && mService.isPlaybackDevice()) { - setAndBroadcastActiveSource(message, physicalAddress); - } handleRoutingChangeAndInformation(physicalAddress, message); return true; } @@ -236,23 +237,21 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { // since service can decide who will be the active source when the device supports // multiple device types in this method. // This method should only be called when the device can be the active source. - protected void setAndBroadcastActiveSource(HdmiCecMessage message, int physicalAddress) { + protected void setAndBroadcastActiveSource(HdmiCecMessage message, int physicalAddress, + String caller) { mService.setAndBroadcastActiveSource( - physicalAddress, getDeviceInfo().getDeviceType(), message.getSource()); + physicalAddress, getDeviceInfo().getDeviceType(), message.getSource(), caller); } + // Indicates if current device is the active source or not @ServiceThreadOnly - void setIsActiveSource(boolean on) { - assertRunOnServiceThread(); - boolean wasActiveSource = mIsActiveSource; - mIsActiveSource = on; - if (wasActiveSource && !mIsActiveSource) { - onActiveSourceLost(); - } + protected boolean isActiveSource() { + return getActiveSource().equals(getDeviceInfo().getLogicalAddress(), + getDeviceInfo().getPhysicalAddress()); } protected void wakeUpIfActiveSource() { - if (!mIsActiveSource) { + if (!isActiveSource()) { return; } // Wake up the device @@ -261,7 +260,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { } protected void maySendActiveSource(int dest) { - if (!mIsActiveSource) { + if (!isActiveSource()) { return; } addAndStartAction(new ActiveSourceAction(this, dest)); diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index b407234457a4..a60a676cfa95 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -1600,7 +1600,7 @@ public class HdmiControlService extends SystemService { if (isPlaybackDevice()) { // if playback device itself is the active source, // return its own device info. - if (playback() != null && playback().mIsActiveSource) { + if (playback() != null && playback().isActiveSource()) { return playback().getDeviceInfo(); } // Otherwise get the active source and look for it from the device list @@ -3242,20 +3242,12 @@ public class HdmiControlService extends SystemService { HdmiUtils.pathRelationship(getPhysicalAddress(), physicalAddress)); // If the current device is a source device, check if the current Active Source matches - // the local device info. Set mIsActiveSource of the local device accordingly. + // the local device info. for (HdmiCecLocalDevice device : getAllLocalDevices()) { - // mIsActiveSource only exists in source device, ignore this setting if the current - // device is not an HdmiCecLocalDeviceSource. - if (!(device instanceof HdmiCecLocalDeviceSource)) { - device.addActiveSourceHistoryItem(new ActiveSource(logicalAddress, physicalAddress), - false, caller); - continue; - } boolean deviceIsActiveSource = logicalAddress == device.getDeviceInfo().getLogicalAddress() && physicalAddress == getPhysicalAddress(); - ((HdmiCecLocalDeviceSource) device).setIsActiveSource(deviceIsActiveSource); device.addActiveSourceHistoryItem(new ActiveSource(logicalAddress, physicalAddress), deviceIsActiveSource, caller); } @@ -3266,22 +3258,22 @@ public class HdmiControlService extends SystemService { // For example, when receiving broadcast messages, all the device types will call this // method but only one of them will be the Active Source. protected void setAndBroadcastActiveSource( - int physicalAddress, int deviceType, int source) { + int physicalAddress, int deviceType, int source, String caller) { // If the device has both playback and audio system logical addresses, // playback will claim active source. Otherwise audio system will. if (deviceType == HdmiDeviceInfo.DEVICE_PLAYBACK) { HdmiCecLocalDevicePlayback playback = playback(); - playback.setIsActiveSource(true); + playback.setActiveSource(playback.getDeviceInfo().getLogicalAddress(), physicalAddress, + caller); playback.wakeUpIfActiveSource(); playback.maySendActiveSource(source); } if (deviceType == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) { HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); - if (playback() != null) { - audioSystem.setIsActiveSource(false); - } else { - audioSystem.setIsActiveSource(true); + if (playback() == null) { + audioSystem.setActiveSource(audioSystem.getDeviceInfo().getLogicalAddress(), + physicalAddress, caller); audioSystem.wakeUpIfActiveSource(); audioSystem.maySendActiveSource(source); } @@ -3294,24 +3286,21 @@ public class HdmiControlService extends SystemService { // and this method updates Active Source in all the device types sharing the same // Physical Address. protected void setAndBroadcastActiveSourceFromOneDeviceType( - int sourceAddress, int physicalAddress) { + int sourceAddress, int physicalAddress, String caller) { // If the device has both playback and audio system logical addresses, // playback will claim active source. Otherwise audio system will. HdmiCecLocalDevicePlayback playback = playback(); HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); if (playback != null) { - playback.setIsActiveSource(true); + playback.setActiveSource(playback.getDeviceInfo().getLogicalAddress(), physicalAddress, + caller); playback.wakeUpIfActiveSource(); playback.maySendActiveSource(sourceAddress); - if (audioSystem != null) { - audioSystem.setIsActiveSource(false); - } - } else { - if (audioSystem != null) { - audioSystem.setIsActiveSource(true); - audioSystem.wakeUpIfActiveSource(); - audioSystem.maySendActiveSource(sourceAddress); - } + } else if (audioSystem != null) { + audioSystem.setActiveSource(audioSystem.getDeviceInfo().getLogicalAddress(), + physicalAddress, caller); + audioSystem.wakeUpIfActiveSource(); + audioSystem.maySendActiveSource(sourceAddress); } } diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java index 4962af176f18..e78a86c21453 100644 --- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java +++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java @@ -85,7 +85,7 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction { // Because only source device can create this action, it's safe to cast. HdmiCecLocalDeviceSource source = source(); source.mService.setAndBroadcastActiveSourceFromOneDeviceType( - mTargetAddress, getSourcePath()); + mTargetAddress, getSourcePath(), "OneTouchPlayAction#broadcastActiveSource()"); // When OneTouchPlay is called, client side should be responsible to send out the intent // of which internal source, for example YouTube, it would like to switch to. // Here we only update the active port and the active source records in the local diff --git a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java index 0907e5d03c78..acafda6619f3 100644 --- a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java +++ b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java @@ -119,7 +119,8 @@ public class SystemAudioInitiationActionFromAvr extends HdmiCecFeatureAction { // claim Active Source and start to query TV system audio mode support. if (audioSystem().mService.isPlaybackDevice()) { audioSystem().mService.setAndBroadcastActiveSourceFromOneDeviceType( - Constants.ADDR_BROADCAST, getSourcePath()); + Constants.ADDR_BROADCAST, getSourcePath(), + "SystemAudioInitiationActionFromAvr#handleActiveSourceTimeout()"); mState = STATE_WAITING_FOR_TV_SUPPORT; queryTvSystemAudioModeSupport(); } else { diff --git a/services/core/java/com/android/server/location/LocationProviderManager.java b/services/core/java/com/android/server/location/LocationProviderManager.java index 48f8da4f4b14..dfdb9fbab63a 100644 --- a/services/core/java/com/android/server/location/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/LocationProviderManager.java @@ -1010,7 +1010,7 @@ class LocationProviderManager extends // if the provider is currently disabled fail immediately int userId = getIdentity().getUserId(); - if (!getRequest().isLocationSettingsIgnored() && !isEnabled(userId)) { + if (!isEnabled(userId)) { deliverLocation(null); } } @@ -1172,7 +1172,7 @@ class LocationProviderManager extends protected final LocationManagerInternal mLocationManagerInternal; protected final SettingsHelper mSettingsHelper; - protected final UserInfoHelper mUserInfoHelper; + protected final UserInfoHelper mUserHelper; protected final AlarmHelper mAlarmHelper; protected final AppOpsHelper mAppOpsHelper; protected final LocationPermissionsHelper mLocationPermissionsHelper; @@ -1234,7 +1234,7 @@ class LocationProviderManager extends mLocationManagerInternal = Objects.requireNonNull( LocalServices.getService(LocationManagerInternal.class)); mSettingsHelper = injector.getSettingsHelper(); - mUserInfoHelper = injector.getUserInfoHelper(); + mUserHelper = injector.getUserInfoHelper(); mAlarmHelper = injector.getAlarmHelper(); mAppOpsHelper = injector.getAppOpsHelper(); mLocationPermissionsHelper = injector.getLocationPermissionsHelper(); @@ -1259,7 +1259,7 @@ class LocationProviderManager extends synchronized (mLock) { mStarted = true; - mUserInfoHelper.addListener(mUserChangedListener); + mUserHelper.addListener(mUserChangedListener); mSettingsHelper.addOnLocationEnabledChangedListener(mLocationEnabledChangedListener); long identity = Binder.clearCallingIdentity(); @@ -1274,20 +1274,19 @@ class LocationProviderManager extends public void stopManager() { synchronized (mLock) { - mUserInfoHelper.removeListener(mUserChangedListener); + mUserHelper.removeListener(mUserChangedListener); mSettingsHelper.removeOnLocationEnabledChangedListener(mLocationEnabledChangedListener); - // notify and remove all listeners + mStarted = false; + long identity = Binder.clearCallingIdentity(); try { - onUserStopped(UserHandle.USER_ALL); + onEnabledChanged(UserHandle.USER_ALL); removeRegistrationIf(key -> true); + mEnabledListeners.clear(); } finally { Binder.restoreCallingIdentity(identity); } - - mEnabledListeners.clear(); - mStarted = false; } } @@ -1439,11 +1438,13 @@ class LocationProviderManager extends identity.getPackageName())) { return null; } - if (!mUserInfoHelper.isCurrentUserId(identity.getUserId())) { - return null; - } - if (!ignoreLocationSettings && !isEnabled(identity.getUserId())) { - return null; + if (!ignoreLocationSettings) { + if (!isEnabled(identity.getUserId())) { + return null; + } + if (!identity.isSystem() && !mUserHelper.isCurrentUserId(identity.getUserId())) { + return null; + } } Location location = getLastLocationUnsafe(identity.getUserId(), permissionLevel, @@ -1471,7 +1472,7 @@ class LocationProviderManager extends if (userId == UserHandle.USER_ALL) { // find the most recent location across all users Location lastLocation = null; - final int[] runningUserIds = mUserInfoHelper.getRunningUserIds(); + final int[] runningUserIds = mUserHelper.getRunningUserIds(); for (int i = 0; i < runningUserIds.length; i++) { Location next = getLastLocationUnsafe(runningUserIds[i], permissionLevel, ignoreLocationSettings, maximumAgeMs); @@ -1516,7 +1517,7 @@ class LocationProviderManager extends private void setLastLocation(Location location, int userId) { if (userId == UserHandle.USER_ALL) { - final int[] runningUserIds = mUserInfoHelper.getRunningUserIds(); + final int[] runningUserIds = mUserHelper.getRunningUserIds(); for (int i = 0; i < runningUserIds.length; i++) { setLastLocation(location, runningUserIds[i]); } @@ -1542,7 +1543,7 @@ class LocationProviderManager extends @Nullable public ICancellationSignal getCurrentLocation(LocationRequest request, - CallerIdentity callerIdentity, int permissionLevel, ILocationCallback callback) { + CallerIdentity identity, int permissionLevel, ILocationCallback callback) { if (request.getDurationMillis() > GET_CURRENT_LOCATION_MAX_TIMEOUT_MS) { request = new LocationRequest.Builder(request) .setDurationMillis(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS) @@ -1552,27 +1553,31 @@ class LocationProviderManager extends GetCurrentLocationListenerRegistration registration = new GetCurrentLocationListenerRegistration( request, - callerIdentity, + identity, new GetCurrentLocationTransport(callback), permissionLevel); synchronized (mLock) { - if (mSettingsHelper.isLocationPackageBlacklisted(callerIdentity.getUserId(), - callerIdentity.getPackageName())) { + // shortcut various failure conditions so that we can return immediately rather than + // waiting for location to timeout + if (mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(), + identity.getPackageName())) { registration.deliverLocation(null); return null; } - if (!mUserInfoHelper.isCurrentUserId(callerIdentity.getUserId())) { - registration.deliverLocation(null); - return null; - } - if (!request.isLocationSettingsIgnored() && !isEnabled(callerIdentity.getUserId())) { - registration.deliverLocation(null); - return null; + if (!request.isLocationSettingsIgnored()) { + if (!isEnabled(identity.getUserId())) { + registration.deliverLocation(null); + return null; + } + if (!identity.isSystem() && !mUserHelper.isCurrentUserId(identity.getUserId())) { + registration.deliverLocation(null); + return null; + } } Location lastLocation = getLastLocationUnsafe( - callerIdentity.getUserId(), + identity.getUserId(), permissionLevel, request.isLocationSettingsIgnored(), MAX_CURRENT_LOCATION_AGE_MS); @@ -1582,11 +1587,11 @@ class LocationProviderManager extends } // if last location isn't good enough then we add a location request - long identity = Binder.clearCallingIdentity(); + long ident = Binder.clearCallingIdentity(); try { addRegistration(callback.asBinder(), registration); } finally { - Binder.restoreCallingIdentity(identity); + Binder.restoreCallingIdentity(ident); } } @@ -1610,20 +1615,20 @@ class LocationProviderManager extends } } - public void registerLocationRequest(LocationRequest request, CallerIdentity callerIdentity, + public void registerLocationRequest(LocationRequest request, CallerIdentity identity, @PermissionLevel int permissionLevel, ILocationListener listener) { synchronized (mLock) { - long identity = Binder.clearCallingIdentity(); + long ident = Binder.clearCallingIdentity(); try { addRegistration( listener.asBinder(), new LocationListenerRegistration( request, - callerIdentity, + identity, new LocationListenerTransport(listener), permissionLevel)); } finally { - Binder.restoreCallingIdentity(identity); + Binder.restoreCallingIdentity(ident); } } } @@ -1850,6 +1855,9 @@ class LocationProviderManager extends if (!isEnabled(identity.getUserId())) { return false; } + if (!identity.isSystem() && !mUserHelper.isCurrentUserId(identity.getUserId())) { + return false; + } switch (mLocationPowerSaveModeHelper.getLocationPowerSaveMode()) { case LOCATION_MODE_FOREGROUND_ONLY: @@ -1978,7 +1986,8 @@ class LocationProviderManager extends synchronized (mLock) { switch (change) { case UserListener.CURRENT_USER_CHANGED: - onEnabledChanged(userId); + updateRegistrations( + registration -> registration.getIdentity().getUserId() == userId); break; case UserListener.USER_STARTED: onUserStarted(userId); @@ -2159,13 +2168,10 @@ class LocationProviderManager extends } if (userId == UserHandle.USER_ALL) { - onEnabledChanged(UserHandle.USER_ALL); mEnabled.clear(); mLastLocations.clear(); } else { Preconditions.checkArgument(userId >= 0); - - onEnabledChanged(userId); mEnabled.delete(userId); mLastLocations.remove(userId); } @@ -2182,7 +2188,7 @@ class LocationProviderManager extends // settings for instance) do not support the null user return; } else if (userId == UserHandle.USER_ALL) { - final int[] runningUserIds = mUserInfoHelper.getRunningUserIds(); + final int[] runningUserIds = mUserHelper.getRunningUserIds(); for (int i = 0; i < runningUserIds.length; i++) { onEnabledChanged(runningUserIds[i]); } @@ -2193,7 +2199,6 @@ class LocationProviderManager extends boolean enabled = mStarted && mProvider.getState().allowed - && mUserInfoHelper.isCurrentUserId(userId) && mSettingsHelper.isLocationEnabled(userId); int index = mEnabled.indexOfKey(userId); @@ -2261,7 +2266,7 @@ class LocationProviderManager extends super.dump(fd, ipw, args); - int[] userIds = mUserInfoHelper.getRunningUserIds(); + int[] userIds = mUserHelper.getRunningUserIds(); for (int userId : userIds) { if (userIds.length != 1) { ipw.print("user "); diff --git a/services/core/java/com/android/server/location/geofence/GeofenceManager.java b/services/core/java/com/android/server/location/geofence/GeofenceManager.java index 58e6d593ed2d..baa01b1506af 100644 --- a/services/core/java/com/android/server/location/geofence/GeofenceManager.java +++ b/services/core/java/com/android/server/location/geofence/GeofenceManager.java @@ -327,7 +327,7 @@ public class GeofenceManager extends protected boolean isActive(GeofenceRegistration registration) { CallerIdentity identity = registration.getIdentity(); return registration.isPermitted() - && mUserInfoHelper.isCurrentUserId(identity.getUserId()) + && (identity.isSystem() || mUserInfoHelper.isCurrentUserId(identity.getUserId())) && mSettingsHelper.isLocationEnabled(identity.getUserId()) && !mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(), identity.getPackageName()); diff --git a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java index e782d5ec436d..1cdb118f5787 100644 --- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java +++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java @@ -259,7 +259,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter CallerIdentity identity = registration.getIdentity(); return registration.isPermitted() && (registration.isForeground() || isBackgroundRestrictionExempt(identity)) - && mUserInfoHelper.isCurrentUserId(identity.getUserId()) + && (identity.isSystem() || mUserInfoHelper.isCurrentUserId(identity.getUserId())) && mLocationManagerInternal.isProviderEnabledForUser(GPS_PROVIDER, identity.getUserId()) && !mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(), diff --git a/services/core/java/com/android/server/location/timezone/ControllerImpl.java b/services/core/java/com/android/server/location/timezone/ControllerImpl.java index 179ce750d106..d48263722d38 100644 --- a/services/core/java/com/android/server/location/timezone/ControllerImpl.java +++ b/services/core/java/com/android/server/location/timezone/ControllerImpl.java @@ -44,16 +44,22 @@ import java.util.List; import java.util.Objects; /** - * A real implementation of {@link LocationTimeZoneProviderController} that supports a single - * {@link LocationTimeZoneProvider}. + * A real implementation of {@link LocationTimeZoneProviderController} that supports a primary and a + * secondary {@link LocationTimeZoneProvider}. * - * TODO(b/152744911): This implementation currently only supports a single ("primary") provider. - * Support for a secondary provider will be added in a later commit. + * <p>The primary is used until it fails or becomes uncertain. The secondary will then be enabled. + * The controller will immediately make suggestions based on "certain" {@link + * LocationTimeZoneEvent}s, i.e. events that demonstrate the provider is certain what the time zone + * is. The controller will not make immediate suggestions based on "uncertain" events, giving + * providers time to change their mind. This also gives the secondary provider time to initialize + * when the primary becomes uncertain. */ class ControllerImpl extends LocationTimeZoneProviderController { @NonNull private final LocationTimeZoneProvider mPrimaryProvider; + @NonNull private final LocationTimeZoneProvider mSecondaryProvider; + @GuardedBy("mSharedLock") // Non-null after initialize() private ConfigurationInternal mCurrentUserConfiguration; @@ -67,7 +73,9 @@ class ControllerImpl extends LocationTimeZoneProviderController { private Callback mCallback; /** - * Used for scheduling uncertainty timeouts, i.e after the provider has reported uncertainty. + * Used for scheduling uncertainty timeouts, i.e after a provider has reported uncertainty. + * This timeout is not provider-specific: it is started when the controller becomes uncertain + * due to events it has received from one or other provider. */ @NonNull private final SingleRunnableQueue mUncertaintyTimeoutQueue; @@ -77,10 +85,12 @@ class ControllerImpl extends LocationTimeZoneProviderController { private GeolocationTimeZoneSuggestion mLastSuggestion; ControllerImpl(@NonNull ThreadingDomain threadingDomain, - @NonNull LocationTimeZoneProvider primaryProvider) { + @NonNull LocationTimeZoneProvider primaryProvider, + @NonNull LocationTimeZoneProvider secondaryProvider) { super(threadingDomain); mUncertaintyTimeoutQueue = threadingDomain.createSingleRunnableQueue(); mPrimaryProvider = Objects.requireNonNull(primaryProvider); + mSecondaryProvider = Objects.requireNonNull(secondaryProvider); } @Override @@ -96,8 +106,9 @@ class ControllerImpl extends LocationTimeZoneProviderController { LocationTimeZoneProvider.ProviderListener providerListener = ControllerImpl.this::onProviderStateChange; mPrimaryProvider.initialize(providerListener); + mSecondaryProvider.initialize(providerListener); - alterProviderEnabledStateIfRequired( + alterProvidersEnabledStateIfRequired( null /* oldConfiguration */, mCurrentUserConfiguration); } } @@ -115,15 +126,15 @@ class ControllerImpl extends LocationTimeZoneProviderController { if (!newConfig.equals(oldConfig)) { if (newConfig.getUserId() != oldConfig.getUserId()) { - // If the user changed, disable the provider if needed. It may be re-enabled for - // the new user below if their settings allow. + // If the user changed, disable the providers if needed. They may be re-enabled + // for the new user immediately afterwards if their settings allow. debugLog("User changed. old=" + oldConfig.getUserId() - + ", new=" + newConfig.getUserId() + ": Disabling provider"); - disableProvider(); + + ", new=" + newConfig.getUserId() + ": Disabling providers"); + disableProviders(); - alterProviderEnabledStateIfRequired(null /* oldConfiguration */, newConfig); + alterProvidersEnabledStateIfRequired(null /* oldConfiguration */, newConfig); } else { - alterProviderEnabledStateIfRequired(oldConfig, newConfig); + alterProvidersEnabledStateIfRequired(oldConfig, newConfig); } } } @@ -140,22 +151,23 @@ class ControllerImpl extends LocationTimeZoneProviderController { } @GuardedBy("mSharedLock") - private void disableProvider() { + private void disableProviders() { disableProviderIfEnabled(mPrimaryProvider); + disableProviderIfEnabled(mSecondaryProvider); - // By definition, if the provider is disabled, the controller is uncertain. + // By definition, if both providers are disabled, the controller is uncertain. cancelUncertaintyTimeout(); } @GuardedBy("mSharedLock") - private void disableProviderIfEnabled(LocationTimeZoneProvider provider) { + private void disableProviderIfEnabled(@NonNull LocationTimeZoneProvider provider) { if (provider.getCurrentState().isEnabled()) { disableProvider(provider); } } @GuardedBy("mSharedLock") - private void disableProvider(LocationTimeZoneProvider provider) { + private void disableProvider(@NonNull LocationTimeZoneProvider provider) { ProviderState providerState = provider.getCurrentState(); switch (providerState.stateEnum) { case PROVIDER_STATE_DISABLED: { @@ -181,7 +193,7 @@ class ControllerImpl extends LocationTimeZoneProviderController { } /** - * Sets the provider into the correct enabled/disabled state for the {@code newConfiguration} + * Sets the providers into the correct enabled/disabled state for the {@code newConfiguration} * and, if there is a provider state change, makes any suggestions required to inform the * downstream time zone detection code. * @@ -190,7 +202,7 @@ class ControllerImpl extends LocationTimeZoneProviderController { * or when a new configuration has been received. */ @GuardedBy("mSharedLock") - private void alterProviderEnabledStateIfRequired( + private void alterProvidersEnabledStateIfRequired( @Nullable ConfigurationInternal oldConfiguration, @NonNull ConfigurationInternal newConfiguration) { @@ -203,21 +215,40 @@ class ControllerImpl extends LocationTimeZoneProviderController { return; } + // The check above ensures that the logic below only executes if providers are going from + // {enabled *} -> {disabled}, or {disabled} -> {enabled initializing}. If this changes in + // future and there could be {enabled *} -> {enabled *} cases, or cases where the provider + // can't be assumed to go straight to the {enabled initializing} state, then the logic below + // would need to cover extra conditions, for example: + // 1) If the primary is in {enabled uncertain}, the secondary should be enabled. + // 2) If (1), and the secondary instantly enters the {perm failed} state, the uncertainty + // timeout started when the primary entered {enabled uncertain} should be cancelled. + if (newGeoDetectionEnabled) { // Try to enable the primary provider. tryEnableProvider(mPrimaryProvider, newConfiguration); + // The secondary should only ever be enabled if the primary now isn't enabled (i.e. it + // couldn't become {enabled initializing} because it is {perm failed}). ProviderState newPrimaryState = mPrimaryProvider.getCurrentState(); if (!newPrimaryState.isEnabled()) { - // If the provider is perm failed then the controller is immediately considered - // uncertain. - GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion( - "Provider is failed:" - + " primary=" + mPrimaryProvider.getCurrentState()); - makeSuggestion(suggestion); + // If the primary provider is {perm failed} then the controller must try to enable + // the secondary. + tryEnableProvider(mSecondaryProvider, newConfiguration); + + ProviderState newSecondaryState = mSecondaryProvider.getCurrentState(); + if (!newSecondaryState.isEnabled()) { + // If both providers are {perm failed} then the controller immediately + // becomes uncertain. + GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion( + "Providers are failed:" + + " primary=" + mPrimaryProvider.getCurrentState() + + " secondary=" + mPrimaryProvider.getCurrentState()); + makeSuggestion(suggestion); + } } } else { - disableProvider(); + disableProviders(); // There can be an uncertainty timeout set if the controller most recently received // an uncertain event. This is a no-op if there isn't a timeout set. @@ -258,78 +289,108 @@ class ControllerImpl extends LocationTimeZoneProviderController { } default: { throw new IllegalStateException("Unknown provider state:" - + " provider=" + provider - + ", state=" + providerState.stateEnum); + + " provider=" + provider); } } } void onProviderStateChange(@NonNull ProviderState providerState) { mThreadingDomain.assertCurrentThread(); - assertProviderKnown(providerState.provider); + LocationTimeZoneProvider provider = providerState.provider; + assertProviderKnown(provider); synchronized (mSharedLock) { switch (providerState.stateEnum) { case PROVIDER_STATE_DISABLED: { - // This should never happen: entering disabled does not trigger an event. + // This should never happen: entering disabled does not trigger a state change. warnLog("onProviderStateChange: Unexpected state change for disabled provider," - + " providerState=" + providerState); + + " provider=" + provider); break; } case PROVIDER_STATE_ENABLED_INITIALIZING: case PROVIDER_STATE_ENABLED_CERTAIN: case PROVIDER_STATE_ENABLED_UNCERTAIN: { - // Entering enabled does not trigger an event, so this only happens if an event - // is received while the provider is enabled. - debugLog("onProviderStateChange: Received notification of an event while" - + " enabled, providerState=" + providerState); - providerEnabledProcessEvent(providerState); + // Entering enabled does not trigger a state change, so this only happens if an + // event is received while the provider is enabled. + debugLog("onProviderStateChange: Received notification of a state change while" + + " enabled, provider=" + provider); + handleProviderEnabledStateChange(providerState); break; } case PROVIDER_STATE_PERM_FAILED: { debugLog("Received notification of permanent failure for" - + " provider=" + providerState); - providerFailedProcessEvent(); + + " provider=" + provider); + handleProviderFailedStateChange(providerState); break; } default: { - warnLog("onProviderStateChange: Unexpected providerState=" + providerState); + warnLog("onProviderStateChange: Unexpected provider=" + provider); } } } } - private void assertProviderKnown(LocationTimeZoneProvider provider) { - if (provider != mPrimaryProvider) { + private void assertProviderKnown(@NonNull LocationTimeZoneProvider provider) { + if (provider != mPrimaryProvider && provider != mSecondaryProvider) { throw new IllegalArgumentException("Unknown provider: " + provider); } } /** - * Called when the provider has reported that it has failed permanently. + * Called when a provider has reported that it has failed permanently. */ @GuardedBy("mSharedLock") - private void providerFailedProcessEvent() { - // If the provider is newly perm failed then the controller is uncertain by - // definition. - cancelUncertaintyTimeout(); + private void handleProviderFailedStateChange(@NonNull ProviderState providerState) { + LocationTimeZoneProvider failedProvider = providerState.provider; + ProviderState primaryCurrentState = mPrimaryProvider.getCurrentState(); + ProviderState secondaryCurrentState = mSecondaryProvider.getCurrentState(); + + // If a provider has failed, the other may need to be enabled. + if (failedProvider == mPrimaryProvider) { + if (secondaryCurrentState.stateEnum != PROVIDER_STATE_PERM_FAILED) { + // The primary must have failed. Try to enable the secondary. This does nothing if + // the provider is already enabled, and will leave the provider in + // {enabled initializing} if the provider is disabled. + tryEnableProvider(mSecondaryProvider, mCurrentUserConfiguration); + } + } else if (failedProvider == mSecondaryProvider) { + // No-op: The secondary will only be active if the primary is uncertain or is failed. + // So, there the primary should not need to be enabled when the secondary fails. + if (primaryCurrentState.stateEnum != PROVIDER_STATE_ENABLED_UNCERTAIN + && primaryCurrentState.stateEnum != PROVIDER_STATE_PERM_FAILED) { + warnLog("Secondary provider unexpected reported a failure:" + + " failed provider=" + failedProvider.getName() + + ", primary provider=" + mPrimaryProvider + + ", secondary provider=" + mSecondaryProvider); + } + } - // If the provider is now failed, then we must send a suggestion informing the time - // zone detector that there are no further updates coming in future. + // If both providers are now failed, the controller needs to tell the next component in the + // time zone detection process. + if (primaryCurrentState.stateEnum == PROVIDER_STATE_PERM_FAILED + && secondaryCurrentState.stateEnum == PROVIDER_STATE_PERM_FAILED) { - GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion( - "The provider is permanently failed:" - + " primary=" + mPrimaryProvider.getCurrentState()); - makeSuggestion(suggestion); + // If both providers are newly failed then the controller is uncertain by definition + // and it will never recover so it can send a suggestion immediately. + cancelUncertaintyTimeout(); + + // If both providers are now failed, then a suggestion must be sent informing the time + // zone detector that there are no further updates coming in future. + GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion( + "Both providers are permanently failed:" + + " primary=" + primaryCurrentState.provider + + ", secondary=" + secondaryCurrentState.provider); + makeSuggestion(suggestion); + } } /** * Called when a provider has changed state but just moved from one enabled state to another * enabled state, usually as a result of a new {@link LocationTimeZoneEvent} being received. - * However, there are rare cases where the event can be null. + * However, there are rare cases where the event can also be null. */ @GuardedBy("mSharedLock") - private void providerEnabledProcessEvent(@NonNull ProviderState providerState) { + private void handleProviderEnabledStateChange(@NonNull ProviderState providerState) { LocationTimeZoneProvider provider = providerState.provider; LocationTimeZoneEvent event = providerState.event; if (event == null) { @@ -353,14 +414,15 @@ class ControllerImpl extends LocationTimeZoneProviderController { if (!mCurrentUserConfiguration.getGeoDetectionEnabledBehavior()) { // This should not happen: the provider should not be in an enabled state if the user // does not have geodetection enabled. - warnLog("Provider=" + providerState + " is enabled, but currentUserConfiguration=" - + mCurrentUserConfiguration + " suggests it shouldn't be."); + warnLog("Provider=" + provider + " is enabled, but" + + " currentUserConfiguration=" + mCurrentUserConfiguration + + " suggests it shouldn't be."); } switch (event.getEventType()) { case EVENT_TYPE_PERMANENT_FAILURE: { - // This shouldn't happen. A provider cannot be enabled and have this event. - warnLog("Provider=" + providerState + // This shouldn't happen. A provider cannot be enabled and have this event type. + warnLog("Provider=" + provider + " is enabled, but event suggests it shouldn't be"); break; } @@ -371,7 +433,7 @@ class ControllerImpl extends LocationTimeZoneProviderController { } case EVENT_TYPE_SUCCESS: { handleProviderCertainty(provider, event.getTimeZoneIds(), - "Event received provider=" + provider.getName() + ", event=" + event); + "Event received provider=" + provider + ", event=" + event); break; } default: { @@ -381,6 +443,9 @@ class ControllerImpl extends LocationTimeZoneProviderController { } } + /** + * Called when a provider has become "certain" about the time zone(s). + */ @GuardedBy("mSharedLock") private void handleProviderCertainty( @NonNull LocationTimeZoneProvider provider, @@ -389,10 +454,14 @@ class ControllerImpl extends LocationTimeZoneProviderController { // By definition, the controller is now certain. cancelUncertaintyTimeout(); + if (provider == mPrimaryProvider) { + disableProviderIfEnabled(mSecondaryProvider); + } + GeolocationTimeZoneSuggestion suggestion = new GeolocationTimeZoneSuggestion(timeZoneIds); suggestion.addDebugInfo(reason); - // Rely on the receiver to dedupe events. It is better to over-communicate. + // Rely on the receiver to dedupe suggestions. It is better to over-communicate. makeSuggestion(suggestion); } @@ -415,6 +484,11 @@ class ControllerImpl extends LocationTimeZoneProviderController { mPrimaryProvider.dump(ipw, args); ipw.decreaseIndent(); // level 2 + ipw.println("Secondary Provider:"); + ipw.increaseIndent(); // level 2 + mSecondaryProvider.dump(ipw, args); + ipw.decreaseIndent(); // level 2 + ipw.decreaseIndent(); // level 1 } } @@ -434,48 +508,59 @@ class ControllerImpl extends LocationTimeZoneProviderController { } /** - * Indicates a provider has become uncertain with the event (if any) received that indicates - * that. + * Called when a provider has become "uncertain" about the time zone. * * <p>A provider is expected to report its uncertainty as soon as it becomes uncertain, as * this enables the most flexibility for the controller to enable other providers when there are * multiple ones available. The controller is therefore responsible for deciding when to make a - * "uncertain" suggestion. + * "uncertain" suggestion to the downstream time zone detector. * - * <p>This method schedules an "uncertain" suggestion (if one isn't already scheduled) to be - * made later if nothing else preempts it. It can be preempted if the provider becomes certain - * (or does anything else that calls {@link #makeSuggestion(GeolocationTimeZoneSuggestion)}) - * within {@link Environment#getUncertaintyDelay()}. Preemption causes the scheduled - * "uncertain" event to be cancelled. If the provider repeatedly sends uncertainty events within - * the uncertainty delay period, those events are effectively ignored (i.e. the timer is not - * reset each time). + * <p>This method schedules an "uncertainty" timeout (if one isn't already scheduled) to be + * triggered later if nothing else preempts it. It can be preempted if the provider becomes + * certain (or does anything else that calls {@link + * #makeSuggestion(GeolocationTimeZoneSuggestion)}) within {@link + * Environment#getUncertaintyDelay()}. Preemption causes the scheduled + * "uncertainty" timeout to be cancelled. If the provider repeatedly sends uncertainty events + * within the uncertainty delay period, those events are effectively ignored (i.e. the timeout + * is not reset each time). */ @GuardedBy("mSharedLock") - void handleProviderUncertainty(@NonNull LocationTimeZoneProvider provider, String reason) { + void handleProviderUncertainty( + @NonNull LocationTimeZoneProvider provider, @NonNull String reason) { Objects.requireNonNull(provider); - // Start the uncertainty timeout if needed. + // Start the uncertainty timeout if needed to ensure the controller will eventually make an + // uncertain suggestion if no success event arrives in time to counteract it. if (!mUncertaintyTimeoutQueue.hasQueued()) { debugLog("Starting uncertainty timeout: reason=" + reason); Duration delay = mEnvironment.getUncertaintyDelay(); - mUncertaintyTimeoutQueue.runDelayed( - this::onProviderUncertaintyTimeout, delay.toMillis()); + mUncertaintyTimeoutQueue.runDelayed(() -> onProviderUncertaintyTimeout(provider), + delay.toMillis()); + } + + if (provider == mPrimaryProvider) { + // (Try to) enable the secondary. It could already be enabled, or enabling might not + // succeed if the provider has previously reported it is perm failed. The uncertainty + // timeout (set above) is used to ensure that an uncertain suggestion will be made if + // the secondary cannot generate a success event in time. + tryEnableProvider(mSecondaryProvider, mCurrentUserConfiguration); } } - private void onProviderUncertaintyTimeout() { + private void onProviderUncertaintyTimeout(@NonNull LocationTimeZoneProvider provider) { mThreadingDomain.assertCurrentThread(); synchronized (mSharedLock) { GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion( - "Uncertainty timeout triggered:" - + " primary=" + mPrimaryProvider.getCurrentState()); + "Uncertainty timeout triggered for " + provider.getName() + ":" + + " primary=" + mPrimaryProvider + + ", secondary=" + mSecondaryProvider); makeSuggestion(suggestion); } } - private static GeolocationTimeZoneSuggestion createUncertainSuggestion(String reason) { + private static GeolocationTimeZoneSuggestion createUncertainSuggestion(@NonNull String reason) { GeolocationTimeZoneSuggestion suggestion = new GeolocationTimeZoneSuggestion(null); suggestion.addDebugInfo(reason); return suggestion; @@ -485,11 +570,13 @@ class ControllerImpl extends LocationTimeZoneProviderController { * Asynchronously passes a {@link SimulatedBinderProviderEvent] to the appropriate provider. * If the provider name does not match a known provider, then the event is logged and discarded. */ - void simulateBinderProviderEvent(SimulatedBinderProviderEvent event) { + void simulateBinderProviderEvent(@NonNull SimulatedBinderProviderEvent event) { String targetProviderName = event.getProviderName(); LocationTimeZoneProvider targetProvider; if (Objects.equals(mPrimaryProvider.getName(), targetProviderName)) { targetProvider = mPrimaryProvider; + } else if (Objects.equals(mSecondaryProvider.getName(), targetProviderName)) { + targetProvider = mSecondaryProvider; } else { warnLog("Unable to process simulated binder provider event," + " unknown providerName in event=" + event); diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java index c9a211d96fc0..a8589d43116d 100644 --- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java +++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java @@ -44,8 +44,8 @@ import java.util.Objects; * are made to the {@link TimeZoneDetectorInternal}, and the {@link LocationTimeZoneProvider}s that * offer {@link android.location.timezone.LocationTimeZoneEvent}s. * - * TODO(b/152744911): This implementation currently only supports a primary provider. Support for a - * secondary provider must be added in a later commit. + * <p>For details of the time zone suggestion behavior, see {@link + * LocationTimeZoneProviderController}. * * <p>Implementation details: * @@ -109,6 +109,7 @@ public class LocationTimeZoneManagerService extends Binder { static final String TAG = "LocationTZDetector"; static final String PRIMARY_PROVIDER_NAME = "primary"; + static final String SECONDARY_PROVIDER_NAME = "secondary"; private static final String SIMULATION_MODE_SYSTEM_PROPERTY_PREFIX = "persist.sys.location_tz_simulation_mode."; @@ -117,6 +118,8 @@ public class LocationTimeZoneManagerService extends Binder { private static final String PRIMARY_LOCATION_TIME_ZONE_SERVICE_ACTION = "com.android.location.timezone.service.v1.PrimaryLocationTimeZoneProvider"; + private static final String SECONDARY_LOCATION_TIME_ZONE_SERVICE_ACTION = + "com.android.location.timezone.service.v1.SecondaryLocationTimeZoneProvider"; @NonNull private final Context mContext; @@ -160,8 +163,9 @@ public class LocationTimeZoneManagerService extends Binder { // Called on an arbitrary thread during initialization. synchronized (mSharedLock) { LocationTimeZoneProvider primary = createPrimaryProvider(); + LocationTimeZoneProvider secondary = createSecondaryProvider(); mLocationTimeZoneDetectorController = - new ControllerImpl(mThreadingDomain, primary); + new ControllerImpl(mThreadingDomain, primary, secondary); ControllerCallbackImpl callback = new ControllerCallbackImpl(mThreadingDomain); ControllerEnvironmentImpl environment = new ControllerEnvironmentImpl( mThreadingDomain, mLocationTimeZoneDetectorController); @@ -178,9 +182,6 @@ public class LocationTimeZoneManagerService extends Binder { if (isInSimulationMode(PRIMARY_PROVIDER_NAME)) { proxy = new SimulatedLocationTimeZoneProviderProxy(mContext, mThreadingDomain); } else { - // TODO Uncomment this code in a later commit. - throw new UnsupportedOperationException("Not implemented"); - /* proxy = RealLocationTimeZoneProviderProxy.createAndRegister( mContext, mThreadingDomain, @@ -188,11 +189,31 @@ public class LocationTimeZoneManagerService extends Binder { com.android.internal.R.bool.config_enablePrimaryLocationTimeZoneOverlay, com.android.internal.R.string.config_primaryLocationTimeZoneProviderPackageName ); - */ } return createLocationTimeZoneProvider(PRIMARY_PROVIDER_NAME, proxy); } + private LocationTimeZoneProvider createSecondaryProvider() { + LocationTimeZoneProviderProxy proxy; + if (isInSimulationMode(SECONDARY_PROVIDER_NAME)) { + proxy = new SimulatedLocationTimeZoneProviderProxy(mContext, mThreadingDomain); + } else { + // TODO Uncomment this code in a later commit. + throw new UnsupportedOperationException("Not implemented"); + /* + proxy = RealLocationTimeZoneProviderProxy.createAndRegister( + mContext, + mThreadingDomain, + SECONDARY_LOCATION_TIME_ZONE_SERVICE_ACTION, + com.android.internal.R.bool.config_enableSecondaryLocationTimeZoneOverlay, + com.android.internal.R.string + .config_secondaryLocationTimeZoneProviderPackageName + ); + */ + } + return createLocationTimeZoneProvider(SECONDARY_PROVIDER_NAME, proxy); + } + private boolean isInSimulationMode(String providerName) { return SystemProperties.getBoolean( SIMULATION_MODE_SYSTEM_PROPERTY_PREFIX + providerName, false); diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneProvider.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneProvider.java index 4b0b5a2cbbe4..4bbda43d0e60 100644 --- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneProvider.java +++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneProvider.java @@ -255,7 +255,9 @@ abstract class LocationTimeZoneProvider implements Dumpable { @Override public String toString() { - return "State{" + // this.provider is omitted deliberately to avoid recursion, since the provider holds + // a reference to its state. + return "ProviderState{" + "stateEnum=" + prettyPrintStateEnum(stateEnum) + ", event=" + event + ", currentUserConfiguration=" + currentUserConfiguration diff --git a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java index ef2e349fceaa..f1d37237872b 100644 --- a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java +++ b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java @@ -21,6 +21,7 @@ import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN; import static com.android.server.location.timezone.LocationTimeZoneManagerService.PRIMARY_PROVIDER_NAME; +import static com.android.server.location.timezone.LocationTimeZoneManagerService.SECONDARY_PROVIDER_NAME; import android.annotation.NonNull; import android.annotation.Nullable; @@ -42,7 +43,8 @@ import java.util.Objects; */ final class SimulatedBinderProviderEvent { - private static final List<String> VALID_PROVIDER_NAMES = Arrays.asList(PRIMARY_PROVIDER_NAME); + private static final List<String> VALID_PROVIDER_NAMES = + Arrays.asList(PRIMARY_PROVIDER_NAME, SECONDARY_PROVIDER_NAME); static final int INJECTED_EVENT_TYPE_ON_BIND = 1; static final int INJECTED_EVENT_TYPE_ON_UNBIND = 2; diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 0450e5bfd011..29928771e73d 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -587,7 +587,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private final NetworkPolicyLogger mLogger = new NetworkPolicyLogger(); - /** List of apps indexed by appId and whether they have the internet permission */ + /** List of apps indexed by uid and whether they have the internet permission */ @GuardedBy("mUidRulesFirstLock") private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray(); @@ -973,7 +973,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid); // Clear the cache for the app synchronized (mUidRulesFirstLock) { - mInternetPermissionMap.delete(UserHandle.getAppId(uid)); + mInternetPermissionMap.delete(uid); updateRestrictionRulesForUidUL(uid); } } @@ -4203,16 +4203,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private boolean hasInternetPermissionUL(int uid) { try { - final int appId = UserHandle.getAppId(uid); - final boolean hasPermission; - if (mInternetPermissionMap.indexOfKey(appId) < 0) { - hasPermission = - mIPm.checkUidPermission(Manifest.permission.INTERNET, uid) - == PackageManager.PERMISSION_GRANTED; - mInternetPermissionMap.put(appId, hasPermission); - } else { - hasPermission = mInternetPermissionMap.get(appId); + if (mInternetPermissionMap.get(uid)) { + return true; } + // If the cache shows that uid doesn't have internet permission, + // then always re-check with PackageManager just to be safe. + final boolean hasPermission = mIPm.checkUidPermission(Manifest.permission.INTERNET, + uid) == PackageManager.PERMISSION_GRANTED; + mInternetPermissionMap.put(uid, hasPermission); return hasPermission; } catch (RemoteException e) { } diff --git a/services/core/java/com/android/server/notification/EventConditionProvider.java b/services/core/java/com/android/server/notification/EventConditionProvider.java index a4a94c29abfa..25ad9280fa99 100644 --- a/services/core/java/com/android/server/notification/EventConditionProvider.java +++ b/services/core/java/com/android/server/notification/EventConditionProvider.java @@ -271,7 +271,7 @@ public class EventConditionProvider extends SystemConditionProviderService { new Intent(ACTION_EVALUATE) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) .putExtra(EXTRA_TIME, time), - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); alarms.cancel(pendingIntent); if (time == 0 || time < now) { if (DEBUG) Slog.d(TAG, "Not scheduling evaluate: " + (time == 0 ? "no time specified" diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b4c98e06a442..4da5fad26960 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -3084,6 +3084,8 @@ public class NotificationManagerService extends SystemService { UserHandle.getUserId(uid), REASON_PACKAGE_BANNED, null); } + mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg, + enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); try { getContext().sendBroadcastAsUser( new Intent(ACTION_APP_BLOCK_STATE_CHANGED) @@ -5247,7 +5249,8 @@ public class NotificationManagerService extends SystemService { Intent appIntent = getContext().getPackageManager().getLaunchIntentForPackage(pkg); if (appIntent != null) { summaryNotification.contentIntent = PendingIntent.getActivityAsUser( - getContext(), 0, appIntent, 0, null, UserHandle.of(userId)); + getContext(), 0, appIntent, PendingIntent.FLAG_IMMUTABLE, null, + UserHandle.of(userId)); } final StatusBarNotification summarySbn = new StatusBarNotification(adjustedSbn.getPackageName(), @@ -6830,7 +6833,7 @@ public class NotificationManagerService extends SystemService { .appendPath(record.getKey()).build()) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) .putExtra(EXTRA_KEY, record.getKey()), - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + record.getNotification().getTimeoutAfter(), pi); } diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java index 961d3db867e9..35170332a077 100644 --- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java +++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java @@ -223,7 +223,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService { new Intent(ACTION_EVALUATE) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) .putExtra(EXTRA_TIME, time), - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); alarms.cancel(pendingIntent); if (time > now) { if (DEBUG) Slog.d(TAG, String.format("Scheduling evaluate for %s, in %s, now=%s", diff --git a/services/core/java/com/android/server/pm/IncrementalStates.java b/services/core/java/com/android/server/pm/IncrementalStates.java new file mode 100644 index 000000000000..dda5fafb8cb1 --- /dev/null +++ b/services/core/java/com/android/server/pm/IncrementalStates.java @@ -0,0 +1,480 @@ +/* + * 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.pm; + +import android.content.pm.IDataLoaderStatusListener; +import android.content.pm.IncrementalStatesInfo; +import android.content.pm.PackageManager; +import android.os.Handler; +import android.os.incremental.IStorageHealthListener; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.os.BackgroundThread; +import com.android.internal.util.function.pooled.PooledLambda; + +import java.util.function.BiConsumer; + +/** + * Manages state transitions of a package installed on Incremental File System. Currently manages: + * 1. startable state (whether a package is allowed to be launched), and + * 2. loading state (whether a package is still loading or has been fully loaded). + * + * The following events might change the states of a package: + * 1. Installation commit + * 2. Incremental storage health + * 3. Data loader stream health + * 4. Loading progress changes + * + * @hide + */ +public final class IncrementalStates { + private static final String TAG = "IncrementalStates"; + private static final boolean DEBUG = false; + private final Handler mHandler = BackgroundThread.getHandler(); + private final Object mLock = new Object(); + @GuardedBy("mLock") + private int mStreamStatus = IDataLoaderStatusListener.STREAM_HEALTHY; + @GuardedBy("mLock") + private int mStorageHealthStatus = IStorageHealthListener.HEALTH_STATUS_OK; + @GuardedBy("mLock") + private final LoadingState mLoadingState; + @GuardedBy("mLock") + private StartableState mStartableState; + @GuardedBy("mLock") + private Callback mCallback = null; + private final BiConsumer<Integer, Integer> mStatusConsumer; + + public IncrementalStates() { + // By default the package is not startable and not fully loaded (i.e., is loading) + this(false, true); + } + + public IncrementalStates(boolean isStartable, boolean isLoading) { + mStartableState = new StartableState(isStartable); + mLoadingState = new LoadingState(isLoading); + mStatusConsumer = new StatusConsumer(); + } + + /** + * Callback interface to report that the startable state of this package has changed. + */ + public interface Callback { + /** + * Reports that the package is now unstartable and the unstartable reason. + */ + void onPackageUnstartable(int reason); + + /** + * Reports that the package is now startable. + */ + void onPackageStartable(); + + /** + * Reports that package is fully loaded. + */ + void onPackageFullyLoaded(); + } + + /** + * By calling this method, the caller indicates that package installation has just been + * committed. The package becomes startable. Set the initial loading state after the package + * is committed. Incremental packages are by-default loading; non-Incremental packages are not. + * + * @param isIncremental whether a package is installed on Incremental or not. + */ + public void onCommit(boolean isIncremental) { + if (DEBUG) { + Slog.i(TAG, "received package commit event"); + } + synchronized (mLock) { + if (!mStartableState.isStartable()) { + mStartableState.adoptNewStartableStateLocked(true); + } + if (mLoadingState.isLoading() != isIncremental) { + mLoadingState.adoptNewLoadingStateLocked(isIncremental); + } + } + mHandler.post(PooledLambda.obtainRunnable( + IncrementalStates::reportStartableState, + IncrementalStates.this).recycleOnUse()); + if (!isIncremental) { + mHandler.post(PooledLambda.obtainRunnable( + IncrementalStates::reportFullyLoaded, + IncrementalStates.this).recycleOnUse()); + } + } + + private void reportStartableState() { + final Callback callback; + final boolean startable; + final int reason; + synchronized (mLock) { + callback = mCallback; + startable = mStartableState.isStartable(); + reason = mStartableState.getUnstartableReason(); + } + if (callback == null) { + return; + } + if (startable) { + callback.onPackageStartable(); + } else { + callback.onPackageUnstartable(reason); + } + } + + private void reportFullyLoaded() { + final Callback callback; + synchronized (mLock) { + callback = mCallback; + } + if (callback != null) { + callback.onPackageFullyLoaded(); + } + } + + private class StatusConsumer implements BiConsumer<Integer, Integer> { + @Override + public void accept(Integer streamStatus, Integer storageStatus) { + if (streamStatus == null && storageStatus == null) { + return; + } + final boolean oldState, newState; + synchronized (mLock) { + if (!mLoadingState.isLoading()) { + // Do nothing if the package is already fully loaded + return; + } + oldState = mStartableState.isStartable(); + if (streamStatus != null) { + mStreamStatus = (Integer) streamStatus; + } + if (storageStatus != null) { + mStorageHealthStatus = (Integer) storageStatus; + } + updateStartableStateLocked(); + newState = mStartableState.isStartable(); + } + if (oldState != newState) { + mHandler.post(PooledLambda.obtainRunnable(IncrementalStates::reportStartableState, + IncrementalStates.this).recycleOnUse()); + } + } + }; + + /** + * By calling this method, the caller indicates that there issues with the Incremental + * Storage, + * on which the package is installed. The state will change according to the status + * code defined in {@code IStorageHealthListener}. + */ + public void onStorageHealthStatusChanged(int storageHealthStatus) { + if (DEBUG) { + Slog.i(TAG, "received storage health status changed event : storageHealthStatus=" + + storageHealthStatus); + } + mStatusConsumer.accept(null, storageHealthStatus); + } + + /** + * By calling this method, the caller indicates that the stream status of the package has + * been + * changed. This could indicate a streaming error. The state will change according to the + * status + * code defined in {@code IDataLoaderStatusListener}. + */ + public void onStreamStatusChanged(int streamState) { + if (DEBUG) { + Slog.i(TAG, "received stream status changed event : streamState=" + streamState); + } + mStatusConsumer.accept(streamState, null); + } + + /** + * Use the specified callback to report state changing events. + * + * @param callback Object to report new state. + */ + public void setCallback(Callback callback) { + if (DEBUG) { + Slog.i(TAG, "registered callback"); + } + synchronized (mLock) { + mCallback = callback; + } + } + + /** + * Update the package loading progress to specified value. This might change startable state. + * + * @param progress Value between [0, 1]. + */ + public void setProgress(float progress) { + final boolean newLoadingState; + final boolean oldStartableState, newStartableState; + synchronized (mLock) { + oldStartableState = mStartableState.isStartable(); + updateProgressLocked(progress); + newLoadingState = mLoadingState.isLoading(); + newStartableState = mStartableState.isStartable(); + } + if (!newLoadingState) { + mHandler.post(PooledLambda.obtainRunnable( + IncrementalStates::reportFullyLoaded, + IncrementalStates.this).recycleOnUse()); + } + if (newStartableState != oldStartableState) { + mHandler.post(PooledLambda.obtainRunnable( + IncrementalStates::reportStartableState, + IncrementalStates.this).recycleOnUse()); + } + } + + /** + * @return the current startable state. + */ + public boolean isStartable() { + synchronized (mLock) { + return mStartableState.isStartable(); + } + } + + /** + * @return Whether the package is still being loaded or has been fully loaded. + */ + public boolean isLoading() { + synchronized (mLock) { + return mLoadingState.isLoading(); + } + } + + /** + * @return all current states in a Parcelable. + */ + public IncrementalStatesInfo getIncrementalStatesInfo() { + synchronized (mLock) { + return new IncrementalStatesInfo(mStartableState.isStartable(), + mLoadingState.isLoading(), + mLoadingState.getProgress()); + } + } + + /** + * Determine the next state based on the current state, current stream status and storage + * health + * status. If the next state is different from the current state, proceed with state + * change. + */ + private void updateStartableStateLocked() { + final boolean currentState = mStartableState.isStartable(); + boolean nextState = currentState; + if (!currentState) { + if (mStorageHealthStatus == IStorageHealthListener.HEALTH_STATUS_OK + && mStreamStatus == IDataLoaderStatusListener.STREAM_HEALTHY) { + // change from unstartable -> startable when both stream and storage are healthy + nextState = true; + } + } else { + if (mStorageHealthStatus == IStorageHealthListener.HEALTH_STATUS_UNHEALTHY) { + // unrecoverable if storage is unhealthy + nextState = false; + } else { + switch (mStreamStatus) { + case IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR: + // unrecoverable, fall through + case IDataLoaderStatusListener.STREAM_SOURCE_ERROR: { + // unrecoverable + nextState = false; + break; + } + case IDataLoaderStatusListener.STREAM_STORAGE_ERROR: { + if (mStorageHealthStatus != IStorageHealthListener.HEALTH_STATUS_OK) { + // unrecoverable if there is a pending read AND storage is limited + nextState = false; + } + break; + } + default: + // anything else, remain startable + break; + } + } + } + if (nextState == currentState) { + return; + } + mStartableState.adoptNewStartableStateLocked(nextState); + } + + private void updateProgressLocked(float progress) { + if (DEBUG) { + Slog.i(TAG, "received progress update: " + progress); + } + mLoadingState.setProgress(progress); + if (1 - progress < 0.001) { + if (DEBUG) { + Slog.i(TAG, "package is fully loaded"); + } + mLoadingState.setProgress(1); + if (mLoadingState.isLoading()) { + mLoadingState.adoptNewLoadingStateLocked(false); + } + // Also updates startable state if necessary + if (!mStartableState.isStartable()) { + mStartableState.adoptNewStartableStateLocked(true); + } + } + } + + private class StartableState { + private boolean mIsStartable; + private int mUnstartableReason = PackageManager.UNSTARTABLE_REASON_UNKNOWN; + + StartableState(boolean isStartable) { + mIsStartable = isStartable; + } + + public boolean isStartable() { + return mIsStartable; + } + + public int getUnstartableReason() { + return mUnstartableReason; + } + + public void adoptNewStartableStateLocked(boolean nextState) { + if (DEBUG) { + Slog.i(TAG, "startable state changed from " + mIsStartable + " to " + nextState); + } + mIsStartable = nextState; + mUnstartableReason = getUnstartableReasonLocked(); + } + + private int getUnstartableReasonLocked() { + if (mIsStartable) { + return PackageManager.UNSTARTABLE_REASON_UNKNOWN; + } + // Translate stream status to reason for unstartable state + switch (mStreamStatus) { + case IDataLoaderStatusListener.STREAM_TRANSPORT_ERROR: + // fall through + case IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR: + // fall through + case IDataLoaderStatusListener.STREAM_SOURCE_ERROR: { + return PackageManager.UNSTARTABLE_REASON_DATALOADER_TRANSPORT; + } + case IDataLoaderStatusListener.STREAM_STORAGE_ERROR: { + return PackageManager.UNSTARTABLE_REASON_DATALOADER_STORAGE; + } + default: + return PackageManager.UNSTARTABLE_REASON_UNKNOWN; + } + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof StartableState)) { + return false; + } + StartableState l = (StartableState) o; + return l.mIsStartable == mIsStartable; + } + + @Override + public int hashCode() { + return Boolean.hashCode(mIsStartable); + } + } + + private class LoadingState { + private boolean mIsLoading; + private float mProgress; + + LoadingState(boolean isLoading) { + mIsLoading = isLoading; + mProgress = isLoading ? 0 : 1; + } + + public boolean isLoading() { + return mIsLoading; + } + + public float getProgress() { + return mProgress; + } + + public void setProgress(float progress) { + mProgress = progress; + } + + public void adoptNewLoadingStateLocked(boolean nextState) { + if (DEBUG) { + Slog.i(TAG, "Loading state changed from " + mIsLoading + " to " + nextState); + } + mIsLoading = nextState; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof LoadingState)) { + return false; + } + LoadingState l = (LoadingState) o; + return l.mIsLoading == mIsLoading && l.mProgress == mProgress; + } + + @Override + public int hashCode() { + int hashCode = Boolean.hashCode(mIsLoading); + hashCode = 31 * hashCode + Float.hashCode(mProgress); + return hashCode; + } + } + + + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof IncrementalStates)) { + return false; + } + IncrementalStates l = (IncrementalStates) o; + return l.mStorageHealthStatus == mStorageHealthStatus + && l.mStreamStatus == mStreamStatus + && l.mStartableState.equals(mStartableState) + && l.mLoadingState.equals(mLoadingState); + } + + @Override + public int hashCode() { + int hashCode = mStartableState.hashCode(); + hashCode = 31 * hashCode + mLoadingState.hashCode(); + hashCode = 31 * hashCode + mStorageHealthStatus; + hashCode = 31 * hashCode + mStreamStatus; + return hashCode; + } +} diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 949dcb254d21..2aafe9a6f9a1 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -141,6 +141,7 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; +import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.dex.DexManager; @@ -1086,6 +1087,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } + private ParcelFileDescriptor openTargetInternal(String path, int flags, int mode) + throws IOException, ErrnoException { + // TODO: this should delegate to DCS so the system process avoids + // holding open FDs into containers. + final FileDescriptor fd = Os.open(path, flags, mode); + return new ParcelFileDescriptor(fd); + } + + private ParcelFileDescriptor createRevocableFdInternal(RevocableFileDescriptor fd, + ParcelFileDescriptor pfd) throws IOException { + int releasedFdInt = pfd.detachFd(); + FileDescriptor releasedFd = new FileDescriptor(); + releasedFd.setInt$(releasedFdInt); + fd.init(mContext, releasedFd); + return fd.getRevocableFileDescriptor(); + } + private ParcelFileDescriptor doWriteInternal(String name, long offsetBytes, long lengthBytes, ParcelFileDescriptor incomingFd) throws IOException { // Quick validity check of state, and allocate a pipe for ourselves. We @@ -1118,21 +1136,20 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { Binder.restoreCallingIdentity(identity); } - // TODO: this should delegate to DCS so the system process avoids - // holding open FDs into containers. - final FileDescriptor targetFd = Os.open(target.getAbsolutePath(), + ParcelFileDescriptor targetPfd = openTargetInternal(target.getAbsolutePath(), O_CREAT | O_WRONLY, 0644); Os.chmod(target.getAbsolutePath(), 0644); // If caller specified a total length, allocate it for them. Free up // cache space to grow, if needed. if (stageDir != null && lengthBytes > 0) { - mContext.getSystemService(StorageManager.class).allocateBytes(targetFd, lengthBytes, + mContext.getSystemService(StorageManager.class).allocateBytes( + targetPfd.getFileDescriptor(), lengthBytes, PackageHelper.translateAllocateFlags(params.installFlags)); } if (offsetBytes > 0) { - Os.lseek(targetFd, offsetBytes, OsConstants.SEEK_SET); + Os.lseek(targetPfd.getFileDescriptor(), offsetBytes, OsConstants.SEEK_SET); } if (incomingFd != null) { @@ -1142,8 +1159,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // inserted above to hold the session active. try { final Int64Ref last = new Int64Ref(0); - FileUtils.copy(incomingFd.getFileDescriptor(), targetFd, lengthBytes, null, - Runnable::run, (long progress) -> { + FileUtils.copy(incomingFd.getFileDescriptor(), targetPfd.getFileDescriptor(), + lengthBytes, null, Runnable::run, + (long progress) -> { if (params.sizeBytes > 0) { final long delta = progress - last.value; last.value = progress; @@ -1154,7 +1172,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } }); } finally { - IoUtils.closeQuietly(targetFd); + IoUtils.closeQuietly(targetPfd); IoUtils.closeQuietly(incomingFd); // We're done here, so remove the "bridge" that was holding @@ -1170,12 +1188,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } return null; } else if (PackageInstaller.ENABLE_REVOCABLE_FD) { - fd.init(mContext, targetFd); - return fd.getRevocableFileDescriptor(); + return createRevocableFdInternal(fd, targetPfd); } else { - bridge.setTargetFile(targetFd); + bridge.setTargetFile(targetPfd); bridge.start(); - return new ParcelFileDescriptor(bridge.getClientSocket()); + return bridge.getClientSocket(); } } catch (ErrnoException e) { @@ -1684,20 +1701,26 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } - private void onStorageUnhealthy() { + private void onStorageHealthStatusChanged(int status) { final String packageName = getPackageName(); if (TextUtils.isEmpty(packageName)) { // The package has not been installed. return; } - final PackageManagerService packageManagerService = mPm; - mHandler.post(() -> { - if (packageManagerService.deletePackageX(packageName, - PackageManager.VERSION_CODE_HIGHEST, UserHandle.USER_SYSTEM, - PackageManager.DELETE_ALL_USERS) != PackageManager.DELETE_SUCCEEDED) { - Slog.e(TAG, "Failed to uninstall package with failed dataloader: " + packageName); - } - }); + mHandler.post(PooledLambda.obtainRunnable( + PackageManagerService::onStorageHealthStatusChanged, + mPm, packageName, status, userId).recycleOnUse()); + } + + private void onStreamHealthStatusChanged(int status) { + final String packageName = getPackageName(); + if (TextUtils.isEmpty(packageName)) { + // The package has not been installed. + return; + } + mHandler.post(PooledLambda.obtainRunnable( + PackageManagerService::onStreamStatusChanged, + mPm, packageName, status, userId).recycleOnUse()); } /** @@ -3245,7 +3268,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (isDestroyedOrDataLoaderFinished) { switch (status) { case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE: - onStorageUnhealthy(); + // treat as unhealthy storage + onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); return; } return; @@ -3342,6 +3367,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { sendPendingStreaming(mContext, statusReceiver, sessionId, e.getMessage()); } } + @Override + public void reportStreamHealth(int dataLoaderId, int streamStatus) { + synchronized (mLock) { + if (!mDestroyed && !mDataLoaderFinished) { + // ignore streaming status if package isn't installed + return; + } + } + onStreamHealthStatusChanged(streamStatus); + } }; if (!manualStartAndDestroy) { @@ -3361,11 +3396,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } if (isDestroyedOrDataLoaderFinished) { // App's installed. - switch (status) { - case IStorageHealthListener.HEALTH_STATUS_UNHEALTHY: - onStorageUnhealthy(); - return; - } + onStorageHealthStatusChanged(status); return; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 67f218e5110e..cc1ef86bfb1a 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -20,10 +20,8 @@ import static android.Manifest.permission.DELETE_PACKAGES; import static android.Manifest.permission.INSTALL_PACKAGES; import static android.Manifest.permission.MANAGE_DEVICE_ADMINS; import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS; -import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.REQUEST_DELETE_PACKAGES; import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS; -import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_DEFAULT; import static android.app.AppOpsManager.MODE_IGNORED; @@ -92,7 +90,6 @@ import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER; import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; -import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.RESTRICTION_NONE; import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN; @@ -3779,6 +3776,8 @@ public class PackageManagerService extends IPackageManager.Stub PackageParser.readConfigUseRoundIcon(mContext.getResources()); mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L); + + Slog.i(TAG, "Fix for b/169414761 is applied"); } /** @@ -16390,12 +16389,24 @@ public class PackageManagerService extends IPackageManager.Stub } else if (!previousUserIds.contains(userId)) { ps.setInstallReason(installReason, userId); } + + // TODO(b/169721400): generalize Incremental States and create a Callback object + // that can be used for all the packages. + final IncrementalStatesCallback incrementalStatesCallback = + new IncrementalStatesCallback(ps, userId); + final String codePath = ps.getPathString(); + if (IncrementalManager.isIncrementalPath(codePath) && mIncrementalManager != null) { + mIncrementalManager.registerCallback(codePath, incrementalStatesCallback); + ps.setIncrementalStatesCallback(incrementalStatesCallback); + } + // Ensure that the uninstall reason is UNKNOWN for users with the package installed. for (int currentUserId : allUsersList) { if (ps.getInstalled(currentUserId)) { ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, currentUserId); } } + mSettings.writeKernelMappingLPr(ps); } res.name = pkgName; @@ -17192,6 +17203,7 @@ public class PackageManagerService extends IPackageManager.Stub mDexManager.notifyPackageUpdated(pkg.getPackageName(), pkg.getBaseApkPath(), pkg.getSplitCodePaths()); } + reconciledPkg.pkgSetting.setStatesOnCommit(); // Prepare the application profiles for the new code paths. // This needs to be done before invoking dexopt so that any install-time profile @@ -17288,6 +17300,155 @@ public class PackageManagerService extends IPackageManager.Stub NativeLibraryHelper.waitForNativeBinariesExtraction(incrementalStorages); } + private class IncrementalStatesCallback extends IPackageLoadingProgressCallback.Stub + implements IncrementalStates.Callback { + @GuardedBy("mPackageSetting") + private final PackageSetting mPackageSetting; + private final String mPackageName; + private final String mPathString; + private final int mUserId; + private final int[] mInstalledUserIds; + + IncrementalStatesCallback(PackageSetting packageSetting, int userId) { + mPackageSetting = packageSetting; + mPackageName = packageSetting.name; + mUserId = userId; + mPathString = packageSetting.getPathString(); + final int[] allUserIds = resolveUserIds(userId); + final ArrayList<Integer> installedUserIds = new ArrayList<>(); + for (int i = 0; i < allUserIds.length; i++) { + if (packageSetting.getInstalled(allUserIds[i])) { + installedUserIds.add(allUserIds[i]); + } + } + final int numInstalledUserId = installedUserIds.size(); + mInstalledUserIds = new int[numInstalledUserId]; + for (int i = 0; i < numInstalledUserId; i++) { + mInstalledUserIds[i] = installedUserIds.get(i); + } + } + + @Override + public void onPackageLoadingProgressChanged(float progress) { + synchronized (mPackageSetting) { + mPackageSetting.setLoadingProgress(progress); + } + } + + @Override + public void onPackageFullyLoaded() { + mIncrementalManager.unregisterCallback(mPathString, this); + final SparseArray<int[]> newBroadcastAllowList; + synchronized (mLock) { + newBroadcastAllowList = mAppsFilter.getVisibilityAllowList( + getPackageSettingInternal(mPackageName, Process.SYSTEM_UID), + mInstalledUserIds, mSettings.mPackages); + } + Bundle extras = new Bundle(1); + extras.putInt(Intent.EXTRA_UID, mUserId); + extras.putString(Intent.EXTRA_PACKAGE_NAME, mPackageName); + sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_LOADED, mPackageName, + extras, 0 /*flags*/, + null /*targetPackage*/, null /*finishedReceiver*/, + mInstalledUserIds, null /* instantUserIds */, newBroadcastAllowList); + } + + @Override + public void onPackageUnstartable(int reason) { + final SparseArray<int[]> newBroadcastAllowList; + synchronized (mLock) { + newBroadcastAllowList = mAppsFilter.getVisibilityAllowList( + getPackageSettingInternal(mPackageName, Process.SYSTEM_UID), + mInstalledUserIds, mSettings.mPackages); + } + Bundle extras = new Bundle(1); + extras.putInt(Intent.EXTRA_UID, mUserId); + extras.putString(Intent.EXTRA_PACKAGE_NAME, mPackageName); + extras.putInt(Intent.EXTRA_REASON, reason); + // send broadcast to users with this app installed + sendPackageBroadcast(Intent.ACTION_PACKAGE_UNSTARTABLE, mPackageName, + extras, 0 /*flags*/, + null /*targetPackage*/, null /*finishedReceiver*/, + mInstalledUserIds, null /* instantUserIds */, newBroadcastAllowList); + } + + @Override + public void onPackageStartable() { + final SparseArray<int[]> newBroadcastAllowList; + synchronized (mLock) { + newBroadcastAllowList = mAppsFilter.getVisibilityAllowList( + getPackageSettingInternal(mPackageName, Process.SYSTEM_UID), + mInstalledUserIds, mSettings.mPackages); + } + Bundle extras = new Bundle(1); + extras.putInt(Intent.EXTRA_UID, mUserId); + extras.putString(Intent.EXTRA_PACKAGE_NAME, mPackageName); + // send broadcast to users with this app installed + sendPackageBroadcast(Intent.ACTION_PACKAGE_STARTABLE, mPackageName, + extras, 0 /*flags*/, + null /*targetPackage*/, null /*finishedReceiver*/, + mInstalledUserIds, null /* instantUserIds */, newBroadcastAllowList); + } + } + + /** + * This is an internal method that is used to indicate changes on the health status of the + * Incremental Storage used by an installed package with an associated user id. This might + * result in a change in the loading state of the package. + */ + public void onStorageHealthStatusChanged(String packageName, int status, int userId) { + final int callingUid = Binder.getCallingUid(); + mPermissionManager.enforceCrossUserPermission( + callingUid, userId, true, false, + "onStorageHealthStatusChanged"); + final PackageSetting ps = getPackageSettingForUser(packageName, callingUid, userId); + if (ps == null) { + return; + } + ps.setStorageHealthStatus(status); + } + + /** + * This is an internal method that is used to indicate changes on the stream status of the + * data loader used by an installed package with an associated user id. This might + * result in a change in the loading state of the package. + */ + public void onStreamStatusChanged(String packageName, int status, int userId) { + final int callingUid = Binder.getCallingUid(); + mPermissionManager.enforceCrossUserPermission( + callingUid, userId, true, false, + "onStreamStatusChanged"); + final PackageSetting ps = getPackageSettingForUser(packageName, callingUid, userId); + if (ps == null) { + return; + } + ps.setStreamStatus(status); + } + + @Nullable PackageSetting getPackageSettingForUser(String packageName, int callingUid, + int userId) { + final PackageSetting ps; + synchronized (mLock) { + ps = mSettings.mPackages.get(packageName); + if (ps == null) { + Slog.w(TAG, "Failed to get package setting. Package " + packageName + + " is not installed"); + return null; + } + if (!ps.getInstalled(userId)) { + Slog.w(TAG, "Failed to get package setting. Package " + packageName + + " is not installed for user " + userId); + return null; + } + if (shouldFilterApplicationLocked(ps, callingUid, userId)) { + Slog.w(TAG, "Failed to get package setting. Package " + packageName + + " is not visible to the calling app"); + return null; + } + } + return ps; + } + private void notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg) { final PackageSetting pkgSetting = reconciledPkg.pkgSetting; final PackageInstalledInfo pkgInstalledInfo = reconciledPkg.installResult; @@ -21756,24 +21917,18 @@ public class PackageManagerService extends IPackageManager.Stub mInjector.getStorageManagerInternal().addExternalStoragePolicy( new StorageManagerInternal.ExternalStorageMountPolicy() { - @Override - public int getMountMode(int uid, String packageName) { - if (Process.isIsolated(uid)) { - return Zygote.MOUNT_EXTERNAL_NONE; - } - if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { - return Zygote.MOUNT_EXTERNAL_DEFAULT; - } - if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { - return Zygote.MOUNT_EXTERNAL_READ; - } - return Zygote.MOUNT_EXTERNAL_WRITE; - } + @Override + public int getMountMode(int uid, String packageName) { + if (Process.isIsolated(uid)) { + return Zygote.MOUNT_EXTERNAL_NONE; + } + return Zygote.MOUNT_EXTERNAL_DEFAULT; + } - @Override - public boolean hasExternalStorage(int uid, String packageName) { - return true; - } + @Override + public boolean hasExternalStorage(int uid, String packageName) { + return true; + } }); // Now that we're mostly running, clean up stale users and apps @@ -25407,24 +25562,15 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean registerInstalledLoadingProgressCallback(String packageName, PackageManagerInternal.InstalledLoadingProgressCallback callback, int userId) { - final int callingUid = Binder.getCallingUid(); - mPermissionManager.enforceCrossUserPermission( - callingUid, userId, true, false, - "registerLoadingProgressCallback"); - final PackageSetting ps; - synchronized (mLock) { - ps = mSettings.mPackages.get(packageName); - if (ps == null) { - Slog.w(TAG, "Failed registering loading progress callback. Package " - + packageName + " is not installed"); - return false; - } - if (shouldFilterApplicationLocked(ps, callingUid, userId)) { - Slog.w(TAG, "Failed registering loading progress callback. Package " - + packageName + " is not visible to the calling app"); - return false; - } - // TODO(b/165841827): return false if package is fully loaded + final PackageSetting ps = getPackageSettingForUser(packageName, Binder.getCallingUid(), + userId); + if (ps == null) { + return false; + } + if (!ps.isPackageLoading()) { + Slog.w(TAG, + "Failed registering loading progress callback. Package is fully loaded."); + return false; } if (mIncrementalManager == null) { Slog.w(TAG, diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index 855a5ff524fd..2ff18f8bdf79 100644 --- a/services/core/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java @@ -333,6 +333,8 @@ public class PackageSetting extends PackageSettingBase { installSource.originatingPackageName); proto.end(sourceToken); } + proto.write(PackageProto.StatesProto.IS_STARTABLE, incrementalStates.isStartable()); + proto.write(PackageProto.StatesProto.IS_LOADING, incrementalStates.isLoading()); writeUsersInfoToProto(proto, PackageProto.USERS); proto.end(packageToken); } diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index a7bbf8d66aac..d52ad46d4b7e 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -25,6 +25,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.ComponentName; import android.content.pm.ApplicationInfo; +import android.content.pm.IncrementalStatesInfo; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.UninstallReason; @@ -33,6 +34,7 @@ import android.content.pm.PackageUserState; import android.content.pm.Signature; import android.content.pm.SuspendDialogInfo; import android.os.PersistableBundle; +import android.os.incremental.IncrementalManager; import android.service.pm.PackageProto; import android.util.ArrayMap; import android.util.ArraySet; @@ -133,6 +135,9 @@ public abstract class PackageSettingBase extends SettingBase { boolean forceQueryableOverride; + @NonNull + public IncrementalStates incrementalStates; + PackageSettingBase(String name, String realName, @NonNull File path, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, @@ -151,6 +156,7 @@ public abstract class PackageSettingBase extends SettingBase { this.versionCode = pVersionCode; this.signatures = new PackageSignatures(); this.installSource = InstallSource.EMPTY; + this.incrementalStates = new IncrementalStates(); } /** @@ -257,6 +263,7 @@ public abstract class PackageSettingBase extends SettingBase { orig.usesStaticLibrariesVersions.length) : null; updateAvailable = orig.updateAvailable; forceQueryableOverride = orig.forceQueryableOverride; + incrementalStates = orig.incrementalStates; } @VisibleForTesting @@ -733,6 +740,66 @@ public abstract class PackageSettingBase extends SettingBase { modifyUserState(userId).resetOverrideComponentLabelIcon(); } + /** + * @return True if package is startable, false otherwise. + */ + public boolean isPackageStartable() { + return incrementalStates.isStartable(); + } + + /** + * @return True if package is still being loaded, false if the package is fully loaded. + */ + public boolean isPackageLoading() { + return incrementalStates.isLoading(); + } + + /** + * @return all current states in a Parcelable. + */ + public IncrementalStatesInfo getIncrementalStates() { + return incrementalStates.getIncrementalStatesInfo(); + } + + /** + * Called to indicate that the package installation has been committed. This will create a + * new startable state and a new loading state with default values. By default, the package is + * startable after commit. For a package installed on Incremental, the loading state is true. + * For non-Incremental packages, the loading state is false. + */ + public void setStatesOnCommit() { + incrementalStates.onCommit(IncrementalManager.isIncrementalPath(getPathString())); + } + + /** + * Called to set the callback to listen for startable state changes. + */ + public void setIncrementalStatesCallback(IncrementalStates.Callback callback) { + incrementalStates.setCallback(callback); + } + + /** + * Called to report progress changes. This might trigger loading state change. + * @see IncrementalStates#setProgress(float) + */ + public void setLoadingProgress(float progress) { + incrementalStates.setProgress(progress); + } + + /** + * @see IncrementalStates#onStorageHealthStatusChanged(int) + */ + public void setStorageHealthStatus(int status) { + incrementalStates.onStorageHealthStatusChanged(status); + } + + /** + * @see IncrementalStates#onStreamStatusChanged(int) + */ + public void setStreamStatus(int status) { + incrementalStates.onStreamStatusChanged(status); + } + protected PackageSettingBase updateFrom(PackageSettingBase other) { super.copyFrom(other); setPath(other.getPath()); @@ -756,6 +823,7 @@ public abstract class PackageSettingBase extends SettingBase { this.updateAvailable = other.updateAvailable; this.verificationInfo = other.verificationInfo; this.forceQueryableOverride = other.forceQueryableOverride; + this.incrementalStates = other.incrementalStates; if (mOldCodePaths != null) { if (other.mOldCodePaths != null) { diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index a922d76cf9eb..c16bd5cdf1fa 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -2809,6 +2809,12 @@ public final class Settings { if (pkg.forceQueryableOverride) { serializer.attribute(null, "forceQueryable", "true"); } + if (pkg.isPackageStartable()) { + serializer.attribute(null, "isStartable", "true"); + } + if (pkg.isPackageLoading()) { + serializer.attribute(null, "isLoading", "true"); + } writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions); @@ -3594,6 +3600,8 @@ public final class Settings { String version = null; long versionCode = 0; String installedForceQueryable = null; + String isStartable = null; + String isLoading = null; try { name = parser.getAttributeValue(null, ATTR_NAME); realName = parser.getAttributeValue(null, "realName"); @@ -3610,6 +3618,8 @@ public final class Settings { cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride"); updateAvailable = parser.getAttributeValue(null, "updateAvailable"); installedForceQueryable = parser.getAttributeValue(null, "forceQueryable"); + isStartable = parser.getAttributeValue(null, "isStartable"); + isLoading = parser.getAttributeValue(null, "isLoading"); if (primaryCpuAbiString == null && legacyCpuAbiString != null) { primaryCpuAbiString = legacyCpuAbiString; @@ -3793,6 +3803,8 @@ public final class Settings { packageSetting.secondaryCpuAbiString = secondaryCpuAbiString; packageSetting.updateAvailable = "true".equals(updateAvailable); packageSetting.forceQueryableOverride = "true".equals(installedForceQueryable); + packageSetting.incrementalStates = new IncrementalStates("true".equals(isStartable), + "true".equals(isLoading)); // Handle legacy string here for single-user mode final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED); if (enabledStr != null) { 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 b293ba6ccc2d..0a514fabb920 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -104,7 +104,6 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.os.storage.StorageManager; -import android.os.storage.StorageManagerInternal; import android.permission.IOnPermissionsChangeListener; import android.permission.IPermissionManager; import android.permission.PermissionControllerManager; @@ -1554,24 +1553,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (bp.isRuntime()) { notifyRuntimePermissionStateChanged(packageName, userId); } - - // Only need to do this if user is initialized. Otherwise it's a new user - // and there are no processes running as the user yet and there's no need - // to make an expensive call to remount processes for the changed permissions. - if (READ_EXTERNAL_STORAGE.equals(permName) - || WRITE_EXTERNAL_STORAGE.equals(permName)) { - final long token = Binder.clearCallingIdentity(); - try { - if (mUserManagerInt.isUserInitialized(userId)) { - StorageManagerInternal storageManagerInternal = LocalServices.getService( - StorageManagerInternal.class); - storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - } @Override diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index cfceaabfc229..7b044edfeea6 100755 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -77,6 +77,7 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; import android.text.TextUtils; +import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.view.InputChannel; @@ -709,8 +710,7 @@ public final class TvInputManagerService extends SystemService { } sessionState.isCurrent = false; sessionState.currentChannel = null; - notifyCurrentChannelInfosUpdatedLocked( - userState, getCurrentTvChannelInfosInternalLocked(userState)); + notifyCurrentChannelInfosUpdatedLocked(userState); } catch (RemoteException | SessionNotFoundException e) { Slog.e(TAG, "error in releaseSession", e); } finally { @@ -851,15 +851,18 @@ public final class TvInputManagerService extends SystemService { } } - private void notifyCurrentChannelInfosUpdatedLocked( - UserState userState, List<TvChannelInfo> infos) { + private void notifyCurrentChannelInfosUpdatedLocked(UserState userState) { if (DEBUG) { Slog.d(TAG, "notifyCurrentChannelInfosUpdatedLocked"); } int n = userState.mCallbacks.beginBroadcast(); for (int i = 0; i < n; ++i) { try { - userState.mCallbacks.getBroadcastItem(i).onCurrentTvChannelInfosUpdated(infos); + ITvInputManagerCallback callback = userState.mCallbacks.getBroadcastItem(i); + Pair<Integer, Integer> pidUid = userState.callbackPidUidMap.get(callback); + List<TvChannelInfo> infos = getCurrentTvChannelInfosInternalLocked( + userState, pidUid.first, pidUid.second); + callback.onCurrentTvChannelInfosUpdated(infos); } catch (RemoteException e) { Slog.e(TAG, "failed to report updated current channel infos to callback", e); } @@ -1063,14 +1066,19 @@ public final class TvInputManagerService extends SystemService { @Override public void registerCallback(final ITvInputManagerCallback callback, int userId) { - final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), - Binder.getCallingUid(), userId, "registerCallback"); + int callingPid = Binder.getCallingPid(); + int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, userId, + "registerCallback"); final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { final UserState userState = getOrCreateUserStateLocked(resolvedUserId); if (!userState.mCallbacks.register(callback)) { Slog.e(TAG, "client process has already died"); + } else { + userState.callbackPidUidMap.put( + callback, Pair.create(callingPid, callingUid)); } } } finally { @@ -1087,6 +1095,7 @@ public final class TvInputManagerService extends SystemService { synchronized (mLock) { UserState userState = getOrCreateUserStateLocked(resolvedUserId); userState.mCallbacks.unregister(callback); + userState.callbackPidUidMap.remove(callback); } } finally { Binder.restoreCallingIdentity(identity); @@ -1419,8 +1428,8 @@ public final class TvInputManagerService extends SystemService { @Override public void tune(IBinder sessionToken, final Uri channelUri, Bundle params, int userId) { final int callingUid = Binder.getCallingUid(); - final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, - userId, "tune"); + final int callingPid = Binder.getCallingPid(); + final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, userId, "tune"); final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { @@ -1432,8 +1441,7 @@ public final class TvInputManagerService extends SystemService { if (sessionState != null) { sessionState.isCurrent = true; sessionState.currentChannel = channelUri; - notifyCurrentChannelInfosUpdatedLocked( - userState, getCurrentTvChannelInfosInternalLocked(userState)); + notifyCurrentChannelInfosUpdatedLocked(userState); } if (TvContract.isChannelUriForPassthroughInput(channelUri)) { // Do not log the watch history for passthrough inputs. @@ -2090,16 +2098,13 @@ public final class TvInputManagerService extends SystemService { @Override public List<TvChannelInfo> getCurrentTvChannelInfos(@UserIdInt int userId) { - final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), - Binder.getCallingUid(), userId, "getTvCurrentChannelInfos"); - final long identity = Binder.clearCallingIdentity(); - try { - synchronized (mLock) { - UserState userState = getOrCreateUserStateLocked(resolvedUserId); - return getCurrentTvChannelInfosInternalLocked(userState); - } - } finally { - Binder.restoreCallingIdentity(identity); + int callingPid = Binder.getCallingPid(); + int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, userId, + "getTvCurrentChannelInfos"); + synchronized (mLock) { + UserState userState = getOrCreateUserStateLocked(resolvedUserId); + return getCurrentTvChannelInfosInternalLocked(userState, callingPid, callingUid); } } @@ -2273,14 +2278,15 @@ public final class TvInputManagerService extends SystemService { } } - private List<TvChannelInfo> getCurrentTvChannelInfosInternalLocked(UserState userState) { + private List<TvChannelInfo> getCurrentTvChannelInfosInternalLocked( + UserState userState, int callingPid, int callingUid) { List<TvChannelInfo> channelInfos = new ArrayList<>(); - boolean watchedProgramsAccess = hasAccessWatchedProgramsPermission(); + boolean watchedProgramsAccess = hasAccessWatchedProgramsPermission(callingPid, callingUid); for (SessionState state : userState.sessionStateMap.values()) { if (state.isCurrent) { Integer appTag; int appType; - if (state.callingUid == Binder.getCallingUid()) { + if (state.callingUid == callingUid) { appTag = APP_TAG_SELF; appType = TvChannelInfo.APP_TYPE_SELF; } else { @@ -2322,8 +2328,8 @@ public final class TvInputManagerService extends SystemService { return false; } - private boolean hasAccessWatchedProgramsPermission() { - return mContext.checkCallingPermission(PERMISSION_ACCESS_WATCHED_PROGRAMS) + private boolean hasAccessWatchedProgramsPermission(int callingPid, int callingUid) { + return mContext.checkPermission(PERMISSION_ACCESS_WATCHED_PROGRAMS, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; } @@ -2360,6 +2366,9 @@ public final class TvInputManagerService extends SystemService { private final RemoteCallbackList<ITvInputManagerCallback> mCallbacks = new RemoteCallbackList<ITvInputManagerCallback>(); + private final Map<ITvInputManagerCallback, Pair<Integer, Integer>> callbackPidUidMap = + new HashMap<>(); + // The token of a "main" TV input session. private IBinder mainSessionToken = null; @@ -2712,8 +2721,7 @@ public final class TvInputManagerService extends SystemService { mSessionState.isCurrent = true; mSessionState.currentChannel = channelUri; UserState userState = getOrCreateUserStateLocked(mSessionState.userId); - notifyCurrentChannelInfosUpdatedLocked( - userState, getCurrentTvChannelInfosInternalLocked(userState)); + notifyCurrentChannelInfosUpdatedLocked(userState); try { // TODO: Consider adding this channel change in the watch log. When we do // that, how we can protect the watch log from malicious tv inputs should diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index b062b284281b..9868fc1657e2 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -116,6 +116,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SWITCH; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; @@ -150,10 +151,7 @@ import static com.android.server.wm.ActivityRecordProto.WINDOW_TOKEN; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; @@ -1133,16 +1131,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A boolean scheduleTopResumedActivityChanged(boolean onTop) { if (!attachedToProcess()) { - if (DEBUG_STATES) { - Slog.w(TAG, "Can't report activity position update - client not running" - + ", activityRecord=" + this); - } + ProtoLog.w(WM_DEBUG_STATES, + "Can't report activity position update - client not running, " + + "activityRecord=%s", this); return false; } try { - if (DEBUG_STATES) { - Slog.v(TAG, "Sending position change to " + this + ", onTop: " + onTop); - } + ProtoLog.v(WM_DEBUG_STATES, "Sending position change to %s, onTop: %b", + this, onTop); mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, TopResumedActivityChangeItem.obtain(onTop)); @@ -2518,10 +2514,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A */ @FinishRequest int finishIfPossible(int resultCode, Intent resultData, NeededUriGrants resultGrants, String reason, boolean oomAdj) { - if (DEBUG_RESULTS || DEBUG_STATES) { - Slog.v(TAG_STATES, "Finishing activity r=" + this + ", result=" + resultCode - + ", data=" + resultData + ", reason=" + reason); - } + ProtoLog.v(WM_DEBUG_STATES, "Finishing activity r=%s, result=%d, data=%s, " + + "reason=%s", this, resultCode, resultData, reason); if (finishing) { Slog.w(TAG, "Duplicate finish request for r=" + this); @@ -2603,7 +2597,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A setVisibility(false); if (stack.mPausingActivity == null) { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + this); + ProtoLog.v(WM_DEBUG_STATES, "Finish needs to pause: %s", this); if (DEBUG_USER_LEAVING) { Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false"); } @@ -2650,7 +2644,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } return removedActivity ? FINISH_RESULT_REMOVED : FINISH_RESULT_REQUESTED; } else { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + this); + ProtoLog.v(WM_DEBUG_STATES, "Finish waiting for pause of: %s", this); } return FINISH_RESULT_REQUESTED; @@ -2807,7 +2801,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A */ @VisibleForTesting boolean addToFinishingAndWaitForIdle() { - if (DEBUG_STATES) Slog.v(TAG, "Enqueueing pending finish: " + this); + ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending finish: %s", this); setState(FINISHING, "addToFinishingAndWaitForIdle"); if (!mStackSupervisor.mFinishingActivities.contains(this)) { mStackSupervisor.mFinishingActivities.add(this); @@ -2835,10 +2829,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } if (isState(DESTROYING, DESTROYED)) { - if (DEBUG_STATES) { - Slog.v(TAG_STATES, "activity " + this + " already destroying." - + "skipping request with reason:" + reason); - } + ProtoLog.v(WM_DEBUG_STATES, "activity %s already destroying, skipping " + + "request with reason:%s", this, reason); return false; } @@ -2879,16 +2871,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // the list yet. Otherwise, we can just immediately put it in the destroyed state since // we are not removing it from the list. if (finishing && !skipDestroy) { - if (DEBUG_STATES) { - Slog.v(TAG_STATES, "Moving to DESTROYING: " + this + " (destroy requested)"); - } + ProtoLog.v(WM_DEBUG_STATES, "Moving to DESTROYING: %s (destroy requested)", this); setState(DESTROYING, "destroyActivityLocked. finishing and not skipping destroy"); mAtmService.mH.postDelayed(mDestroyTimeoutRunnable, DESTROY_TIMEOUT); } else { - if (DEBUG_STATES) { - Slog.v(TAG_STATES, "Moving to DESTROYED: " + this + " (destroy skipped)"); - } + ProtoLog.v(WM_DEBUG_STATES, "Moving to DESTROYED: %s " + + "(destroy skipped)", this); setState(DESTROYED, "destroyActivityLocked. not finishing or skipping destroy"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + this); @@ -2900,7 +2889,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A removeFromHistory(reason + " hadNoApp"); removedFromHistory = true; } else { - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + this + " (no app)"); + ProtoLog.v(WM_DEBUG_STATES, "Moving to DESTROYED: %s (no app)", this); setState(DESTROYED, "destroyActivityLocked. not finishing and had no app"); } } @@ -2935,9 +2924,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A takeFromHistory(); removeTimeouts(); - if (DEBUG_STATES) { - Slog.v(TAG_STATES, "Moving to DESTROYED: " + this + " (removed from history)"); - } + ProtoLog.v(WM_DEBUG_STATES, "Moving to DESTROYED: %s (removed from history)", + this); setState(DESTROYED, "removeFromHistory"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + this); detachFromProcess(); @@ -4455,12 +4443,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void setState(ActivityState state, String reason) { - if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState() - + " to:" + state + " reason:" + reason); + ProtoLog.v(WM_DEBUG_STATES, "State movement: %s from:%s to:%s reason:%s", + this, getState(), state, reason); if (state == mState) { // No need to do anything if state doesn't change. - if (DEBUG_STATES) Slog.v(TAG_STATES, "State unchanged from:" + state); + ProtoLog.v(WM_DEBUG_STATES, "State unchanged from:%s", state); return; } @@ -4943,7 +4931,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A static void activityResumedLocked(IBinder token) { final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r); + ProtoLog.i(WM_DEBUG_STATES, "Resumed activity; dropping state of: %s", r); if (r == null) { // If an app reports resumed after a long delay, the record on server side might have // been removed (e.g. destroy timeout), so the token could be null. @@ -5014,8 +5002,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void activityPaused(boolean timeout) { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, - "Activity paused: token=" + appToken + ", timeout=" + timeout); + ProtoLog.v(WM_DEBUG_STATES, "Activity paused: token=%s, timeout=%b", appToken, + timeout); final Task stack = getStack(); @@ -5023,8 +5011,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A removePauseTimeout(); if (stack.mPausingActivity == this) { - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + this - + (timeout ? " (due to timeout)" : " (pause complete)")); + ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this, + (timeout ? "(due to timeout)" : " (pause complete)")); mAtmService.deferWindowLayout(); try { stack.completePauseLocked(true /* resumeNext */, null /* resumingActivity */); @@ -5039,8 +5027,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (isState(PAUSING)) { setState(PAUSED, "activityPausedLocked"); if (finishing) { - if (DEBUG_PAUSE) Slog.v(TAG, - "Executing finish of failed to pause activity: " + this); + ProtoLog.v(WM_DEBUG_STATES, + "Executing finish of failed to pause activity: %s", this); completeFinishing("activityPausedLocked"); } } @@ -5057,7 +5045,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void schedulePauseTimeout() { pauseTime = SystemClock.uptimeMillis(); mAtmService.mH.postDelayed(mPauseTimeoutRunnable, PAUSE_TIMEOUT); - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete..."); + ProtoLog.v(WM_DEBUG_STATES, "Waiting for pause to complete..."); } private void removePauseTimeout() { @@ -5086,17 +5074,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (isNoHistory()) { if (!finishing) { if (!stack.shouldSleepActivities()) { - if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + this); + ProtoLog.d(WM_DEBUG_STATES, "no-history finish of %s", this); if (finishIfPossible("stop-no-history", false /* oomAdj */) != FINISH_RESULT_CANCELLED) { resumeKeyDispatchingLocked(); return; } } else { - if (DEBUG_STATES) { - Slog.d(TAG_STATES, "Not finishing noHistory " + this - + " on stop because we're just sleeping"); - } + ProtoLog.d(WM_DEBUG_STATES, "Not finishing noHistory %s on stop " + + "because we're just sleeping", this); } } } @@ -5107,9 +5093,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A resumeKeyDispatchingLocked(); try { stopped = false; - if (DEBUG_STATES) { - Slog.v(TAG_STATES, "Moving to STOPPING: " + this + " (stop requested)"); - } + ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPING: %s (stop requested)", this); + setState(STOPPING, "stopIfPossible"); if (DEBUG_VISIBILITY) { Slog.v(TAG_VISIBILITY, "Stopping:" + this); @@ -5129,7 +5114,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A Slog.w(TAG, "Exception thrown during pause", e); // Just in case, assume it to be stopped. stopped = true; - if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + this); + ProtoLog.v(WM_DEBUG_STATES, "Stop failed; moving to STOPPED: %s", this); setState(STOPPED, "stopIfPossible"); if (deferRelaunchUntilPaused) { destroyImmediately("stop-except"); @@ -5158,9 +5143,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A launchCount = 0; updateTaskDescription(description); } - if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + mIcicle); + ProtoLog.i(WM_DEBUG_STATES, "Saving icicle of %s: %s", this, mIcicle); if (!stopped) { - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)"); + ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPED: %s (stop complete)", this); removeStopTimeout(); stopped = true; if (isStopping) { @@ -5196,10 +5181,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE || (isRootOfTask() && stack.getChildCount() <= 1); if (scheduleIdle || forceIdle) { - if (DEBUG_PAUSE) { - Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle=" + forceIdle - + "immediate=" + !idleDelayed); - } + ProtoLog.v(WM_DEBUG_STATES, + "Scheduling idle now: forceIdle=%b immediate=%b", forceIdle, !idleDelayed); + if (!idleDelayed) { mStackSupervisor.scheduleIdle(); } else { @@ -7126,9 +7110,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } else { ProtoLog.v(WM_DEBUG_CONFIGURATION, "Config is relaunching %s", this); - if (DEBUG_STATES && !mVisibleRequested) { - Slog.v(TAG_STATES, "Config is relaunching invisible activity " + this - + " called by " + Debug.getCallers(4)); + if (!mVisibleRequested) { + ProtoLog.v(WM_DEBUG_STATES, "Config is relaunching invisible " + + "activity %s called by %s", this, Debug.getCallers(4)); } relaunchActivityLocked(preserveWindow); } @@ -7261,9 +7245,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A startFreezingScreenLocked(0); try { - if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, - "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this - + " callers=" + Debug.getCallers(6)); + ProtoLog.i(WM_DEBUG_STATES, "Moving to %s Relaunching %s callers=%s" , + (andResume ? "RESUMED" : "PAUSED"), this, Debug.getCallers(6)); forceNewConfig = false; startRelaunching(); final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults, @@ -7286,13 +7269,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // request resume if this activity is currently resumed, which implies we aren't // sleeping. } catch (RemoteException e) { - if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e); + ProtoLog.i(WM_DEBUG_STATES, "Relaunch failed %s", e); } if (andResume) { - if (DEBUG_STATES) { - Slog.d(TAG_STATES, "Resumed after relaunch " + this); - } + ProtoLog.d(WM_DEBUG_STATES, "Resumed after relaunch %s", this); results = null; newIntents = null; mAtmService.getAppWarningsLocked().onResumeActivity(this); diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index 3ef383b2eed7..e2c130379df3 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -44,15 +44,14 @@ import static android.os.Process.INVALID_UID; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IDLE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS; @@ -66,7 +65,6 @@ import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_SUPERVISO import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS; import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE; -import static com.android.server.wm.RootWindowContainer.TAG_STATES; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; import static com.android.server.wm.Task.ActivityState.PAUSED; @@ -135,6 +133,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.ReferrerIntent; import com.android.internal.os.TransferPipe; +import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.ArrayUtils; import com.android.internal.util.function.pooled.PooledConsumer; import com.android.internal.util.function.pooled.PooledLambda; @@ -721,9 +720,9 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // While there are activities pausing we skipping starting any new activities until // pauses are complete. NOTE: that we also do this for activities that are starting in // the paused state because they will first be resumed then paused on the client side. - if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, - "realStartActivityLocked: Skipping start of r=" + r - + " some activities pausing..."); + ProtoLog.v(WM_DEBUG_STATES, + "realStartActivityLocked: Skipping start of r=%s some activities pausing...", + r); return false; } @@ -919,8 +918,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // This activity is not starting in the resumed state... which should look like we asked // it to pause+stop (but remain visible), and it has done so and reported back the // current icicle and other state. - if (DEBUG_STATES) Slog.v(TAG_STATES, - "Moving to PAUSED: " + r + " (starting in paused state)"); + ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s " + + "(starting in paused state)", r); r.setState(PAUSED, "realStartActivityLocked"); mRootWindowContainer.executeAppTransitionForAllDisplay(); } @@ -1071,11 +1070,11 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { /** Check if caller is allowed to launch activities on specified display. */ boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId, ActivityInfo aInfo) { - if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: displayId=" + launchDisplayId - + " callingPid=" + callingPid + " callingUid=" + callingUid); + ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: displayId=%d callingPid=%d " + + "callingUid=%d", launchDisplayId, callingPid, callingUid); if (callingPid == -1 && callingUid == -1) { - if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: no caller info, skip check"); + ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: no caller info, skip check"); return true; } @@ -1091,8 +1090,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid, callingUid); if (startAnyPerm == PERMISSION_GRANTED) { - if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" - + " allow launch any on display"); + ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch any on display"); return true; } @@ -1104,36 +1102,36 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // Limit launching on untrusted displays because their contents can be read from Surface // by apps that created them. if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { - if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" - + " disallow launch on virtual display for not-embedded activity."); + ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: disallow launch on " + + "virtual display for not-embedded activity."); return false; } // Check if the caller is allowed to embed activities from other apps. if (mService.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid) == PERMISSION_DENIED && !uidPresentOnDisplay) { - if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" - + " disallow activity embedding without permission."); + ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: disallow activity " + + "embedding without permission."); return false; } } if (!displayContent.isPrivate()) { // Anyone can launch on a public display. - if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" - + " allow launch on public display"); + ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch on public " + + "display"); return true; } // Check if the caller is the owner of the display. if (display.getOwnerUid() == callingUid) { - if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" - + " allow launch for owner of the display"); + ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch for owner of the" + + " display"); return true; } if (uidPresentOnDisplay) { - if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" - + " allow launch for caller present on the display"); + ProtoLog.d(WM_DEBUG_TASKS, "Launch on display check: allow launch for caller " + + "present on the display"); return true; } @@ -1832,8 +1830,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { final boolean animating = s.isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS) || mService.getTransitionController().inTransition(s); - if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + s.nowVisible - + " animating=" + animating + " finishing=" + s.finishing); + ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b " + + "finishing=%s", s, s.nowVisible, animating, s.finishing); if (!animating || mService.mShuttingDown) { if (!processPausingActivities && s.isState(PAUSING)) { // Defer processing pausing activities in this iteration and reschedule @@ -1843,7 +1841,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { continue; } - if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s); + ProtoLog.v(WM_DEBUG_STATES, "Ready to stop: %s", s); if (readyToStopActivities == null) { readyToStopActivities = new ArrayList<>(); } @@ -2077,7 +2075,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { msg.obj = r; r.topResumedStateLossTime = SystemClock.uptimeMillis(); mHandler.sendMessageDelayed(msg, TOP_RESUMED_STATE_LOSS_TIMEOUT); - if (DEBUG_STATES) Slog.v(TAG_STATES, "Waiting for top state to be released by " + r); + ProtoLog.v(WM_DEBUG_STATES, "Waiting for top state to be released by %s", r); } /** @@ -2085,10 +2083,9 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { * activity if needed. */ void handleTopResumedStateReleased(boolean timeout) { - if (DEBUG_STATES) { - Slog.v(TAG_STATES, "Top resumed state released " - + (timeout ? " (due to timeout)" : " (transition complete)")); - } + ProtoLog.v(WM_DEBUG_STATES, "Top resumed state released %s", + (timeout ? "(due to timeout)" : "(transition complete)")); + mHandler.removeMessages(TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG); if (!mTopResumedActivityWaitingForPrev) { // Top resumed activity state loss already handled. diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index fa4373ff2f3a..28e71fa7230a 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -57,14 +57,13 @@ import static android.os.Process.INVALID_UID; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; -import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS; @@ -1909,10 +1908,8 @@ class ActivityStarter { // if that is the case, so this is it! And for paranoia, make sure we have // correctly resumed the top activity. if (!mMovedToFront && mDoResume) { - if (DEBUG_TASKS) { - Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack - + " from " + targetTaskTop); - } + ProtoLog.d(WM_DEBUG_TASKS, "Bring to front target: %s from %s", mTargetStack, + targetTaskTop); mTargetStack.moveToFront("intentActivityFound"); } resumeTargetStackIfNeeded(); @@ -2564,10 +2561,8 @@ class ActivityStarter { mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions); addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask"); - if (DEBUG_TASKS) { - Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity - + " in new task " + mStartActivity.getTask()); - } + ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s", + mStartActivity, mStartActivity.getTask()); if (taskToAffiliate != null) { mStartActivity.setTaskToAffiliateWith(taskToAffiliate); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java index 3c562a6472b2..b5675a903144 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerDebugConfig.java @@ -43,14 +43,10 @@ public class ActivityTaskManagerDebugConfig { // Enable all debug log categories for activities. private static final boolean DEBUG_ALL_ACTIVITIES = DEBUG_ALL || false; - static final boolean DEBUG_PAUSE = DEBUG_ALL || false; static final boolean DEBUG_RECENTS = DEBUG_ALL || false; static final boolean DEBUG_RECENTS_TRIM_TASKS = DEBUG_RECENTS || false; - static final boolean DEBUG_SAVED_STATE = DEBUG_ALL_ACTIVITIES || false; static final boolean DEBUG_STACK = DEBUG_ALL || false; - static final boolean DEBUG_STATES = DEBUG_ALL_ACTIVITIES || false; public static final boolean DEBUG_SWITCH = DEBUG_ALL || false; - static final boolean DEBUG_TASKS = DEBUG_ALL || false; static final boolean DEBUG_TRANSITION = DEBUG_ALL || false; static final boolean DEBUG_VISIBILITY = DEBUG_ALL || false; static final boolean DEBUG_APP = DEBUG_ALL_ACTIVITIES || false; diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index c0e31f90b0ae..0938d22a12f5 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -70,6 +70,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IMMERSIVE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR; import static com.android.server.am.ActivityManagerService.MY_PID; import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS; @@ -96,9 +97,7 @@ import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS; @@ -324,14 +323,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** Hardware-reported OpenGLES version. */ final int GL_ES_VERSION; - public static final String DUMP_ACTIVITIES_CMD = "activities" ; - public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ; - public static final String DUMP_LASTANR_CMD = "lastanr" ; - public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ; - public static final String DUMP_STARTER_CMD = "starter" ; - public static final String DUMP_CONTAINERS_CMD = "containers" ; - public static final String DUMP_RECENTS_CMD = "recents" ; - public static final String DUMP_RECENTS_SHORT_CMD = "r" ; + public static final String DUMP_ACTIVITIES_CMD = "activities"; + public static final String DUMP_ACTIVITIES_SHORT_CMD = "a"; + public static final String DUMP_LASTANR_CMD = "lastanr"; + public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces"; + public static final String DUMP_STARTER_CMD = "starter"; + public static final String DUMP_CONTAINERS_CMD = "containers"; + public static final String DUMP_RECENTS_CMD = "recents"; + public static final String DUMP_RECENTS_SHORT_CMD = "r"; /** This activity is not being relaunched, or being relaunched for a non-resize reason. */ public static final int RELAUNCH_REASON_NONE = 0; @@ -614,7 +613,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { LAYOUT_REASON_CONFIG_CHANGED, LAYOUT_REASON_VISIBILITY_CHANGED, }) - @interface LayoutReason {} + @interface LayoutReason { + } + static final int LAYOUT_REASON_CONFIG_CHANGED = 0x1; static final int LAYOUT_REASON_VISIBILITY_CHANGED = 0x2; @@ -653,7 +654,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { * * @see #updateResumedAppTrace */ - private @Nullable ActivityRecord mTracedResumedActivity; + @Nullable + private ActivityRecord mTracedResumedActivity; /** If non-null, we are tracking the time the user spends in the currently focused app. */ AppTimeTracker mCurAppTimeTracker; @@ -716,6 +718,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { int OOM_ADJUSTMENT = 1; int LRU_UPDATE = 2; int PROCESS_CHANGE = 3; + int caller() default NONE; } @@ -873,7 +876,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } protected ActivityStackSupervisor createStackSupervisor() { - final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper()); + final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, + mH.getLooper()); supervisor.initialize(); return supervisor; } @@ -1128,7 +1132,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { throw new IllegalArgumentException("Bad PendingIntent object"); } - PendingIntentRecord pir = (PendingIntentRecord)target; + PendingIntentRecord pir = (PendingIntentRecord) target; synchronized (mGlobalLock) { // If this is coming from the currently resumed activity, it is @@ -1181,14 +1185,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // Look for the original activity in the list... final int N = resolves != null ? resolves.size() : 0; - for (int i=0; i<N; i++) { + for (int i = 0; i < N; i++) { ResolveInfo rInfo = resolves.get(i); if (rInfo.activityInfo.packageName.equals(r.packageName) && rInfo.activityInfo.name.equals(r.info.name)) { // We found the current one... the next matching is // after it. i++; - if (i<N) { + if (i < N) { aInfo = resolves.get(i).activityInfo; } if (debug) { @@ -1212,11 +1216,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { intent.setComponent(new ComponentName( aInfo.applicationInfo.packageName, aInfo.name)); - intent.setFlags(intent.getFlags()&~( - Intent.FLAG_ACTIVITY_FORWARD_RESULT| - Intent.FLAG_ACTIVITY_CLEAR_TOP| - Intent.FLAG_ACTIVITY_MULTIPLE_TASK| - FLAG_ACTIVITY_NEW_TASK)); + intent.setFlags(intent.getFlags() & ~(Intent.FLAG_ACTIVITY_FORWARD_RESULT + | Intent.FLAG_ACTIVITY_CLEAR_TOP + | Intent.FLAG_ACTIVITY_MULTIPLE_TASK + | FLAG_ACTIVITY_NEW_TASK)); // Okay now we need to start the new activity, replacing the currently running activity. // This is a little tricky because we want to start the new one as if the current one is @@ -1581,11 +1584,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** * Start the recents activity to perform the recents animation. * - * @param intent The intent to start the recents activity. + * @param intent The intent to start the recents activity. + * @param eventTime When the (touch) event is triggered to start recents activity. * @param recentsAnimationRunner Pass {@code null} to only preload the activity. */ @Override - public void startRecentsActivity(Intent intent, @Deprecated IAssistDataReceiver unused, + public void startRecentsActivity(Intent intent, long eventTime, @Nullable IRecentsAnimationRunner recentsAnimationRunner) { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()"); final int callingPid = Binder.getCallingPid(); @@ -1605,7 +1609,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (recentsAnimationRunner == null) { anim.preloadRecentsActivity(); } else { - anim.startRecentsActivity(recentsAnimationRunner); + anim.startRecentsActivity(recentsAnimationRunner, eventTime); } } } finally { @@ -1637,12 +1641,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { * * If the target display is private or virtual, some restrictions will apply. * - * @param displayId Target display id. - * @param intent Intent used to launch the activity. + * @param displayId Target display id. + * @param intent Intent used to launch the activity. * @param resolvedType The MIME type of the intent. - * @param userId The id of the user for whom the call is made. + * @param userId The id of the user for whom the call is made. * @return {@code true} if a call to start an activity on the target display should succeed and - * no {@link SecurityException} will be thrown, {@code false} otherwise. + * no {@link SecurityException} will be thrown, {@code false} otherwise. */ @Override public final boolean isActivityStartAllowedOnDisplay(int displayId, Intent intent, @@ -1671,11 +1675,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** * This is the internal entry point for handling Activity.finish(). * - * @param token The Binder token referencing the Activity we want to finish. + * @param token The Binder token referencing the Activity we want to finish. * @param resultCode Result code, if any, from this Activity. * @param resultData Result data (Intent), if any, from this Activity. * @param finishTask Whether to finish the task associated with this Activity. - * * @return Returns true if the activity successfully finished, or false if it is still running. */ @Override @@ -2310,14 +2313,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { * There are several possible results of this call: * - if the task is locked, then we will show the lock toast * - if there is a task behind the provided task, then that task is made visible and resumed as - * this task is moved to the back + * this task is moved to the back * - otherwise, if there are no other tasks in the stack: - * - if this task is in the pinned stack, then we remove the stack completely, which will - * have the effect of moving the task to the top or bottom of the fullscreen stack - * (depending on whether it is visible) - * - otherwise, we simply return home and hide this task + * - if this task is in the pinned stack, then we remove the stack completely, which will + * have the effect of moving the task to the top or bottom of the fullscreen stack + * (depending on whether it is visible) + * - otherwise, we simply return home and hide this task * - * @param token A reference to the activity we wish to move + * @param token A reference to the activity we wish to move * @param nonRoot If false then this only works if the activity is the root * of a task; if true it will work for any activity in a task. * @return Returns true if the move completed, false if not. @@ -2398,8 +2401,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return false; } - if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId - + " to windowingMode=" + windowingMode + " toTop=" + toTop); + ProtoLog.d(WM_DEBUG_TASKS, "setTaskWindowingMode: moving task=%d " + + "to windowingMode=%d toTop=%b", taskId, windowingMode, toTop); if (!task.isActivityTypeStandardOrUndefined()) { throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move" @@ -2462,7 +2465,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void unhandledBack() { - mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()"); + mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, + "unhandledBack()"); synchronized (mGlobalLock) { final long origId = Binder.clearCallingIdentity(); @@ -2509,9 +2513,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void moveTaskToFront(IApplicationThread appThread, String callingPackage, int taskId, int flags, Bundle bOptions) { - mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()"); + mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, + "moveTaskToFront()"); - if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId); + ProtoLog.d(WM_DEBUG_TASKS, "moveTaskToFront: moving taskId=%d", taskId); synchronized (mGlobalLock) { moveTaskToFrontLocked(appThread, callingPackage, taskId, flags, SafeActivityOptions.fromBundle(bOptions)); @@ -2543,7 +2548,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { try { final Task task = mRootWindowContainer.anyTaskForId(taskId); if (task == null) { - Slog.d(TAG, "Could not find task for id: "+ taskId); + ProtoLog.d(WM_DEBUG_TASKS, "Could not find task for id: %d", taskId); SafeActivityOptions.abort(options); return; } @@ -2756,8 +2761,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return; } - if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId - + " to stackId=" + stackId + " toTop=" + toTop); + ProtoLog.d(WM_DEBUG_TASKS, "moveTaskToStack: moving task=%d to " + + "stackId=%d toTop=%b", taskId, stackId, toTop); final Task stack = mRootWindowContainer.getStack(stackId); if (stack == null) { @@ -2780,7 +2785,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { * Moves the specified task to the primary-split-screen stack. * * @param taskId Id of task to move. - * @param toTop If the task and stack should be moved to the top. + * @param toTop If the task and stack should be moved to the top. * @return Whether the task was successfully put into splitscreen. */ @Override @@ -3293,8 +3298,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (intent.getSourceBounds() != null) { intent.setSourceBounds(null); } - if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { - if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { + if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { + if ((intent.getFlags() & Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { // The caller has added this as an auto-remove task... that makes no // sense, so turn off auto-remove. intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); @@ -3492,8 +3497,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { - if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId - + " to displayId=" + displayId); + ProtoLog.d(WM_DEBUG_TASKS, "moveStackToDisplay: moving stackId=%d to " + + "displayId=%d", stackId, displayId); mRootWindowContainer.moveStackToDisplay(stackId, displayId, ON_TOP); } finally { Binder.restoreCallingIdentity(ident); @@ -3652,14 +3657,16 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { try { if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { allowed = true; - if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid - + " is using old GET_TASKS but privileged; allowing"); + ProtoLog.w(WM_DEBUG_TASKS, + "%s: caller %d is using old GET_TASKS but privileged; allowing", + caller, callingUid); } } catch (RemoteException e) { } } - if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid - + " does not hold REAL_GET_TASKS; limiting output"); + ProtoLog.w(WM_DEBUG_TASKS, + "%s: caller %d does not hold REAL_GET_TASKS; limiting output", caller, + callingUid); } return allowed; } @@ -3978,7 +3985,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, + "suppressResizeConfigChanges()"); synchronized (mGlobalLock) { mSuppressResizeConfigChanges = suppress; } @@ -3988,10 +3996,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { * Moves the top activity in the input stackId to the pinned stack. * * @param stackId Id of stack to move the top activity to pinned stack. - * @param bounds Bounds to use for pinned stack. - * + * @param bounds Bounds to use for pinned stack. * @return True if the top activity of the input stack was successfully moved to the pinned - * stack. + * stack. */ @Override public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) { @@ -4146,7 +4153,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (params.hasSetAspectRatio() && !mWindowManager.isValidPictureInPictureAspectRatio( - r.mDisplayContent, params.getAspectRatio())) { + r.mDisplayContent, params.getAspectRatio())) { final float minAspectRatio = mContext.getResources().getFloat( com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); final float maxAspectRatio = mContext.getResources().getFloat( @@ -4194,8 +4201,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final WindowContainerTransaction wct = new WindowContainerTransaction(); final Rect primaryRect = tempDockedTaskInsetBounds != null ? tempDockedTaskInsetBounds - : (tempDockedTaskBounds != null ? tempDockedTaskBounds - : dockedBounds); + : (tempDockedTaskBounds != null ? tempDockedTaskBounds + : dockedBounds); wct.setBounds(primary.mRemoteToken.toWindowContainerToken(), primaryRect); Rect otherRect = tempOtherTaskInsetBounds != null ? tempOtherTaskInsetBounds : tempOtherTaskBounds; @@ -4464,7 +4471,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void updateLockTaskFeatures(int userId, int flags) { final int callingUid = Binder.getCallingUid(); if (callingUid != 0 && callingUid != SYSTEM_UID) { - mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES, + mAmInternal.enforceCallingPermission( + android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES, "updateLockTaskFeatures()"); } synchronized (mGlobalLock) { @@ -4768,11 +4776,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** * Clears launch params for the given package. + * * @param packageNames the names of the packages of which the launch params are to be cleared */ @Override public void clearLaunchParamsForPackages(List<String> packageNames) { - mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "clearLaunchParamsForPackages"); synchronized (mGlobalLock) { for (int i = 0; i < packageNames.size(); ++i) { @@ -4787,7 +4796,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void setDisplayToSingleTaskInstance(int displayId) { - mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setDisplayToSingleTaskInstance"); final long origId = Binder.clearCallingIdentity(); try { @@ -4806,7 +4815,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void requestPictureInPictureMode(IBinder token) throws RemoteException { - mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "requestPictureInPictureMode"); final long origId = Binder.clearCallingIdentity(); try { @@ -4902,7 +4911,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { boolean needSep = printedAnything; boolean printed = ActivityStackSupervisor.printThisActivity(pw, - mRootWindowContainer.getTopResumedActivity(), dumpPackage, needSep, + mRootWindowContainer.getTopResumedActivity(), dumpPackage, needSep, " ResumedActivity: ", null); if (printed) { printedAnything = true; @@ -4936,19 +4945,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** * There are three things that cmd can be: - * - a flattened component name that matches an existing activity - * - the cmd arg isn't the flattened component name of an existing activity: - * dump all activity whose component contains the cmd as a substring - * - A hex number of the ActivityRecord object instance. + * - a flattened component name that matches an existing activity + * - the cmd arg isn't the flattened component name of an existing activity: + * dump all activity whose component contains the cmd as a substring + * - A hex number of the ActivityRecord object instance. * <p> * The caller should not hold lock when calling this method because it will wait for the * activities to complete the dump. * - * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack - * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack + * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack + * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack */ protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, - int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) { + int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, + boolean dumpFocusedStackOnly) { ArrayList<ActivityRecord> activities; synchronized (mGlobalLock) { @@ -4975,9 +4985,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final Task task = r.getTask(); if (lastTask != task) { lastTask = task; - pw.print("TASK "); pw.print(lastTask.affinity); - pw.print(" id="); pw.print(lastTask.mTaskId); - pw.print(" userId="); pw.println(lastTask.mUserId); + pw.print("TASK "); + pw.print(lastTask.affinity); + pw.print(" id="); + pw.print(lastTask.mTaskId); + pw.print(" userId="); + pw.println(lastTask.mUserId); if (dumpAll) { lastTask.dump(pw, " "); } @@ -4997,8 +5010,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { String innerPrefix = prefix + " "; IApplicationThread appThread = null; synchronized (mGlobalLock) { - pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); - pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); + pw.print(prefix); + pw.print("ACTIVITY "); + pw.print(r.shortComponentName); + pw.print(" "); + pw.print(Integer.toHexString(System.identityHashCode(r))); pw.print(" pid="); if (r.hasProcess()) { pw.println(r.app.getPid()); @@ -5057,7 +5073,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public Configuration getConfiguration() { Configuration ci; - synchronized(mGlobalLock) { + synchronized (mGlobalLock) { ci = new Configuration(getGlobalConfigurationForCallingPid()); ci.userSetLocale = false; } @@ -5902,7 +5918,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final IBinder threadBinder = thread.asBinder(); final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap(); - for (int i = pmap.size()-1; i >= 0; i--) { + for (int i = pmap.size() - 1; i >= 0; i--) { final SparseArray<WindowProcessController> procs = pmap.valueAt(i); for (int j = procs.size() - 1; j >= 0; j--) { final WindowProcessController proc = procs.valueAt(j); @@ -5967,7 +5983,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { TimeMigrationUtils.formatMillisWithFixedFormat(System.currentTimeMillis()); sb.append(timeString); sb.append(": "); - TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); + TimeUtils.formatDuration(SystemClock.uptimeMillis() - startTime, sb); sb.append(" since "); sb.append(msg); FileOutputStream fos = new FileOutputStream(tracesFile); @@ -5990,7 +6006,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { File lastTracesFile = null; File curTracesFile = null; - for (int i=9; i>=0; i--) { + for (int i = 9; i >= 0; i--) { String name = String.format(Locale.US, "slow%02d.txt", i); curTracesFile = new File(tracesDir, name); if (curTracesFile.exists()) { @@ -6037,7 +6053,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { case REPORT_TIME_TRACKER_MSG: { AppTimeTracker tracker = (AppTimeTracker) msg.obj; tracker.deliverResult(mContext); - } break; + } + break; } } } @@ -6233,7 +6250,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void setVr2dDisplayId(int vr2dDisplayId) { - if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId); + ProtoLog.d(WM_DEBUG_TASKS, "setVr2dDisplayId called for: %d", vr2dDisplayId); synchronized (mGlobalLock) { mVr2dDisplayId = vr2dDisplayId; } @@ -6541,7 +6558,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { * Set the corresponding display information for the process global configuration. To be * called when we need to show IME on a different display. * - * @param pid The process id associated with the IME window. + * @param pid The process id associated with the IME window. * @param displayId The ID of the display showing the IME. */ @Override @@ -6553,7 +6570,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (pid == MY_PID || pid < 0) { ProtoLog.w(WM_DEBUG_CONFIGURATION, - "Trying to update display configuration for system/invalid process."); + "Trying to update display configuration for system/invalid process."); return; } synchronized (mGlobalLock) { @@ -6943,7 +6960,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { pw.println(); getActivityStartController().dump(pw, " ", null); pw.println(); - pw.println("-------------------------------------------------------------------------------"); + pw.println("-------------------------------------------------------------------" + + "------------"); dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */, true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */, "" /* header */); diff --git a/services/core/java/com/android/server/wm/DisplayAreaGroup.java b/services/core/java/com/android/server/wm/DisplayAreaGroup.java new file mode 100644 index 000000000000..bcf8c7c901af --- /dev/null +++ b/services/core/java/com/android/server/wm/DisplayAreaGroup.java @@ -0,0 +1,57 @@ +/* + * 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; + +import static android.content.pm.ActivityInfo.reverseOrientation; + +import android.content.pm.ActivityInfo; +import android.graphics.Rect; + +/** The root of a partition of the logical display. */ +class DisplayAreaGroup extends RootDisplayArea { + + DisplayAreaGroup(WindowManagerService wms, String name, int featureId) { + super(wms, name, featureId); + } + + @Override + boolean isOrientationDifferentFromDisplay() { + if (mDisplayContent == null) { + return false; + } + + final Rect bounds = getBounds(); + final Rect displayBounds = mDisplayContent.getBounds(); + + return (bounds.width() < bounds.height()) + != (displayBounds.width() < displayBounds.height()); + } + + @ActivityInfo.ScreenOrientation + @Override + int getOrientation(int candidate) { + int orientation = super.getOrientation(candidate); + + // Reverse the requested orientation if the orientation of this DAG is different from the + // display, so that when the display rotates to the reversed orientation, this DAG will be + // in the requested orientation, so as the requested app. + // For example, if the display is 1200x900 (landscape), and this DAG is 600x900 (portrait). + // When an app below this DAG is requesting landscape, it should actually request the + // display to be portrait, so that the DAG and the app will be in landscape. + return isOrientationDifferentFromDisplay() ? reverseOrientation(orientation) : orientation; + } +} diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java index 56e1187d51da..a0074a2d760c 100644 --- a/services/core/java/com/android/server/wm/LaunchParamsController.java +++ b/services/core/java/com/android/server/wm/LaunchParamsController.java @@ -144,11 +144,11 @@ class LaunchParamsController { mTmpParams.mPreferredTaskDisplayArea, true /* onTop */); } - if (mTmpParams.hasWindowingMode() - && mTmpParams.mWindowingMode != task.getRootTask().getWindowingMode()) { + if (mTmpParams.hasWindowingMode() && task.isRootTask() + && mTmpParams.mWindowingMode != task.getWindowingMode()) { final int activityType = activity != null ? activity.getActivityType() : task.getActivityType(); - task.getRootTask().setWindowingMode(task.getDisplayArea().validateWindowingMode( + task.setWindowingMode(task.getDisplayArea().validateWindowingMode( mTmpParams.mWindowingMode, activity, task, activityType)); } diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index 255b3f147d30..d29258049acc 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -35,10 +35,10 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.os.Process.SYSTEM_UID; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS_TRIM_TASKS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; @@ -72,6 +72,7 @@ import android.view.MotionEvent; import android.view.WindowManagerPolicyConstants.PointerEventListener; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.am.ActivityManagerService; @@ -157,7 +158,8 @@ class RecentTasks { */ private int mRecentsUid = -1; private ComponentName mRecentsComponent = null; - private @Nullable String mFeatureId; + @Nullable + private String mFeatureId; /** * Mapping of user id -> whether recent tasks have been loaded for that user. @@ -397,7 +399,7 @@ class RecentTasks { /** * @return whether the given component is the recents component and shares the same uid as the - * recents component. + * recents component. */ boolean isRecentsComponent(ComponentName cn, int uid) { return cn.equals(mRecentsComponent) && UserHandle.isSameApp(uid, mRecentsUid); @@ -423,7 +425,8 @@ class RecentTasks { /** * @return the featureId for the recents component. */ - @Nullable String getRecentsComponentFeatureId() { + @Nullable + String getRecentsComponentFeatureId() { return mFeatureId; } @@ -617,7 +620,7 @@ class RecentTasks { /** Remove recent tasks for a user. */ private void removeTasksForUserLocked(int userId) { - if(userId <= 0) { + if (userId <= 0) { Slog.i(TAG, "Can't remove recent task on user " + userId); return; } @@ -625,8 +628,8 @@ class RecentTasks { for (int i = mTasks.size() - 1; i >= 0; --i) { Task task = mTasks.get(i); if (task.mUserId == userId) { - if(DEBUG_TASKS) Slog.i(TAG_TASKS, - "remove RecentTask " + task + " when finishing user" + userId); + ProtoLog.i(WM_DEBUG_TASKS, "remove RecentTask %s when finishing user " + + "%d", task, userId); remove(task); } } @@ -640,11 +643,11 @@ class RecentTasks { && packageNames.contains(task.realActivity.getPackageName()) && task.mUserId == userId && task.realActivitySuspended != suspended) { - task.realActivitySuspended = suspended; - if (suspended) { - mSupervisor.removeTask(task, false, REMOVE_FROM_RECENTS, "suspended-package"); - } - notifyTaskPersisterLocked(task, false); + task.realActivitySuspended = suspended; + if (suspended) { + mSupervisor.removeTask(task, false, REMOVE_FROM_RECENTS, "suspended-package"); + } + notifyTaskPersisterLocked(task, false); } } } @@ -780,25 +783,31 @@ class RecentTasks { continue; } else { // Otherwise just not available for now. - if (DEBUG_RECENTS && task.isAvailable) Slog.d(TAG_RECENTS, - "Making recent unavailable: " + task); + if (DEBUG_RECENTS && task.isAvailable) { + Slog.d(TAG_RECENTS, + "Making recent unavailable: " + task); + } task.isAvailable = false; } } else { if (!ai.enabled || !ai.applicationInfo.enabled || (ai.applicationInfo.flags - & ApplicationInfo.FLAG_INSTALLED) == 0) { - if (DEBUG_RECENTS && task.isAvailable) Slog.d(TAG_RECENTS, - "Making recent unavailable: " + task - + " (enabled=" + ai.enabled + "/" - + ai.applicationInfo.enabled - + " flags=" - + Integer.toHexString(ai.applicationInfo.flags) - + ")"); + & ApplicationInfo.FLAG_INSTALLED) == 0) { + if (DEBUG_RECENTS && task.isAvailable) { + Slog.d(TAG_RECENTS, + "Making recent unavailable: " + task + + " (enabled=" + ai.enabled + "/" + + ai.applicationInfo.enabled + + " flags=" + + Integer.toHexString(ai.applicationInfo.flags) + + ")"); + } task.isAvailable = false; } else { - if (DEBUG_RECENTS && !task.isAvailable) Slog.d(TAG_RECENTS, - "Making recent available: " + task); + if (DEBUG_RECENTS && !task.isAvailable) { + Slog.d(TAG_RECENTS, + "Making recent available: " + task); + } task.isAvailable = true; } } @@ -974,16 +983,20 @@ class RecentTasks { final int size = mTasks.size(); for (int i = 0; i < size; i++) { final Task task = mTasks.get(i); - if (TaskPersister.DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task - + " persistable=" + task.isPersistable); + if (TaskPersister.DEBUG) { + Slog.d(TAG, "LazyTaskWriter: task=" + task + + " persistable=" + task.isPersistable); + } final Task rootTask = task.getRootTask(); if ((task.isPersistable || task.inRecents) && (rootTask == null || !rootTask.isHomeOrRecentsStack())) { if (TaskPersister.DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task); persistentTaskIds.add(task.mTaskId); } else { - if (TaskPersister.DEBUG) Slog.d(TAG, "omitting from persistentTaskIds task=" - + task); + if (TaskPersister.DEBUG) { + Slog.d(TAG, "omitting from persistentTaskIds task=" + + task); + } } } } @@ -1051,8 +1064,10 @@ class RecentTasks { // TODO: VI what about if it's just an activity? // Probably nothing to do here if (task.voiceSession != null) { - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "addRecent: not adding voice interaction " + task); + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, + "addRecent: not adding voice interaction " + task); + } return; } // Another quick case: check if the top-most recent task is the same. @@ -1064,8 +1079,10 @@ class RecentTasks { // tasks that are at the top. if (isAffiliated && recentsCount > 0 && task.inRecents && task.mAffiliatedTaskId == mTasks.get(0).mAffiliatedTaskId) { - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: affiliated " + mTasks.get(0) - + " at top when adding " + task); + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "addRecent: affiliated " + mTasks.get(0) + + " at top when adding " + task); + } return; } @@ -1122,14 +1139,17 @@ class RecentTasks { if (other == task.mNextAffiliate) { // We found the index of our next affiliation, which is who is // before us in the list, so add after that point. - taskIndex = otherIndex+1; + taskIndex = otherIndex + 1; } else { // We found the index of our previous affiliation, which is who is // after us in the list, so add at their position. taskIndex = otherIndex; } - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "addRecent: new affiliated task added at " + taskIndex + ": " + task); + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, + "addRecent: new affiliated task added at " + taskIndex + ": " + + task); + } mTasks.add(taskIndex, task); notifyTaskAdded(task); @@ -1143,13 +1163,17 @@ class RecentTasks { // everything and then go through our general path of adding a new task. needAffiliationFix = true; } else { - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "addRecent: couldn't find other affiliation " + other); + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, + "addRecent: couldn't find other affiliation " + other); + } needAffiliationFix = true; } } else { - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "addRecent: adding affiliated task without next/prev:" + task); + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, + "addRecent: adding affiliated task without next/prev:" + task); + } needAffiliationFix = true; } } @@ -1204,8 +1228,10 @@ class RecentTasks { final Task task = mTasks.remove(recentsCount - 1); notifyTaskRemoved(task, true /* wasTrimmed */, false /* killProcess */); recentsCount--; - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "Trimming over max-recents task=" + task - + " max=" + mGlobalMaxNumTasks); + if (DEBUG_RECENTS_TRIM_TASKS) { + Slog.d(TAG, "Trimming over max-recents task=" + task + + " max=" + mGlobalMaxNumTasks); + } } // Remove any tasks that belong to currently quiet profiles @@ -1216,13 +1242,15 @@ class RecentTasks { if (userInfo != null && userInfo.isManagedProfile() && userInfo.isQuietModeEnabled()) { mTmpQuietProfileUserIds.put(userId, true); } - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "User: " + userInfo - + " quiet=" + mTmpQuietProfileUserIds.get(userId)); + if (DEBUG_RECENTS_TRIM_TASKS) { + Slog.d(TAG, "User: " + userInfo + + " quiet=" + mTmpQuietProfileUserIds.get(userId)); + } } // Remove any inactive tasks, calculate the latest set of visible tasks. int numVisibleTasks = 0; - for (int i = 0; i < mTasks.size();) { + for (int i = 0; i < mTasks.size(); ) { final Task task = mTasks.get(i); if (isActiveRecentTask(task, mTmpQuietProfileUserIds)) { @@ -1246,8 +1274,10 @@ class RecentTasks { } else { // Fall through to trim visible tasks that are no longer in range and // trimmable - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, - "Trimming out-of-range visible task=" + task); + if (DEBUG_RECENTS_TRIM_TASKS) { + Slog.d(TAG, + "Trimming out-of-range visible task=" + task); + } } } } else { @@ -1266,8 +1296,10 @@ class RecentTasks { * @return whether the given task should be considered active. */ private boolean isActiveRecentTask(Task task, SparseBooleanArray quietProfileUserIds) { - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "isActiveRecentTask: task=" + task - + " globalMax=" + mGlobalMaxNumTasks); + if (DEBUG_RECENTS_TRIM_TASKS) { + Slog.d(TAG, "isActiveRecentTask: task=" + task + + " globalMax=" + mGlobalMaxNumTasks); + } if (quietProfileUserIds.get(task.mUserId)) { // Quiet profile user's tasks are never active @@ -1280,8 +1312,10 @@ class RecentTasks { final Task affiliatedTask = getTask(task.mAffiliatedTaskId); if (affiliatedTask != null) { if (!isActiveRecentTask(affiliatedTask, quietProfileUserIds)) { - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, - "\taffiliatedWithTask=" + affiliatedTask + " is not active"); + if (DEBUG_RECENTS_TRIM_TASKS) { + Slog.d(TAG, + "\taffiliatedWithTask=" + affiliatedTask + " is not active"); + } return false; } } @@ -1296,13 +1330,15 @@ class RecentTasks { */ @VisibleForTesting boolean isVisibleRecentTask(Task task) { - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "isVisibleRecentTask: task=" + task - + " minVis=" + mMinNumVisibleTasks + " maxVis=" + mMaxNumVisibleTasks - + " sessionDuration=" + mActiveTasksSessionDurationMs - + " inactiveDuration=" + task.getInactiveDuration() - + " activityType=" + task.getActivityType() - + " windowingMode=" + task.getWindowingMode() - + " intentFlags=" + task.getBaseIntent().getFlags()); + if (DEBUG_RECENTS_TRIM_TASKS) { + Slog.d(TAG, "isVisibleRecentTask: task=" + task + + " minVis=" + mMinNumVisibleTasks + " maxVis=" + mMaxNumVisibleTasks + + " sessionDuration=" + mActiveTasksSessionDurationMs + + " inactiveDuration=" + task.getInactiveDuration() + + " activityType=" + task.getActivityType() + + " windowingMode=" + task.getWindowingMode() + + " intentFlags=" + task.getBaseIntent().getFlags()); + } switch (task.getActivityType()) { case ACTIVITY_TYPE_HOME: @@ -1468,8 +1504,10 @@ class RecentTasks { mHiddenTasks.add(removedTask); } notifyTaskRemoved(removedTask, false /* wasTrimmed */, false /* killProcess */); - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "Trimming task=" + removedTask - + " for addition of task=" + task); + if (DEBUG_RECENTS_TRIM_TASKS) { + Slog.d(TAG, "Trimming task=" + removedTask + + " for addition of task=" + task); + } } notifyTaskPersisterLocked(removedTask, false /* flush */); } @@ -1622,16 +1660,20 @@ class RecentTasks { top = top.mNextAffiliate; topIndex--; } - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: adding affilliates starting at " - + topIndex + " from intial " + taskIndex); + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "addRecent: adding affiliates starting at " + + topIndex + " from initial " + taskIndex); + } // Find the end of the chain, doing a validity check along the way. boolean isValid = top.mAffiliatedTaskId == task.mAffiliatedTaskId; int endIndex = topIndex; Task prev = top; while (endIndex < recentsCount) { Task cur = mTasks.get(endIndex); - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: looking at next chain @" - + endIndex + " " + cur); + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "addRecent: looking at next chain @" + + endIndex + " " + cur); + } if (cur == top) { // Verify start of the chain. if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { @@ -1701,14 +1743,18 @@ class RecentTasks { if (isValid) { // All looks good, we can just move all of the affiliated tasks // to the top. - for (int i=topIndex; i<=endIndex; i++) { - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: moving affiliated " + task - + " from " + i + " to " + (i-topIndex)); + for (int i = topIndex; i <= endIndex; i++) { + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "addRecent: moving affiliated " + task + + " from " + i + " to " + (i - topIndex)); + } Task cur = mTasks.remove(i); mTasks.add(i - topIndex, cur); } - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: done moving tasks " + topIndex - + " to " + endIndex); + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "addRecent: done moving tasks " + topIndex + + " to " + endIndex); + } return true; } @@ -1768,7 +1814,9 @@ class RecentTasks { printedHeader = true; printedAnything = true; } - pw.print(" * Recent #"); pw.print(i); pw.print(": "); + pw.print(" * Recent #"); + pw.print(i); + pw.print(": "); pw.println(task); if (dumpAll) { task.dump(pw, " "); @@ -1787,7 +1835,7 @@ class RecentTasks { boolean match = taskInfo.baseIntent != null && taskInfo.baseIntent.getComponent() != null && dumpPackage.equals( - taskInfo.baseIntent.getComponent().getPackageName()); + taskInfo.baseIntent.getComponent().getPackageName()); if (!match) { match |= taskInfo.baseActivity != null && dumpPackage.equals(taskInfo.baseActivity.getPackageName()); @@ -1818,7 +1866,9 @@ class RecentTasks { printedAnything = true; } - pw.print(" * RecentTaskInfo #"); pw.print(i); pw.print(": "); + pw.print(" * RecentTaskInfo #"); + pw.print(i); + pw.print(": "); taskInfo.dump(pw, " "); } } @@ -1842,8 +1892,8 @@ class RecentTasks { /** * @return Whether the activity types and windowing modes of the two tasks are considered - * compatible. This is necessary because we currently don't persist the activity type - * or the windowing mode with the task, so they can be undefined when restored. + * compatible. This is necessary because we currently don't persist the activity type + * or the windowing mode with the task, so they can be undefined when restored. */ private boolean hasCompatibleActivityTypeAndWindowingMode(Task t1, Task t2) { final int activityType = t1.getActivityType(); diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index 35338bb67469..1cf50ab25240 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -161,7 +161,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } } - void startRecentsActivity(IRecentsAnimationRunner recentsAnimationRunner) { + void startRecentsActivity(IRecentsAnimationRunner recentsAnimationRunner, long eventTime) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "startRecentsActivity(): intent=%s", mTargetIntent); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "RecentsAnimation#startRecentsActivity"); @@ -249,8 +249,13 @@ class RecentsAnimation implements RecentsAnimationCallbacks, // we fetch the visible tasks to be controlled by the animation mService.mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); + ActivityOptions options = null; + if (eventTime > 0) { + options = ActivityOptions.makeBasic(); + options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime); + } mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, - START_TASK_TO_FRONT, targetActivity, null /* options */); + START_TASK_TO_FRONT, targetActivity, options); // Register for stack order changes mDefaultTaskDisplayArea.registerStackOrderChangedListener(this); diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java index c3953b4efa16..9181a0fb0734 100644 --- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java +++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java @@ -17,14 +17,12 @@ package com.android.server.wm; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; -import static com.android.server.wm.Task.TAG_TASKS; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import android.app.ActivityOptions; import android.content.Intent; import android.content.pm.ActivityInfo; import android.os.Debug; -import android.util.Slog; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.function.pooled.PooledConsumer; @@ -201,8 +199,8 @@ class ResetTargetTaskHelper { noOptions = takeOption(p, noOptions); - if (DEBUG_TASKS) Slog.w(TAG_TASKS, - "resetTaskIntendedTask: calling finishActivity on " + p); + ProtoLog.w(WM_DEBUG_TASKS, "resetTaskIntendedTask: calling finishActivity " + + "on %s", p); p.finishIfPossible(reason, false /* oomAdj */); } } @@ -213,15 +211,15 @@ class ResetTargetTaskHelper { while (!mResultActivities.isEmpty()) { final ActivityRecord p = mResultActivities.remove(0); - if (ignoreFinishing&& p.finishing) continue; + if (ignoreFinishing && p.finishing) continue; if (takeOptions) { noOptions = takeOption(p, noOptions); } ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Removing activity %s from task=%s " - + "adding to task=%s Callers=%s", p, mTask, targetTask, Debug.getCallers(4)); - if (DEBUG_TASKS) Slog.v(TAG_TASKS, - "Pushing next activity " + p + " out to target's task " + target); + + "adding to task=%s Callers=%s", p, mTask, targetTask, Debug.getCallers(4)); + ProtoLog.v(WM_DEBUG_TASKS, "Pushing next activity %s out to target's task %s", p, + target); p.reparent(targetTask, position, "resetTargetTaskIfNeeded"); } } @@ -253,8 +251,8 @@ class ResetTargetTaskHelper { // If the activity currently at the bottom has the same task affinity as // the one we are moving, then merge it into the same task. targetTask = task; - if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " - + r + " out to bottom task " + targetTask); + ProtoLog.v(WM_DEBUG_TASKS, "Start pushing activity %s out to bottom task %s", r, + targetTask); } if (targetTask == null) { if (alwaysCreateTask) { diff --git a/services/core/java/com/android/server/wm/RootDisplayArea.java b/services/core/java/com/android/server/wm/RootDisplayArea.java index faed7fa99fdd..d9a87734e9e7 100644 --- a/services/core/java/com/android/server/wm/RootDisplayArea.java +++ b/services/core/java/com/android/server/wm/RootDisplayArea.java @@ -27,7 +27,8 @@ import java.util.Map; /** * Root of a {@link DisplayArea} hierarchy. It can be either the {@link DisplayContent} as the root - * of the whole logical display, or the root of a {@link DisplayArea} group. + * of the whole logical display, or a {@link DisplayAreaGroup} as the root of a partition of the + * logical display. */ class RootDisplayArea extends DisplayArea<DisplayArea> { @@ -50,6 +51,16 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { super(wms, Type.ANY, name, featureId); } + @Override + RootDisplayArea getRootDisplayArea() { + return this; + } + + /** Whether the orientation (based on dimensions) of this root is different from the Display. */ + boolean isOrientationDifferentFromDisplay() { + return false; + } + /** Finds the {@link DisplayArea.Tokens} that this type of window should be attached to. */ DisplayArea.Tokens findAreaForToken(WindowToken token) { int windowLayerFromType = token.getWindowLayerFromType(); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 2df56a3ec843..cabf1bf0db3d 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -44,6 +44,8 @@ import static android.view.WindowManager.TRANSIT_TASK_TO_BACK; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST; @@ -55,11 +57,8 @@ import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS; import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; @@ -179,7 +178,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1; private static final int SET_USER_ACTIVITY_TIMEOUT = 2; static final String TAG_TASKS = TAG + POSTFIX_TASKS; - private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; static final String TAG_STATES = TAG + POSTFIX_STATES; private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; @@ -235,7 +233,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE }) - public @interface AnyTaskForIdMatchTaskMode {} + public @interface AnyTaskForIdMatchTaskMode { + } + // Match only tasks in the current stacks static final int MATCH_TASK_IN_STACKS_ONLY = 0; // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks @@ -305,6 +305,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> }; private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); + static class FindTaskResult implements Function<Task, Boolean> { ActivityRecord mRecord; boolean mIdealMatch; @@ -335,7 +336,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // If documentData is non-null then it must match the existing task data. documentData = isDocument ? intent.getData() : null; - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent); + ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s in %s", target, + parent); parent.forAllLeafTasks(this); } @@ -353,12 +355,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent> public Boolean apply(Task task) { if (task.voiceSession != null) { // We never match voice sessions; those always run independently. - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session"); + ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: voice session", task); return false; } if (task.mUserId != userId) { // Looking for a different task. - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user"); + ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: different user", task); return false; } @@ -366,11 +368,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */); if (r == null || r.finishing || r.mUserId != userId || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r); + ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch root %s", task, r); return false; } if (!r.hasCompatibleActivityType(mTarget)) { - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type"); + ProtoLog.d(WM_DEBUG_TASKS, "Skipping %s: mismatch activity type", task); return false; } @@ -389,40 +391,40 @@ class RootWindowContainer extends WindowContainer<DisplayContent> taskDocumentData = null; } - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls=" - + (task.realActivity != null ? task.realActivity.flattenToShortString() : "") - + "/aff=" + r.getTask().rootAffinity + " to new cls=" - + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity); + ProtoLog.d(WM_DEBUG_TASKS, "Comparing existing cls=%s /aff=%s to new cls=%s /aff=%s", + r.getTask().rootAffinity, intent.getComponent().flattenToShortString(), + info.taskAffinity, (task.realActivity != null + ? task.realActivity.flattenToShortString() : "")); // TODO Refactor to remove duplications. Check if logic can be simplified. if (task.realActivity != null && task.realActivity.compareTo(cls) == 0 && Objects.equals(documentData, taskDocumentData)) { - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!"); + ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!"); //dump(); - if (DEBUG_TASKS) Slog.d(TAG_TASKS, - "For Intent " + intent + " bringing to top: " + r.intent); + ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", intent, r.intent); mRecord = r; mIdealMatch = true; return true; } else if (affinityIntent != null && affinityIntent.getComponent() != null && affinityIntent.getComponent().compareTo(cls) == 0 && Objects.equals(documentData, taskDocumentData)) { - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!"); - if (DEBUG_TASKS) Slog.d(TAG_TASKS, - "For Intent " + intent + " bringing to top: " + r.intent); + ProtoLog.d(WM_DEBUG_TASKS, "Found matching class!"); + ProtoLog.d(WM_DEBUG_TASKS, "For Intent %s bringing to top: %s", intent, r.intent); mRecord = r; mIdealMatch = true; return true; } else if (!isDocument && !taskIsDocument && mRecord == null && task.rootAffinity != null) { if (task.rootAffinity.equals(mTarget.taskAffinity)) { - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!"); + ProtoLog.d(WM_DEBUG_TASKS, "Found matching affinity candidate!"); // It is possible for multiple tasks to have the same root affinity especially // if they are in separate stacks. We save off this candidate, but keep looking // to see if there is a better candidate. mRecord = r; mIdealMatch = false; } - } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task); + } else { + ProtoLog.d(WM_DEBUG_TASKS, "Not a match: %s", task); + } return false; } @@ -578,6 +580,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * Returns {@code true} if the callingUid has any non-toast window currently visible to the * user. Also ignores {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_STARTING}, * since those windows don't belong to apps. + * * @see WindowState#isNonToastOrStarting() */ boolean isAnyNonToastWindowVisibleForUid(int callingUid) { @@ -791,7 +794,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> "Looks like we have reclaimed some memory, clearing surface for retry."); if (surfaceController != null) { ProtoLog.i(WM_SHOW_SURFACE_ALLOC, - "SURFACE RECOVER DESTROY: %s", winAnimator.mWin); + "SURFACE RECOVER DESTROY: %s", winAnimator.mWin); winAnimator.destroySurface(); if (winAnimator.mWin.mActivityRecord != null) { winAnimator.mWin.mActivityRecord.removeStartingWindow(); @@ -822,8 +825,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // "Something has changed! Let's make it correct now." // TODO: Super long method that should be broken down... void performSurfacePlacementNoTrace() { - if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by " - + Debug.getCallers(3)); + if (DEBUG_WINDOW_TRACE) { + Slog.v(TAG, "performSurfacePlacementInner: entry. Called by " + + Debug.getCallers(3)); + } int i; @@ -851,8 +856,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final DisplayContent defaultDisplay = mWmService.getDefaultDisplayContentLocked(); final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked; - if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, - ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); + if (SHOW_LIGHT_TRANSACTIONS) { + Slog.i(TAG, + ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); + } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges"); mWmService.openSurfaceTransaction(); try { @@ -862,8 +869,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } finally { mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces"); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, - "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); + if (SHOW_LIGHT_TRANSACTIONS) { + Slog.i(TAG, + "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); + } } mWmService.mAnimator.executeAfterPrepareSurfacesRunnables(); @@ -896,8 +905,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (isLayoutNeeded()) { defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT; - if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded", - defaultDisplay.pendingLayoutChanges); + if (DEBUG_LAYOUT_REPEATS) { + surfacePlacer.debugLayoutRepeats("mLayoutNeeded", + defaultDisplay.pendingLayoutChanges); + } } handleResizingWindows(); @@ -1105,11 +1116,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } /** - * @param w WindowState this method is applied to. + * @param w WindowState this method is applied to. * @param obscured True if there is a window on top of this obscuring the display. - * @param syswin System window? + * @param syswin System window? * @return True when the display contains content to show the user. When false, the display - * manager may choose to mirror or blank the display. + * manager may choose to mirror or blank the display. */ boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) { final WindowManager.LayoutParams attrs = w.mAttrs; @@ -1243,7 +1254,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } void dumpTopFocusedDisplayId(PrintWriter pw) { - pw.print(" mTopFocusedDisplayId="); pw.println(mTopFocusedDisplayId); + pw.print(" mTopFocusedDisplayId="); + pw.println(mTopFocusedDisplayId); } void dumpLayoutNeededDisplayIds(PrintWriter pw) { @@ -1359,7 +1371,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } } - @Nullable Context getDisplayUiContext(int displayId) { + @Nullable + Context getDisplayUiContext(int displayId) { return getDisplayContent(displayId) != null ? getDisplayContent(displayId).getDisplayUiContext() : null; } @@ -1437,7 +1450,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * corresponding record in display manager. */ // TODO: Look into consolidating with getDisplayContent() - @Nullable DisplayContent getDisplayContentOrCreate(int displayId) { + @Nullable + DisplayContent getDisplayContentOrCreate(int displayId) { DisplayContent displayContent = getDisplayContent(displayId); if (displayContent != null) { return displayContent; @@ -1494,8 +1508,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final DisplayContent display = getDisplayContent(displayId); return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> - result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea, - allowInstrumenting, fromHomeKey), + result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea, + allowInstrumenting, fromHomeKey), false /* initValue */); } @@ -1504,11 +1518,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * displayId - default display area always uses primary home component. * For secondary display areas, the home activity must have category SECONDARY_HOME and then * resolves according to the priorities listed below. - * - If default home is not set, always use the secondary home defined in the config. - * - Use currently selected primary home activity. - * - Use the activity in the same package as currently selected primary home activity. - * If there are multiple activities matched, use first one. - * - Use the secondary home defined in the config. + * - If default home is not set, always use the secondary home defined in the config. + * - Use currently selected primary home activity. + * - Use the activity in the same package as currently selected primary home activity. + * If there are multiple activities matched, use first one. + * - Use the secondary home defined in the config. */ boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea, boolean allowInstrumenting, boolean fromHomeKey) { @@ -1556,6 +1570,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * This resolves the home activity info. + * * @return the home activity info if any. */ @VisibleForTesting @@ -1629,7 +1644,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } if (aInfo != null) { - if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, false /* allowInstrumenting */)) { + if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, + false /* allowInstrumenting */)) { aInfo = null; } } @@ -1687,6 +1703,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Check if the display area is valid for secondary home activity. + * * @param taskDisplayArea The target display area. * @return {@code true} if allow to launch, {@code false} otherwise. */ @@ -1727,8 +1744,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Check if home activity start should be allowed on a display. - * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched. - * @param taskDisplayArea The target display area. + * + * @param homeInfo {@code ActivityInfo} of the home activity that is going to be + * launched. + * @param taskDisplayArea The target display area. * @param allowInstrumenting Whether launching home should be allowed if being instrumented. * @return {@code true} if allow to launch, {@code false} otherwise. */ @@ -1773,13 +1792,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Ensure all activities visibility, update orientation and configuration. * - * @param starting The currently starting activity or {@code null} if there is none. - * @param displayId The id of the display where operation is executed. + * @param starting The currently starting activity or {@code null} if there is + * none. + * @param displayId The id of the display where operation is executed. * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to * {@code true} if config changed. - * @param deferResume Whether to defer resume while updating config. + * @param deferResume Whether to defer resume while updating config. * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched - * because of configuration update. + * because of configuration update. */ boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId, boolean markFrozenIfConfigChanged, boolean deferResume) { @@ -2066,9 +2086,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Move stack with all its existing content to specified task display area. - * @param stackId Id of stack to move. + * + * @param stackId Id of stack to move. * @param taskDisplayArea The task display area to move stack to. - * @param onTop Indicates whether container should be place on top or on bottom. + * @param onTop Indicates whether container should be place on top or on bottom. */ void moveStackToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea, boolean onTop) { final Task stack = getStack(stackId); @@ -2098,9 +2119,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Move stack with all its existing content to specified display. - * @param stackId Id of stack to move. + * + * @param stackId Id of stack to move. * @param displayId Id of display to move stack to. - * @param onTop Indicates whether container should be place on top or on bottom. + * @param onTop Indicates whether container should be place on top or on bottom. */ void moveStackToDisplay(int stackId, int displayId, boolean onTop) { final DisplayContent displayContent = getDisplayContentOrCreate(displayId); @@ -2192,7 +2214,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final ActivityRecord oldTopActivity = task.getTopMostActivity(); if (oldTopActivity != null && oldTopActivity.isState(STOPPED) && task.getDisplayContent().mAppTransition.getAppTransition() - == TRANSIT_TASK_TO_BACK) { + == TRANSIT_TASK_TO_BACK) { task.getDisplayContent().mClosingApps.add(oldTopActivity); oldTopActivity.mRequestForceTransition = true; } @@ -2227,6 +2249,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Notifies when an activity enters or leaves PIP mode. + * * @param r indicates the activity currently in PIP, can be null to indicate no activity is * currently in PIP mode. */ @@ -2249,7 +2272,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> @Nullable ActivityRecord findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea) { - if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); + ProtoLog.d(WM_DEBUG_TASKS, "Looking for task of %s", r); mTmpFindTaskResult.clear(); // Looking up task on preferred display area first @@ -2277,13 +2300,16 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return task; } - if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found"); + if (WM_DEBUG_TASKS.isEnabled() && mTmpFindTaskResult.mRecord == null) { + ProtoLog.d(WM_DEBUG_TASKS, "No task found"); + } return mTmpFindTaskResult.mRecord; } /** * Finish the topmost activities in all stacks that belong to the crashed app. - * @param app The app that crashed. + * + * @param app The app that crashed. * @param reason Reason to perform this action. * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished. */ @@ -2751,9 +2777,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private void destroyActivity(ActivityRecord r) { if (r.finishing || !r.isDestroyable()) return; - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState() - + " resumed=" + r.getStack().mResumedActivity + " pausing=" - + r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason); + if (DEBUG_SWITCH) { + Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState() + + " resumed=" + r.getStack().mResumedActivity + " pausing=" + + r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason); + } r.destroyImmediately(mDestroyAllActivitiesReason); } @@ -2814,7 +2842,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private static boolean matchesActivity(ActivityRecord r, int userId, boolean compareIntentFilters, Intent intent, ComponentName cls) { - if (!r.canBeTopRunning() || r.mUserId != userId) return false; + if (!r.canBeTopRunning() || r.mUserId != userId) return false; if (compareIntentFilters) { if (r.intent.filterEquals(intent)) { @@ -2849,10 +2877,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Returns the right stack to use for launching factoring in all the input parameters. * - * @param r The activity we are trying to launch. Can be null. - * @param options The activity options used to the launch. Can be null. - * @param candidateTask The possible task the activity might be launched in. Can be null. - * @param launchParams The resolved launch params to use. + * @param r The activity we are trying to launch. Can be null. + * @param options The activity options used to the launch. Can be null. + * @param candidateTask The possible task the activity might be launched in. Can be null. + * @param launchParams The resolved launch params to use. * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid} * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid} * @return The stack to use for the launch or INVALID_STACK_ID. @@ -2986,9 +3014,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Get a topmost stack on the display area, that is a valid launch stack for specified activity. * If there is no such stack, new dynamic stack can be created. + * * @param taskDisplayArea Target display area. - * @param r Activity that should be launched there. - * @param candidateTask The possible task the activity might be put in. + * @param r Activity that should be launched there. + * @param candidateTask The possible task the activity might be put in. * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null. */ @VisibleForTesting @@ -3054,10 +3083,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // TODO: Can probably be consolidated into getLaunchStack()... private boolean isValidLaunchStack(Task stack, ActivityRecord r, int windowingMode) { switch (stack.getActivityType()) { - case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome(); - case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents(); - case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant(); - case ACTIVITY_TYPE_DREAM: return r.isActivityTypeDream(); + case ACTIVITY_TYPE_HOME: + return r.isActivityTypeHome(); + case ACTIVITY_TYPE_RECENTS: + return r.isActivityTypeRecents(); + case ACTIVITY_TYPE_ASSISTANT: + return r.isActivityTypeAssistant(); + case ACTIVITY_TYPE_DREAM: + return r.isActivityTypeDream(); } if (stack.mCreatedByOrganizer) { // Don't launch directly into task created by organizer...but why can't we? @@ -3097,9 +3130,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * from the target stack. If no valid candidates will be found, it will then go through all * displays and stacks in last-focused order. * - * @param currentFocus The stack that previously had focus. + * @param currentFocus The stack that previously had focus. * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next - * candidate. + * candidate. * @return Next focusable {@link Task}, {@code null} if not found. */ Task getNextFocusableStack(@NonNull Task currentFocus, @@ -3162,6 +3195,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper = new FinishDisabledPackageActivitiesHelper(); + class FinishDisabledPackageActivitiesHelper { private String mPackageName; private Set<String> mFilterByClasses; @@ -3318,10 +3352,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } final ActivityRecord resumedActivity = stack.getResumedActivity(); if (resumedActivity == null || !resumedActivity.idle) { - if (DEBUG_STATES) { - Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack=" - + stack.getRootTaskId() + " " + resumedActivity + " not idle"); - } + ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: stack=%d %s " + + "not idle", stack.getRootTaskId(), resumedActivity); return false; } } @@ -3360,9 +3392,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final Task stack = taskDisplayArea.getStackAt(sNdx); final ActivityRecord r = stack.mPausingActivity; if (r != null && !r.isState(PAUSED, STOPPED, STOPPING, FINISHING)) { - if (DEBUG_STATES) { - Slog.d(TAG_STATES, "allPausedActivitiesComplete: r=" + r - + " state=" + r.getState()); + ProtoLog.d(WM_DEBUG_STATES, "allPausedActivitiesComplete: " + + "r=%s state=%s", r, r.getState()); + if (WM_DEBUG_STATES.isEnabled()) { pausing[0] = false; } else { return true; @@ -3441,10 +3473,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Returns a {@link Task} for the input id if available. {@code null} otherwise. - * @param id Id of the task we would like returned. + * + * @param id Id of the task we would like returned. * @param matchMode The mode to match the given task id in. - * @param aOptions The activity options to use for restoration. Can be null. - * @param onTop If the stack for the task should be the topmost on the display. + * @param aOptions The activity options to use for restoration. Can be null. + * @param onTop If the stack for the task should be the topmost on the display. */ Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode, @Nullable ActivityOptions aOptions, boolean onTop) { @@ -3499,8 +3532,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) { - if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, - "Couldn't restore task id=" + id + " found in recents"); + if (DEBUG_RECENTS) { + Slog.w(TAG_RECENTS, + "Couldn't restore task id=" + id + " found in recents"); + } return null; } if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents"); @@ -3611,14 +3646,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent> /** * Dump all connected displays' configurations. + * * @param prefix Prefix to apply to each line of the dump. */ void dumpDisplayConfigs(PrintWriter pw, String prefix) { - pw.print(prefix); pw.println("Display override configurations:"); + pw.print(prefix); + pw.println("Display override configurations:"); final int displayCount = getChildCount(); for (int i = 0; i < displayCount; i++) { final DisplayContent displayContent = getChildAt(i); - pw.print(prefix); pw.print(" "); pw.print(displayContent.mDisplayId); pw.print(": "); + pw.print(prefix); + pw.print(" "); + pw.print(displayContent.mDisplayId); + pw.print(": "); pw.println(displayContent.getRequestedOverrideConfiguration()); } } @@ -3632,7 +3672,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (printed[0]) { pw.println(); } - pw.print("Display #"); pw.print(displayContent.mDisplayId); + pw.print("Display #"); + pw.print(displayContent.mDisplayId); pw.println(" (activities from top to bottom):"); displayContent.forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 14230cd3a768..f984576e6e2e 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -80,6 +80,8 @@ import static com.android.internal.policy.DecorView.DECOR_SHADOW_UNFOCUSED_HEIGH import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN; import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; @@ -87,13 +89,9 @@ import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE; @@ -1280,7 +1278,7 @@ class Task extends WindowContainer<WindowContainer> { _intent.setSourceBounds(null); } } - if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Setting Intent of " + this + " to " + _intent); + ProtoLog.v(WM_DEBUG_TASKS, "Setting Intent of %s to %s", this, _intent); intent = _intent; realActivity = _intent != null ? _intent.getComponent() : null; origActivity = null; @@ -1291,8 +1289,7 @@ class Task extends WindowContainer<WindowContainer> { Intent targetIntent = new Intent(_intent); targetIntent.setSelector(null); targetIntent.setSourceBounds(null); - if (DEBUG_TASKS) Slog.v(TAG_TASKS, - "Setting Intent of " + this + " to target " + targetIntent); + ProtoLog.v(WM_DEBUG_TASKS, "Setting Intent of %s to target %s", this, targetIntent); intent = targetIntent; realActivity = targetComponent; origActivity = _intent.getComponent(); @@ -5317,8 +5314,8 @@ class Task extends WindowContainer<WindowContainer> { } void minimalResumeActivityLocked(ActivityRecord r) { - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)" - + " callers=" + Debug.getCallers(5)); + ProtoLog.v(WM_DEBUG_STATES, "Moving to RESUMED: %s (starting new instance) " + + "callers=%s", r, Debug.getCallers(5)); r.setState(RESUMED, "minimalResumeActivityLocked"); r.completeResumeLocked(); } @@ -5362,7 +5359,7 @@ class Task extends WindowContainer<WindowContainer> { if (mResumedActivity != null) { // Still have something resumed; can't sleep until it is paused. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity); + ProtoLog.v(WM_DEBUG_STATES, "Sleep needs to pause %s", mResumedActivity); if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, "Sleep => pause with userLeaving=false"); @@ -5371,15 +5368,15 @@ class Task extends WindowContainer<WindowContainer> { shouldSleep = false ; } else if (mPausingActivity != null) { // Still waiting for something to pause; can't sleep yet. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity); + ProtoLog.v(WM_DEBUG_STATES, "Sleep still waiting to pause %s", mPausingActivity); shouldSleep = false; } if (!shuttingDown) { if (containsActivityFromStack(mStackSupervisor.mStoppingActivities)) { // Still need to tell some activities to stop; can't sleep yet. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop " - + mStackSupervisor.mStoppingActivities.size() + " activities"); + ProtoLog.v(WM_DEBUG_STATES, "Sleep still need to stop %d activities", + mStackSupervisor.mStoppingActivities.size()); mStackSupervisor.scheduleIdle(); shouldSleep = false; @@ -5458,8 +5455,7 @@ class Task extends WindowContainer<WindowContainer> { return false; } - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev); - else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev); + ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSING: %s", prev); mPausingActivity = prev; mLastPausedActivity = prev; mLastNoHistoryActivity = prev.isNoHistory() ? prev : null; @@ -5490,13 +5486,13 @@ class Task extends WindowContainer<WindowContainer> { boolean didAutoPip = false; if (prev.attachedToProcess()) { if (shouldAutoPip) { - if (DEBUG_PAUSE) { - Slog.d(TAG_PAUSE, "Auto-PIP allowed, entering PIP mode directly: " + prev); - } + ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode " + + "directly: %s", prev); + didAutoPip = mAtmService.enterPictureInPictureMode(prev, prev.pictureInPictureArgs); mPausingActivity = null; } else { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev); + ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev); try { EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev), prev.shortComponentName, "userLeaving=" + userLeaving, reason); @@ -5536,8 +5532,8 @@ class Task extends WindowContainer<WindowContainer> { // key dispatch; the same activity will pick it up again on wakeup. if (!uiSleeping) { prev.pauseKeyDispatchingLocked(); - } else if (DEBUG_PAUSE) { - Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off"); + } else { + ProtoLog.v(WM_DEBUG_STATES, "Key dispatch not paused for screen off"); } if (pauseImmediately) { @@ -5554,7 +5550,7 @@ class Task extends WindowContainer<WindowContainer> { } else { // This activity failed to schedule the // pause, so just treat it as being paused now. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next."); + ProtoLog.v(WM_DEBUG_STATES, "Activity not running, resuming next."); if (resuming == null) { mRootWindowContainer.resumeFocusedStacksTopActivities(); } @@ -5565,22 +5561,22 @@ class Task extends WindowContainer<WindowContainer> { @VisibleForTesting void completePauseLocked(boolean resumeNext, ActivityRecord resuming) { ActivityRecord prev = mPausingActivity; - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev); + ProtoLog.v(WM_DEBUG_STATES, "Complete pause: %s", prev); if (prev != null) { prev.setWillCloseOrEnterPip(false); final boolean wasStopping = prev.isState(STOPPING); prev.setState(PAUSED, "completePausedLocked"); if (prev.finishing) { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev); + ProtoLog.v(WM_DEBUG_STATES, "Executing finish of activity: %s", prev); prev = prev.completeFinishing("completePausedLocked"); } else if (prev.hasProcess()) { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev - + " wasStopping=" + wasStopping - + " visibleRequested=" + prev.mVisibleRequested); + ProtoLog.v(WM_DEBUG_STATES, "Enqueue pending stop if needed: %s " + + "wasStopping=%b visibleRequested=%b", prev, wasStopping, + prev.mVisibleRequested); if (prev.deferRelaunchUntilPaused) { // Complete the deferred relaunch that was waiting for pause to complete. - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev); + ProtoLog.v(WM_DEBUG_STATES, "Re-launching after pause: %s", prev); prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch); } else if (wasStopping) { // We are also stopping, the stop request must have gone soon after the pause. @@ -5596,7 +5592,7 @@ class Task extends WindowContainer<WindowContainer> { "completePauseLocked"); } } else { - if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev); + ProtoLog.v(WM_DEBUG_STATES, "App died during pause, not stopping: %s", prev); prev = null; } // It is possible the activity was freezing the screen before it was paused. @@ -5892,8 +5888,8 @@ class Task extends WindowContainer<WindowContainer> { // Make sure we have executed any pending transitions, since there // should be nothing left to do at this point. executeAppTransition(options); - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeTopActivityLocked: Top activity resumed " + next); + ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Top activity " + + "resumed %s", next); return false; } @@ -5904,9 +5900,9 @@ class Task extends WindowContainer<WindowContainer> { // If we are currently pausing an activity, then don't do anything until that is done. final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete(); if (!allPausedComplete) { - if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) { - Slog.v(TAG_PAUSE, "resumeTopActivityLocked: Skip resume: some activity pausing."); - } + ProtoLog.v(WM_DEBUG_STATES, + "resumeTopActivityLocked: Skip resume: some activity pausing."); + return false; } @@ -5918,8 +5914,8 @@ class Task extends WindowContainer<WindowContainer> { // Make sure we have executed any pending transitions, since there // should be nothing left to do at this point. executeAppTransition(options); - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeTopActivityLocked: Going to sleep and all paused"); + ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Going to sleep and" + + " all paused"); return false; } @@ -5941,7 +5937,7 @@ class Task extends WindowContainer<WindowContainer> { // If we are currently pausing an activity, then don't do anything until that is done. if (!mRootWindowContainer.allPausedActivitiesComplete()) { - if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, + ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivityLocked: Skip resume: some activity pausing."); return false; @@ -5967,14 +5963,13 @@ class Task extends WindowContainer<WindowContainer> { boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next); if (mResumedActivity != null) { - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeTopActivityLocked: Pausing " + mResumedActivity); + ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Pausing %s", mResumedActivity); pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next, - "resumeTopActivityInnerLocked"); + "resumeTopActivityInnerLocked"); } if (pausing) { - if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES, - "resumeTopActivityLocked: Skip resume: need to start pausing"); + ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivityLocked: Skip resume: need to" + + " start pausing"); // At this point we want to put the upcoming activity's process // at the top of the LRU list, since we know we will be needing it // very soon and it would be a waste to let it get killed if it @@ -6003,8 +5998,8 @@ class Task extends WindowContainer<WindowContainer> { // Make sure we have executed any pending transitions, since there // should be nothing left to do at this point. executeAppTransition(options); - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next); + ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Top activity resumed " + + "(dontWaitForPause) %s", next); return true; } @@ -6014,8 +6009,8 @@ class Task extends WindowContainer<WindowContainer> { if (shouldSleepActivities() && mLastNoHistoryActivity != null && !mLastNoHistoryActivity.finishing && mLastNoHistoryActivity != next) { - if (DEBUG_STATES) Slog.d(TAG_STATES, - "no-history finish of " + mLastNoHistoryActivity + " on new resume"); + ProtoLog.d(WM_DEBUG_STATES, "no-history finish of %s on new resume", + mLastNoHistoryActivity); mLastNoHistoryActivity.finishIfPossible("resume-no-history", false /* oomAdj */); mLastNoHistoryActivity = null; } @@ -6134,8 +6129,7 @@ class Task extends WindowContainer<WindowContainer> { mAtmService.updateCpuStats(); - if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next - + " (in existing)"); + ProtoLog.v(WM_DEBUG_STATES, "Moving to RESUMED: %s (in existing)", next); next.setState(RESUMED, "resumeTopActivityInnerLocked"); @@ -6165,9 +6159,8 @@ class Task extends WindowContainer<WindowContainer> { // is still at the top and schedule another run if something // weird happened. ActivityRecord nextNext = topRunningActivity(); - if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES, - "Activity config changed during resume: " + next - + ", new next: " + nextNext); + ProtoLog.i(WM_DEBUG_STATES, "Activity config changed during resume: " + + "%s, new next: %s", next, nextNext); if (nextNext != next) { // Do over! mStackSupervisor.scheduleResumeTopActivities(); @@ -6214,12 +6207,11 @@ class Task extends WindowContainer<WindowContainer> { dc.isNextTransitionForward())); mAtmService.getLifecycleManager().scheduleTransaction(transaction); - if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " - + next); + ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Resumed %s", next); } catch (Exception e) { // Whoops, need to restart this activity! - if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to " - + lastState + ": " + next); + ProtoLog.v(WM_DEBUG_STATES, "Resume failed; resetting state to %s: " + + "%s", lastState, next); next.setState(lastState, "resumeTopActivityInnerLocked"); // lastResumedActivity being non-null implies there is a lastStack present. @@ -6261,7 +6253,7 @@ class Task extends WindowContainer<WindowContainer> { } if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next); } - if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next); + ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Restarting %s", next); mStackSupervisor.startSpecificActivity(next, true, true); } @@ -6293,8 +6285,8 @@ class Task extends WindowContainer<WindowContainer> { // If the current stack is a home stack, or if focus didn't switch to a different stack - // just start up the Launcher... ActivityOptions.abort(options); - if (DEBUG_STATES) Slog.d(TAG_STATES, - "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home"); + ProtoLog.d(WM_DEBUG_STATES, "resumeNextFocusableActivityWhenStackIsEmpty: %s, " + + "go home", reason); return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea()); } @@ -7022,8 +7014,8 @@ class Task extends WindowContainer<WindowContainer> { boolean handleAppDied(WindowProcessController app) { boolean isPausingDied = false; if (mPausingActivity != null && mPausingActivity.app == app) { - if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE, - "App died while pausing: " + mPausingActivity); + ProtoLog.v(WM_DEBUG_STATES, "App died while pausing: %s", + mPausingActivity); mPausingActivity = null; isPausingDied = true; } diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 2c8770f110fa..ce99102fddb3 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -33,12 +33,10 @@ 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.server.wm.ActivityStackSupervisor.TAG_TASKS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerService.TAG_STACK; import static com.android.server.wm.DisplayContent.alwaysCreateStack; -import static com.android.server.wm.RootWindowContainer.TAG_STATES; import static com.android.server.wm.Task.ActivityState.RESUMED; import static com.android.server.wm.Task.STACK_VISIBILITY_VISIBLE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK; @@ -212,11 +210,13 @@ final class TaskDisplayArea extends DisplayArea<Task> { return mChildren.indexOf(task); } - @Nullable Task getRootHomeTask() { + @Nullable + Task getRootHomeTask() { return mRootHomeTask; } - @Nullable Task getRootRecentsTask() { + @Nullable + Task getRootRecentsTask() { return mRootRecentsTask; } @@ -526,19 +526,20 @@ final class TaskDisplayArea extends DisplayArea<Task> { * When stack is added or repositioned, find a proper position for it. * * The order is defined as: - * - Dream is on top of everything - * - PiP is directly below the Dream - * - always-on-top stacks are directly below PiP; new always-on-top stacks are added above - * existing ones - * - other non-always-on-top stacks come directly below always-on-top stacks; new - * non-always-on-top stacks are added directly below always-on-top stacks and above existing - * non-always-on-top stacks - * - if {@link #mAssistantOnTopOfDream} is enabled, then Assistant is on top of everything - * (including the Dream); otherwise, it is a normal non-always-on-top stack + * - Dream is on top of everything + * - PiP is directly below the Dream + * - always-on-top stacks are directly below PiP; new always-on-top stacks are added above + * existing ones + * - other non-always-on-top stacks come directly below always-on-top stacks; new + * non-always-on-top stacks are added directly below always-on-top stacks and above existing + * non-always-on-top stacks + * - if {@link #mAssistantOnTopOfDream} is enabled, then Assistant is on top of everything + * (including the Dream); otherwise, it is a normal non-always-on-top stack * * @param requestedPosition Position requested by caller. - * @param stack Stack to be added or positioned. - * @param adding Flag indicates whether we're adding a new stack or positioning an existing. + * @param stack Stack to be added or positioned. + * @param adding Flag indicates whether we're adding a new stack or positioning an + * existing. * @return The proper position for the stack. */ private int findPositionForStack(int requestedPosition, Task stack, boolean adding) { @@ -655,6 +656,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { /** * Sets whether the task display area should ignore fixed-orientation request from apps. + * * @return Whether the display orientation changed */ boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) { @@ -774,7 +776,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { * Adjusts the layer of the stack which belongs to the same group. * Note that there are three stack groups: home stacks, always on top stacks, and normal stacks. * - * @param startLayer The beginning layer of this group of stacks. + * @param startLayer The beginning layer of this group of stacks. * @param normalStacks Set {@code true} if this group is neither home nor always on top. * @return The adjusted layer value. */ @@ -921,6 +923,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { /** * Returns an existing stack compatible with the windowing mode and activity type or creates one * if a compatible stack doesn't exist. + * * @see #getOrCreateStack(int, int, boolean, Intent, Task) */ Task getOrCreateStack(int windowingMode, int activityType, boolean onTop) { @@ -933,6 +936,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { * existing compatible root task or creates a new one. * For one level task, the candidate task would be reused to also be the root task or create * a new root task if no candidate task. + * * @see #getStack(int, int) * @see #createStack(int, int, boolean) */ @@ -978,6 +982,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { /** * Returns an existing stack compatible with the input params or creates one * if a compatible stack doesn't exist. + * * @see #getOrCreateStack(int, int, boolean) */ Task getOrCreateStack(@Nullable ActivityRecord r, @@ -1006,17 +1011,21 @@ final class TaskDisplayArea extends DisplayArea<Task> { /** * Creates a stack matching the input windowing mode and activity type on this display. - * @param windowingMode The windowing mode the stack should be created in. If - * {@link WindowConfiguration#WINDOWING_MODE_UNDEFINED} then the stack will - * inherit its parent's windowing mode. - * @param activityType The activityType the stack should be created in. If - * {@link WindowConfiguration#ACTIVITY_TYPE_UNDEFINED} then the stack will - * be created in {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}. - * @param onTop If true the stack will be created at the top of the display, else at the bottom. - * @param info The started activity info. - * @param intent The intent that started this task. + * + * @param windowingMode The windowing mode the stack should be created in. If + * {@link WindowConfiguration#WINDOWING_MODE_UNDEFINED} then the stack + * will + * inherit its parent's windowing mode. + * @param activityType The activityType the stack should be created in. If + * {@link WindowConfiguration#ACTIVITY_TYPE_UNDEFINED} then the stack + * will + * be created in {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}. + * @param onTop If true the stack will be created at the top of the display, else + * at the bottom. + * @param info The started activity info. + * @param intent The intent that started this task. * @param createdByOrganizer @{code true} if this is created by task organizer, @{code false} - * otherwise. + * otherwise. * @return The newly created stack. */ Task createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info, @@ -1223,8 +1232,9 @@ final class TaskDisplayArea extends DisplayArea<Task> { * paused in stacks that are no longer visible or in pinned windowing mode. This does not * pause activities in visible stacks, so if an activity is launched within the same stack/task, * then we should explicitly pause that stack's top activity. + * * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). - * @param resuming The resuming activity. + * @param resuming The resuming activity. * @return {@code true} if any activity was paused as a result of this call. */ boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming) { @@ -1235,10 +1245,8 @@ final class TaskDisplayArea extends DisplayArea<Task> { if (resumedActivity != null && (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE || !stack.isTopActivityFocusable())) { - if (DEBUG_STATES) { - Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack - + " mResumedActivity=" + resumedActivity); - } + ProtoLog.d(WM_DEBUG_STATES, "pauseBackStacks: stack=%s " + + "mResumedActivity=%s", stack, resumedActivity); someActivityPaused |= stack.startPausingLocked(userLeaving, false /* uiSleeping*/, resuming, "pauseBackStacks"); } @@ -1255,9 +1263,8 @@ final class TaskDisplayArea extends DisplayArea<Task> { for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) { final Task stack = getStackAt(stackNdx); if (!r.hasCompatibleActivityType(stack) && stack.isLeafTask()) { - if (DEBUG_TASKS) { - Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " + stack); - } + ProtoLog.d(WM_DEBUG_TASKS, "Skipping stack: (mismatch activity/stack) " + + "%s", stack); continue; } @@ -1298,10 +1305,9 @@ final class TaskDisplayArea extends DisplayArea<Task> { final int windowingMode = windowingModes[j]; for (int i = getStackCount() - 1; i >= 0; --i) { final Task stack = getStackAt(i); - if (!stack.isActivityTypeStandardOrUndefined()) { - continue; - } - if (stack.getWindowingMode() != windowingMode) { + if (stack.mCreatedByOrganizer + || !stack.isActivityTypeStandardOrUndefined() + || stack.getWindowingMode() != windowingMode) { continue; } stacks.add(stack); @@ -1400,12 +1406,13 @@ final class TaskDisplayArea extends DisplayArea<Task> { /** * Returns true if the {@param windowingMode} is supported based on other parameters passed in. - * @param windowingMode The windowing mode we are checking support for. + * + * @param windowingMode The windowing mode we are checking support for. * @param supportsMultiWindow If we should consider support for multi-window mode in general. * @param supportsSplitScreen If we should consider support for split-screen multi-window. - * @param supportsFreeform If we should consider support for freeform multi-window. - * @param supportsPip If we should consider support for picture-in-picture mutli-window. - * @param activityType The activity type under consideration. + * @param supportsFreeform If we should consider support for freeform multi-window. + * @param supportsPip If we should consider support for picture-in-picture mutli-window. + * @param activityType The activity type under consideration. * @return true if the windowing mode is supported. */ private boolean isWindowingModeSupported(int windowingMode, boolean supportsMultiWindow, @@ -1444,9 +1451,9 @@ final class TaskDisplayArea extends DisplayArea<Task> { * Resolves the windowing mode that an {@link ActivityRecord} would be in if started on this * display with the provided parameters. * - * @param r The ActivityRecord in question. - * @param options Options to start with. - * @param task The task within-which the activity would start. + * @param r The ActivityRecord in question. + * @param options Options to start with. + * @param task The task within-which the activity would start. * @param activityType The type of activity to start. * @return The resolved (not UNDEFINED) windowing-mode that the activity would be in. */ @@ -1481,9 +1488,9 @@ final class TaskDisplayArea extends DisplayArea<Task> { * on this display. * * @param windowingMode The windowing-mode to validate. - * @param r The {@link ActivityRecord} to check against. - * @param task The {@link Task} to check against. - * @param activityType An activity type. + * @param r The {@link ActivityRecord} to check against. + * @param task The {@link Task} to check against. + * @param activityType An activity type. * @return {@code true} if windowingMode is valid, {@code false} otherwise. */ boolean isValidWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task, @@ -1508,7 +1515,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { return windowingMode != WINDOWING_MODE_UNDEFINED && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen, - supportsFreeform, supportsPip, activityType); + supportsFreeform, supportsPip, activityType); } /** @@ -1516,9 +1523,9 @@ final class TaskDisplayArea extends DisplayArea<Task> { * on this display. * * @param windowingMode The windowing-mode to validate. - * @param r The {@link ActivityRecord} to check against. - * @param task The {@link Task} to check against. - * @param activityType An activity type. + * @param r The {@link ActivityRecord} to check against. + * @param task The {@link Task} to check against. + * @param activityType An activity type. * @return The provided windowingMode or the closest valid mode which is appropriate. */ int validateWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task, @@ -1606,6 +1613,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { /** * Returns the existing home stack or creates and returns a new one if it should exist for the * display. + * * @param onTop Only be used when there is no existing home stack. If true the home stack will * be created at the top of the display, else at the bottom. */ @@ -1743,7 +1751,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { /** * @return the stack currently above the {@param stack}. Can be null if the {@param stack} is - * already top-most. + * already top-most. */ static Task getStackAbove(Task stack) { final WindowContainer wc = stack.getParent(); @@ -1789,6 +1797,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { /** * Notifies of a stack order change + * * @param stack The stack which triggered the order change */ void onStackOrderChanged(Task stack) { @@ -1832,6 +1841,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { /** * Removes the stacks in the node applying the content removal node from the display. + * * @return last reparented stack, or {@code null} if the stacks had to be destroyed. */ Task remove() { diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 2ece30d24b3a..38ec924ec670 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -22,6 +22,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.isFixedOrientationLandscape; import static android.content.pm.ActivityInfo.isFixedOrientationPortrait; +import static android.content.pm.ActivityInfo.reverseOrientation; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; @@ -809,6 +810,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return parent != null ? parent.getDisplayArea() : null; } + /** Get the first node of type {@link RootDisplayArea} above or at this node. */ + @Nullable + RootDisplayArea getRootDisplayArea() { + WindowContainer parent = getParent(); + return parent != null ? parent.getRootDisplayArea() : null; + } + boolean isAttached() { return getDisplayArea() != null; } @@ -1154,17 +1162,30 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * {@link Configuration#ORIENTATION_UNDEFINED}). */ int getRequestedConfigurationOrientation() { - if (mOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { + int requestedOrientation = mOrientation; + final RootDisplayArea root = getRootDisplayArea(); + if (root != null && root.isOrientationDifferentFromDisplay()) { + // Reverse the requested orientation if the orientation of its root is different from + // the display, so that when the display rotates to the reversed orientation, the + // requested app will be in the requested orientation. + // For example, if the display is 1200x900 (landscape), and the DAG is 600x900 + // (portrait). + // When an app below the DAG is requesting landscape, it should actually request the + // display to be portrait, so that the DAG and the app will be in landscape. + requestedOrientation = reverseOrientation(mOrientation); + } + + if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { // NOSENSOR means the display's "natural" orientation, so return that. if (mDisplayContent != null) { return mDisplayContent.getNaturalOrientation(); } - } else if (mOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) { + } else if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) { // LOCKED means the activity's orientation remains unchanged, so return existing value. return getConfiguration().orientation; - } else if (isFixedOrientationLandscape(mOrientation)) { + } else if (isFixedOrientationLandscape(requestedOrientation)) { return ORIENTATION_LANDSCAPE; - } else if (isFixedOrientationPortrait(mOrientation)) { + } else if (isFixedOrientationPortrait(requestedOrientation)) { return ORIENTATION_PORTRAIT; } return ORIENTATION_UNDEFINED; diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 9f653d6124b9..13d8dc4c6be1 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -23,12 +23,10 @@ import static android.graphics.Matrix.MSKEW_Y; import static android.graphics.Matrix.MTRANS_X; import static android.graphics.Matrix.MTRANS_Y; import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; -import static android.view.WindowManager.LayoutParams.FLAG_SCALED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; -import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.TRANSIT_NONE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_DRAW; @@ -46,19 +44,16 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER; import static com.android.server.wm.WindowManagerService.logWithStack; import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE; -import static com.android.server.wm.WindowStateAnimatorProto.LAST_CLIP_RECT; import static com.android.server.wm.WindowStateAnimatorProto.SURFACE; import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT; import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE; -import android.app.WindowConfiguration; import android.content.Context; import android.graphics.Matrix; import android.graphics.PixelFormat; @@ -365,7 +360,7 @@ class WindowStateAnimator { if (mSurfaceController != null && mPendingDestroySurface != null) { mPostDrawTransaction.reparentChildren( mSurfaceController.getClientViewRootSurface(), - mPendingDestroySurface.mSurfaceControl).apply(); + mPendingDestroySurface.getClientViewRootSurface()).apply(); } destroySurfaceLocked(); mSurfaceDestroyDeferred = true; @@ -399,7 +394,7 @@ class WindowStateAnimator { && (mWin.mActivityRecord == null || !mWin.mActivityRecord.isRelaunching())) { mPostDrawTransaction.reparentChildren( mPendingDestroySurface.getClientViewRootSurface(), - mSurfaceController.mSurfaceControl).apply(); + mSurfaceController.getClientViewRootSurface()).apply(); } destroyDeferredSurfaceLocked(); @@ -993,7 +988,7 @@ class WindowStateAnimator { if (!mPendingDestroySurface.mChildrenDetached) { mPostDrawTransaction.reparentChildren( mPendingDestroySurface.getClientViewRootSurface(), - mSurfaceController.mSurfaceControl); + mSurfaceController.getClientViewRootSurface()); } } diff --git a/services/core/xsd/vts/Android.mk b/services/core/xsd/vts/Android.mk deleted file mode 100644 index 6dc2c437a2f9..000000000000 --- a/services/core/xsd/vts/Android.mk +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := VtsValidateDefaultPermissions -include test/vts/tools/build/Android.host_config.mk diff --git a/services/core/xsd/vts/AndroidTest.xml b/services/core/xsd/vts/AndroidTest.xml deleted file mode 100644 index 4f3b2ef1ace1..000000000000 --- a/services/core/xsd/vts/AndroidTest.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Config for VTS VtsValidateDefaultPermissions."> - <option name="config-descriptor:metadata" key="plan" value="vts-treble" /> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher"> - <option name="abort-on-push-failure" value="false"/> - <option name="push-group" value="HostDrivenTest.push"/> - <option name="push" value="DATA/etc/default-permissions.xsd->/data/local/tmp/default-permissions.xsd"/> - </target_preparer> - <test class="com.android.tradefed.testtype.VtsMultiDeviceTest"> - <option name="test-module-name" value="VtsValidateDefaultPermissions"/> - <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_defaultPermissions_validate_test/vts_defaultPermissions_validate_test" /> - <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_defaultPermissions_validate_test/vts_defaultPermissions_validate_test" /> - <option name="binary-test-type" value="gtest"/> - <option name="test-timeout" value="30s"/> - </test> -</configuration> diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index f348664213cd..282cee0ea253 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -2129,7 +2129,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle, boolean parent) { ensureLocked(); if (parent) { - enforceManagedProfile(userHandle, "call APIs on the parent profile"); + Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format( + "You can not call APIs on the parent profile outside a managed profile, " + + "userId = %d", userHandle)); } ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); if (admin != null && parent) { @@ -2280,8 +2282,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy, boolean parent) - throws SecurityException { + ActiveAdmin getActiveAdminForCallerLocked(@Nullable ComponentName who, int reqPolicy, + boolean parent) throws SecurityException { return getActiveAdminOrCheckPermissionForCallerLocked( who, reqPolicy, parent, /* permission= */ null); } @@ -2295,14 +2297,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { */ @Nullable ActiveAdmin getActiveAdminOrCheckPermissionForCallerLocked( - ComponentName who, + @Nullable ComponentName who, int reqPolicy, boolean parent, @Nullable String permission) throws SecurityException { ensureLocked(); if (parent) { - enforceManagedProfile(mInjector.userHandleGetCallingUserId(), - "call APIs on the parent profile"); + Preconditions.checkCallingUser(isManagedProfile(getCallerIdentity().getUserId())); } ActiveAdmin admin = getActiveAdminOrCheckPermissionForCallerLocked( who, reqPolicy, permission); @@ -2894,7 +2895,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); synchronized (getLockObject()) { final DevicePolicyData policy = getUserData(userHandle.getIdentifier()); @@ -4090,10 +4091,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return true; } - final int userId = mInjector.userHandleGetCallingUserId(); - enforceProfileOrDeviceOwner(admin); - enforceManagedProfile(userId, "query unified challenge status"); - return !isSeparateProfileChallengeEnabled(userId); + Objects.requireNonNull(admin, "ComponentName is null"); + + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + Preconditions.checkCallingUser(isManagedProfile(caller.getUserId())); + + return !isSeparateProfileChallengeEnabled(caller.getUserId()); } @Override @@ -4105,7 +4109,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); - enforceManagedProfile(userHandle, "call APIs refering to the parent profile"); + Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format( + "can not call APIs refering to the parent profile outside a managed profile, " + + "userId = %d", userHandle)); synchronized (getLockObject()) { final int targetUser = getProfileParentId(userHandle); @@ -4127,7 +4133,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); - enforceNotManagedProfile(userHandle, "check password sufficiency"); + Preconditions.checkCallAuthorization(!isManagedProfile(userHandle), String.format( + "You can not check password sufficiency for a managed profile, userId = %d", + userHandle)); enforceUserUnlocked(userHandle); synchronized (getLockObject()) { @@ -4683,8 +4691,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature && !hasCallingPermission(permission.LOCK_DEVICE)) { return; } + final CallerIdentity caller = getCallerIdentity(); - final int callingUserId = mInjector.userHandleGetCallingUserId(); + final int callingUserId = caller.getUserId(); ComponentName adminComponent = null; synchronized (getLockObject()) { // Make sure the caller has any active admin with the right policy or @@ -4701,16 +4710,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // For Profile Owners only, callers with only permission not allowed. if ((flags & DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY) != 0) { // Evict key - enforceManagedProfile( - callingUserId, "set FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY"); + Preconditions.checkCallingUser(isManagedProfile(callingUserId)); + Preconditions.checkArgument(!parent, + "Cannot set FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY for the parent"); if (!isProfileOwner(adminComponent, callingUserId)) { throw new SecurityException("Only profile owner admins can set " + "FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY"); } - if (parent) { - throw new IllegalArgumentException( - "Cannot set FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY for the parent"); - } if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()) { throw new UnsupportedOperationException( "FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY only applies to FBE devices"); @@ -4755,32 +4761,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void enforceCanManageCaCerts(ComponentName who, String callerPackage) { - if (who == null) { - if (!isCallerDelegate(callerPackage, mInjector.binderGetCallingUid(), - DELEGATION_CERT_INSTALL)) { - mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null); - } - } else { - enforceProfileOrDeviceOwner(who); - } - } - - private void enforceProfileOrDeviceOwner(ComponentName who) { - synchronized (getLockObject()) { - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); - } + final CallerIdentity caller = getCallerIdentity(who, callerPackage); + Preconditions.checkCallAuthorization(canManageCaCerts(caller)); } - private void enforceNetworkStackOrProfileOrDeviceOwner(ComponentName who) { - if (hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)) { - return; - } - enforceProfileOrDeviceOwner(who); + private boolean canManageCaCerts(CallerIdentity caller) { + return (caller.hasAdminComponent() && (isDeviceOwner(caller) || isProfileOwner(caller))) + || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_CERT_INSTALL)) + || hasCallingOrSelfPermission(MANAGE_CA_CERTIFICATES); } @Override public boolean approveCaCert(String alias, int userId, boolean approval) { - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + synchronized (getLockObject()) { Set<String> certs = getUserData(userId).mAcceptedCaCertificates; boolean changed = (approval ? certs.add(alias) : certs.remove(alias)); @@ -4795,7 +4789,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isCaCertApproved(String alias, int userId) { - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + synchronized (getLockObject()) { return getUserData(userId).mAcceptedCaCertificates.contains(alias); } @@ -4820,21 +4815,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override - public boolean installCaCert(ComponentName admin, String callerPackage, byte[] certBuffer) - throws RemoteException { + public boolean installCaCert(ComponentName admin, String callerPackage, byte[] certBuffer) { if (!mHasFeature) { return false; } - enforceCanManageCaCerts(admin, callerPackage); + final CallerIdentity caller = getCallerIdentity(admin, callerPackage); + Preconditions.checkCallAuthorization(canManageCaCerts(caller)); - final UserHandle userHandle = mInjector.binderGetCallingUserHandle(); final String alias = mInjector.binderWithCleanCallingIdentity(() -> { - String installedAlias = mCertificateMonitor.installCaCert(userHandle, certBuffer); - final boolean isDelegate = (admin == null); + String installedAlias = mCertificateMonitor.installCaCert( + caller.getUserHandle(), certBuffer); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.INSTALL_CA_CERT) - .setAdmin(callerPackage) - .setBoolean(isDelegate) + .setAdmin(caller.getPackageName()) + .setBoolean(/* isDelegate */ admin == null) .write(); return installedAlias; }); @@ -4845,8 +4839,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } synchronized (getLockObject()) { - getUserData(userHandle.getIdentifier()).mOwnerInstalledCaCerts.add(alias); - saveSettingsLocked(userHandle.getIdentifier()); + getUserData(caller.getUserId()).mOwnerInstalledCaCerts.add(alias); + saveSettingsLocked(caller.getUserId()); } return true; } @@ -4856,22 +4850,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - enforceCanManageCaCerts(admin, callerPackage); + final CallerIdentity caller = getCallerIdentity(admin, callerPackage); + Preconditions.checkCallAuthorization(canManageCaCerts(caller)); - final int userId = mInjector.userHandleGetCallingUserId(); mInjector.binderWithCleanCallingIdentity(() -> { - mCertificateMonitor.uninstallCaCerts(UserHandle.of(userId), aliases); - final boolean isDelegate = (admin == null); + mCertificateMonitor.uninstallCaCerts(caller.getUserHandle(), aliases); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.UNINSTALL_CA_CERTS) - .setAdmin(callerPackage) - .setBoolean(isDelegate) + .setAdmin(caller.getPackageName()) + .setBoolean(/* isDelegate */ admin == null) .write(); }); synchronized (getLockObject()) { - if (getUserData(userId).mOwnerInstalledCaCerts.removeAll(Arrays.asList(aliases))) { - saveSettingsLocked(userId); + if (getUserData(caller.getUserId()).mOwnerInstalledCaCerts.removeAll( + Arrays.asList(aliases))) { + saveSettingsLocked(caller.getUserId()); } } } @@ -5668,8 +5662,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { throws SecurityException { Objects.requireNonNull(who, "ComponentName is null"); - enforceProfileOrDeviceOwner(who); final CallerIdentity caller = getCallerIdentity(who); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); final int userId = caller.getUserId(); mInjector.binderWithCleanCallingIdentity(() -> { @@ -5695,7 +5689,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_ALWAYS_ON_VPN_PACKAGE) - .setAdmin(who) + .setAdmin(caller.getComponentName()) .setStrings(vpnPackage) .setBoolean(lockdown) .setInt(lockdownWhitelist != null ? lockdownWhitelist.size() : 0) @@ -5715,11 +5709,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public String getAlwaysOnVpnPackage(ComponentName admin) throws SecurityException { - enforceProfileOrDeviceOwner(admin); + Objects.requireNonNull(admin, "ComponentName is null"); + + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - final int userId = mInjector.userHandleGetCallingUserId(); return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getConnectivityManager().getAlwaysOnVpnPackageForUser(userId)); + () -> mInjector.getConnectivityManager().getAlwaysOnVpnPackageForUser( + caller.getUserId())); } @Override @@ -5733,11 +5730,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isAlwaysOnVpnLockdownEnabled(ComponentName admin) throws SecurityException { - enforceNetworkStackOrProfileOrDeviceOwner(admin); + Objects.requireNonNull(admin, "ComponentName is null"); + + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller) + || hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)); - final int userId = mInjector.userHandleGetCallingUserId(); return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getConnectivityManager().isVpnLockdownEnabled(userId)); + () -> mInjector.getConnectivityManager().isVpnLockdownEnabled(caller.getUserId())); } @Override @@ -5752,11 +5752,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public List<String> getAlwaysOnVpnLockdownWhitelist(ComponentName admin) throws SecurityException { - enforceProfileOrDeviceOwner(admin); + Objects.requireNonNull(admin, "ComponentName is null"); + + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - final int userId = mInjector.userHandleGetCallingUserId(); return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getConnectivityManager().getVpnLockdownWhitelist(userId)); + () -> mInjector.getConnectivityManager().getVpnLockdownWhitelist( + caller.getUserId())); } private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc) { @@ -6046,11 +6049,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) { return; } - enforceSystemCaller("report password change"); + final CallerIdentity caller = getCallerIdentity(); + Preconditions.checkCallAuthorization(isSystemUid(caller)); // Managed Profile password can only be changed when it has a separate challenge. if (!isSeparateProfileChallengeEnabled(userId)) { - enforceNotManagedProfile(userId, "set the active password"); + Preconditions.checkCallAuthorization(!isManagedProfile(userId), String.format("You can " + + "not set the active password for a managed profile, userId = %d", userId)); } DevicePolicyData policy = getUserData(userId); @@ -6103,8 +6108,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN)); if (!isSeparateProfileChallengeEnabled(userHandle)) { - enforceNotManagedProfile(userHandle, - "report failed password attempt if separate profile challenge is not in place"); + Preconditions.checkCallAuthorization(!isManagedProfile(userHandle), String.format( + "You can not report failed password attempt if separate profile challenge is " + + "not in place for a managed profile, userId = %d", userHandle)); } boolean wipeData = false; @@ -7329,7 +7335,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; } if (!callingUserOnly) { - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); } synchronized (getLockObject()) { if (!mOwners.hasDeviceOwner()) { @@ -7348,7 +7354,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return UserHandle.USER_NULL; } - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + synchronized (getLockObject()) { return mOwners.hasDeviceOwner() ? mOwners.getDeviceOwnerUserId() : UserHandle.USER_NULL; } @@ -7363,7 +7370,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return null; } - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + synchronized (getLockObject()) { if (!mOwners.hasDeviceOwner()) { return null; @@ -7588,8 +7596,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } Objects.requireNonNull(who, "ComponentName is null"); - final int userId = mInjector.userHandleGetCallingUserId(); - enforceNotManagedProfile(userId, "clear profile owner"); + final CallerIdentity caller = getCallerIdentity(who); + final int userId = caller.getUserId(); + Preconditions.checkCallingUser(!isManagedProfile(userId)); + enforceUserUnlocked(userId); synchronized (getLockObject()) { // Check if this is the profile owner who is calling @@ -7706,9 +7716,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return DevicePolicyManager.STATE_USER_UNMANAGED; } - enforceManageUsers(); - int userHandle = mInjector.userHandleGetCallingUserId(); - return getUserProvisioningState(userHandle); + final CallerIdentity caller = getCallerIdentity(); + Preconditions.checkCallAuthorization(canManageUsers(caller)); + + return getUserProvisioningState(caller.getUserId()); } private int getUserProvisioningState(int userHandle) { @@ -7746,8 +7757,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } transitionCheckNeeded = false; } else { - // For all other cases, caller must have MANAGE_PROFILE_AND_DEVICE_OWNERS. - enforceCanManageProfileAndDeviceOwners(); + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); } final DevicePolicyData policyData = getUserData(userHandle); @@ -7802,11 +7813,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } Objects.requireNonNull(who, "ComponentName is null"); + + final CallerIdentity caller = getCallerIdentity(who); + final int userId = caller.getUserId(); + Preconditions.checkCallAuthorization(isProfileOwner(caller) || isDeviceOwner(caller)); + Preconditions.checkCallingUser(isManagedProfile(userId)); + synchronized (getLockObject()) { - // Check if this is the profile owner who is calling - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); - final int userId = UserHandle.getCallingUserId(); - enforceManagedProfile(userId, "enable the profile"); // Check if the profile is already enabled. UserInfo managedProfile = getUserInfo(userId); if (managedProfile.isEnabled()) { @@ -7832,14 +7845,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setProfileName(ComponentName who, String profileName) { Objects.requireNonNull(who, "ComponentName is null"); - enforceProfileOrDeviceOwner(who); - final int userId = UserHandle.getCallingUserId(); + final CallerIdentity caller = getCallerIdentity(who); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + mInjector.binderWithCleanCallingIdentity(() -> { - mUserManager.setUserName(userId, profileName); + mUserManager.setUserName(caller.getUserId(), profileName); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_PROFILE_NAME) - .setAdmin(who) + .setAdmin(caller.getComponentName()) .write(); }); } @@ -7948,7 +7962,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return null; } - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + ComponentName profileOwner = getProfileOwner(userHandle); if (profileOwner == null) { return null; @@ -8120,7 +8135,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } return; } - enforceCanManageProfileAndDeviceOwners(); + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); if ((mIsWatch || hasUserSetupCompleted(userHandle))) { if (!isCallerWithSystemUid()) { @@ -8156,7 +8172,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @UserIdInt int userId, boolean hasIncompatibleAccountsOrNonAdb) { if (!isAdb()) { - enforceCanManageProfileAndDeviceOwners(); + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); } final int code = checkDeviceOwnerProvisioningPreConditionLocked( @@ -8210,11 +8227,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void enforceManageUsers() { - final int callingUid = mInjector.binderGetCallingUid(); - if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); - } + private boolean canManageUsers(CallerIdentity caller) { + return isSystemUid(caller) || isRootUid(caller) + || hasCallingOrSelfPermission(permission.MANAGE_USERS); } private boolean hasCallingPermission(String permission) { @@ -8244,20 +8259,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS); } - private void enforceManagedProfile(int userId, String message) { - if (!isManagedProfile(userId)) { - throw new SecurityException(String.format( - "You can not %s outside a managed profile, userId = %d", message, userId)); - } - } - - private void enforceNotManagedProfile(int userId, String message) { - if (isManagedProfile(userId)) { - throw new SecurityException(String.format( - "You can not %s for a managed profile, userId = %d", message, userId)); - } - } - private void enforceDeviceOwnerOrManageUsers() { synchronized (getLockObject()) { if (getActiveAdminWithPolicyForUidLocked(null, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, @@ -8265,7 +8266,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } } - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); } private void enforceProfileOwnerOrSystemUser() { @@ -8879,7 +8880,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return null; } - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + synchronized (getLockObject()) { List<String> result = null; // If we have multiple profiles we return the intersection of the @@ -8964,6 +8966,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } Objects.requireNonNull(who, "ComponentName is null"); + final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); @@ -9005,6 +9008,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; } Objects.requireNonNull(who, "ComponentName is null"); + final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); @@ -9016,13 +9020,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public List getPermittedInputMethodsForCurrentUser() { - enforceManageUsers(); + final CallerIdentity caller = getCallerIdentity(); + Preconditions.checkCallAuthorization(canManageUsers(caller)); - final int callingUserId = mInjector.userHandleGetCallingUserId(); synchronized (getLockObject()) { List<String> result = null; // Only device or profile owners can have permitted lists set. - DevicePolicyData policy = getUserDataUnchecked(callingUserId); + DevicePolicyData policy = getUserDataUnchecked(caller.getUserId()); for (int i = 0; i < policy.mAdminList.size(); i++) { ActiveAdmin admin = policy.mAdminList.get(i); List<String> fromAdmin = admin.permittedInputMethods; @@ -9037,8 +9041,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // If we have a permitted list add all system input methods. if (result != null) { - List<InputMethodInfo> imes = - InputMethodManagerInternal.get().getInputMethodListAsUser(callingUserId); + List<InputMethodInfo> imes = InputMethodManagerInternal + .get().getInputMethodListAsUser(caller.getUserId()); if (imes != null) { for (InputMethodInfo ime : imes) { ServiceInfo serviceInfo = ime.getServiceInfo(); @@ -9482,11 +9486,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isEphemeralUser(ComponentName who) { Objects.requireNonNull(who, "ComponentName is null"); - enforceProfileOrDeviceOwner(who); - final int callingUserId = mInjector.userHandleGetCallingUserId(); + final CallerIdentity caller = getCallerIdentity(who); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + return mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getUserManager().isUserEphemeral(callingUserId)); + () -> mInjector.getUserManager().isUserEphemeral(caller.getUserId())); } @Override @@ -10225,6 +10230,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } Objects.requireNonNull(who, "ComponentName is null"); + final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); @@ -10248,6 +10254,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } Objects.requireNonNull(who, "ComponentName is null"); + final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); @@ -10270,12 +10277,23 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setSecondaryLockscreenEnabled(ComponentName who, boolean enabled) { - enforceCanSetSecondaryLockscreenEnabled(who); + Objects.requireNonNull(who, "ComponentName is null"); + + // Check can set secondary lockscreen enabled + final CallerIdentity caller = getCallerIdentity(who); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + Preconditions.checkCallAuthorization(!isManagedProfile(caller.getUserId()), + String.format("User %d is not allowed to call setSecondaryLockscreenEnabled", + caller.getUserId())); + // Allow testOnly admins to bypass supervision config requirement. + Preconditions.checkCallAuthorization(isAdminTestOnlyLocked(who, caller.getUserId()) + || isDefaultSupervisor(caller), String.format("Admin %s is not the " + + "default supervision component", caller.getComponentName())); + synchronized (getLockObject()) { - final int userId = mInjector.userHandleGetCallingUserId(); - DevicePolicyData policy = getUserData(userId); + DevicePolicyData policy = getUserData(caller.getUserId()); policy.mSecondaryLockscreenEnabled = enabled; - saveSettingsLocked(userId); + saveSettingsLocked(caller.getUserId()); } } @@ -10286,31 +10304,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void enforceCanSetSecondaryLockscreenEnabled(ComponentName who) { - enforceProfileOrDeviceOwner(who); - final int userId = mInjector.userHandleGetCallingUserId(); - if (isManagedProfile(userId)) { - throw new SecurityException( - "User " + userId + " is not allowed to call setSecondaryLockscreenEnabled"); - } - synchronized (getLockObject()) { - if (isAdminTestOnlyLocked(who, userId)) { - // Allow testOnly admins to bypass supervision config requirement. - return; - } - } - // Only the default supervision app can use this API. + private boolean isDefaultSupervisor(CallerIdentity caller) { final String supervisor = mContext.getResources().getString( com.android.internal.R.string.config_defaultSupervisionProfileOwnerComponent); if (supervisor == null) { - throw new SecurityException("Unable to set secondary lockscreen setting, no " - + "default supervision component defined"); + return false; } final ComponentName supervisorComponent = ComponentName.unflattenFromString(supervisor); - if (!who.equals(supervisorComponent)) { - throw new SecurityException( - "Admin " + who + " is not the default supervision component"); - } + return caller.getComponentName().equals(supervisorComponent); } @Override @@ -11655,7 +11656,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public SystemUpdateInfo getPendingSystemUpdate(ComponentName admin) { Objects.requireNonNull(admin, "ComponentName is null"); - enforceProfileOrDeviceOwner(admin); + + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); return mOwners.getSystemUpdateInfo(); } @@ -11848,8 +11851,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public int checkProvisioningPreCondition(String action, String packageName) { - Objects.requireNonNull(packageName); - enforceCanManageProfileAndDeviceOwners(); + Objects.requireNonNull(packageName, "packageName is null"); + + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); + return checkProvisioningPreConditionSkipPermission(action, packageName); } @@ -12110,8 +12116,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isManagedProfile(ComponentName admin) { - enforceProfileOrDeviceOwner(admin); - return isManagedProfile(mInjector.userHandleGetCallingUserId()); + Objects.requireNonNull(admin, "ComponentName is null"); + + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + + return isManagedProfile(caller.getUserId()); } @Override @@ -12237,8 +12247,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } Objects.requireNonNull(who, "ComponentName is null"); + final CallerIdentity caller = getCallerIdentity(who); - enforceManagedProfile(caller.getUserId(), "set organization color"); + Preconditions.checkCallingUser(isManagedProfile(caller.getUserId())); + synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller); admin.organizationColor = color; @@ -12246,7 +12258,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_ORGANIZATION_COLOR) - .setAdmin(who) + .setAdmin(caller.getComponentName()) .write(); } @@ -12259,9 +12271,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId)); + Preconditions.checkCallAuthorization(canManageUsers(caller)); + Preconditions.checkCallAuthorization(isManagedProfile(userId), String.format("You can not " + + "set organization color outside a managed profile, userId = %d", userId)); - enforceManageUsers(); - enforceManagedProfile(userId, "set organization color"); synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerAdminLocked(userId); admin.organizationColor = color; @@ -12275,8 +12288,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return ActiveAdmin.DEF_ORGANIZATION_COLOR; } Objects.requireNonNull(who, "ComponentName is null"); + final CallerIdentity caller = getCallerIdentity(who); - enforceManagedProfile(caller.getUserId(), "get organization color"); + Preconditions.checkCallingUser(isManagedProfile(caller.getUserId())); + synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller); return admin.organizationColor; @@ -12292,8 +12307,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); + Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format("You can " + + "not get organization color outside a managed profile, userId = %d", userHandle)); - enforceManagedProfile(userHandle, "get organization color"); synchronized (getLockObject()) { ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userHandle); return (profileOwner != null) @@ -12326,8 +12342,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; } Objects.requireNonNull(who, "ComponentName is null"); + final CallerIdentity caller = getCallerIdentity(who); - enforceManagedProfile(caller.getUserId(), "get organization name"); + Preconditions.checkCallingUser(isManagedProfile(caller.getUserId())); + synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller); return admin.organizationName; @@ -12355,8 +12373,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); + Preconditions.checkCallAuthorization(isManagedProfile(userHandle), String.format( + "You can not get organization name outside a managed profile, userId = %d", + userHandle)); - enforceManagedProfile(userHandle, "get organization name"); synchronized (getLockObject()) { ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userHandle); return (profileOwner != null) @@ -12793,16 +12813,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return mSecurityLogMonitor.forceLogs(); } - private void enforceCanManageDeviceAdmin() { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS, - null); - } - - private void enforceCanManageProfileAndDeviceOwners() { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); - } - private void enforceCallerSystemUserHandle() { final int callingUid = mInjector.binderGetCallingUid(); final int userId = UserHandle.getUserId(callingUid); @@ -12813,9 +12823,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isUninstallInQueue(final String packageName) { - enforceCanManageDeviceAdmin(); - final int userId = mInjector.userHandleGetCallingUserId(); - Pair<String, Integer> packageUserPair = new Pair<>(packageName, userId); + final CallerIdentity caller = getCallerIdentity(); + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS)); + + Pair<String, Integer> packageUserPair = new Pair<>(packageName, caller.getUserId()); synchronized (getLockObject()) { return mPackagesToRemove.contains(packageUserPair); } @@ -12823,11 +12835,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void uninstallPackageWithActiveAdmins(final String packageName) { - enforceCanManageDeviceAdmin(); Preconditions.checkArgument(!TextUtils.isEmpty(packageName)); - final int userId = mInjector.userHandleGetCallingUserId(); + final CallerIdentity caller = getCallerIdentity(); + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS)); + final int userId = caller.getUserId(); enforceUserUnlocked(userId); final ComponentName profileOwner = getProfileOwner(userId); @@ -12876,7 +12890,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isDeviceProvisioned() { - enforceManageUsers(); + final CallerIdentity caller = getCallerIdentity(); + Preconditions.checkCallAuthorization(canManageUsers(caller)); + synchronized (getLockObject()) { return getUserDataUnchecked(UserHandle.USER_SYSTEM).mUserSetupComplete; } @@ -12960,7 +12976,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setDeviceProvisioningConfigApplied() { - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + synchronized (getLockObject()) { DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM); policy.mDeviceProvisioningConfigApplied = true; @@ -12970,7 +12987,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isDeviceProvisioningConfigApplied() { - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + synchronized (getLockObject()) { final DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM); return policy.mDeviceProvisioningConfigApplied; @@ -12986,8 +13004,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { */ @Override public void forceUpdateUserSetupComplete() { - enforceCanManageProfileAndDeviceOwners(); + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); enforceCallerSystemUserHandle(); + // no effect if it's called from user build if (!mInjector.isBuildDebuggable()) { return; @@ -13008,25 +13028,28 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - Objects.requireNonNull(admin); - enforceProfileOrDeviceOwner(admin); - int userId = mInjector.userHandleGetCallingUserId(); - toggleBackupServiceActive(userId, enabled); + Objects.requireNonNull(admin, "ComponentName is null"); + + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + + toggleBackupServiceActive(caller.getUserId(), enabled); } @Override public boolean isBackupServiceEnabled(ComponentName admin) { - Objects.requireNonNull(admin); if (!mHasFeature) { return true; } + Objects.requireNonNull(admin, "ComponentName is null"); + + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - enforceProfileOrDeviceOwner(admin); synchronized (getLockObject()) { try { IBackupManager ibm = mInjector.getIBackupManager(); - return ibm != null && ibm.isBackupServiceActive( - mInjector.userHandleGetCallingUserId()); + return ibm != null && ibm.isBackupServiceActive(caller.getUserId()); } catch (RemoteException e) { throw new IllegalStateException("Failed requesting backup service state.", e); } @@ -13608,13 +13631,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(admin, "ComponentName is null"); Objects.requireNonNull(packageName, "packageName is null"); Objects.requireNonNull(callback, "callback is null"); - enforceProfileOrDeviceOwner(admin); - final int userId = UserHandle.getCallingUserId(); + + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); long ident = mInjector.binderClearCallingIdentity(); try { ActivityManager.getService().clearApplicationUserData(packageName, false, callback, - userId); + caller.getUserId()); } catch(RemoteException re) { // Same process, should not happen. } catch (SecurityException se) { @@ -13667,7 +13691,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public List<String> getDisallowedSystemApps(ComponentName admin, int userId, String provisioningAction) throws RemoteException { - enforceCanManageProfileAndDeviceOwners(); + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); + return new ArrayList<>( mOverlayPackagesProvider.getNonRequiredApps(admin, userId, provisioningAction)); } @@ -13678,31 +13704,23 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - - Objects.requireNonNull(admin, "Admin cannot be null."); + Objects.requireNonNull(admin, "ComponentName is null"); Objects.requireNonNull(target, "Target cannot be null."); + Preconditions.checkArgument(!admin.equals(target), + "Provided administrator and target are the same object."); + Preconditions.checkArgument(!admin.getPackageName().equals(target.getPackageName()), + "Provided administrator and target have the same package name."); - enforceProfileOrDeviceOwner(admin); - - if (admin.equals(target)) { - throw new IllegalArgumentException("Provided administrator and target are " - + "the same object."); - } - - if (admin.getPackageName().equals(target.getPackageName())) { - throw new IllegalArgumentException("Provided administrator and target have " - + "the same package name."); - } + final CallerIdentity caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); - final int callingUserId = mInjector.userHandleGetCallingUserId(); + final int callingUserId = caller.getUserId(); final DevicePolicyData policy = getUserData(callingUserId); final DeviceAdminInfo incomingDeviceInfo = findAdmin(target, callingUserId, /* throwForMissingPermission= */ true); checkActiveAdminPrecondition(target, incomingDeviceInfo, policy); - if (!incomingDeviceInfo.supportsTransferOwnership()) { - throw new IllegalArgumentException("Provided target does not support " - + "ownership transfer."); - } + Preconditions.checkArgument(incomingDeviceInfo.supportsTransferOwnership(), + "Provided target does not support ownership transfer."); final long id = mInjector.binderClearCallingIdentity(); String ownerType = null; @@ -13725,7 +13743,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (bundle == null) { bundle = new PersistableBundle(); } - if (isProfileOwner(admin, callingUserId)) { + if (isProfileOwner(caller)) { ownerType = ADMIN_TYPE_PROFILE_OWNER; prepareTransfer(admin, target, bundle, callingUserId, ADMIN_TYPE_PROFILE_OWNER); @@ -13736,7 +13754,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (isUserAffiliatedWithDeviceLocked(callingUserId)) { notifyAffiliatedProfileTransferOwnershipComplete(callingUserId); } - } else if (isDeviceOwner(admin, callingUserId)) { + } else if (isDeviceOwner(caller)) { ownerType = ADMIN_TYPE_DEVICE_OWNER; prepareTransfer(admin, target, bundle, callingUserId, ADMIN_TYPE_DEVICE_OWNER); @@ -14406,7 +14424,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return false; } - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + long id = mInjector.binderClearCallingIdentity(); try { return isManagedKioskInternal(); @@ -14431,7 +14450,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return false; } - enforceManageUsers(); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + return mInjector.binderWithCleanCallingIdentity(() -> isUnattendedManagedKioskUnchecked()); } diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp index bbcb3122c9bb..5f145f33f628 100644 --- a/services/incremental/IncrementalService.cpp +++ b/services/incremental/IncrementalService.cpp @@ -2135,6 +2135,11 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount return binder::Status::ok(); } +binder::Status IncrementalService::DataLoaderStub::reportStreamHealth(MountId mountId, + int newStatus) { + return binder::Status::ok(); +} + bool IncrementalService::DataLoaderStub::isHealthParamsValid() const { return mHealthCheckParams.blockedTimeoutMs > 0 && mHealthCheckParams.blockedTimeoutMs < mHealthCheckParams.unhealthyTimeoutMs; diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h index d820417e73ed..504c02a57b86 100644 --- a/services/incremental/IncrementalService.h +++ b/services/incremental/IncrementalService.h @@ -200,6 +200,7 @@ private: private: binder::Status onStatusChanged(MountId mount, int newStatus) final; + binder::Status reportStreamHealth(MountId mount, int newStatus) final; sp<content::pm::IDataLoader> getDataLoader(); diff --git a/services/people/java/com/android/server/people/PeopleService.java b/services/people/java/com/android/server/people/PeopleService.java index 8b1e9c52ec58..91cb481a3b23 100644 --- a/services/people/java/com/android/server/people/PeopleService.java +++ b/services/people/java/com/android/server/people/PeopleService.java @@ -30,6 +30,7 @@ import android.content.Context; import android.content.pm.ParceledListSlice; import android.os.Binder; import android.os.CancellationSignal; +import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; @@ -73,7 +74,7 @@ public class PeopleService extends SystemService { @Override public void onStart() { - publishBinderService(Context.PEOPLE_SERVICE, new BinderService()); + publishBinderService(Context.PEOPLE_SERVICE, mService); publishLocalService(PeopleServiceInternal.class, new LocalService()); } @@ -117,7 +118,7 @@ public class PeopleService extends SystemService { message); } - private final class BinderService extends IPeopleManager.Stub { + final IBinder mService = new IPeopleManager.Stub() { @Override public ParceledListSlice<ConversationChannel> getRecentConversations() { @@ -146,7 +147,7 @@ public class PeopleService extends SystemService { enforceSystemRootOrSystemUI(getContext(), "get last interaction"); return mDataManager.getLastInteraction(packageName, userId, shortcutId); } - } + }; @VisibleForTesting final class LocalService extends PeopleServiceInternal { diff --git a/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java index be258dc5963e..3cd415ecb1c5 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java @@ -202,22 +202,20 @@ public class LocationProviderManagerTest { @Test public void testIsEnabled() { assertThat(mManager.isEnabled(CURRENT_USER)).isTrue(); + assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER); assertThat(mManager.isEnabled(CURRENT_USER)).isFalse(); + assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER); mProvider.setAllowed(false); assertThat(mManager.isEnabled(CURRENT_USER)).isFalse(); + assertThat(mManager.isEnabled(OTHER_USER)).isFalse(); mProvider.setAllowed(true); - mInjector.getUserInfoHelper().setCurrentUserId(OTHER_USER); - assertThat(mManager.isEnabled(CURRENT_USER)).isFalse(); - assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); - - mInjector.getUserInfoHelper().setCurrentUserId(CURRENT_USER); assertThat(mManager.isEnabled(CURRENT_USER)).isTrue(); - assertThat(mManager.isEnabled(OTHER_USER)).isFalse(); + assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); } @Test @@ -237,23 +235,15 @@ public class LocationProviderManagerTest { mProvider.setAllowed(false); verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER, false); + verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER, + false); mProvider.setAllowed(true); verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER, true); - - mInjector.getUserInfoHelper().setCurrentUserId(OTHER_USER); - verify(listener, timeout(TIMEOUT_MS).times(3)).onProviderEnabledChanged(NAME, CURRENT_USER, - false); verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER, true); - mInjector.getUserInfoHelper().setCurrentUserId(CURRENT_USER); - verify(listener, timeout(TIMEOUT_MS).times(3)).onProviderEnabledChanged(NAME, CURRENT_USER, - true); - verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER, - false); - mManager.removeEnabledListener(listener); mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER); verifyNoMoreInteractions(listener); @@ -397,16 +387,6 @@ public class LocationProviderManagerTest { mProvider.setAllowed(true); verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, true); - mInjector.getUserInfoHelper().setCurrentUserId(OTHER_USER); - verify(listener, timeout(TIMEOUT_MS).times(3)).onProviderEnabledChanged(NAME, false); - loc = createLocation(NAME, mRandom); - mProvider.setProviderLocation(loc); - verify(listener, times(1)).onLocationChanged(any(Location.class), - nullable(IRemoteCallback.class)); - - mInjector.getUserInfoHelper().setCurrentUserId(CURRENT_USER); - verify(listener, timeout(TIMEOUT_MS).times(3)).onProviderEnabledChanged(NAME, true); - loc = createLocation(NAME, mRandom); mProvider.setProviderLocation(loc); verify(listener, times(2)).onLocationChanged(locationCaptor.capture(), diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 4ce6411dc306..631b4d48e9f2 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -4407,7 +4407,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Caller is Profile Owner, but no supervision app is configured. setAsProfileOwner(admin1); - assertExpectException(SecurityException.class, "no default supervision component defined", + assertExpectException(SecurityException.class, "is not the default supervision component", () -> dpm.setSecondaryLockscreenEnabled(admin1, true)); assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java index 63ad53bcab4a..2a9c3942211c 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java @@ -160,7 +160,7 @@ public class ActiveSourceActionTest { assertThat(playbackDevice.getActiveSource().logicalAddress).isEqualTo( playbackDevice.mAddress); assertThat(playbackDevice.getActiveSource().physicalAddress).isEqualTo(mPhysicalAddress); - assertThat(playbackDevice.mIsActiveSource).isTrue(); + assertThat(playbackDevice.isActiveSource()).isTrue(); } @Test diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java index 415ae0731edb..74fd6830de61 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java @@ -30,10 +30,15 @@ import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF; import static com.google.common.truth.Truth.assertThat; +import android.content.Context; import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.HdmiPortInfo; import android.media.AudioManager; +import android.os.Handler; +import android.os.IPowerManager; +import android.os.IThermalService; import android.os.Looper; +import android.os.PowerManager; import android.os.test.TestLooper; import android.platform.test.annotations.Presubmit; @@ -47,6 +52,8 @@ import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import java.util.ArrayList; @@ -81,8 +88,17 @@ public class HdmiCecLocalDeviceAudioSystemTest { private HdmiPortInfo[] mHdmiPortInfo; private boolean mWokenUp; + @Mock private IPowerManager mIPowerManagerMock; + @Mock private IThermalService mIThermalServiceMock; + @Before public void setUp() { + MockitoAnnotations.initMocks(this); + + Context context = InstrumentationRegistry.getTargetContext(); + mMyLooper = mTestLooper.getLooper(); + PowerManager powerManager = new PowerManager(context, mIPowerManagerMock, + mIThermalServiceMock, new Handler(mMyLooper)); mHdmiControlService = new HdmiControlService(InstrumentationRegistry.getTargetContext()) { @Override @@ -166,6 +182,11 @@ public class HdmiCecLocalDeviceAudioSystemTest { return defVal; } } + + @Override + PowerManager getPowerManager() { + return powerManager; + } }; mHdmiControlService.setHdmiCecVolumeControlEnabled(true); @@ -174,11 +195,6 @@ public class HdmiCecLocalDeviceAudioSystemTest { mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService); mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService) { @Override - void setIsActiveSource(boolean on) { - mIsActiveSource = on; - } - - @Override protected int getPreferredAddress() { return ADDR_PLAYBACK_1; } @@ -827,4 +843,68 @@ public class HdmiCecLocalDeviceAudioSystemTest { assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpected); } + + @Test + public void setActiveSource_localDevice_playback() { + mHdmiControlService.setActiveSource(mHdmiCecLocalDevicePlayback.mAddress, + SELF_PHYSICAL_ADDRESS, + "HdmiControlServiceTest"); + + assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( + mHdmiCecLocalDevicePlayback.mAddress); + assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo( + SELF_PHYSICAL_ADDRESS); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); + assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse(); + } + + @Test + public void setActiveSource_localDevice_audio() { + mHdmiControlService.setActiveSource(mHdmiCecLocalDeviceAudioSystem.mAddress, + SELF_PHYSICAL_ADDRESS, + "HdmiControlServiceTest"); + + assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( + mHdmiCecLocalDeviceAudioSystem.mAddress); + assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo( + SELF_PHYSICAL_ADDRESS); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isTrue(); + } + + @Test + public void setActiveSource_remoteDevice() { + mHdmiControlService.setActiveSource(Constants.ADDR_TV, 0x0000, "HdmiControlServiceTest"); + + assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( + Constants.ADDR_TV); + assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(0x000); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse(); + } + + @Test + public void setActiveSource_nonCecDevice() { + mHdmiControlService.setActiveSource(Constants.ADDR_INVALID, 0x1234, + "HdmiControlServiceTest"); + + assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( + Constants.ADDR_INVALID); + assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(0x1234); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse(); + } + + @Test + public void setActiveSource_unknown() { + mHdmiControlService.setActiveSource(Constants.ADDR_INVALID, + Constants.INVALID_PHYSICAL_ADDRESS, "HdmiControlServiceTest"); + + assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( + Constants.ADDR_INVALID); + assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo( + Constants.INVALID_PHYSICAL_ADDRESS); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse(); + } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java index 498ebf4a2ef9..7cbf571d6f60 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -17,6 +17,7 @@ package com.android.server.hdmi; import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; import static com.android.server.hdmi.Constants.ADDR_BROADCAST; +import static com.android.server.hdmi.Constants.ADDR_INVALID; import static com.android.server.hdmi.Constants.ADDR_TV; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; @@ -266,106 +267,197 @@ public class HdmiCecLocalDevicePlaybackTest { @Test public void handleRoutingChange_otherDevice_None() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = - HdmiProperties.power_state_change_on_active_source_lost_values.NONE; - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + 0x5000); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); + assertThat(mStandby).isFalse(); + } + + @Test + public void handleRoutingChange_sameDevice_None_ActiveSource() { + mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); + mStandby = false; + HdmiCecMessage message = + HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + mPlaybackLogicalAddress); + assertThat(mStandby).isFalse(); + } + + @Test + public void handleRoutingChange_sameDevice_None_InactiveSource() { + mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); + mStandby = false; + HdmiCecMessage message = + HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); assertThat(mStandby).isFalse(); } @Test public void handleRoutingChange_otherDevice_StandbyNow() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = - HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mStandby).isTrue(); } @Test public void handleRoutingChange_otherDevice_StandbyNow_InactiveSource() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = - HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; - mHdmiCecLocalDevicePlayback.setIsActiveSource(false); + HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mStandby).isFalse(); } @Test public void handleRoutingChange_sameDevice_StandbyNow_ActiveSource() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = - HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, mPlaybackPhysicalAddress); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); assertThat(mStandby).isFalse(); } @Test public void handleRoutingInformation_otherDevice_None() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = - HdmiProperties.power_state_change_on_active_source_lost_values.NONE; - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); + mStandby = false; + HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000); + assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + 0x5000); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); + assertThat(mStandby).isFalse(); + } + + @Test + public void handleRoutingInformation_sameDevice_None_ActiveSource() { + mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = - HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000); + HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + mPlaybackLogicalAddress); + assertThat(mStandby).isFalse(); + } + + @Test + public void handleRoutingInformation_sameDevice_None_InactiveSource() { + mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); + mStandby = false; + HdmiCecMessage message = + HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, + mPlaybackPhysicalAddress); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); assertThat(mStandby).isFalse(); } @Test public void handleRoutingInformation_otherDevice_StandbyNow() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = - HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mStandby).isTrue(); } @Test public void handleRoutingInformation_otherDevice_StandbyNow_InactiveSource() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = - HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; - mHdmiCecLocalDevicePlayback.setIsActiveSource(false); + HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mStandby).isFalse(); } @Test public void handleRoutingInformation_sameDevice_StandbyNow_ActiveSource() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = - HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, mPlaybackPhysicalAddress); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); assertThat(mStandby).isFalse(); } @@ -430,7 +522,8 @@ public class HdmiCecLocalDevicePlaybackTest { mHdmiCecLocalDevicePlayback.mService.writeStringSetting( Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV); - mHdmiCecLocalDevicePlayback.setIsActiveSource(false); + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true); mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF); mTestLooper.dispatchAll(); @@ -449,7 +542,8 @@ public class HdmiCecLocalDevicePlaybackTest { mHdmiCecLocalDevicePlayback.mService.writeStringSetting( Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST); - mHdmiCecLocalDevicePlayback.setIsActiveSource(false); + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true); mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF); mTestLooper.dispatchAll(); @@ -468,7 +562,8 @@ public class HdmiCecLocalDevicePlaybackTest { mHdmiCecLocalDevicePlayback.mService.writeStringSetting( Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE); - mHdmiCecLocalDevicePlayback.setIsActiveSource(false); + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true); mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF); mTestLooper.dispatchAll(); @@ -487,7 +582,8 @@ public class HdmiCecLocalDevicePlaybackTest { mHdmiCecLocalDevicePlayback.mService.writeStringSetting( Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV); - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true); mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF); mTestLooper.dispatchAll(); @@ -506,7 +602,8 @@ public class HdmiCecLocalDevicePlaybackTest { mHdmiCecLocalDevicePlayback.mService.writeStringSetting( Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST); - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true); mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF); mTestLooper.dispatchAll(); @@ -525,7 +622,8 @@ public class HdmiCecLocalDevicePlaybackTest { mHdmiCecLocalDevicePlayback.mService.writeStringSetting( Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE); - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true); mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF); mTestLooper.dispatchAll(); @@ -549,6 +647,11 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue(); mTestLooper.dispatchAll(); assertThat(mStandby).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + mPlaybackLogicalAddress); } @Test @@ -560,6 +663,11 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue(); mTestLooper.dispatchAll(); assertThat(mStandby).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + 0x0000); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_TV); } @Test @@ -572,6 +680,7 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue(); mTestLooper.dispatchAll(); assertThat(mStandby).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); } @Test @@ -583,6 +692,7 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue(); mTestLooper.dispatchAll(); assertThat(mStandby).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); } @Test @@ -703,7 +813,7 @@ public class HdmiCecLocalDevicePlaybackTest { mPlaybackLogicalAddress, ADDR_TV); mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); assertThat(mNativeWrapper.getResultMessages()).containsAllOf(pressed, released); } @@ -723,7 +833,7 @@ public class HdmiCecLocalDevicePlaybackTest { mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM); mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); assertThat(mNativeWrapper.getResultMessages()).containsAllOf(pressed, released); } @@ -742,7 +852,7 @@ public class HdmiCecLocalDevicePlaybackTest { mPlaybackLogicalAddress, ADDR_TV); mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mNativeWrapper.getResultMessages()).containsAllOf(pressed, released); } @@ -761,7 +871,7 @@ public class HdmiCecLocalDevicePlaybackTest { mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM); mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mNativeWrapper.getResultMessages()).containsAllOf(pressed, released); } @@ -805,21 +915,28 @@ public class HdmiCecLocalDevicePlaybackTest { mHdmiCecLocalDevicePlayback.dispatchMessage(setStreamPath); mTestLooper.dispatchAll(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress()); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); } @Test public void handleSetStreamPath_otherDevice_None() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = - HdmiProperties.power_state_change_on_active_source_lost_values.NONE; - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + 0x5000); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); assertThat(mStandby).isFalse(); } @@ -827,12 +944,13 @@ public class HdmiCecLocalDevicePlaybackTest { public void handleSetStreamPath_otherDevice_StandbyNow() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; - mHdmiCecLocalDevicePlayback.setIsActiveSource(true); + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mStandby).isTrue(); } @@ -840,12 +958,13 @@ public class HdmiCecLocalDevicePlaybackTest { public void handleSetStreamPath_otherDevice_StandbyNow_InactiveSource() { mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW; - mHdmiCecLocalDevicePlayback.setIsActiveSource(false); + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); mStandby = false; HdmiCecMessage message = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue(); - assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mStandby).isFalse(); } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java index 7560a34e63cc..c4068d34c00d 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java @@ -138,11 +138,6 @@ public class HdmiControlServiceBinderAPITest { mPlaybackDevice = new HdmiCecLocalDevicePlayback(mHdmiControlService) { @Override - void setIsActiveSource(boolean on) { - mIsActiveSource = on; - } - - @Override protected void wakeUpIfActiveSource() {} @Override @@ -186,13 +181,13 @@ public class HdmiControlServiceBinderAPITest { } }); assertEquals(mResult, -1); - assertThat(mPlaybackDevice.mIsActiveSource).isFalse(); + assertThat(mPlaybackDevice.isActiveSource()).isFalse(); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); assertThat(mHdmiControlService.isAddressAllocated()).isTrue(); assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS); - assertThat(mPlaybackDevice.mIsActiveSource).isTrue(); + assertThat(mPlaybackDevice.isActiveSource()).isTrue(); } @Test @@ -207,6 +202,6 @@ public class HdmiControlServiceBinderAPITest { } }); assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS); - assertThat(mPlaybackDevice.mIsActiveSource).isTrue(); + assertThat(mPlaybackDevice.isActiveSource()).isTrue(); } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java index 4849dd417041..2f48b5ee4c70 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -405,82 +405,6 @@ public class HdmiControlServiceTest { assertThat(callback2.mVolumeControlEnabled).isTrue(); } - @Test - public void setActiveSource_localDevice_playback() { - int physicalAddress = 0x1000; - mNativeWrapper.setPhysicalAddress(physicalAddress); - - mHdmiControlService.setActiveSource(mMyPlaybackDevice.mAddress, physicalAddress, - "HdmiControlServiceTest"); - - assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( - mMyPlaybackDevice.mAddress); - assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo( - physicalAddress); - assertThat(mMyPlaybackDevice.mIsActiveSource).isTrue(); - assertThat(mMyAudioSystemDevice.mIsActiveSource).isFalse(); - } - - @Test - public void setActiveSource_localDevice_audio() { - int physicalAddress = 0x1000; - mNativeWrapper.setPhysicalAddress(physicalAddress); - - mHdmiControlService.setActiveSource(mMyAudioSystemDevice.mAddress, physicalAddress, - "HdmiControlServiceTest"); - - assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( - mMyAudioSystemDevice.mAddress); - assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo( - physicalAddress); - assertThat(mMyPlaybackDevice.mIsActiveSource).isFalse(); - assertThat(mMyAudioSystemDevice.mIsActiveSource).isTrue(); - } - - @Test - public void setActiveSource_remoteDevice() { - int physicalAddress = 0x1000; - mNativeWrapper.setPhysicalAddress(physicalAddress); - - mHdmiControlService.setActiveSource(Constants.ADDR_TV, 0x0000, "HdmiControlServiceTest"); - - assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( - Constants.ADDR_TV); - assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(0x000); - assertThat(mMyPlaybackDevice.mIsActiveSource).isFalse(); - assertThat(mMyAudioSystemDevice.mIsActiveSource).isFalse(); - } - - @Test - public void setActiveSource_nonCecDevice() { - int physicalAddress = 0x1000; - mNativeWrapper.setPhysicalAddress(physicalAddress); - - mHdmiControlService.setActiveSource(Constants.ADDR_INVALID, 0x1234, - "HdmiControlServiceTest"); - - assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( - Constants.ADDR_INVALID); - assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo(0x1234); - assertThat(mMyPlaybackDevice.mIsActiveSource).isFalse(); - assertThat(mMyAudioSystemDevice.mIsActiveSource).isFalse(); - } - - @Test - public void setActiveSource_unknown() { - int physicalAddress = 0x1000; - mNativeWrapper.setPhysicalAddress(physicalAddress); - - mHdmiControlService.setActiveSource(Constants.ADDR_INVALID, - Constants.INVALID_PHYSICAL_ADDRESS, "HdmiControlServiceTest"); - - assertThat(mHdmiControlService.getLocalActiveSource().logicalAddress).isEqualTo( - Constants.ADDR_INVALID); - assertThat(mHdmiControlService.getLocalActiveSource().physicalAddress).isEqualTo( - Constants.INVALID_PHYSICAL_ADDRESS); - assertThat(mMyPlaybackDevice.mIsActiveSource).isFalse(); - assertThat(mMyAudioSystemDevice.mIsActiveSource).isFalse(); - } private static class VolumeControlFeatureCallback extends IHdmiCecVolumeControlFeatureListener.Stub { diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java index c7342426c80c..6be28d9a13be 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java @@ -150,7 +150,7 @@ public class SystemAudioInitiationActionFromAvrTest { @Override public void setAndBroadcastActiveSourceFromOneDeviceType( - int sourceAddress, int physicalAddress) { + int sourceAddress, int physicalAddress, String caller) { mBroadcastActiveSource = true; } diff --git a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java index 9ee9259a23c2..292b7c6bf5ad 100644 --- a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java +++ b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java @@ -77,6 +77,7 @@ public class ControllerImplTest { private TestThreadingDomain mTestThreadingDomain; private TestCallback mTestCallback; private TestLocationTimeZoneProvider mTestPrimaryLocationTimeZoneProvider; + private TestLocationTimeZoneProvider mTestSecondaryLocationTimeZoneProvider; @Before public void setUp() { @@ -87,26 +88,30 @@ public class ControllerImplTest { mTestCallback = new TestCallback(mTestThreadingDomain); mTestPrimaryLocationTimeZoneProvider = new TestLocationTimeZoneProvider(mTestThreadingDomain, "primary"); + mTestSecondaryLocationTimeZoneProvider = + new TestLocationTimeZoneProvider(mTestThreadingDomain, "secondary"); } @Test public void initialState_enabled() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); Duration expectedInitTimeout = testEnvironment.getProviderInitializationTimeout() .plus(testEnvironment.getProviderInitializationTimeoutFuzz()); - // Initialize. After initialization the provider must be initialized and should be + // Initialize. After initialization the providers must be initialized and one should be // enabled. controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertInitialized(); + mTestSecondaryLocationTimeZoneProvider.assertInitialized(); mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestPrimaryLocationTimeZoneProvider.assertInitializationTimeoutSet(expectedInitTimeout); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @@ -114,17 +119,19 @@ public class ControllerImplTest { @Test public void initialState_disabled() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_DISABLED); - // Initialize. After initialization the provider must be initialized but should not be + // Initialize. After initialization the providers must be initialized but neither should be // enabled. controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertInitialized(); + mTestSecondaryLocationTimeZoneProvider.assertInitialized(); mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @@ -132,7 +139,7 @@ public class ControllerImplTest { @Test public void enabled_uncertaintySuggestionSentIfNoEventReceived() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); @@ -141,6 +148,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -148,9 +156,24 @@ public class ControllerImplTest { mTestThreadingDomain.executeNext(); // The primary should have reported uncertainty, which should trigger the controller to - // start the uncertainty timeout. + // start the uncertainty timeout and enable the secondary. mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + + // Simulate time passing with no provider event being received from either the primary or + // secondary. + mTestThreadingDomain.executeNext(); + + // Now both initialization timeouts should have triggered. The uncertainty timeout should + // still not be triggered. + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestCallback.assertNoSuggestionMade(); assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); @@ -160,6 +183,8 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestCallback.assertUncertainSuggestionMadeAndCommit(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @@ -167,7 +192,7 @@ public class ControllerImplTest { @Test public void enabled_eventReceivedBeforeInitializationTimeout() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); @@ -176,6 +201,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -186,6 +212,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertSuggestionMadeAndCommit( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds()); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -194,7 +221,7 @@ public class ControllerImplTest { @Test public void enabled_eventReceivedFromPrimaryAfterInitializationTimeout() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); @@ -203,6 +230,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -211,16 +239,59 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestCallback.assertNoSuggestionMade(); assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); // Simulate a location event being received from the primary provider. This should cause a - // suggestion to be made. + // suggestion to be made and the secondary to be shut down. mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1); mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestCallback.assertSuggestionMadeAndCommit( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds()); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + } + + @Test + public void enabled_eventReceivedFromSecondaryAfterInitializationTimeout() { + ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); + TestEnvironment testEnvironment = new TestEnvironment( + mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); + + // Initialize and check initial state. + controllerImpl.initialize(testEnvironment, mTestCallback); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate time passing with no provider event being received from the primary. + mTestThreadingDomain.executeNext(); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + + // Simulate a location event being received from the secondary provider. This should cause a + // suggestion to be made. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestCallback.assertSuggestionMadeAndCommit( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds()); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -229,7 +300,7 @@ public class ControllerImplTest { @Test public void enabled_repeatedPrimaryCertainty() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); @@ -238,6 +309,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -248,6 +320,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertSuggestionMadeAndCommit( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds()); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -258,6 +331,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -267,6 +341,70 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestCallback.assertSuggestionMadeAndCommit( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds()); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + } + + @Test + public void enabled_repeatedSecondaryCertainty() { + ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); + TestEnvironment testEnvironment = new TestEnvironment( + mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); + + // Initialize and check initial state. + controllerImpl.initialize(testEnvironment, mTestCallback); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate time passing with no provider event being received from the primary. + mTestThreadingDomain.executeNext(); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + + // Simulate a location event being received from the secondary provider. This should cause a + // suggestion to be made. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertSuggestionMadeAndCommit( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds()); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // A second, identical event should not cause another suggestion. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // And a third, different event should cause another suggestion. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestCallback.assertSuggestionMadeAndCommit( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds()); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -275,7 +413,7 @@ public class ControllerImplTest { @Test public void enabled_uncertaintyTriggersASuggestionAfterUncertaintyTimeout() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); @@ -284,6 +422,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -294,18 +433,48 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertSuggestionMadeAndCommit( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds()); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); // Simulate an uncertain event being received from the primary provider. This should not // cause a suggestion to be made straight away, but the uncertainty timeout should be - // started. + // started and the secondary should be enabled. mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT); mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + + // Simulate a location event being received from the secondary provider. This should cause a + // suggestion to be made, cancel the uncertainty timeout and ensure the secondary is + // considered initialized. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertSuggestionMadeAndCommit( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds()); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate an uncertain event being received from the secondary provider. This should not + // cause a suggestion to be made straight away, but the uncertainty timeout should be + // started. Both providers are now enabled, with no initialization timeout set. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestCallback.assertNoSuggestionMade(); assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); @@ -315,6 +484,8 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestCallback.assertUncertainSuggestionMadeAndCommit(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @@ -322,7 +493,7 @@ public class ControllerImplTest { @Test public void enabled_briefUncertaintyTriggersNoSuggestion() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); @@ -331,6 +502,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -341,27 +513,32 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertSuggestionMadeAndCommit( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds()); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); // Uncertainty should not cause a suggestion to be made straight away, but the uncertainty - // timeout should be started. + // timeout should be started and the secondary should be enabled. mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT); mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestCallback.assertNoSuggestionMade(); assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); // And a success event from the primary provider should cause the controller to make another - // suggestion, the uncertainty timeout should be cancelled. + // suggestion, the uncertainty timeout should be cancelled and the secondary should be + // disabled again. mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2); mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertSuggestionMadeAndCommit( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds()); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -370,7 +547,7 @@ public class ControllerImplTest { @Test public void configChanges_enableAndDisableWithNoPreviousSuggestion() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_DISABLED); @@ -378,6 +555,7 @@ public class ControllerImplTest { controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -386,6 +564,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -393,6 +572,7 @@ public class ControllerImplTest { testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED); mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @@ -400,7 +580,7 @@ public class ControllerImplTest { @Test public void configChanges_enableAndDisableWithPreviousSuggestion() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_DISABLED); @@ -408,6 +588,7 @@ public class ControllerImplTest { controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -416,6 +597,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -425,6 +607,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertSuggestionMadeAndCommit( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds()); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -436,6 +619,7 @@ public class ControllerImplTest { testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED); mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertUncertainSuggestionMadeAndCommit(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @@ -443,7 +627,7 @@ public class ControllerImplTest { @Test public void configChanges_userSwitch_enabledToEnabled() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); @@ -452,6 +636,7 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -463,6 +648,7 @@ public class ControllerImplTest { // and also clear the scheduled uncertainty suggestion. mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertSuggestionMadeAndCommit( USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds()); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -477,13 +663,74 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateChangesAndCommit(expectedStateTransitions); mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfig( PROVIDER_STATE_ENABLED_INITIALIZING, USER2_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @Test + public void primaryPermFailure_secondaryEventsReceived() { + ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); + TestEnvironment testEnvironment = new TestEnvironment( + mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); + + // Initialize and check initial state. + controllerImpl.initialize(testEnvironment, mTestCallback); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate a failure location event being received from the primary provider. This should + // cause the secondary to be enabled. + mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate uncertainty from the secondary. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + + // And a success event from the secondary provider should cause the controller to make + // another suggestion, the uncertainty timeout should be cancelled. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2); + + mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertSuggestionMadeAndCommit( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds()); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate uncertainty from the secondary. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + } + + @Test public void primaryPermFailure_disableAndEnable() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, - mTestPrimaryLocationTimeZoneProvider); + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); @@ -492,22 +739,26 @@ public class ControllerImplTest { mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); // Simulate a failure location event being received from the primary provider. This should - // cause an uncertain suggestion to be made. + // cause the secondary to be enabled. mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT); mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); - mTestCallback.assertUncertainSuggestionMadeAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); // Now signal a config change so that geo detection is disabled. testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED); mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); @@ -515,6 +766,164 @@ public class ControllerImplTest { testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_ENABLED); mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + } + + @Test + public void secondaryPermFailure_primaryEventsReceived() { + ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); + TestEnvironment testEnvironment = new TestEnvironment( + mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); + + // Initialize and check initial state. + controllerImpl.initialize(testEnvironment, mTestCallback); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate an uncertain event from the primary. This will enable the secondary, which will + // give this test the opportunity to simulate its failure. Then it will be possible to + // demonstrate controller behavior with only the primary working. + mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + + // Simulate failure event from the secondary. This should just affect the secondary's state. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + + // And a success event from the primary provider should cause the controller to make + // a suggestion, the uncertainty timeout should be cancelled. + mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestCallback.assertSuggestionMadeAndCommit( + USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds()); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate uncertainty from the primary. The secondary cannot be enabled. + mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + } + + @Test + public void secondaryPermFailure_disableAndEnable() { + ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); + TestEnvironment testEnvironment = new TestEnvironment( + mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); + + // Initialize and check initial state. + controllerImpl.initialize(testEnvironment, mTestCallback); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate an uncertain event from the primary. This will enable the secondary, which will + // give this test the opportunity to simulate its failure. Then it will be possible to + // demonstrate controller behavior with only the primary working. + mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + + // Simulate failure event from the secondary. This should just affect the secondary's state. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertUncertaintyTimeoutSet(testEnvironment, controllerImpl); + + // Now signal a config change so that geo detection is disabled. + testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED); + + mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Now signal a config change so that geo detection is enabled. Only the primary can be + // enabled. + testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_ENABLED); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + } + + @Test + public void bothPermFailure_disableAndEnable() { + ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, + mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); + TestEnvironment testEnvironment = new TestEnvironment( + mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); + + // Initialize and check initial state. + controllerImpl.initialize(testEnvironment, mTestCallback); + + mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit(); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate a failure event from the primary. This will enable the secondary. + mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( + PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); + mTestCallback.assertNoSuggestionMade(); + assertFalse(controllerImpl.isUncertaintyTimeoutSet()); + + // Simulate failure event from the secondary. + mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent( + USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT); + + mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); + mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); mTestCallback.assertUncertainSuggestionMadeAndCommit(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } diff --git a/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java b/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java new file mode 100644 index 000000000000..62e135b09593 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java @@ -0,0 +1,316 @@ +/* + * 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.pm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.content.pm.IDataLoaderStatusListener; +import android.content.pm.PackageManager; +import android.os.ConditionVariable; +import android.os.incremental.IStorageHealthListener; +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.MediumTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Unit tests for {@link IncrementalStates}. + * Run with: atest -c FrameworksServicesTests:com.android.server.pm.IncrementalStatesTest + */ +@Presubmit +@RunWith(AndroidJUnit4.class) +@MediumTest +public class IncrementalStatesTest { + private IncrementalStates mIncrementalStates; + private ConditionVariable mUnstartableCalled = new ConditionVariable(); + private ConditionVariable mStartableCalled = new ConditionVariable(); + private ConditionVariable mFullyLoadedCalled = new ConditionVariable(); + private AtomicInteger mUnstartableReason = new AtomicInteger(0); + private static final int WAIT_TIMEOUT_MILLIS = 1000; /* 1 second */ + private IncrementalStates.Callback mCallback = new IncrementalStates.Callback() { + @Override + public void onPackageUnstartable(int reason) { + mUnstartableCalled.open(); + mUnstartableReason.set(reason); + } + + @Override + public void onPackageStartable() { + mStartableCalled.open(); + } + + @Override + public void onPackageFullyLoaded() { + mFullyLoadedCalled.open(); + } + }; + + /** + * Setup the tests as if the package has just been committed. + * By default the package is now startable and is loading. + */ + @Before + public void setUp() { + mIncrementalStates = new IncrementalStates(); + assertFalse(mIncrementalStates.isStartable()); + mIncrementalStates.setCallback(mCallback); + mIncrementalStates.onCommit(true); + // Test that package is now startable and loading + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + assertTrue(mIncrementalStates.isLoading()); + mStartableCalled.close(); + mUnstartableCalled.close(); + mFullyLoadedCalled.close(); + } + + /** + * Test that startable state changes to false when Incremental Storage is unhealthy. + */ + @Test + public void testStartableTransition_IncrementalStorageUnhealthy() { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_UNKNOWN, mUnstartableReason.get()); + } + + /** + * Test that the package is still startable when Incremental Storage has pending reads. + */ + @Test + public void testStartableTransition_IncrementalStorageReadsPending() + throws InterruptedException { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_READS_PENDING); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package is still startable when Incremental Storage is at blocked status. + */ + @Test + public void testStartableTransition_IncrementalStorageBlocked() { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_BLOCKED); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package is still startable when Data Loader has unknown transportation issues. + */ + @Test + public void testStartableTransition_DataLoaderTransportError() { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_TRANSPORT_ERROR); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package becomes unstartable when Data Loader has data integrity issues. + */ + @Test + public void testStartableTransition_DataLoaderIntegrityError() { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_DATALOADER_TRANSPORT, + mUnstartableReason.get()); + } + + /** + * Test that the package becomes unstartable when Data Loader has data source issues. + */ + @Test + public void testStartableTransition_DataLoaderSourceError() { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_SOURCE_ERROR); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_DATALOADER_TRANSPORT, + mUnstartableReason.get()); + } + + /** + * Test that the package becomes unstartable when Data Loader hits limited storage while + * Incremental storage has a pending reads. + */ + @Test + public void testStartableTransition_DataLoaderStorageErrorWhenIncrementalStoragePending() + throws InterruptedException { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_STORAGE_ERROR); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_READS_PENDING); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_DATALOADER_STORAGE, + mUnstartableReason.get()); + } + + /** + * Test that the package becomes unstartable when Data Loader hits limited storage while + * Incremental storage is at blocked status. + */ + @Test + public void testStartableTransition_DataLoaderStorageErrorWhenIncrementalStorageBlocked() + throws InterruptedException { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_STORAGE_ERROR); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_BLOCKED); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_DATALOADER_STORAGE, + mUnstartableReason.get()); + } + + /** + * Test that the package becomes unstartable when Incremental Storage is unhealthy, and it + * becomes startable again when Incremental Storage is healthy again. + */ + @Test + public void testStartableTransition_IncrementalStorageUnhealthyBackToHealthy() + throws InterruptedException { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + // Test that package is unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_OK); + // Test that package is now startable + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package becomes unstartable when Data Loader has data integrity issue, and it + * becomes startable again when Data Loader is healthy again. + */ + @Test + public void testStartableTransition_DataLoaderUnhealthyBackToHealthy() + throws InterruptedException { + mIncrementalStates.onStreamStatusChanged(IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR); + // Test that package is unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + + mIncrementalStates.onStreamStatusChanged(IDataLoaderStatusListener.STREAM_HEALTHY); + // Test that package is now startable + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package becomes unstartable when both Incremental Storage and Data Loader + * are unhealthy, and it becomes startable again when both Incremental Storage and Data Loader + * are healthy again. + */ + @Test + public void testStartableTransition_DataLoaderAndIncrementalStorageUnhealthyBackToHealthy() + throws InterruptedException { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + mIncrementalStates.onStreamStatusChanged(IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR); + // Test that package is unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + + mIncrementalStates.onStreamStatusChanged(IDataLoaderStatusListener.STREAM_HEALTHY); + // Test that package is still unstartable + assertFalse(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + mIncrementalStates.onStorageHealthStatusChanged(IStorageHealthListener.HEALTH_STATUS_OK); + // Test that package is now startable + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that when loading progress is 1, the package becomes fully loaded, and the change of + * Incremental Storage health status does not affect the startable state. + */ + @Test + public void testStartableTransition_HealthStatusChangeWhenFullyLoaded() + throws InterruptedException { + mIncrementalStates.setProgress(1.0f); + // Test that package is now fully loaded + assertTrue(mFullyLoadedCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isLoading()); + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that when loading progress is 1, the package becomes fully loaded, and if the package + * was unstartable, it becomes startable. + */ + @Test + public void testLoadingTransition_FullyLoadedWhenUnstartable() throws InterruptedException { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + // Test that package is unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + // Test that package is still loading + assertTrue(mIncrementalStates.isLoading()); + + mIncrementalStates.setProgress(0.5f); + // Test that package is still unstartable + assertFalse(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + mIncrementalStates.setProgress(1.0f); + // Test that package is now startable + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + // Test that package is now fully loaded + assertTrue(mFullyLoadedCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isLoading()); + } +} diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java new file mode 100644 index 000000000000..9a668b91c656 --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java @@ -0,0 +1,118 @@ +/* + * 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; + +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; +import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; + +import static com.android.server.wm.WindowContainer.POSITION_TOP; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; + +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Tests for the {@link DisplayAreaGroup} container. + * + * Build/Install/Run: + * atest WmTests:DisplayAreaGroupTest + */ +@SmallTest +@Presubmit +@RunWith(WindowTestRunner.class) +public class DisplayAreaGroupTest extends WindowTestsBase { + + private DisplayAreaGroup mDisplayAreaGroup; + private TaskDisplayArea mTaskDisplayArea; + private Task mStack; + private ActivityRecord mActivity; + + @Before + public void setUp() { + mDisplayAreaGroup = new DisplayAreaGroup( + mWm, "DisplayAreaGroup", FEATURE_VENDOR_FIRST); + final TaskDisplayArea defaultTda = mDisplayContent.getDefaultTaskDisplayArea(); + final WindowContainer parentDA = defaultTda.getParent(); + parentDA.addChild(mDisplayAreaGroup, parentDA.mChildren.indexOf(defaultTda) + 1); + mTaskDisplayArea = new TaskDisplayArea( + mDisplayContent, mWm, "TDA1", FEATURE_VENDOR_FIRST + 1); + mDisplayAreaGroup.addChild(mTaskDisplayArea, POSITION_TOP); + mStack = mTaskDisplayArea.createStack( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); + mActivity = new ActivityBuilder(mAtm).setCreateTask(true).setStack(mStack).build(); + mDisplayContent.setLastFocusedTaskDisplayArea(mTaskDisplayArea); + } + + @Test + public void testIsOrientationDifferentFromDisplay() { + // Display is portrait, DisplayAreaGroup inherits that + mDisplayContent.setBounds(0, 0, 600, 900); + + assertThat(mDisplayAreaGroup.isOrientationDifferentFromDisplay()).isFalse(); + + // DisplayAreaGroup is landscape, different Display + mDisplayAreaGroup.setBounds(0, 0, 600, 450); + + assertThat(mDisplayAreaGroup.isOrientationDifferentFromDisplay()).isTrue(); + + // DisplayAreaGroup is portrait, same as Display + mDisplayAreaGroup.setBounds(0, 0, 300, 900); + + assertThat(mDisplayAreaGroup.isOrientationDifferentFromDisplay()).isFalse(); + } + + @Test + public void testGetOrientation() { + doReturn(true).when(mDisplayContent).onDescendantOrientationChanged(any(), any()); + mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); + + // Display is portrait, DisplayAreaGroup inherits that + mDisplayContent.setBounds(0, 0, 600, 900); + + assertThat(mDisplayAreaGroup.getOrientation()).isEqualTo(SCREEN_ORIENTATION_PORTRAIT); + assertThat(mActivity.getRequestedConfigurationOrientation()) + .isEqualTo(ORIENTATION_PORTRAIT); + + // DisplayAreaGroup is landscape, different from Display + mDisplayAreaGroup.setBounds(0, 0, 600, 450); + + assertThat(mDisplayAreaGroup.getOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE); + assertThat(mActivity.getRequestedConfigurationOrientation()) + .isEqualTo(ORIENTATION_LANDSCAPE); + + // DisplayAreaGroup is portrait, same as Display + mDisplayAreaGroup.setBounds(0, 0, 300, 900); + + assertThat(mDisplayAreaGroup.getOrientation()).isEqualTo(SCREEN_ORIENTATION_PORTRAIT); + assertThat(mActivity.getRequestedConfigurationOrientation()) + .isEqualTo(ORIENTATION_PORTRAIT); + } +} diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java index 820eca4a49a8..bc7516f6514f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.view.Display.INVALID_DISPLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; @@ -319,6 +320,29 @@ public class LaunchParamsControllerTests extends WindowTestsBase { } /** + * Ensures that {@link LaunchParamsModifier} doesn't alter non-root tasks' windowingMode. + */ + @Test + public void testLayoutNonRootTaskWindowingModeChange() { + final LaunchParams params = new LaunchParams(); + final int windowingMode = WINDOWING_MODE_FREEFORM; + params.mWindowingMode = windowingMode; + final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params); + final Task task = new TaskBuilder(mAtm.mStackSupervisor).setCreateParentTask(true).build(); + task.getRootTask().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); + + mController.registerModifier(positioner); + + final int beforeWindowMode = task.getWindowingMode(); + assertNotEquals(windowingMode, beforeWindowMode); + + mController.layoutTask(task, null /* windowLayout */); + + final int afterWindowMode = task.getWindowingMode(); + assertEquals(afterWindowMode, beforeWindowMode); + } + + /** * Ensures that {@link LaunchParamsModifier} requests specifying bounds during * layout are honored if window is in freeform. */ diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index f4f172d8e5b5..7a30c377ae09 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -1188,7 +1188,7 @@ public class RecentTasksTest extends WindowTestsBase { () -> mAtm.unregisterTaskStackListener(null)); assertSecurityException(expectCallable, () -> mAtm.getTaskDescription(0)); assertSecurityException(expectCallable, () -> mAtm.cancelTaskWindowTransition(0)); - assertSecurityException(expectCallable, () -> mAtm.startRecentsActivity(null, null, + assertSecurityException(expectCallable, () -> mAtm.startRecentsActivity(null, 0, null)); assertSecurityException(expectCallable, () -> mAtm.cancelRecentsAnimation(true)); assertSecurityException(expectCallable, () -> mAtm.stopAppSwitches()); diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java index d821d38ea297..c10d4fa7f189 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java @@ -147,7 +147,7 @@ public class RecentsAnimationTest extends WindowTestsBase { Intent recentsIntent = new Intent().setComponent(mRecentsComponent); // Null animation indicates to preload. - mAtm.startRecentsActivity(recentsIntent, null /* assistDataReceiver */, + mAtm.startRecentsActivity(recentsIntent, 0 /* eventTime */, null /* recentsAnimationRunner */); Task recentsStack = defaultTaskDisplayArea.getStack(WINDOWING_MODE_FULLSCREEN, @@ -167,7 +167,7 @@ public class RecentsAnimationTest extends WindowTestsBase { spyOn(recentsActivity); // Start when the recents activity exists. It should ensure the configuration. - mAtm.startRecentsActivity(recentsIntent, null /* assistDataReceiver */, + mAtm.startRecentsActivity(recentsIntent, 0 /* eventTime */, null /* recentsAnimationRunner */); verify(recentsActivity).ensureActivityConfiguration(anyInt() /* globalChanges */, @@ -381,7 +381,7 @@ public class RecentsAnimationTest extends WindowTestsBase { Intent recentsIntent = new Intent(); recentsIntent.setComponent(recentsComponent); - mAtm.startRecentsActivity(recentsIntent, null /* assistDataReceiver */, + mAtm.startRecentsActivity(recentsIntent, 0 /* eventTime */, mock(IRecentsAnimationRunner.class)); return recentsAnimation[0]; } diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java index d7eedd990f04..d0a5644f5025 100644 --- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java +++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java @@ -147,13 +147,6 @@ public class StubTransaction extends SurfaceControl.Transaction { } @Override - public SurfaceControl.Transaction deferTransactionUntilSurface(SurfaceControl sc, - Surface barrierSurface, - long frameNumber) { - return this; - } - - @Override public SurfaceControl.Transaction reparentChildren(SurfaceControl sc, SurfaceControl newParent) { return this; diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 7b84385aead6..12e56cc26546 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -85,8 +85,6 @@ import android.telephony.emergency.EmergencyNumber; import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories; import android.telephony.ims.ImsMmTelManager; import android.telephony.ims.aidl.IImsConfig; -import android.telephony.ims.aidl.IImsMmTelFeature; -import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; @@ -94,7 +92,6 @@ import android.text.TextUtils; import android.util.Log; import android.util.Pair; -import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.CellNetworkScanResult; @@ -7384,80 +7381,6 @@ public class TelephonyManager { } /** - * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id and MMTel - * feature or {@link null} if the service is not available. If an MMTelFeature is available, the - * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates. - * @param slotIndex The SIM slot that we are requesting the {@link IImsMmTelFeature} for. - * @param callback Listener that will send updates to ImsManager when there are updates to - * ImsServiceController. - * @return {@link IImsMmTelFeature} interface for the feature specified or {@code null} if - * it is unavailable. - * @hide - */ - public @Nullable IImsMmTelFeature getImsMmTelFeatureAndListen(int slotIndex, - IImsServiceFeatureCallback callback) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getMmTelFeatureAndListen(slotIndex, callback); - } - } catch (RemoteException e) { - Rlog.e(TAG, "getImsMmTelFeatureAndListen, RemoteException: " - + e.getMessage()); - } - return null; - } - - /** - * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id and RCS - * feature for emergency calling or {@link null} if the service is not available. If an - * RcsFeature is available, the {@link IImsServiceFeatureCallback} callback is registered as a - * listener for feature updates. - * @param slotIndex The SIM slot that we are requesting the {@link IImsRcsFeature} for. - * @param callback Listener that will send updates to ImsManager when there are updates to - * ImsServiceController. - * @return {@link IImsRcsFeature} interface for the feature specified or {@code null} if - * it is unavailable. - * @hide - */ - public @Nullable IImsRcsFeature getImsRcsFeatureAndListen(int slotIndex, - IImsServiceFeatureCallback callback) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getRcsFeatureAndListen(slotIndex, callback); - } - } catch (RemoteException e) { - Rlog.e(TAG, "getImsRcsFeatureAndListen, RemoteException: " - + e.getMessage()); - } - return null; - } - - /** - * Unregister a IImsServiceFeatureCallback previously associated with an ImsFeature through - * {@link #getImsMmTelFeatureAndListen(int, IImsServiceFeatureCallback)} or - * {@link #getImsRcsFeatureAndListen(int, IImsServiceFeatureCallback)}. - * @param slotIndex The SIM slot associated with the callback. - * @param featureType The {@link android.telephony.ims.feature.ImsFeature.FeatureType} - * associated with the callback. - * @param callback The callback to be unregistered. - * @hide - */ - public void unregisterImsFeatureCallback(int slotIndex, int featureType, - IImsServiceFeatureCallback callback) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - telephony.unregisterImsFeatureCallback(slotIndex, featureType, callback); - } - } catch (RemoteException e) { - Rlog.e(TAG, "unregisterImsFeatureCallback, RemoteException: " - + e.getMessage()); - } - } - - /** * @return the {@IImsRegistration} interface that corresponds with the slot index and feature. * @param slotIndex The SIM slot corresponding to the ImsService ImsRegistration is active for. * @param feature An integer indicating the feature that we wish to get the ImsRegistration for. diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java index f6c14e67306b..ee2fce7e7dd5 100644 --- a/telephony/java/android/telephony/ims/ImsMmTelManager.java +++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java @@ -59,6 +59,7 @@ import java.util.function.Consumer; * manager. */ public class ImsMmTelManager implements RegistrationManager { + private static final String TAG = "ImsMmTelManager"; /** * @hide @@ -809,7 +810,7 @@ public class ImsMmTelManager implements RegistrationManager { } try { - getITelephony().isMmTelCapabilitySupported(mSubId, new IIntegerConsumer.Stub() { + iTelephony.isMmTelCapabilitySupported(mSubId, new IIntegerConsumer.Stub() { @Override public void accept(int result) { executor.execute(() -> callback.accept(result == 1)); diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java index da7311c08307..8a05bdfc8401 100644 --- a/telephony/java/android/telephony/ims/ImsService.java +++ b/telephony/java/android/telephony/ims/ImsService.java @@ -16,6 +16,7 @@ package android.telephony.ims; +import android.annotation.LongDef; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.Service; @@ -41,6 +42,11 @@ import android.util.SparseArray; import com.android.ims.internal.IImsFeatureStatusCallback; import com.android.internal.annotations.VisibleForTesting; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.HashMap; +import java.util.Map; + /** * Main ImsService implementation, which binds via the Telephony ImsResolver. Services that extend * ImsService must register the service in their AndroidManifest to be detected by the framework. @@ -98,6 +104,32 @@ public class ImsService extends Service { private static final String LOG_TAG = "ImsService"; /** + * This ImsService supports the capability to place emergency calls over MMTEL. + * @hide This is encoded into the {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, but we will be + * adding other capabilities in a central location, so track this capability here as well. + */ + public static final long CAPABILITY_EMERGENCY_OVER_MMTEL = 1 << 0; + + /** + * @hide + */ + @LongDef(flag = true, + prefix = "CAPABILITY_", + value = { + CAPABILITY_EMERGENCY_OVER_MMTEL + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ImsServiceCapability {} + + /** + * Used for logging purposes, see {@link #getCapabilitiesString(long)} + * @hide + */ + private static final Map<Long, String> CAPABILITIES_LOG_MAP = new HashMap<Long, String>() {{ + put(CAPABILITY_EMERGENCY_OVER_MMTEL, "EMERGENCY_OVER_MMTEL"); + }}; + + /** * The intent that must be defined as an intent-filter in the AndroidManifest of the ImsService. * @hide */ @@ -409,4 +441,30 @@ public class ImsService extends Service { public ImsRegistrationImplBase getRegistration(int slotId) { return new ImsRegistrationImplBase(); } + + /** + * @return A string representation of the ImsService capabilties for logging. + * @hide + */ + public static String getCapabilitiesString(@ImsServiceCapability long caps) { + StringBuffer result = new StringBuffer(); + result.append("capabilities={ "); + // filter incrementally fills 0s from left to right. This is used to keep filtering out + // more bits in the long until the remaining leftmost bits are all zero. + long filter = 0xFFFFFFFFFFFFFFFFL; + // position of iterator to potentially print capability. + long i = 0; + while ((caps & filter) != 0 && i <= 63) { + long bitToCheck = (1L << i); + if ((caps & bitToCheck) != 0) { + result.append(CAPABILITIES_LOG_MAP.getOrDefault(bitToCheck, bitToCheck + "?")); + result.append(" "); + } + // shift left by one and fill in another 1 on the leftmost bit. + filter <<= 1; + i++; + } + result.append("}"); + return result.toString(); + } }
\ No newline at end of file diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl index 9e461420e126..e01ea9179452 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl @@ -22,6 +22,8 @@ import android.telephony.ims.aidl.IRcsUceControllerCallback; import android.telephony.ims.aidl.IRcsUcePublishStateCallback; import android.telephony.ims.aidl.IImsRegistrationCallback; +import com.android.ims.ImsFeatureContainer; +import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.telephony.IIntegerConsumer; /** @@ -50,4 +52,8 @@ interface IImsRcsController { void setUceSettingEnabled(int subId, boolean isEnabled); void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c); void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c); + + // Internal commands that should not be made public + void registerRcsFeatureCallback(int slotId, in IImsServiceFeatureCallback callback); + void unregisterImsFeatureCallback(in IImsServiceFeatureCallback callback); } diff --git a/packages/services/PacProcessor/jni/jni_init.cpp b/telephony/java/com/android/ims/ImsFeatureContainer.aidl index de844c87ec0b..9706f20c59ca 100644 --- a/packages/services/PacProcessor/jni/jni_init.cpp +++ b/telephony/java/com/android/ims/ImsFeatureContainer.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,25 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "PacProcessor" +package com.android.ims; -#include <utils/Log.h> -#include "jni.h" - -namespace android { - extern int register_com_android_pacprocessor_PacNative(JNIEnv *env); -} - -using namespace android; - -extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { - JNIEnv *env; - if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { - ALOGE("ERROR: GetEnv failed"); - return -1; - } - - register_com_android_pacprocessor_PacNative(env); - - return JNI_VERSION_1_6; -} +parcelable ImsFeatureContainer;
\ No newline at end of file diff --git a/telephony/java/com/android/ims/ImsFeatureContainer.java b/telephony/java/com/android/ims/ImsFeatureContainer.java new file mode 100644 index 000000000000..b259679ea1bf --- /dev/null +++ b/telephony/java/com/android/ims/ImsFeatureContainer.java @@ -0,0 +1,172 @@ +/* + * 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.ims; + +import android.annotation.NonNull; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.ims.ImsService; +import android.telephony.ims.aidl.IImsConfig; +import android.telephony.ims.aidl.IImsRegistration; +import android.telephony.ims.feature.ImsFeature; + +import java.util.Objects; + +/** + * Contains an IBinder linking to the appropriate ImsFeature as well as the associated + * interfaces. + * @hide + */ +public final class ImsFeatureContainer implements Parcelable { + /** + * ImsFeature that is being tracked. + */ + public final IBinder imsFeature; + + /** + * IImsConfig interface that should be associated with the ImsFeature. + */ + public final android.telephony.ims.aidl.IImsConfig imsConfig; + + /** + * IImsRegistration interface that should be associated with this ImsFeature. + */ + public final IImsRegistration imsRegistration; + + /** + * State of the feature that is being tracked. + */ + private @ImsFeature.ImsState int mState = ImsFeature.STATE_UNAVAILABLE; + + /** + * Capabilities of this ImsService. + */ + private @ImsService.ImsServiceCapability long mCapabilities; + /** + * Contains the ImsFeature IBinder as well as the ImsService interfaces associated with + * that feature. + * @param iFace IBinder connection to the ImsFeature. + * @param iConfig IImsConfig interface associated with the ImsFeature. + * @param iReg IImsRegistration interface associated with the ImsFeature + * @param initialCaps The initial capabilities that the ImsService supports. + */ + public ImsFeatureContainer(@NonNull IBinder iFace, @NonNull IImsConfig iConfig, + @NonNull IImsRegistration iReg, long initialCaps) { + imsFeature = iFace; + imsConfig = iConfig; + imsRegistration = iReg; + mCapabilities = initialCaps; + } + + /** + * Create an ImsFeatureContainer from a Parcel. + */ + private ImsFeatureContainer(Parcel in) { + imsFeature = in.readStrongBinder(); + imsConfig = IImsConfig.Stub.asInterface(in.readStrongBinder()); + imsRegistration = IImsRegistration.Stub.asInterface(in.readStrongBinder()); + mState = in.readInt(); + mCapabilities = in.readLong(); + } + + /** + * @return the capabilties that are associated with the ImsService that this ImsFeature + * belongs to. + */ + public @ImsService.ImsServiceCapability long getCapabilities() { + return mCapabilities; + } + + /** + * Update the capabilities that are associated with the ImsService that this ImsFeature + * belongs to. + */ + public void setCapabilities(@ImsService.ImsServiceCapability long caps) { + mCapabilities = caps; + } + + /** + * @return The state of the ImsFeature. + */ + public @ImsFeature.ImsState int getState() { + return mState; + } + + /** + * Set the state that is associated with the ImsService that this ImsFeature + * belongs to. + */ + public void setState(@ImsFeature.ImsState int state) { + mState = state; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ImsFeatureContainer that = (ImsFeatureContainer) o; + return imsFeature.equals(that.imsFeature) && + imsConfig.equals(that.imsConfig) && + imsRegistration.equals(that.imsRegistration) && + mState == that.getState() && + mCapabilities == that.getCapabilities(); + } + + @Override + public int hashCode() { + return Objects.hash(imsFeature, imsConfig, imsRegistration, mState, mCapabilities); + } + + @Override + public String toString() { + return "FeatureContainer{" + + "imsFeature=" + imsFeature + + ", imsConfig=" + imsConfig + + ", imsRegistration=" + imsRegistration + + ", state=" + ImsFeature.STATE_LOG_MAP.get(mState) + + ", capabilities = " + ImsService.getCapabilitiesString(mCapabilities) + + '}'; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeStrongBinder(imsFeature); + dest.writeStrongInterface(imsConfig); + dest.writeStrongInterface(imsRegistration); + dest.writeInt(mState); + dest.writeLong(mCapabilities); + } + + + public static final Creator<ImsFeatureContainer> CREATOR = new Creator<ImsFeatureContainer>() { + @Override + public ImsFeatureContainer createFromParcel(Parcel source) { + return new ImsFeatureContainer(source); + } + + @Override + public ImsFeatureContainer[] newArray(int size) { + return new ImsFeatureContainer[size]; + } + }; +} diff --git a/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl index 9a9cf5325310..f5f67bd36ec3 100644 --- a/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl +++ b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl @@ -16,13 +16,18 @@ package com.android.ims.internal; +import com.android.ims.ImsFeatureContainer; /** - * Interface from ImsResolver to ImsServiceProxy in ImsManager. - * Callback to ImsManager when a feature changes in the ImsServiceController. + * Interface from ImsResolver to FeatureConnections. + * Callback to FeatureConnections when a feature's status changes. * {@hide} */ oneway interface IImsServiceFeatureCallback { - void imsFeatureCreated(int slotId, int feature); - void imsFeatureRemoved(int slotId, int feature); - void imsStatusChanged(int slotId, int feature, int status); + void imsFeatureCreated(in ImsFeatureContainer feature); + // Reason defined in FeatureConnector.UnavailableReason + void imsFeatureRemoved(int reason); + // Status defined in ImsFeature.ImsState. + void imsStatusChanged(int status); + //Capabilities defined in ImsService.ImsServiceCapability + void updateCapabilities(long capabilities); }
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index d67384c6f582..53069a1691a0 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -829,22 +829,14 @@ interface ITelephony { * as well as registering the MmTelFeature for callbacks using the IImsServiceFeatureCallback * interface. */ - IImsMmTelFeature getMmTelFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback); - - /** - * Get IImsRcsFeature binder from ImsResolver that corresponds to the subId and RCS feature - * as well as registering the RcsFeature for callbacks using the IImsServiceFeatureCallback - * interface. - */ - IImsRcsFeature getRcsFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback); + void registerMmTelFeatureCallback(int slotId, in IImsServiceFeatureCallback callback); /** * Unregister a callback that was previously registered through - * {@link #getMmTelFeatureAndListen} or {@link #getRcsFeatureAndListen}. This should always be - * called when the callback is no longer being used. + * {@link #registerMmTelFeatureCallback}. This should always be called when the callback is no + * longer being used. */ - void unregisterImsFeatureCallback(int slotId, int featureType, - in IImsServiceFeatureCallback callback); + void unregisterImsFeatureCallback(in IImsServiceFeatureCallback callback); /** * Returns the IImsRegistration associated with the slot and feature specified. diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java index 030ddd2792bb..3c3076f11727 100644 --- a/tests/net/common/java/android/net/LinkPropertiesTest.java +++ b/tests/net/common/java/android/net/LinkPropertiesTest.java @@ -32,6 +32,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.net.LinkProperties.ProvisioningChange; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.os.Build; import android.system.OsConstants; import android.util.ArraySet; @@ -40,7 +41,6 @@ import androidx.core.os.BuildCompat; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.net.module.util.LinkPropertiesUtils.CompareResult; import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java index 6de31f6b4be1..91c9a2a38036 100644 --- a/tests/net/java/android/net/MacAddressTest.java +++ b/tests/net/java/android/net/MacAddressTest.java @@ -22,11 +22,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.net.util.MacAddressUtils; + import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.net.module.util.MacAddressUtils; - import org.junit.Test; import org.junit.runner.RunWith; diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl index cf2cb4ae5eb4..57055f78d03d 100644 --- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl +++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.net.wifi.p2p.servicediscovery; +package android.net.wifi.p2p.nsd; parcelable WifiP2pServiceInfo; diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl index d5a1e8f505a9..e4d28bb2d39f 100644 --- a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl +++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.net.wifi.p2p.servicediscovery; +package android.net.wifi.p2p.nsd; parcelable WifiP2pServiceRequest; diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index a4f802a28cb7..fc6c59a882cf 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -29,6 +29,7 @@ import android.net.NetworkSpecifier; import android.net.ProxyInfo; import android.net.StaticIpConfiguration; import android.net.Uri; +import android.net.util.MacAddressUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -40,7 +41,6 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; -import com.android.net.module.util.MacAddressUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java index e2f40cfa058c..dad431c1ca2c 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java @@ -17,11 +17,10 @@ package android.net.wifi.p2p.nsd; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.nsd.DnsSdTxtRecord; import android.os.Build; import android.text.TextUtils; -import com.android.net.module.util.DnsSdTxtRecord; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 6894ba074f51..8af75002c029 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -33,14 +33,13 @@ import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import android.net.MacAddress; +import android.net.util.MacAddressUtils; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; import android.os.Parcel; import androidx.test.filters.SmallTest; -import com.android.net.module.util.MacAddressUtils; - import org.junit.Before; import org.junit.Test; |