diff options
1276 files changed, 17930 insertions, 11750 deletions
diff --git a/Android.bp b/Android.bp index 586350df36b1..6b55cc9f5ea8 100644 --- a/Android.bp +++ b/Android.bp @@ -380,9 +380,6 @@ filegroup { // etc. ":framework-javastream-protos", ":statslog-framework-java-gen", // FrameworkStatsLog.java - - // telephony annotations - ":framework-telephony-annotations", ], } @@ -636,6 +633,7 @@ java_library { "//frameworks/base/apex/blobstore/framework", "//frameworks/base/apex/jobscheduler/framework", "//frameworks/base/packages/Tethering/tests/unit", + "//packages/modules/Connectivity/Tethering/tests/unit", ], errorprone: { javacflags: [ @@ -1270,23 +1268,6 @@ filegroup { } // Avoid including Parcelable classes as we don't want to have two copies of -// Parcelable cross the process. This is used by framework-telephony (frameworks/base/telephony). -filegroup { - name: "framework-telephony-shared-srcs", - srcs: [ - "core/java/android/util/IndentingPrintWriter.java", - "core/java/android/util/RecurrenceRule.java", - "core/java/com/android/internal/os/SomeArgs.java", - "core/java/com/android/internal/util/BitwiseInputStream.java", - "core/java/com/android/internal/util/BitwiseOutputStream.java", - "core/java/com/android/internal/util/FunctionalUtils.java", - "core/java/com/android/internal/util/HexDump.java", - "core/java/com/android/internal/util/IndentingPrintWriter.java", - "core/java/com/android/internal/util/Preconditions.java", - ], -} - -// Avoid including Parcelable classes as we don't want to have two copies of // Parcelable cross the process. filegroup { name: "framework-cellbroadcast-shared-srcs", @@ -1314,7 +1295,7 @@ filegroup { // into wifi-service java_library { name: "framework-wifi-util-lib", - sdk_version: "module_current", + sdk_version: "module_30", srcs: [ "core/java/android/content/pm/BaseParceledListSlice.java", "core/java/android/content/pm/ParceledListSlice.java", @@ -1383,73 +1364,6 @@ build = [ "ApiDocs.bp", ] -// TODO(b/147699819): move to frameworks/base/telephony/ folder -droidstubs { - name: "framework-telephony-stubs-srcs", - srcs: [ - ":framework-telephony-sources", - ":framework_native_aidl", - ":framework-javastream-protos", - ], - aidl: { - local_include_dirs: [ - "core/java", - "telecomm/java" - ], - }, - libs: [ - "framework-annotations-lib", - "android.hardware.radio-V1.6-java", - ], - check_api: { - current: { - // TODO(b/147699819): remove telephony prefix when moved - api_file: "telephony/api/system-current.txt", - removed_api_file: "telephony/api/system-removed.txt", - }, - }, - // TODO: make telephony inherit the shared stubs and remove this - args: "--show-annotation android.annotation.SystemApi\\(" + - "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + - "\\) " + - "--error UnhiddenSystemApi " + - "--hide BroadcastBehavior " + - "--hide DeprecationMismatch " + - "--hide HiddenSuperclass " + - "--hide HiddenTypedefConstant " + - "--hide HiddenTypeParameter " + - "--hide MissingPermission " + - "--hide RequiresPermission " + - "--hide SdkConstant " + - "--hide Todo " + - "--hide Typo " + - "--hide UnavailableSymbol ", - filter_packages: ["android.telephony"], - sdk_version: "system_current", -} - -java_library { - name: "framework-telephony-stubs", - srcs: [":framework-telephony-stubs-srcs"], - // TODO(b/147699819): move public aidls to a separate folder and potentially remove - // below aidl exports. - aidl: { - export_include_dirs: ["telephony/java"], - }, - sdk_version: "module_current", -} - -filegroup { - // TODO (b/147690217): move to frameworks/base/telephony/common. - name: "framework-telephony-annotations", - srcs: ["telephony/java/android/telephony/Annotation.java"], -} - -filegroup { - name: "framework-telephony-jarjar-rules", - srcs: ["telephony/framework-telephony-jarjar-rules.txt"], -} - // protolog start filegroup { name: "protolog-common-src", diff --git a/StubLibraries.bp b/StubLibraries.bp index 9604466a0edd..754c4e94e73a 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -77,6 +77,7 @@ stubs_defaults { "android.hardware.vibrator-V1.3-java", "framework-protos", ], + high_mem: true, // Lots of sources => high memory use, see b/170701554 installable: false, annotations_enabled: true, previous_api: ":android.api.public.latest", diff --git a/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl b/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl index 6f624ee672e6..2c51935dc446 100644 --- a/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl +++ b/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl @@ -29,16 +29,16 @@ import android.os.WorkSource; */ interface IAlarmManager { /** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void set(String callingPackage, int type, long triggerAtTime, long windowLength, long interval, int flags, in PendingIntent operation, in IAlarmListener listener, String listenerTag, in WorkSource workSource, in AlarmManager.AlarmClockInfo alarmClock); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean setTime(long millis); void setTimeZone(String zone); void remove(in PendingIntent operation, in IAlarmListener listener); long getNextWakeFromIdleTime(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) AlarmManager.AlarmClockInfo getNextAlarmClock(int userId); long currentNetworkTimeMillis(); } diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java index 9f98f8efc774..c2d530d00058 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java @@ -210,7 +210,7 @@ public class JobInfo implements Parcelable { public static final int PRIORITY_BOUND_FOREGROUND_SERVICE = 30; /** @hide For backward compatibility. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PRIORITY_FOREGROUND_APP = PRIORITY_BOUND_FOREGROUND_SERVICE; /** @@ -218,7 +218,7 @@ public class JobInfo implements Parcelable { * JobInfo priority if it is smaller). * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PRIORITY_FOREGROUND_SERVICE = 35; /** @@ -257,7 +257,7 @@ public class JobInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int FLAG_WILL_BE_FOREGROUND = 1 << 0; /** @@ -1007,14 +1007,14 @@ public class JobInfo implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Builder setPriority(int priority) { mPriority = priority; return this; } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Builder setFlags(int flags) { mFlags = flags; return this; diff --git a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl index 643d47ca5c6a..7d02d2d6cd29 100644 --- a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl +++ b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl @@ -31,13 +31,13 @@ interface IDeviceIdleController { String[] getSystemPowerWhitelistExceptIdle(); String[] getSystemPowerWhitelist(); String[] getUserPowerWhitelist(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String[] getFullPowerWhitelistExceptIdle(); String[] getFullPowerWhitelist(); int[] getAppIdWhitelistExceptIdle(); int[] getAppIdWhitelist(); int[] getAppIdUserWhitelist(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int[] getAppIdTempWhitelist(); boolean isPowerSaveWhitelistExceptIdleApp(String name); boolean isPowerSaveWhitelistApp(String name); diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index 6c14233dba13..34e82b0ce45e 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -339,6 +339,11 @@ public class JobSchedulerService extends com.android.server.SystemService public void onPropertiesChanged(DeviceConfig.Properties properties) { boolean apiQuotaScheduleUpdated = false; boolean concurrencyUpdated = false; + for (int controller = 0; controller < mControllers.size(); controller++) { + final StateController sc = mControllers.get(controller); + sc.prepareForUpdatedConstantsLocked(); + } + synchronized (mLock) { for (String name : properties.getKeyset()) { if (name == null) { @@ -384,6 +389,11 @@ public class JobSchedulerService extends com.android.server.SystemService && !concurrencyUpdated) { mConstants.updateConcurrencyConstantsLocked(); concurrencyUpdated = true; + } else { + for (int ctrlr = 0; ctrlr < mControllers.size(); ctrlr++) { + final StateController sc = mControllers.get(ctrlr); + sc.processConstantLocked(properties, name); + } } break; } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index c7cc2f03b062..00dbb8235d29 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -1388,6 +1388,11 @@ public final class JobStatus { } if (isReady()) { sb.append(" READY"); + } else { + sb.append(" satisfied:0x").append(Integer.toHexString(satisfiedConstraints)); + sb.append(" unsatisfied:0x").append(Integer.toHexString( + (satisfiedConstraints & mRequiredConstraintsOfInterest) + ^ mRequiredConstraintsOfInterest)); } sb.append("}"); return sb.toString(); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java index c06e19cbf687..b7ace70f0cd4 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java @@ -37,12 +37,9 @@ import android.app.AlarmManager; import android.app.AppGlobals; import android.app.IUidObserver; import android.content.BroadcastReceiver; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.database.ContentObserver; -import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.os.Handler; @@ -50,10 +47,9 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.UserHandle; -import android.provider.Settings; +import android.provider.DeviceConfig; import android.util.ArraySet; import android.util.IndentingPrintWriter; -import android.util.KeyValueListParser; import android.util.Log; import android.util.Pair; import android.util.Slog; @@ -494,7 +490,7 @@ public final class QuotaController extends StateController { mChargeTracker.startTracking(); mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); - mQcConstants = new QcConstants(mHandler); + mQcConstants = new QcConstants(); final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); mContext.registerReceiverAsUser(mPackageAddedReceiver, UserHandle.ALL, filter, null, null); @@ -513,11 +509,6 @@ public final class QuotaController extends StateController { } @Override - public void onSystemServicesReady() { - mQcConstants.start(mContext.getContentResolver()); - } - - @Override public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) { final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); @@ -2028,38 +2019,109 @@ public final class QuotaController extends StateController { } } + @Override + public void prepareForUpdatedConstantsLocked() { + mQcConstants.mShouldReevaluateConstraints = false; + mQcConstants.mRateLimitingConstantsUpdated = false; + mQcConstants.mExecutionPeriodConstantsUpdated = false; + } + + @Override + public void processConstantLocked(DeviceConfig.Properties properties, String key) { + mQcConstants.processConstantLocked(properties, key); + } + + @Override + public void onConstantsUpdatedLocked() { + if (mQcConstants.mShouldReevaluateConstraints) { + // Update job bookkeeping out of band. + JobSchedulerBackgroundThread.getHandler().post(() -> { + synchronized (mLock) { + invalidateAllExecutionStatsLocked(); + maybeUpdateAllConstraintsLocked(); + } + }); + } + } + @VisibleForTesting - class QcConstants extends ContentObserver { - private ContentResolver mResolver; - private final KeyValueListParser mParser = new KeyValueListParser(','); - - private static final String KEY_ALLOWED_TIME_PER_PERIOD_MS = "allowed_time_per_period_ms"; - private static final String KEY_IN_QUOTA_BUFFER_MS = "in_quota_buffer_ms"; - private static final String KEY_WINDOW_SIZE_ACTIVE_MS = "window_size_active_ms"; - private static final String KEY_WINDOW_SIZE_WORKING_MS = "window_size_working_ms"; - private static final String KEY_WINDOW_SIZE_FREQUENT_MS = "window_size_frequent_ms"; - private static final String KEY_WINDOW_SIZE_RARE_MS = "window_size_rare_ms"; - private static final String KEY_WINDOW_SIZE_RESTRICTED_MS = "window_size_restricted_ms"; - private static final String KEY_MAX_EXECUTION_TIME_MS = "max_execution_time_ms"; - private static final String KEY_MAX_JOB_COUNT_ACTIVE = "max_job_count_active"; - private static final String KEY_MAX_JOB_COUNT_WORKING = "max_job_count_working"; - private static final String KEY_MAX_JOB_COUNT_FREQUENT = "max_job_count_frequent"; - private static final String KEY_MAX_JOB_COUNT_RARE = "max_job_count_rare"; - private static final String KEY_MAX_JOB_COUNT_RESTRICTED = "max_job_count_restricted"; - private static final String KEY_RATE_LIMITING_WINDOW_MS = "rate_limiting_window_ms"; - private static final String KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW = - "max_job_count_per_rate_limiting_window"; - private static final String KEY_MAX_SESSION_COUNT_ACTIVE = "max_session_count_active"; - private static final String KEY_MAX_SESSION_COUNT_WORKING = "max_session_count_working"; - private static final String KEY_MAX_SESSION_COUNT_FREQUENT = "max_session_count_frequent"; - private static final String KEY_MAX_SESSION_COUNT_RARE = "max_session_count_rare"; - private static final String KEY_MAX_SESSION_COUNT_RESTRICTED = - "max_session_count_restricted"; - private static final String KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = - "max_session_count_per_rate_limiting_window"; - private static final String KEY_TIMING_SESSION_COALESCING_DURATION_MS = - "timing_session_coalescing_duration_ms"; - private static final String KEY_MIN_QUOTA_CHECK_DELAY_MS = "min_quota_check_delay_ms"; + class QcConstants { + private boolean mShouldReevaluateConstraints = false; + private boolean mRateLimitingConstantsUpdated = false; + private boolean mExecutionPeriodConstantsUpdated = false; + + /** Prefix to use with all constant keys in order to "sub-namespace" the keys. */ + private static final String QC_CONSTANT_PREFIX = "qc_"; + + @VisibleForTesting + static final String KEY_ALLOWED_TIME_PER_PERIOD_MS = + QC_CONSTANT_PREFIX + "allowed_time_per_period_ms"; + @VisibleForTesting + static final String KEY_IN_QUOTA_BUFFER_MS = + QC_CONSTANT_PREFIX + "in_quota_buffer_ms"; + @VisibleForTesting + static final String KEY_WINDOW_SIZE_ACTIVE_MS = + QC_CONSTANT_PREFIX + "window_size_active_ms"; + @VisibleForTesting + static final String KEY_WINDOW_SIZE_WORKING_MS = + QC_CONSTANT_PREFIX + "window_size_working_ms"; + @VisibleForTesting + static final String KEY_WINDOW_SIZE_FREQUENT_MS = + QC_CONSTANT_PREFIX + "window_size_frequent_ms"; + @VisibleForTesting + static final String KEY_WINDOW_SIZE_RARE_MS = + QC_CONSTANT_PREFIX + "window_size_rare_ms"; + @VisibleForTesting + static final String KEY_WINDOW_SIZE_RESTRICTED_MS = + QC_CONSTANT_PREFIX + "window_size_restricted_ms"; + @VisibleForTesting + static final String KEY_MAX_EXECUTION_TIME_MS = + QC_CONSTANT_PREFIX + "max_execution_time_ms"; + @VisibleForTesting + static final String KEY_MAX_JOB_COUNT_ACTIVE = + QC_CONSTANT_PREFIX + "max_job_count_active"; + @VisibleForTesting + static final String KEY_MAX_JOB_COUNT_WORKING = + QC_CONSTANT_PREFIX + "max_job_count_working"; + @VisibleForTesting + static final String KEY_MAX_JOB_COUNT_FREQUENT = + QC_CONSTANT_PREFIX + "max_job_count_frequent"; + @VisibleForTesting + static final String KEY_MAX_JOB_COUNT_RARE = + QC_CONSTANT_PREFIX + "max_job_count_rare"; + @VisibleForTesting + static final String KEY_MAX_JOB_COUNT_RESTRICTED = + QC_CONSTANT_PREFIX + "max_job_count_restricted"; + @VisibleForTesting + static final String KEY_RATE_LIMITING_WINDOW_MS = + QC_CONSTANT_PREFIX + "rate_limiting_window_ms"; + @VisibleForTesting + static final String KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW = + QC_CONSTANT_PREFIX + "max_job_count_per_rate_limiting_window"; + @VisibleForTesting + static final String KEY_MAX_SESSION_COUNT_ACTIVE = + QC_CONSTANT_PREFIX + "max_session_count_active"; + @VisibleForTesting + static final String KEY_MAX_SESSION_COUNT_WORKING = + QC_CONSTANT_PREFIX + "max_session_count_working"; + @VisibleForTesting + static final String KEY_MAX_SESSION_COUNT_FREQUENT = + QC_CONSTANT_PREFIX + "max_session_count_frequent"; + @VisibleForTesting + static final String KEY_MAX_SESSION_COUNT_RARE = + QC_CONSTANT_PREFIX + "max_session_count_rare"; + @VisibleForTesting + static final String KEY_MAX_SESSION_COUNT_RESTRICTED = + QC_CONSTANT_PREFIX + "max_session_count_restricted"; + @VisibleForTesting + static final String KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = + QC_CONSTANT_PREFIX + "max_session_count_per_rate_limiting_window"; + @VisibleForTesting + static final String KEY_TIMING_SESSION_COALESCING_DURATION_MS = + QC_CONSTANT_PREFIX + "timing_session_coalescing_duration_ms"; + @VisibleForTesting + static final String KEY_MIN_QUOTA_CHECK_DELAY_MS = + QC_CONSTANT_PREFIX + "min_quota_check_delay_ms"; private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_MS = 10 * 60 * 1000L; // 10 minutes @@ -2260,238 +2322,273 @@ public final class QuotaController extends StateController { /** The minimum value that {@link #RATE_LIMITING_WINDOW_MS} can have. */ private static final long MIN_RATE_LIMITING_WINDOW_MS = 30 * SECOND_IN_MILLIS; - QcConstants(Handler handler) { - super(handler); - } + public void processConstantLocked(@NonNull DeviceConfig.Properties properties, + @NonNull String key) { + switch (key) { + case KEY_ALLOWED_TIME_PER_PERIOD_MS: + case KEY_IN_QUOTA_BUFFER_MS: + case KEY_MAX_EXECUTION_TIME_MS: + case KEY_WINDOW_SIZE_ACTIVE_MS: + case KEY_WINDOW_SIZE_WORKING_MS: + case KEY_WINDOW_SIZE_FREQUENT_MS: + case KEY_WINDOW_SIZE_RARE_MS: + case KEY_WINDOW_SIZE_RESTRICTED_MS: + updateExecutionPeriodConstantsLocked(); + break; - private void start(ContentResolver resolver) { - mResolver = resolver; - mResolver.registerContentObserver(Settings.Global.getUriFor( - Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS), false, this); - onChange(true, null); - } + case KEY_RATE_LIMITING_WINDOW_MS: + case KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW: + case KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW: + updateRateLimitingConstantsLocked(); + break; - @Override - public void onChange(boolean selfChange, Uri uri) { - final String constants = Settings.Global.getString( - mResolver, Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS); - - try { - mParser.setString(constants); - } catch (Exception e) { - // Failed to parse the settings string, log this and move on with defaults. - Slog.e(TAG, "Bad jobscheduler quota controller settings", e); - } - - ALLOWED_TIME_PER_PERIOD_MS = mParser.getDurationMillis( - KEY_ALLOWED_TIME_PER_PERIOD_MS, DEFAULT_ALLOWED_TIME_PER_PERIOD_MS); - IN_QUOTA_BUFFER_MS = mParser.getDurationMillis( - KEY_IN_QUOTA_BUFFER_MS, DEFAULT_IN_QUOTA_BUFFER_MS); - WINDOW_SIZE_ACTIVE_MS = mParser.getDurationMillis( - KEY_WINDOW_SIZE_ACTIVE_MS, DEFAULT_WINDOW_SIZE_ACTIVE_MS); - WINDOW_SIZE_WORKING_MS = mParser.getDurationMillis( - KEY_WINDOW_SIZE_WORKING_MS, DEFAULT_WINDOW_SIZE_WORKING_MS); - WINDOW_SIZE_FREQUENT_MS = mParser.getDurationMillis( - KEY_WINDOW_SIZE_FREQUENT_MS, DEFAULT_WINDOW_SIZE_FREQUENT_MS); - WINDOW_SIZE_RARE_MS = mParser.getDurationMillis( - KEY_WINDOW_SIZE_RARE_MS, DEFAULT_WINDOW_SIZE_RARE_MS); - WINDOW_SIZE_RESTRICTED_MS = mParser.getDurationMillis( - KEY_WINDOW_SIZE_RESTRICTED_MS, DEFAULT_WINDOW_SIZE_RESTRICTED_MS); - MAX_EXECUTION_TIME_MS = mParser.getDurationMillis( - KEY_MAX_EXECUTION_TIME_MS, DEFAULT_MAX_EXECUTION_TIME_MS); - MAX_JOB_COUNT_ACTIVE = mParser.getInt( - KEY_MAX_JOB_COUNT_ACTIVE, DEFAULT_MAX_JOB_COUNT_ACTIVE); - MAX_JOB_COUNT_WORKING = mParser.getInt( - KEY_MAX_JOB_COUNT_WORKING, DEFAULT_MAX_JOB_COUNT_WORKING); - MAX_JOB_COUNT_FREQUENT = mParser.getInt( - KEY_MAX_JOB_COUNT_FREQUENT, DEFAULT_MAX_JOB_COUNT_FREQUENT); - MAX_JOB_COUNT_RARE = mParser.getInt( - KEY_MAX_JOB_COUNT_RARE, DEFAULT_MAX_JOB_COUNT_RARE); - MAX_JOB_COUNT_RESTRICTED = mParser.getInt( - KEY_MAX_JOB_COUNT_RESTRICTED, DEFAULT_MAX_JOB_COUNT_RESTRICTED); - RATE_LIMITING_WINDOW_MS = mParser.getLong( - KEY_RATE_LIMITING_WINDOW_MS, DEFAULT_RATE_LIMITING_WINDOW_MS); - MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW = mParser.getInt( - KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, - DEFAULT_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW); - MAX_SESSION_COUNT_ACTIVE = mParser.getInt( - KEY_MAX_SESSION_COUNT_ACTIVE, DEFAULT_MAX_SESSION_COUNT_ACTIVE); - MAX_SESSION_COUNT_WORKING = mParser.getInt( - KEY_MAX_SESSION_COUNT_WORKING, DEFAULT_MAX_SESSION_COUNT_WORKING); - MAX_SESSION_COUNT_FREQUENT = mParser.getInt( - KEY_MAX_SESSION_COUNT_FREQUENT, DEFAULT_MAX_SESSION_COUNT_FREQUENT); - MAX_SESSION_COUNT_RARE = mParser.getInt( - KEY_MAX_SESSION_COUNT_RARE, DEFAULT_MAX_SESSION_COUNT_RARE); - MAX_SESSION_COUNT_RESTRICTED = mParser.getInt( - KEY_MAX_SESSION_COUNT_RESTRICTED, DEFAULT_MAX_SESSION_COUNT_RESTRICTED); - MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = mParser.getInt( - KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW, - DEFAULT_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW); - TIMING_SESSION_COALESCING_DURATION_MS = mParser.getLong( - KEY_TIMING_SESSION_COALESCING_DURATION_MS, - DEFAULT_TIMING_SESSION_COALESCING_DURATION_MS); - MIN_QUOTA_CHECK_DELAY_MS = mParser.getDurationMillis(KEY_MIN_QUOTA_CHECK_DELAY_MS, - DEFAULT_MIN_QUOTA_CHECK_DELAY_MS); - - updateConstants(); + case KEY_MAX_JOB_COUNT_ACTIVE: + MAX_JOB_COUNT_ACTIVE = properties.getInt(key, DEFAULT_MAX_JOB_COUNT_ACTIVE); + int newActiveMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_ACTIVE); + if (mMaxBucketJobCounts[ACTIVE_INDEX] != newActiveMaxJobCount) { + mMaxBucketJobCounts[ACTIVE_INDEX] = newActiveMaxJobCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MAX_JOB_COUNT_WORKING: + MAX_JOB_COUNT_WORKING = properties.getInt(key, DEFAULT_MAX_JOB_COUNT_WORKING); + int newWorkingMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, + MAX_JOB_COUNT_WORKING); + if (mMaxBucketJobCounts[WORKING_INDEX] != newWorkingMaxJobCount) { + mMaxBucketJobCounts[WORKING_INDEX] = newWorkingMaxJobCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MAX_JOB_COUNT_FREQUENT: + MAX_JOB_COUNT_FREQUENT = properties.getInt(key, DEFAULT_MAX_JOB_COUNT_FREQUENT); + int newFrequentMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, + MAX_JOB_COUNT_FREQUENT); + if (mMaxBucketJobCounts[FREQUENT_INDEX] != newFrequentMaxJobCount) { + mMaxBucketJobCounts[FREQUENT_INDEX] = newFrequentMaxJobCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MAX_JOB_COUNT_RARE: + MAX_JOB_COUNT_RARE = properties.getInt(key, DEFAULT_MAX_JOB_COUNT_RARE); + int newRareMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_RARE); + if (mMaxBucketJobCounts[RARE_INDEX] != newRareMaxJobCount) { + mMaxBucketJobCounts[RARE_INDEX] = newRareMaxJobCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MAX_JOB_COUNT_RESTRICTED: + MAX_JOB_COUNT_RESTRICTED = + properties.getInt(key, DEFAULT_MAX_JOB_COUNT_RESTRICTED); + int newRestrictedMaxJobCount = + Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_RESTRICTED); + if (mMaxBucketJobCounts[RESTRICTED_INDEX] != newRestrictedMaxJobCount) { + mMaxBucketJobCounts[RESTRICTED_INDEX] = newRestrictedMaxJobCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MAX_SESSION_COUNT_ACTIVE: + MAX_SESSION_COUNT_ACTIVE = + properties.getInt(key, DEFAULT_MAX_SESSION_COUNT_ACTIVE); + int newActiveMaxSessionCount = + Math.max(MIN_BUCKET_SESSION_COUNT, MAX_SESSION_COUNT_ACTIVE); + if (mMaxBucketSessionCounts[ACTIVE_INDEX] != newActiveMaxSessionCount) { + mMaxBucketSessionCounts[ACTIVE_INDEX] = newActiveMaxSessionCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MAX_SESSION_COUNT_WORKING: + MAX_SESSION_COUNT_WORKING = + properties.getInt(key, DEFAULT_MAX_SESSION_COUNT_WORKING); + int newWorkingMaxSessionCount = + Math.max(MIN_BUCKET_SESSION_COUNT, MAX_SESSION_COUNT_WORKING); + if (mMaxBucketSessionCounts[WORKING_INDEX] != newWorkingMaxSessionCount) { + mMaxBucketSessionCounts[WORKING_INDEX] = newWorkingMaxSessionCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MAX_SESSION_COUNT_FREQUENT: + MAX_SESSION_COUNT_FREQUENT = + properties.getInt(key, DEFAULT_MAX_SESSION_COUNT_FREQUENT); + int newFrequentMaxSessionCount = + Math.max(MIN_BUCKET_SESSION_COUNT, MAX_SESSION_COUNT_FREQUENT); + if (mMaxBucketSessionCounts[FREQUENT_INDEX] != newFrequentMaxSessionCount) { + mMaxBucketSessionCounts[FREQUENT_INDEX] = newFrequentMaxSessionCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MAX_SESSION_COUNT_RARE: + MAX_SESSION_COUNT_RARE = properties.getInt(key, DEFAULT_MAX_SESSION_COUNT_RARE); + int newRareMaxSessionCount = + Math.max(MIN_BUCKET_SESSION_COUNT, MAX_SESSION_COUNT_RARE); + if (mMaxBucketSessionCounts[RARE_INDEX] != newRareMaxSessionCount) { + mMaxBucketSessionCounts[RARE_INDEX] = newRareMaxSessionCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MAX_SESSION_COUNT_RESTRICTED: + MAX_SESSION_COUNT_RESTRICTED = + properties.getInt(key, DEFAULT_MAX_SESSION_COUNT_RESTRICTED); + int newRestrictedMaxSessionCount = Math.max(0, MAX_SESSION_COUNT_RESTRICTED); + if (mMaxBucketSessionCounts[RESTRICTED_INDEX] != newRestrictedMaxSessionCount) { + mMaxBucketSessionCounts[RESTRICTED_INDEX] = newRestrictedMaxSessionCount; + mShouldReevaluateConstraints = true; + } + break; + case KEY_TIMING_SESSION_COALESCING_DURATION_MS: + TIMING_SESSION_COALESCING_DURATION_MS = + properties.getLong(key, DEFAULT_TIMING_SESSION_COALESCING_DURATION_MS); + long newSessionCoalescingDurationMs = Math.min(15 * MINUTE_IN_MILLIS, + Math.max(0, TIMING_SESSION_COALESCING_DURATION_MS)); + if (mTimingSessionCoalescingDurationMs != newSessionCoalescingDurationMs) { + mTimingSessionCoalescingDurationMs = newSessionCoalescingDurationMs; + mShouldReevaluateConstraints = true; + } + break; + case KEY_MIN_QUOTA_CHECK_DELAY_MS: + MIN_QUOTA_CHECK_DELAY_MS = + properties.getLong(key, DEFAULT_MIN_QUOTA_CHECK_DELAY_MS); + // We don't need to re-evaluate execution stats or constraint status for this. + // Limit the delay to the range [0, 15] minutes. + mInQuotaAlarmListener.setMinQuotaCheckDelayMs( + Math.min(15 * MINUTE_IN_MILLIS, Math.max(0, MIN_QUOTA_CHECK_DELAY_MS))); + break; + } } - @VisibleForTesting - void updateConstants() { - synchronized (mLock) { - boolean changed = false; - - long newMaxExecutionTimeMs = Math.max(MIN_MAX_EXECUTION_TIME_MS, - Math.min(MAX_PERIOD_MS, MAX_EXECUTION_TIME_MS)); - if (mMaxExecutionTimeMs != newMaxExecutionTimeMs) { - mMaxExecutionTimeMs = newMaxExecutionTimeMs; - mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs; - changed = true; - } - long newAllowedTimeMs = Math.min(mMaxExecutionTimeMs, - Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_MS)); - if (mAllowedTimePerPeriodMs != newAllowedTimeMs) { - mAllowedTimePerPeriodMs = newAllowedTimeMs; - mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs; - changed = true; - } - // Make sure quota buffer is non-negative, not greater than allowed time per period, - // and no more than 5 minutes. - long newQuotaBufferMs = Math.max(0, Math.min(mAllowedTimePerPeriodMs, - Math.min(5 * MINUTE_IN_MILLIS, IN_QUOTA_BUFFER_MS))); - if (mQuotaBufferMs != newQuotaBufferMs) { - mQuotaBufferMs = newQuotaBufferMs; - mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs; - mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs; - changed = true; - } - long newActivePeriodMs = Math.max(mAllowedTimePerPeriodMs, - Math.min(MAX_PERIOD_MS, WINDOW_SIZE_ACTIVE_MS)); - if (mBucketPeriodsMs[ACTIVE_INDEX] != newActivePeriodMs) { - mBucketPeriodsMs[ACTIVE_INDEX] = newActivePeriodMs; - changed = true; - } - long newWorkingPeriodMs = Math.max(mAllowedTimePerPeriodMs, - Math.min(MAX_PERIOD_MS, WINDOW_SIZE_WORKING_MS)); - if (mBucketPeriodsMs[WORKING_INDEX] != newWorkingPeriodMs) { - mBucketPeriodsMs[WORKING_INDEX] = newWorkingPeriodMs; - changed = true; - } - long newFrequentPeriodMs = Math.max(mAllowedTimePerPeriodMs, - Math.min(MAX_PERIOD_MS, WINDOW_SIZE_FREQUENT_MS)); - if (mBucketPeriodsMs[FREQUENT_INDEX] != newFrequentPeriodMs) { - mBucketPeriodsMs[FREQUENT_INDEX] = newFrequentPeriodMs; - changed = true; - } - long newRarePeriodMs = Math.max(mAllowedTimePerPeriodMs, - Math.min(MAX_PERIOD_MS, WINDOW_SIZE_RARE_MS)); - if (mBucketPeriodsMs[RARE_INDEX] != newRarePeriodMs) { - mBucketPeriodsMs[RARE_INDEX] = newRarePeriodMs; - changed = true; - } - // Fit in the range [allowed time (10 mins), 1 week]. - long newRestrictedPeriodMs = Math.max(mAllowedTimePerPeriodMs, - Math.min(7 * 24 * 60 * MINUTE_IN_MILLIS, WINDOW_SIZE_RESTRICTED_MS)); - if (mBucketPeriodsMs[RESTRICTED_INDEX] != newRestrictedPeriodMs) { - mBucketPeriodsMs[RESTRICTED_INDEX] = newRestrictedPeriodMs; - changed = true; - } - long newRateLimitingWindowMs = Math.min(MAX_PERIOD_MS, - Math.max(MIN_RATE_LIMITING_WINDOW_MS, RATE_LIMITING_WINDOW_MS)); - if (mRateLimitingWindowMs != newRateLimitingWindowMs) { - mRateLimitingWindowMs = newRateLimitingWindowMs; - changed = true; - } - int newMaxJobCountPerRateLimitingWindow = Math.max( - MIN_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, - MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW); - if (mMaxJobCountPerRateLimitingWindow != newMaxJobCountPerRateLimitingWindow) { - mMaxJobCountPerRateLimitingWindow = newMaxJobCountPerRateLimitingWindow; - changed = true; - } - int newActiveMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_ACTIVE); - if (mMaxBucketJobCounts[ACTIVE_INDEX] != newActiveMaxJobCount) { - mMaxBucketJobCounts[ACTIVE_INDEX] = newActiveMaxJobCount; - changed = true; - } - int newWorkingMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_WORKING); - if (mMaxBucketJobCounts[WORKING_INDEX] != newWorkingMaxJobCount) { - mMaxBucketJobCounts[WORKING_INDEX] = newWorkingMaxJobCount; - changed = true; - } - int newFrequentMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_FREQUENT); - if (mMaxBucketJobCounts[FREQUENT_INDEX] != newFrequentMaxJobCount) { - mMaxBucketJobCounts[FREQUENT_INDEX] = newFrequentMaxJobCount; - changed = true; - } - int newRareMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_RARE); - if (mMaxBucketJobCounts[RARE_INDEX] != newRareMaxJobCount) { - mMaxBucketJobCounts[RARE_INDEX] = newRareMaxJobCount; - changed = true; - } - int newRestrictedMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, - MAX_JOB_COUNT_RESTRICTED); - if (mMaxBucketJobCounts[RESTRICTED_INDEX] != newRestrictedMaxJobCount) { - mMaxBucketJobCounts[RESTRICTED_INDEX] = newRestrictedMaxJobCount; - changed = true; - } - int newMaxSessionCountPerRateLimitPeriod = Math.max( - MIN_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW, - MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW); - if (mMaxSessionCountPerRateLimitingWindow != newMaxSessionCountPerRateLimitPeriod) { - mMaxSessionCountPerRateLimitingWindow = newMaxSessionCountPerRateLimitPeriod; - changed = true; - } - int newActiveMaxSessionCount = - Math.max(MIN_BUCKET_SESSION_COUNT, MAX_SESSION_COUNT_ACTIVE); - if (mMaxBucketSessionCounts[ACTIVE_INDEX] != newActiveMaxSessionCount) { - mMaxBucketSessionCounts[ACTIVE_INDEX] = newActiveMaxSessionCount; - changed = true; - } - int newWorkingMaxSessionCount = - Math.max(MIN_BUCKET_SESSION_COUNT, MAX_SESSION_COUNT_WORKING); - if (mMaxBucketSessionCounts[WORKING_INDEX] != newWorkingMaxSessionCount) { - mMaxBucketSessionCounts[WORKING_INDEX] = newWorkingMaxSessionCount; - changed = true; - } - int newFrequentMaxSessionCount = - Math.max(MIN_BUCKET_SESSION_COUNT, MAX_SESSION_COUNT_FREQUENT); - if (mMaxBucketSessionCounts[FREQUENT_INDEX] != newFrequentMaxSessionCount) { - mMaxBucketSessionCounts[FREQUENT_INDEX] = newFrequentMaxSessionCount; - changed = true; - } - int newRareMaxSessionCount = - Math.max(MIN_BUCKET_SESSION_COUNT, MAX_SESSION_COUNT_RARE); - if (mMaxBucketSessionCounts[RARE_INDEX] != newRareMaxSessionCount) { - mMaxBucketSessionCounts[RARE_INDEX] = newRareMaxSessionCount; - changed = true; - } - int newRestrictedMaxSessionCount = Math.max(0, MAX_SESSION_COUNT_RESTRICTED); - if (mMaxBucketSessionCounts[RESTRICTED_INDEX] != newRestrictedMaxSessionCount) { - mMaxBucketSessionCounts[RESTRICTED_INDEX] = newRestrictedMaxSessionCount; - changed = true; - } - long newSessionCoalescingDurationMs = Math.min(15 * MINUTE_IN_MILLIS, - Math.max(0, TIMING_SESSION_COALESCING_DURATION_MS)); - if (mTimingSessionCoalescingDurationMs != newSessionCoalescingDurationMs) { - mTimingSessionCoalescingDurationMs = newSessionCoalescingDurationMs; - changed = true; - } - // Don't set changed to true for this one since we don't need to re-evaluate - // execution stats or constraint status. Limit the delay to the range [0, 15] - // minutes. - mInQuotaAlarmListener.setMinQuotaCheckDelayMs( - Math.min(15 * MINUTE_IN_MILLIS, Math.max(0, MIN_QUOTA_CHECK_DELAY_MS))); + private void updateExecutionPeriodConstantsLocked() { + if (mExecutionPeriodConstantsUpdated) { + return; + } + mExecutionPeriodConstantsUpdated = true; + + // Query the values as an atomic set. + final DeviceConfig.Properties properties = DeviceConfig.getProperties( + DeviceConfig.NAMESPACE_JOB_SCHEDULER, + KEY_ALLOWED_TIME_PER_PERIOD_MS, KEY_IN_QUOTA_BUFFER_MS, + KEY_MAX_EXECUTION_TIME_MS, KEY_WINDOW_SIZE_ACTIVE_MS, + KEY_WINDOW_SIZE_WORKING_MS, + KEY_WINDOW_SIZE_FREQUENT_MS, KEY_WINDOW_SIZE_RARE_MS, + KEY_WINDOW_SIZE_RESTRICTED_MS); + ALLOWED_TIME_PER_PERIOD_MS = + properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_MS, + DEFAULT_ALLOWED_TIME_PER_PERIOD_MS); + IN_QUOTA_BUFFER_MS = properties.getLong(KEY_IN_QUOTA_BUFFER_MS, + DEFAULT_IN_QUOTA_BUFFER_MS); + MAX_EXECUTION_TIME_MS = properties.getLong(KEY_MAX_EXECUTION_TIME_MS, + DEFAULT_MAX_EXECUTION_TIME_MS); + WINDOW_SIZE_ACTIVE_MS = properties.getLong(KEY_WINDOW_SIZE_ACTIVE_MS, + DEFAULT_WINDOW_SIZE_ACTIVE_MS); + WINDOW_SIZE_WORKING_MS = + properties.getLong(KEY_WINDOW_SIZE_WORKING_MS, DEFAULT_WINDOW_SIZE_WORKING_MS); + WINDOW_SIZE_FREQUENT_MS = + properties.getLong(KEY_WINDOW_SIZE_FREQUENT_MS, + DEFAULT_WINDOW_SIZE_FREQUENT_MS); + WINDOW_SIZE_RARE_MS = properties.getLong(KEY_WINDOW_SIZE_RARE_MS, + DEFAULT_WINDOW_SIZE_RARE_MS); + WINDOW_SIZE_RESTRICTED_MS = + properties.getLong(KEY_WINDOW_SIZE_RESTRICTED_MS, + DEFAULT_WINDOW_SIZE_RESTRICTED_MS); + + long newMaxExecutionTimeMs = Math.max(MIN_MAX_EXECUTION_TIME_MS, + Math.min(MAX_PERIOD_MS, MAX_EXECUTION_TIME_MS)); + if (mMaxExecutionTimeMs != newMaxExecutionTimeMs) { + mMaxExecutionTimeMs = newMaxExecutionTimeMs; + mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs; + mShouldReevaluateConstraints = true; + } + long newAllowedTimeMs = Math.min(mMaxExecutionTimeMs, + Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_MS)); + if (mAllowedTimePerPeriodMs != newAllowedTimeMs) { + mAllowedTimePerPeriodMs = newAllowedTimeMs; + mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs; + mShouldReevaluateConstraints = true; + } + // Make sure quota buffer is non-negative, not greater than allowed time per period, + // and no more than 5 minutes. + long newQuotaBufferMs = Math.max(0, Math.min(mAllowedTimePerPeriodMs, + Math.min(5 * MINUTE_IN_MILLIS, IN_QUOTA_BUFFER_MS))); + if (mQuotaBufferMs != newQuotaBufferMs) { + mQuotaBufferMs = newQuotaBufferMs; + mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs; + mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs; + mShouldReevaluateConstraints = true; + } + long newActivePeriodMs = Math.max(mAllowedTimePerPeriodMs, + Math.min(MAX_PERIOD_MS, WINDOW_SIZE_ACTIVE_MS)); + if (mBucketPeriodsMs[ACTIVE_INDEX] != newActivePeriodMs) { + mBucketPeriodsMs[ACTIVE_INDEX] = newActivePeriodMs; + mShouldReevaluateConstraints = true; + } + long newWorkingPeriodMs = Math.max(mAllowedTimePerPeriodMs, + Math.min(MAX_PERIOD_MS, WINDOW_SIZE_WORKING_MS)); + if (mBucketPeriodsMs[WORKING_INDEX] != newWorkingPeriodMs) { + mBucketPeriodsMs[WORKING_INDEX] = newWorkingPeriodMs; + mShouldReevaluateConstraints = true; + } + long newFrequentPeriodMs = Math.max(mAllowedTimePerPeriodMs, + Math.min(MAX_PERIOD_MS, WINDOW_SIZE_FREQUENT_MS)); + if (mBucketPeriodsMs[FREQUENT_INDEX] != newFrequentPeriodMs) { + mBucketPeriodsMs[FREQUENT_INDEX] = newFrequentPeriodMs; + mShouldReevaluateConstraints = true; + } + long newRarePeriodMs = Math.max(mAllowedTimePerPeriodMs, + Math.min(MAX_PERIOD_MS, WINDOW_SIZE_RARE_MS)); + if (mBucketPeriodsMs[RARE_INDEX] != newRarePeriodMs) { + mBucketPeriodsMs[RARE_INDEX] = newRarePeriodMs; + mShouldReevaluateConstraints = true; + } + // Fit in the range [allowed time (10 mins), 1 week]. + long newRestrictedPeriodMs = Math.max(mAllowedTimePerPeriodMs, + Math.min(7 * 24 * 60 * MINUTE_IN_MILLIS, WINDOW_SIZE_RESTRICTED_MS)); + if (mBucketPeriodsMs[RESTRICTED_INDEX] != newRestrictedPeriodMs) { + mBucketPeriodsMs[RESTRICTED_INDEX] = newRestrictedPeriodMs; + mShouldReevaluateConstraints = true; + } + } + + private void updateRateLimitingConstantsLocked() { + if (mRateLimitingConstantsUpdated) { + return; + } + mRateLimitingConstantsUpdated = true; - if (changed) { - // Update job bookkeeping out of band. - JobSchedulerBackgroundThread.getHandler().post(() -> { - synchronized (mLock) { - invalidateAllExecutionStatsLocked(); - maybeUpdateAllConstraintsLocked(); - } - }); - } + // Query the values as an atomic set. + final DeviceConfig.Properties properties = DeviceConfig.getProperties( + DeviceConfig.NAMESPACE_JOB_SCHEDULER, + KEY_RATE_LIMITING_WINDOW_MS, KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, + KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW); + + RATE_LIMITING_WINDOW_MS = + properties.getLong(KEY_RATE_LIMITING_WINDOW_MS, + DEFAULT_RATE_LIMITING_WINDOW_MS); + + MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW = + properties.getInt(KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, + DEFAULT_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW); + + MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = + properties.getInt(KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW, + DEFAULT_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW); + + long newRateLimitingWindowMs = Math.min(MAX_PERIOD_MS, + Math.max(MIN_RATE_LIMITING_WINDOW_MS, RATE_LIMITING_WINDOW_MS)); + if (mRateLimitingWindowMs != newRateLimitingWindowMs) { + mRateLimitingWindowMs = newRateLimitingWindowMs; + mShouldReevaluateConstraints = true; + } + int newMaxJobCountPerRateLimitingWindow = Math.max( + MIN_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, + MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW); + if (mMaxJobCountPerRateLimitingWindow != newMaxJobCountPerRateLimitingWindow) { + mMaxJobCountPerRateLimitingWindow = newMaxJobCountPerRateLimitingWindow; + mShouldReevaluateConstraints = true; + } + int newMaxSessionCountPerRateLimitPeriod = Math.max( + MIN_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW, + MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW); + if (mMaxSessionCountPerRateLimitingWindow != newMaxSessionCountPerRateLimitPeriod) { + mMaxSessionCountPerRateLimitingWindow = newMaxSessionCountPerRateLimitPeriod; + mShouldReevaluateConstraints = true; } } @@ -2634,6 +2731,11 @@ public final class QuotaController extends StateController { } @VisibleForTesting + long getMinQuotaCheckDelayMs() { + return mInQuotaAlarmListener.mMinQuotaCheckDelayMs; + } + + @VisibleForTesting long getRateLimitingWindowMs() { return mRateLimitingWindowMs; } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java index 71c759931f57..56b30907b2a1 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java @@ -18,7 +18,9 @@ package com.android.server.job.controllers; import static com.android.server.job.JobSchedulerService.DEBUG; +import android.annotation.NonNull; import android.content.Context; +import android.provider.DeviceConfig; import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -84,6 +86,13 @@ public abstract class StateController { public void rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule) { } + /** Notice that updated configuration constants are about to be read. */ + public void prepareForUpdatedConstantsLocked() {} + + /** Process the specified constant and update internal constants if relevant. */ + public void processConstantLocked(@NonNull DeviceConfig.Properties properties, + @NonNull String key) {} + /** * Called when the JobScheduler.Constants are updated. */ diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java index 227b8276abe1..56b97f2e5757 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java @@ -50,6 +50,9 @@ public final class TimeController extends StateController { private static final boolean DEBUG = JobSchedulerService.DEBUG || Log.isLoggable(TAG, Log.DEBUG); + @VisibleForTesting + static final long DELAY_COALESCE_TIME_MS = 30_000L; + /** Deadline alarm tag for logging purposes */ private final String DEADLINE_TAG = "*job.deadline*"; /** Delay alarm tag for logging purposes */ @@ -57,6 +60,7 @@ public final class TimeController extends StateController { private long mNextJobExpiredElapsedMillis; private long mNextDelayExpiredElapsedMillis; + private volatile long mLastFiredDelayExpiredElapsedMillis; private final boolean mChainedAttributionEnabled; @@ -273,7 +277,6 @@ public final class TimeController extends StateController { @VisibleForTesting void checkExpiredDelaysAndResetAlarm() { synchronized (mLock) { - final long nowElapsedMillis = sElapsedRealtimeClock.millis(); long nextDelayTime = Long.MAX_VALUE; int nextDelayUid = 0; String nextDelayPackageName = null; @@ -284,7 +287,7 @@ public final class TimeController extends StateController { if (!job.hasTimingDelayConstraint()) { continue; } - if (evaluateTimingDelayConstraint(job, nowElapsedMillis)) { + if (evaluateTimingDelayConstraint(job, sElapsedRealtimeClock.millis())) { if (canStopTrackingJobLocked(job)) { it.remove(); } @@ -356,7 +359,11 @@ public final class TimeController extends StateController { * This alarm <b>will not</b> wake up the phone. */ private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis, WorkSource ws) { - alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis); + // To avoid spamming AlarmManager in the case where many delay times are a few milliseconds + // apart, make sure the alarm is set no earlier than DELAY_COALESCE_TIME_MS since the last + // time a delay alarm went off and that the alarm is not scheduled for the past. + alarmTimeElapsedMillis = maybeAdjustAlarmTime(Math.max(alarmTimeElapsedMillis, + mLastFiredDelayExpiredElapsedMillis + DELAY_COALESCE_TIME_MS)); if (mNextDelayExpiredElapsedMillis == alarmTimeElapsedMillis) { return; } @@ -416,6 +423,7 @@ public final class TimeController extends StateController { if (DEBUG) { Slog.d(TAG, "Delay-expired alarm fired"); } + mLastFiredDelayExpiredElapsedMillis = sElapsedRealtimeClock.millis(); checkExpiredDelaysAndResetAlarm(); } }; @@ -429,6 +437,9 @@ public final class TimeController extends StateController { pw.print("Next delay alarm in "); TimeUtils.formatDuration(mNextDelayExpiredElapsedMillis, nowElapsed, pw); pw.println(); + pw.print("Last delay alarm fired @ "); + TimeUtils.formatDuration(nowElapsed, mLastFiredDelayExpiredElapsedMillis, pw); + pw.println(); pw.print("Next deadline alarm in "); TimeUtils.formatDuration(mNextJobExpiredElapsedMillis, nowElapsed, pw); pw.println(); diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index 22e1eec8883d..6f7dde292c56 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -92,11 +92,11 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; +import android.provider.DeviceConfig; import android.provider.Settings.Global; import android.telephony.TelephonyManager; import android.util.ArraySet; import android.util.IndentingPrintWriter; -import android.util.KeyValueListParser; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; @@ -117,8 +117,6 @@ import com.android.server.usage.AppIdleHistory.AppUsageHistory; import java.io.File; import java.io.PrintWriter; -import java.time.Duration; -import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -144,10 +142,11 @@ public class AppStandbyController implements AppStandbyInternal { private static final long ONE_DAY = ONE_HOUR * 24; /** - * The minimum amount of time the screen must have been on before an app can time out from its - * current bucket to the next bucket. + * The default minimum amount of time the screen must have been on before an app can time out + * from its current bucket to the next bucket. */ - private static final long[] SCREEN_TIME_THRESHOLDS = { + @VisibleForTesting + static final long[] DEFAULT_SCREEN_TIME_THRESHOLDS = { 0, 0, COMPRESS_TIME ? 2 * ONE_MINUTE : 1 * ONE_HOUR, @@ -155,9 +154,10 @@ public class AppStandbyController implements AppStandbyInternal { COMPRESS_TIME ? 8 * ONE_MINUTE : 6 * ONE_HOUR }; - /** The minimum allowed values for each index in {@link #SCREEN_TIME_THRESHOLDS}. */ - private static final long[] MINIMUM_SCREEN_TIME_THRESHOLDS = COMPRESS_TIME - ? new long[SCREEN_TIME_THRESHOLDS.length] + /** The minimum allowed values for each index in {@link #DEFAULT_SCREEN_TIME_THRESHOLDS}. */ + @VisibleForTesting + static final long[] MINIMUM_SCREEN_TIME_THRESHOLDS = COMPRESS_TIME + ? new long[DEFAULT_SCREEN_TIME_THRESHOLDS.length] : new long[]{ 0, 0, @@ -167,20 +167,22 @@ public class AppStandbyController implements AppStandbyInternal { }; /** - * The minimum amount of elapsed time that must have passed before an app can time out from its - * current bucket to the next bucket. + * The default minimum amount of elapsed time that must have passed before an app can time out + * from its current bucket to the next bucket. */ - private static final long[] ELAPSED_TIME_THRESHOLDS = { + @VisibleForTesting + static final long[] DEFAULT_ELAPSED_TIME_THRESHOLDS = { 0, - COMPRESS_TIME ? 1 * ONE_MINUTE : 12 * ONE_HOUR, - COMPRESS_TIME ? 4 * ONE_MINUTE : 24 * ONE_HOUR, + COMPRESS_TIME ? 1 * ONE_MINUTE : 12 * ONE_HOUR, + COMPRESS_TIME ? 4 * ONE_MINUTE : 24 * ONE_HOUR, COMPRESS_TIME ? 16 * ONE_MINUTE : 48 * ONE_HOUR, COMPRESS_TIME ? 32 * ONE_MINUTE : 30 * ONE_DAY }; - /** The minimum allowed values for each index in {@link #ELAPSED_TIME_THRESHOLDS}. */ - private static final long[] MINIMUM_ELAPSED_TIME_THRESHOLDS = COMPRESS_TIME - ? new long[ELAPSED_TIME_THRESHOLDS.length] + /** The minimum allowed values for each index in {@link #DEFAULT_ELAPSED_TIME_THRESHOLDS}. */ + @VisibleForTesting + static final long[] MINIMUM_ELAPSED_TIME_THRESHOLDS = COMPRESS_TIME + ? new long[DEFAULT_ELAPSED_TIME_THRESHOLDS.length] : new long[]{ 0, ONE_HOUR, @@ -198,7 +200,8 @@ public class AppStandbyController implements AppStandbyInternal { }; /** Default expiration time for bucket prediction. After this, use thresholds to downgrade. */ - private static final long DEFAULT_PREDICTION_TIMEOUT = 12 * ONE_HOUR; + private static final long DEFAULT_PREDICTION_TIMEOUT = + COMPRESS_TIME ? 10 * ONE_MINUTE : 12 * ONE_HOUR; /** * Indicates the maximum wait time for admin data to be available; @@ -269,58 +272,64 @@ public class AppStandbyController implements AppStandbyInternal { static final int MSG_REPORT_SYNC_SCHEDULED = 12; static final int MSG_REPORT_EXEMPTED_SYNC_START = 13; - long mCheckIdleIntervalMillis; + long mCheckIdleIntervalMillis = Math.min(DEFAULT_ELAPSED_TIME_THRESHOLDS[1] / 4, + ConstantsObserver.DEFAULT_CHECK_IDLE_INTERVAL_MS); /** * The minimum amount of time the screen must have been on before an app can time out from its * current bucket to the next bucket. */ - long[] mAppStandbyScreenThresholds = SCREEN_TIME_THRESHOLDS; + long[] mAppStandbyScreenThresholds = DEFAULT_SCREEN_TIME_THRESHOLDS; /** * The minimum amount of elapsed time that must have passed before an app can time out from its * current bucket to the next bucket. */ - long[] mAppStandbyElapsedThresholds = ELAPSED_TIME_THRESHOLDS; + long[] mAppStandbyElapsedThresholds = DEFAULT_ELAPSED_TIME_THRESHOLDS; /** Minimum time a strong usage event should keep the bucket elevated. */ - long mStrongUsageTimeoutMillis; + long mStrongUsageTimeoutMillis = ConstantsObserver.DEFAULT_STRONG_USAGE_TIMEOUT; /** Minimum time a notification seen event should keep the bucket elevated. */ - long mNotificationSeenTimeoutMillis; + long mNotificationSeenTimeoutMillis = ConstantsObserver.DEFAULT_NOTIFICATION_TIMEOUT; /** Minimum time a system update event should keep the buckets elevated. */ - long mSystemUpdateUsageTimeoutMillis; + long mSystemUpdateUsageTimeoutMillis = ConstantsObserver.DEFAULT_SYSTEM_UPDATE_TIMEOUT; /** Maximum time to wait for a prediction before using simple timeouts to downgrade buckets. */ - long mPredictionTimeoutMillis; + long mPredictionTimeoutMillis = DEFAULT_PREDICTION_TIMEOUT; /** Maximum time a sync adapter associated with a CP should keep the buckets elevated. */ - long mSyncAdapterTimeoutMillis; + long mSyncAdapterTimeoutMillis = ConstantsObserver.DEFAULT_SYNC_ADAPTER_TIMEOUT; /** * Maximum time an exempted sync should keep the buckets elevated, when sync is scheduled in * non-doze */ - long mExemptedSyncScheduledNonDozeTimeoutMillis; + long mExemptedSyncScheduledNonDozeTimeoutMillis = + ConstantsObserver.DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT; /** * Maximum time an exempted sync should keep the buckets elevated, when sync is scheduled in * doze */ - long mExemptedSyncScheduledDozeTimeoutMillis; + long mExemptedSyncScheduledDozeTimeoutMillis = + ConstantsObserver.DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT; /** * Maximum time an exempted sync should keep the buckets elevated, when sync is started. */ - long mExemptedSyncStartTimeoutMillis; + long mExemptedSyncStartTimeoutMillis = ConstantsObserver.DEFAULT_EXEMPTED_SYNC_START_TIMEOUT; /** * Maximum time an unexempted sync should keep the buckets elevated, when sync is scheduled */ - long mUnexemptedSyncScheduledTimeoutMillis; + long mUnexemptedSyncScheduledTimeoutMillis = + ConstantsObserver.DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT; /** Maximum time a system interaction should keep the buckets elevated. */ - long mSystemInteractionTimeoutMillis; + long mSystemInteractionTimeoutMillis = ConstantsObserver.DEFAULT_SYSTEM_INTERACTION_TIMEOUT; /** * Maximum time a foreground service start should keep the buckets elevated if the service * start is the first usage of the app */ - long mInitialForegroundServiceStartTimeoutMillis; + long mInitialForegroundServiceStartTimeoutMillis = + ConstantsObserver.DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT; /** * User usage that would elevate an app's standby bucket will also elevate the standby bucket of * cross profile connected apps. Explicit standby bucket setting via * {@link #setAppStandbyBucket(String, int, int, int, int)} will not be propagated. */ - boolean mLinkCrossProfileApps; + boolean mLinkCrossProfileApps = + ConstantsObserver.DEFAULT_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS; /** * Whether we should allow apps into the * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket or not. @@ -481,9 +490,8 @@ public class AppStandbyController implements AppStandbyInternal { if (phase == PHASE_SYSTEM_SERVICES_READY) { Slog.d(TAG, "Setting app idle enabled state"); // Observe changes to the threshold - SettingsObserver settingsObserver = new SettingsObserver(mHandler); - settingsObserver.registerObserver(); - settingsObserver.updateSettings(); + ConstantsObserver settingsObserver = new ConstantsObserver(mHandler); + settingsObserver.start(); mAppWidgetManager = mContext.getSystemService(AppWidgetManager.class); @@ -1964,7 +1972,8 @@ public class AppStandbyController implements AppStandbyInternal { * The minimum amount of time required since the last user interaction before an app can be * automatically placed in the RESTRICTED bucket. */ - long mAutoRestrictedBucketDelayMs = ONE_DAY; + long mAutoRestrictedBucketDelayMs = + ConstantsObserver.DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS; /** * Cached set of apps that are power whitelisted, including those not whitelisted from idle. */ @@ -2136,9 +2145,9 @@ public class AppStandbyController implements AppStandbyInternal { return appWidgetManager.isBoundWidgetPackage(packageName, userId); } - String getAppIdleSettings() { - return Global.getString(mContext.getContentResolver(), - Global.APP_IDLE_CONSTANTS); + @NonNull + DeviceConfig.Properties getDeviceConfigProperties(String... keys) { + return DeviceConfig.getProperties(DeviceConfig.NAMESPACE_APP_STANDBY, keys); } /** Whether the device is in doze or not. */ @@ -2162,6 +2171,12 @@ public class AppStandbyController implements AppStandbyInternal { return mCrossProfileAppsInternal.getTargetUserProfiles(pkg, userId); } + void registerDeviceConfigPropertiesChangedListener( + @NonNull DeviceConfig.OnPropertiesChangedListener listener) { + DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APP_STANDBY, + JobSchedulerBackgroundThread.getExecutor(), listener); + } + void dump(PrintWriter pw) { pw.println("mPowerWhitelistedApps=["); synchronized (mPowerWhitelistedApps) { @@ -2286,11 +2301,11 @@ public class AppStandbyController implements AppStandbyInternal { }; /** - * Observe settings changes for {@link Global#APP_IDLE_CONSTANTS}. + * Observe changes for {@link DeviceConfig#NAMESPACE_APP_STANDBY} and other standby related + * Settings constants. */ - private class SettingsObserver extends ContentObserver { - private static final String KEY_SCREEN_TIME_THRESHOLDS = "screen_thresholds"; - private static final String KEY_ELAPSED_TIME_THRESHOLDS = "elapsed_thresholds"; + private class ConstantsObserver extends ContentObserver implements + DeviceConfig.OnPropertiesChangedListener { private static final String KEY_STRONG_USAGE_HOLD_DURATION = "strong_usage_duration"; private static final String KEY_NOTIFICATION_SEEN_HOLD_DURATION = "notification_seen_duration"; @@ -2314,33 +2329,69 @@ public class AppStandbyController implements AppStandbyInternal { "auto_restricted_bucket_delay_ms"; private static final String KEY_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS = "cross_profile_apps_share_standby_buckets"; - public static final long DEFAULT_STRONG_USAGE_TIMEOUT = 1 * ONE_HOUR; - public static final long DEFAULT_NOTIFICATION_TIMEOUT = 12 * ONE_HOUR; - public static final long DEFAULT_SYSTEM_UPDATE_TIMEOUT = 2 * ONE_HOUR; - public static final long DEFAULT_SYSTEM_INTERACTION_TIMEOUT = 10 * ONE_MINUTE; - public static final long DEFAULT_SYNC_ADAPTER_TIMEOUT = 10 * ONE_MINUTE; - public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT = 10 * ONE_MINUTE; - public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT = 4 * ONE_HOUR; - public static final long DEFAULT_EXEMPTED_SYNC_START_TIMEOUT = 10 * ONE_MINUTE; - public static final long DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT = 10 * ONE_MINUTE; - public static final long DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT = 30 * ONE_MINUTE; - public static final long DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS = ONE_DAY; + private static final String KEY_PREFIX_SCREEN_TIME_THRESHOLD = "screen_threshold_"; + private final String[] KEYS_SCREEN_TIME_THRESHOLDS = { + KEY_PREFIX_SCREEN_TIME_THRESHOLD + "active", + KEY_PREFIX_SCREEN_TIME_THRESHOLD + "working_set", + KEY_PREFIX_SCREEN_TIME_THRESHOLD + "frequent", + KEY_PREFIX_SCREEN_TIME_THRESHOLD + "rare", + KEY_PREFIX_SCREEN_TIME_THRESHOLD + "restricted" + }; + private static final String KEY_PREFIX_ELAPSED_TIME_THRESHOLD = "elapsed_threshold_"; + private final String[] KEYS_ELAPSED_TIME_THRESHOLDS = { + KEY_PREFIX_ELAPSED_TIME_THRESHOLD + "active", + KEY_PREFIX_ELAPSED_TIME_THRESHOLD + "working_set", + KEY_PREFIX_ELAPSED_TIME_THRESHOLD + "frequent", + KEY_PREFIX_ELAPSED_TIME_THRESHOLD + "rare", + KEY_PREFIX_ELAPSED_TIME_THRESHOLD + "restricted" + }; + public static final long DEFAULT_CHECK_IDLE_INTERVAL_MS = + COMPRESS_TIME ? ONE_MINUTE : 4 * ONE_HOUR; + public static final long DEFAULT_STRONG_USAGE_TIMEOUT = + COMPRESS_TIME ? ONE_MINUTE : 1 * ONE_HOUR; + public static final long DEFAULT_NOTIFICATION_TIMEOUT = + COMPRESS_TIME ? 12 * ONE_MINUTE : 12 * ONE_HOUR; + public static final long DEFAULT_SYSTEM_UPDATE_TIMEOUT = + COMPRESS_TIME ? 2 * ONE_MINUTE : 2 * ONE_HOUR; + public static final long DEFAULT_SYSTEM_INTERACTION_TIMEOUT = + COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE; + public static final long DEFAULT_SYNC_ADAPTER_TIMEOUT = + COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE; + public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT = + COMPRESS_TIME ? (ONE_MINUTE / 2) : 10 * ONE_MINUTE; + public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT = + COMPRESS_TIME ? ONE_MINUTE : 4 * ONE_HOUR; + public static final long DEFAULT_EXEMPTED_SYNC_START_TIMEOUT = + COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE; + public static final long DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT = + COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE; + public static final long DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT = + COMPRESS_TIME ? ONE_MINUTE : 30 * ONE_MINUTE; + public static final long DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS = + COMPRESS_TIME ? ONE_MINUTE : ONE_DAY; public static final boolean DEFAULT_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS = true; - private final KeyValueListParser mParser = new KeyValueListParser(','); - - SettingsObserver(Handler handler) { + ConstantsObserver(Handler handler) { super(handler); } - void registerObserver() { + public void start() { final ContentResolver cr = mContext.getContentResolver(); - cr.registerContentObserver(Global.getUriFor(Global.APP_IDLE_CONSTANTS), false, this); + // APP_STANDBY_ENABLED is a SystemApi that some apps may be watching, so best to + // leave it in Settings. cr.registerContentObserver(Global.getUriFor(Global.APP_STANDBY_ENABLED), false, this); + // Leave ENABLE_RESTRICTED_BUCKET as a user-controlled setting which will stay in + // Settings. + // TODO: make setting user-specific cr.registerContentObserver(Global.getUriFor(Global.ENABLE_RESTRICTED_BUCKET), false, this); + // ADAPTIVE_BATTERY_MANAGEMENT_ENABLED is a user setting, so it has to stay in Settings. cr.registerContentObserver(Global.getUriFor(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED), false, this); + mInjector.registerDeviceConfigPropertiesChangedListener(this); + // Load all the constants. + onPropertiesChanged(mInjector.getDeviceConfigProperties()); + updateSettings(); } @Override @@ -2349,6 +2400,107 @@ public class AppStandbyController implements AppStandbyInternal { postOneTimeCheckIdleStates(); } + @Override + public void onPropertiesChanged(DeviceConfig.Properties properties) { + boolean timeThresholdsUpdated = false; + synchronized (mAppIdleLock) { + for (String name : properties.getKeyset()) { + if (name == null) { + continue; + } + switch (name) { + case KEY_AUTO_RESTRICTED_BUCKET_DELAY_MS: + mInjector.mAutoRestrictedBucketDelayMs = Math.max( + COMPRESS_TIME ? ONE_MINUTE : 2 * ONE_HOUR, + properties.getLong(KEY_AUTO_RESTRICTED_BUCKET_DELAY_MS, + DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS)); + break; + case KEY_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS: + mLinkCrossProfileApps = properties.getBoolean( + KEY_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS, + DEFAULT_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS); + break; + case KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION: + mInitialForegroundServiceStartTimeoutMillis = properties.getLong( + KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION, + DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT); + break; + case KEY_NOTIFICATION_SEEN_HOLD_DURATION: + mNotificationSeenTimeoutMillis = properties.getLong( + KEY_NOTIFICATION_SEEN_HOLD_DURATION, + DEFAULT_NOTIFICATION_TIMEOUT); + break; + case KEY_STRONG_USAGE_HOLD_DURATION: + mStrongUsageTimeoutMillis = properties.getLong( + KEY_STRONG_USAGE_HOLD_DURATION, DEFAULT_STRONG_USAGE_TIMEOUT); + break; + case KEY_PREDICTION_TIMEOUT: + mPredictionTimeoutMillis = properties.getLong( + KEY_PREDICTION_TIMEOUT, DEFAULT_PREDICTION_TIMEOUT); + break; + case KEY_SYSTEM_INTERACTION_HOLD_DURATION: + mSystemInteractionTimeoutMillis = properties.getLong( + KEY_SYSTEM_INTERACTION_HOLD_DURATION, + DEFAULT_SYSTEM_INTERACTION_TIMEOUT); + break; + case KEY_SYSTEM_UPDATE_HOLD_DURATION: + mSystemUpdateUsageTimeoutMillis = properties.getLong( + KEY_SYSTEM_UPDATE_HOLD_DURATION, DEFAULT_SYSTEM_UPDATE_TIMEOUT); + break; + case KEY_SYNC_ADAPTER_HOLD_DURATION: + mSyncAdapterTimeoutMillis = properties.getLong( + KEY_SYNC_ADAPTER_HOLD_DURATION, DEFAULT_SYNC_ADAPTER_TIMEOUT); + break; + case KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION: + mExemptedSyncScheduledDozeTimeoutMillis = properties.getLong( + KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION, + DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT); + break; + case KEY_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_HOLD_DURATION: + mExemptedSyncScheduledNonDozeTimeoutMillis = properties.getLong( + KEY_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_HOLD_DURATION, + DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT); + break; + case KEY_EXEMPTED_SYNC_START_HOLD_DURATION: + mExemptedSyncStartTimeoutMillis = properties.getLong( + KEY_EXEMPTED_SYNC_START_HOLD_DURATION, + DEFAULT_EXEMPTED_SYNC_START_TIMEOUT); + break; + case KEY_UNEXEMPTED_SYNC_SCHEDULED_HOLD_DURATION: + mUnexemptedSyncScheduledTimeoutMillis = properties.getLong( + KEY_UNEXEMPTED_SYNC_SCHEDULED_HOLD_DURATION, + DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT); + break; + default: + if (!timeThresholdsUpdated + && (name.startsWith(KEY_PREFIX_SCREEN_TIME_THRESHOLD) + || name.startsWith(KEY_PREFIX_ELAPSED_TIME_THRESHOLD))) { + updateTimeThresholds(); + timeThresholdsUpdated = true; + } + break; + } + } + } + postOneTimeCheckIdleStates(); + } + + private void updateTimeThresholds() { + // Query the values as an atomic set. + final DeviceConfig.Properties screenThresholdProperties = + mInjector.getDeviceConfigProperties(KEYS_SCREEN_TIME_THRESHOLDS); + final DeviceConfig.Properties elapsedThresholdProperties = + mInjector.getDeviceConfigProperties(KEYS_ELAPSED_TIME_THRESHOLDS); + mAppStandbyScreenThresholds = generateThresholdArray( + screenThresholdProperties, KEYS_SCREEN_TIME_THRESHOLDS, + DEFAULT_SCREEN_TIME_THRESHOLDS, MINIMUM_SCREEN_TIME_THRESHOLDS); + mAppStandbyElapsedThresholds = generateThresholdArray( + elapsedThresholdProperties, KEYS_ELAPSED_TIME_THRESHOLDS, + DEFAULT_ELAPSED_TIME_THRESHOLDS, MINIMUM_ELAPSED_TIME_THRESHOLDS); + mCheckIdleIntervalMillis = Math.min(mAppStandbyElapsedThresholds[1] / 4, + DEFAULT_CHECK_IDLE_INTERVAL_MS); + } + void updateSettings() { if (DEBUG) { Slog.d(TAG, @@ -2357,126 +2509,43 @@ public class AppStandbyController implements AppStandbyInternal { Slog.d(TAG, "adaptivebat=" + Global.getString(mContext.getContentResolver(), Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED)); - Slog.d(TAG, "appidleconstants=" + Global.getString( - mContext.getContentResolver(), - Global.APP_IDLE_CONSTANTS)); - } - - // Look at global settings for this. - // TODO: Maybe apply different thresholds for different users. - try { - mParser.setString(mInjector.getAppIdleSettings()); - } catch (IllegalArgumentException e) { - Slog.e(TAG, "Bad value for app idle settings: " + e.getMessage()); - // fallthrough, mParser is empty and all defaults will be returned. } synchronized (mAppIdleLock) { - - String screenThresholdsValue = mParser.getString(KEY_SCREEN_TIME_THRESHOLDS, null); - mAppStandbyScreenThresholds = parseLongArray(screenThresholdsValue, - SCREEN_TIME_THRESHOLDS, MINIMUM_SCREEN_TIME_THRESHOLDS); - - String elapsedThresholdsValue = mParser.getString(KEY_ELAPSED_TIME_THRESHOLDS, - null); - mAppStandbyElapsedThresholds = parseLongArray(elapsedThresholdsValue, - ELAPSED_TIME_THRESHOLDS, MINIMUM_ELAPSED_TIME_THRESHOLDS); - mCheckIdleIntervalMillis = Math.min(mAppStandbyElapsedThresholds[1] / 4, - COMPRESS_TIME ? ONE_MINUTE : 4 * 60 * ONE_MINUTE); // 4 hours - mStrongUsageTimeoutMillis = mParser.getDurationMillis( - KEY_STRONG_USAGE_HOLD_DURATION, - COMPRESS_TIME ? ONE_MINUTE : DEFAULT_STRONG_USAGE_TIMEOUT); - mNotificationSeenTimeoutMillis = mParser.getDurationMillis( - KEY_NOTIFICATION_SEEN_HOLD_DURATION, - COMPRESS_TIME ? 12 * ONE_MINUTE : DEFAULT_NOTIFICATION_TIMEOUT); - mSystemUpdateUsageTimeoutMillis = mParser.getDurationMillis( - KEY_SYSTEM_UPDATE_HOLD_DURATION, - COMPRESS_TIME ? 2 * ONE_MINUTE : DEFAULT_SYSTEM_UPDATE_TIMEOUT); - mPredictionTimeoutMillis = mParser.getDurationMillis( - KEY_PREDICTION_TIMEOUT, - COMPRESS_TIME ? 10 * ONE_MINUTE : DEFAULT_PREDICTION_TIMEOUT); - mSyncAdapterTimeoutMillis = mParser.getDurationMillis( - KEY_SYNC_ADAPTER_HOLD_DURATION, - COMPRESS_TIME ? ONE_MINUTE : DEFAULT_SYNC_ADAPTER_TIMEOUT); - - mExemptedSyncScheduledNonDozeTimeoutMillis = mParser.getDurationMillis( - KEY_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_HOLD_DURATION, - COMPRESS_TIME ? (ONE_MINUTE / 2) - : DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT); - - mExemptedSyncScheduledDozeTimeoutMillis = mParser.getDurationMillis( - KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION, - COMPRESS_TIME ? ONE_MINUTE - : DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT); - - mExemptedSyncStartTimeoutMillis = mParser.getDurationMillis( - KEY_EXEMPTED_SYNC_START_HOLD_DURATION, - COMPRESS_TIME ? ONE_MINUTE - : DEFAULT_EXEMPTED_SYNC_START_TIMEOUT); - - mUnexemptedSyncScheduledTimeoutMillis = mParser.getDurationMillis( - KEY_UNEXEMPTED_SYNC_SCHEDULED_HOLD_DURATION, - COMPRESS_TIME - ? ONE_MINUTE : DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT); - - mSystemInteractionTimeoutMillis = mParser.getDurationMillis( - KEY_SYSTEM_INTERACTION_HOLD_DURATION, - COMPRESS_TIME ? ONE_MINUTE : DEFAULT_SYSTEM_INTERACTION_TIMEOUT); - - mInitialForegroundServiceStartTimeoutMillis = mParser.getDurationMillis( - KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION, - COMPRESS_TIME ? ONE_MINUTE : - DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT); - - mInjector.mAutoRestrictedBucketDelayMs = Math.max( - COMPRESS_TIME ? ONE_MINUTE : 2 * ONE_HOUR, - mParser.getDurationMillis(KEY_AUTO_RESTRICTED_BUCKET_DELAY_MS, - COMPRESS_TIME - ? ONE_MINUTE : DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS)); - - mLinkCrossProfileApps = mParser.getBoolean( - KEY_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS, - DEFAULT_CROSS_PROFILE_APPS_SHARE_STANDBY_BUCKETS); - mAllowRestrictedBucket = mInjector.isRestrictedBucketEnabled(); } - // Check if app_idle_enabled has changed. Do this after getting the rest of the settings - // in case we need to change something based on the new values. setAppIdleEnabled(mInjector.isAppIdleEnabled()); } - long[] parseLongArray(String values, long[] defaults, long[] minValues) { - if (values == null) return defaults; - if (values.isEmpty()) { + long[] generateThresholdArray(@NonNull DeviceConfig.Properties properties, + @NonNull String[] keys, long[] defaults, long[] minValues) { + if (properties.getKeyset().isEmpty()) { // Reset to defaults return defaults; - } else { - String[] thresholds = values.split("/"); - if (thresholds.length == THRESHOLD_BUCKETS.length) { - if (minValues.length != THRESHOLD_BUCKETS.length) { - Slog.wtf(TAG, "minValues array is the wrong size"); - // Use zeroes as the minimums. - minValues = new long[THRESHOLD_BUCKETS.length]; - } - long[] array = new long[THRESHOLD_BUCKETS.length]; - for (int i = 0; i < THRESHOLD_BUCKETS.length; i++) { - try { - if (thresholds[i].startsWith("P") || thresholds[i].startsWith("p")) { - array[i] = Math.max(minValues[i], - Duration.parse(thresholds[i]).toMillis()); - } else { - array[i] = Math.max(minValues[i], Long.parseLong(thresholds[i])); - } - } catch (NumberFormatException|DateTimeParseException e) { - return defaults; - } - } - return array; - } else { - return defaults; - } } + if (keys.length != THRESHOLD_BUCKETS.length) { + // This should only happen in development. + throw new IllegalStateException( + "# keys (" + keys.length + ") != # buckets (" + + THRESHOLD_BUCKETS.length + ")"); + } + if (defaults.length != THRESHOLD_BUCKETS.length) { + // This should only happen in development. + throw new IllegalStateException( + "# defaults (" + defaults.length + ") != # buckets (" + + THRESHOLD_BUCKETS.length + ")"); + } + if (minValues.length != THRESHOLD_BUCKETS.length) { + Slog.wtf(TAG, "minValues array is the wrong size"); + // Use zeroes as the minimums. + minValues = new long[THRESHOLD_BUCKETS.length]; + } + long[] array = new long[THRESHOLD_BUCKETS.length]; + for (int i = 0; i < THRESHOLD_BUCKETS.length; i++) { + array[i] = Math.max(minValues[i], properties.getLong(keys[i], defaults[i])); + } + return array; } } } diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp index 813631e28a88..b3c9a9aca444 100644 --- a/apex/media/framework/Android.bp +++ b/apex/media/framework/Android.bp @@ -35,7 +35,6 @@ java_library { libs: [ "framework_media_annotation", ], - static_libs: [ "exoplayer2-extractor" ], @@ -111,10 +110,33 @@ java_sdk_library { impl_library_visibility: ["//frameworks/av/apex:__subpackages__"], } - java_library { name: "framework_media_annotation", srcs: [":framework-media-annotation-srcs"], installable: false, sdk_version: "core_current", } + +cc_library_shared { + name: "libmediaparser-jni", + srcs: [ + "jni/android_media_MediaParserJNI.cpp", + ], + header_libs: ["jni_headers"], + shared_libs: [ + "libandroid", + "liblog", + "libmediametrics", + ], + cflags: [ + "-Wall", + "-Werror", + "-Wno-unused-parameter", + "-Wunreachable-code", + "-Wunused", + ], + apex_available: [ + "com.android.media", + ], + min_sdk_version: "29", +} diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java index e4b5d19e67c9..045b4136a710 100644 --- a/apex/media/framework/java/android/media/MediaParser.java +++ b/apex/media/framework/java/android/media/MediaParser.java @@ -75,6 +75,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.function.Function; /** * Parses media container formats and extracts contained media samples and metadata. @@ -882,6 +884,7 @@ public final class MediaParser { // Private constants. private static final String TAG = "MediaParser"; + private static final String JNI_LIBRARY_NAME = "mediaparser-jni"; private static final Map<String, ExtractorFactory> EXTRACTOR_FACTORIES_BY_NAME; private static final Map<String, Class> EXPECTED_TYPE_BY_PARAMETER_NAME; private static final String TS_MODE_SINGLE_PMT = "single_pmt"; @@ -889,6 +892,14 @@ public final class MediaParser { private static final String TS_MODE_HLS = "hls"; private static final int BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY = 6; private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + private static final String MEDIAMETRICS_ELEMENT_SEPARATOR = "|"; + private static final int MEDIAMETRICS_MAX_STRING_SIZE = 200; + private static final int MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH; + /** + * Intentional error introduced to reported metrics to prevent identification of the parsed + * media. Note: Increasing this value may cause older hostside CTS tests to fail. + */ + private static final float MEDIAMETRICS_DITHER = .02f; @IntDef( value = { @@ -920,7 +931,7 @@ public final class MediaParser { @NonNull @ParserName String name, @NonNull OutputConsumer outputConsumer) { String[] nameAsArray = new String[] {name}; assertValidNames(nameAsArray); - return new MediaParser(outputConsumer, /* sniff= */ false, name); + return new MediaParser(outputConsumer, /* createdByName= */ true, name); } /** @@ -940,7 +951,7 @@ public final class MediaParser { if (parserNames.length == 0) { parserNames = EXTRACTOR_FACTORIES_BY_NAME.keySet().toArray(new String[0]); } - return new MediaParser(outputConsumer, /* sniff= */ true, parserNames); + return new MediaParser(outputConsumer, /* createdByName= */ false, parserNames); } // Misc static methods. @@ -1052,6 +1063,14 @@ public final class MediaParser { private long mPendingSeekPosition; private long mPendingSeekTimeMicros; private boolean mLoggedSchemeInitDataCreationException; + private boolean mReleased; + + // MediaMetrics fields. + private final boolean mCreatedByName; + private final SparseArray<Format> mTrackFormats; + private String mLastObservedExceptionName; + private long mDurationMillis; + private long mResourceByteCount; // Public methods. @@ -1166,11 +1185,16 @@ public final class MediaParser { if (mExtractorInput == null) { // TODO: For efficiency, the same implementation should be used, by providing a // clearBuffers() method, or similar. + long resourceLength = seekableInputReader.getLength(); + if (resourceLength == -1) { + mResourceByteCount = -1; + } + if (mResourceByteCount != -1) { + mResourceByteCount += resourceLength; + } mExtractorInput = new DefaultExtractorInput( - mExoDataReader, - seekableInputReader.getPosition(), - seekableInputReader.getLength()); + mExoDataReader, seekableInputReader.getPosition(), resourceLength); } mExoDataReader.mInputReader = seekableInputReader; @@ -1195,7 +1219,10 @@ public final class MediaParser { } } if (mExtractor == null) { - throw UnrecognizedInputFormatException.createForExtractors(mParserNamesPool); + UnrecognizedInputFormatException exception = + UnrecognizedInputFormatException.createForExtractors(mParserNamesPool); + mLastObservedExceptionName = exception.getClass().getName(); + throw exception; } return true; } @@ -1223,8 +1250,13 @@ public final class MediaParser { int result; try { result = mExtractor.read(mExtractorInput, mPositionHolder); - } catch (ParserException e) { - throw new ParsingException(e); + } catch (Exception e) { + mLastObservedExceptionName = e.getClass().getName(); + if (e instanceof ParserException) { + throw new ParsingException((ParserException) e); + } else { + throw e; + } } if (result == Extractor.RESULT_END_OF_INPUT) { mExtractorInput = null; @@ -1264,21 +1296,64 @@ public final class MediaParser { * invoked. */ public void release() { - // TODO: Dump media metrics here. mExtractorInput = null; mExtractor = null; + if (mReleased) { + // Nothing to do. + return; + } + mReleased = true; + + String trackMimeTypes = buildMediaMetricsString(format -> format.sampleMimeType); + String trackCodecs = buildMediaMetricsString(format -> format.codecs); + int videoWidth = -1; + int videoHeight = -1; + for (int i = 0; i < mTrackFormats.size(); i++) { + Format format = mTrackFormats.valueAt(i); + if (format.width != Format.NO_VALUE && format.height != Format.NO_VALUE) { + videoWidth = format.width; + videoHeight = format.height; + break; + } + } + + String alteredParameters = + String.join( + MEDIAMETRICS_ELEMENT_SEPARATOR, + mParserParameters.keySet().toArray(new String[0])); + alteredParameters = + alteredParameters.substring( + 0, + Math.min( + alteredParameters.length(), + MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH)); + + nativeSubmitMetrics( + mParserName, + mCreatedByName, + String.join(MEDIAMETRICS_ELEMENT_SEPARATOR, mParserNamesPool), + mLastObservedExceptionName, + addDither(mResourceByteCount), + addDither(mDurationMillis), + trackMimeTypes, + trackCodecs, + alteredParameters, + videoWidth, + videoHeight); } // Private methods. - private MediaParser(OutputConsumer outputConsumer, boolean sniff, String... parserNamesPool) { + private MediaParser( + OutputConsumer outputConsumer, boolean createdByName, String... parserNamesPool) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { throw new UnsupportedOperationException("Android version must be R or greater."); } mParserParameters = new HashMap<>(); mOutputConsumer = outputConsumer; mParserNamesPool = parserNamesPool; - mParserName = sniff ? PARSER_NAME_UNKNOWN : parserNamesPool[0]; + mCreatedByName = createdByName; + mParserName = createdByName ? parserNamesPool[0] : PARSER_NAME_UNKNOWN; mPositionHolder = new PositionHolder(); mExoDataReader = new InputReadingDataReader(); removePendingSeek(); @@ -1286,6 +1361,24 @@ public final class MediaParser { mScratchParsableByteArrayAdapter = new ParsableByteArrayAdapter(); mSchemeInitDataConstructor = getSchemeInitDataConstructor(); mMuxedCaptionFormats = new ArrayList<>(); + + // MediaMetrics. + mTrackFormats = new SparseArray<>(); + mLastObservedExceptionName = ""; + mDurationMillis = -1; + } + + private String buildMediaMetricsString(Function<Format, String> formatFieldGetter) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < mTrackFormats.size(); i++) { + if (i > 0) { + stringBuilder.append(MEDIAMETRICS_ELEMENT_SEPARATOR); + } + String fieldValue = formatFieldGetter.apply(mTrackFormats.valueAt(i)); + stringBuilder.append(fieldValue != null ? fieldValue : ""); + } + return stringBuilder.substring( + 0, Math.min(stringBuilder.length(), MEDIAMETRICS_MAX_STRING_SIZE)); } private void setMuxedCaptionFormats(List<MediaFormat> mediaFormats) { @@ -1528,6 +1621,10 @@ public final class MediaParser { @Override public void seekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) { + long durationUs = exoplayerSeekMap.getDurationUs(); + if (durationUs != C.TIME_UNSET) { + mDurationMillis = C.usToMs(durationUs); + } if (mExposeChunkIndexAsMediaFormat && exoplayerSeekMap instanceof ChunkIndex) { ChunkIndex chunkIndex = (ChunkIndex) exoplayerSeekMap; MediaFormat mediaFormat = new MediaFormat(); @@ -1575,6 +1672,7 @@ public final class MediaParser { @Override public void format(Format format) { + mTrackFormats.put(mTrackIndex, format); mOutputConsumer.onTrackDataFound( mTrackIndex, new TrackData( @@ -2031,6 +2129,20 @@ public final class MediaParser { return new SeekPoint(exoPlayerSeekPoint.timeUs, exoPlayerSeekPoint.position); } + /** + * Introduces random error to the given metric value in order to prevent the identification of + * the parsed media. + */ + private static long addDither(long value) { + // Generate a random in [0, 1]. + double randomDither = ThreadLocalRandom.current().nextFloat(); + // Clamp the random number to [0, 2 * MEDIAMETRICS_DITHER]. + randomDither *= 2 * MEDIAMETRICS_DITHER; + // Translate the random number to [1 - MEDIAMETRICS_DITHER, 1 + MEDIAMETRICS_DITHER]. + randomDither += 1 - MEDIAMETRICS_DITHER; + return value != -1 ? (long) (value * randomDither) : -1; + } + private static void assertValidNames(@NonNull String[] names) { for (String name : names) { if (!EXTRACTOR_FACTORIES_BY_NAME.containsKey(name)) { @@ -2070,9 +2182,26 @@ public final class MediaParser { } } + // Native methods. + + private native void nativeSubmitMetrics( + String parserName, + boolean createdByName, + String parserPool, + String lastObservedExceptionName, + long resourceByteCount, + long durationMillis, + String trackMimeTypes, + String trackCodecs, + String alteredParameters, + int videoWidth, + int videoHeight); + // Static initialization. static { + System.loadLibrary(JNI_LIBRARY_NAME); + // Using a LinkedHashMap to keep the insertion order when iterating over the keys. LinkedHashMap<String, ExtractorFactory> extractorFactoriesByName = new LinkedHashMap<>(); // Parsers are ordered to match ExoPlayer's DefaultExtractorsFactory extractor ordering, @@ -2125,6 +2254,15 @@ public final class MediaParser { // We do not check PARAMETER_EXPOSE_CAPTION_FORMATS here, and we do it in setParameters // instead. Checking that the value is a List is insufficient to catch wrong parameter // value types. + int sumOfParameterNameLengths = + expectedTypeByParameterName.keySet().stream() + .map(String::length) + .reduce(0, Integer::sum); + sumOfParameterNameLengths += PARAMETER_EXPOSE_CAPTION_FORMATS.length(); + // Add space for any required separators. + MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH = + sumOfParameterNameLengths + expectedTypeByParameterName.size(); + EXPECTED_TYPE_BY_PARAMETER_NAME = Collections.unmodifiableMap(expectedTypeByParameterName); } } diff --git a/apex/media/framework/jni/android_media_MediaParserJNI.cpp b/apex/media/framework/jni/android_media_MediaParserJNI.cpp new file mode 100644 index 000000000000..7fc4628984f5 --- /dev/null +++ b/apex/media/framework/jni/android_media_MediaParserJNI.cpp @@ -0,0 +1,92 @@ +/* + * 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. + */ + +#include <jni.h> +#include <media/MediaMetrics.h> + +#define JNI_FUNCTION(RETURN_TYPE, NAME, ...) \ + extern "C" { \ + JNIEXPORT RETURN_TYPE Java_android_media_MediaParser_##NAME(JNIEnv* env, jobject thiz, \ + ##__VA_ARGS__); \ + } \ + JNIEXPORT RETURN_TYPE Java_android_media_MediaParser_##NAME(JNIEnv* env, jobject thiz, \ + ##__VA_ARGS__) + +namespace { + +constexpr char kMediaMetricsKey[] = "mediaparser"; + +constexpr char kAttributeParserName[] = "android.media.mediaparser.parserName"; +constexpr char kAttributeCreatedByName[] = "android.media.mediaparser.createdByName"; +constexpr char kAttributeParserPool[] = "android.media.mediaparser.parserPool"; +constexpr char kAttributeLastException[] = "android.media.mediaparser.lastException"; +constexpr char kAttributeResourceByteCount[] = "android.media.mediaparser.resourceByteCount"; +constexpr char kAttributeDurationMillis[] = "android.media.mediaparser.durationMillis"; +constexpr char kAttributeTrackMimeTypes[] = "android.media.mediaparser.trackMimeTypes"; +constexpr char kAttributeTrackCodecs[] = "android.media.mediaparser.trackCodecs"; +constexpr char kAttributeAlteredParameters[] = "android.media.mediaparser.alteredParameters"; +constexpr char kAttributeVideoWidth[] = "android.media.mediaparser.videoWidth"; +constexpr char kAttributeVideoHeight[] = "android.media.mediaparser.videoHeight"; + +// Util class to handle string resource management. +class JstringHandle { +public: + JstringHandle(JNIEnv* env, jstring value) : mEnv(env), mJstringValue(value) { + mCstringValue = env->GetStringUTFChars(value, /* isCopy= */ nullptr); + } + + ~JstringHandle() { + if (mCstringValue != nullptr) { + mEnv->ReleaseStringUTFChars(mJstringValue, mCstringValue); + } + } + + [[nodiscard]] const char* value() const { + return mCstringValue != nullptr ? mCstringValue : ""; + } + + JNIEnv* mEnv; + jstring mJstringValue; + const char* mCstringValue; +}; + +} // namespace + +JNI_FUNCTION(void, nativeSubmitMetrics, jstring parserNameJstring, jboolean createdByName, + jstring parserPoolJstring, jstring lastExceptionJstring, jlong resourceByteCount, + jlong durationMillis, jstring trackMimeTypesJstring, jstring trackCodecsJstring, + jstring alteredParameters, jint videoWidth, jint videoHeight) { + mediametrics_handle_t item(mediametrics_create(kMediaMetricsKey)); + mediametrics_setCString(item, kAttributeParserName, + JstringHandle(env, parserNameJstring).value()); + mediametrics_setInt32(item, kAttributeCreatedByName, createdByName ? 1 : 0); + mediametrics_setCString(item, kAttributeParserPool, + JstringHandle(env, parserPoolJstring).value()); + mediametrics_setCString(item, kAttributeLastException, + JstringHandle(env, lastExceptionJstring).value()); + mediametrics_setInt64(item, kAttributeResourceByteCount, resourceByteCount); + mediametrics_setInt64(item, kAttributeDurationMillis, durationMillis); + mediametrics_setCString(item, kAttributeTrackMimeTypes, + JstringHandle(env, trackMimeTypesJstring).value()); + mediametrics_setCString(item, kAttributeTrackCodecs, + JstringHandle(env, trackCodecsJstring).value()); + mediametrics_setCString(item, kAttributeAlteredParameters, + JstringHandle(env, alteredParameters).value()); + mediametrics_setInt32(item, kAttributeVideoWidth, videoWidth); + mediametrics_setInt32(item, kAttributeVideoHeight, videoHeight); + mediametrics_selfRecord(item); + mediametrics_delete(item); +} diff --git a/api/current.txt b/api/current.txt index 1c05b6041ef4..014f124c5dd2 100644 --- a/api/current.txt +++ b/api/current.txt @@ -97,6 +97,7 @@ package android { field public static final String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE"; field public static final String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS"; field public static final String MANAGE_EXTERNAL_STORAGE = "android.permission.MANAGE_EXTERNAL_STORAGE"; + field public static final String MANAGE_ONGOING_CALLS = "android.permission.MANAGE_ONGOING_CALLS"; field public static final String MANAGE_OWN_CALLS = "android.permission.MANAGE_OWN_CALLS"; field public static final String MASTER_CLEAR = "android.permission.MASTER_CLEAR"; field public static final String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL"; @@ -17864,6 +17865,7 @@ package android.hardware.camera2 { public class CaptureResult extends android.hardware.camera2.CameraMetadata<android.hardware.camera2.CaptureResult.Key<?>> { method @Nullable public <T> T get(android.hardware.camera2.CaptureResult.Key<T>); + method @NonNull public String getCameraId(); method public long getFrameNumber(); method @NonNull public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys(); method @NonNull public android.hardware.camera2.CaptureRequest getRequest(); @@ -28808,6 +28810,7 @@ package android.media.session { public final class MediaController { ctor public MediaController(@NonNull android.content.Context, @NonNull android.media.session.MediaSession.Token); method public void adjustVolume(int, int); + method @Deprecated public boolean controlsSameSession(@Nullable android.media.session.MediaController); method public boolean dispatchMediaButtonEvent(@NonNull android.view.KeyEvent); method @Nullable public android.os.Bundle getExtras(); method public long getFlags(); @@ -31859,6 +31862,15 @@ package android.net.wifi.aware { method public void onAttached(android.net.wifi.aware.WifiAwareSession); } + public final class AwareResources implements android.os.Parcelable { + method public int describeContents(); + method public int getNumOfAvailableDataPaths(); + method public int getNumOfAvailablePublishSessions(); + method public int getNumOfAvailableSubscribeSessions(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.AwareResources> CREATOR; + } + public final class Characteristics implements android.os.Parcelable { method public int describeContents(); method public int getMaxMatchFilterLength(); @@ -31961,7 +31973,8 @@ package android.net.wifi.aware { public class WifiAwareManager { method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @Nullable android.os.Handler); method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler); - method public android.net.wifi.aware.Characteristics getCharacteristics(); + method @Nullable public android.net.wifi.aware.AwareResources getAvailableAwareResources(); + method @Nullable public android.net.wifi.aware.Characteristics getCharacteristics(); method public boolean isAvailable(); method public boolean isDeviceAttached(); method public boolean isInstantCommunicationModeEnabled(); @@ -38882,6 +38895,9 @@ package android.provider { ctor public CallLog.Calls(); method public static String getLastOutgoingCall(android.content.Context); field public static final int ANSWERED_EXTERNALLY_TYPE = 7; // 0x7 + field public static final long AUTO_MISSED_EMERGENCY_CALL = 1L; // 0x1L + field public static final long AUTO_MISSED_MAXIMUM_DIALING = 4L; // 0x4L + field public static final long AUTO_MISSED_MAXIMUM_RINGING = 2L; // 0x2L field public static final int BLOCKED_TYPE = 6; // 0x6 field public static final String BLOCK_REASON = "block_reason"; field public static final int BLOCK_REASON_BLOCKED_NUMBER = 3; // 0x3 @@ -38927,6 +38943,8 @@ package android.provider { field public static final String IS_READ = "is_read"; field public static final String LAST_MODIFIED = "last_modified"; field public static final String LIMIT_PARAM_KEY = "limit"; + field public static final String MISSED_REASON = "missed_reason"; + field public static final long MISSED_REASON_NOT_MISSED = 0L; // 0x0L field public static final int MISSED_TYPE = 3; // 0x3 field public static final String NEW = "new"; field public static final String NUMBER = "number"; @@ -38943,6 +38961,13 @@ package android.provider { field public static final int REJECTED_TYPE = 5; // 0x5 field public static final String TRANSCRIPTION = "transcription"; field public static final String TYPE = "type"; + field public static final long USER_MISSED_CALL_FILTERS_TIMEOUT = 4194304L; // 0x400000L + field public static final long USER_MISSED_CALL_SCREENING_SERVICE_SILENCED = 2097152L; // 0x200000L + field public static final long USER_MISSED_DND_MODE = 262144L; // 0x40000L + field public static final long USER_MISSED_LOW_RING_VOLUME = 524288L; // 0x80000L + field public static final long USER_MISSED_NO_ANSWER = 65536L; // 0x10000L + field public static final long USER_MISSED_NO_VIBRATE = 1048576L; // 0x100000L + field public static final long USER_MISSED_SHORT_RING = 131072L; // 0x20000L field public static final String VIA_NUMBER = "via_number"; field public static final int VOICEMAIL_TYPE = 4; // 0x4 field public static final String VOICEMAIL_URI = "voicemail_uri"; @@ -44135,13 +44160,13 @@ package android.service.notification { method public boolean canBubble(); method public boolean canShowBadge(); method public android.app.NotificationChannel getChannel(); + method @Nullable public android.content.pm.ShortcutInfo getConversationShortcutInfo(); method public int getImportance(); method public CharSequence getImportanceExplanation(); method public String getKey(); method public long getLastAudiblyAlertedMillis(); method public String getOverrideGroupKey(); method public int getRank(); - method @Nullable public android.content.pm.ShortcutInfo getShortcutInfo(); method @NonNull public java.util.List<android.app.Notification.Action> getSmartActions(); method @NonNull public java.util.List<java.lang.CharSequence> getSmartReplies(); method public int getSuppressedVisualEffects(); @@ -46495,6 +46520,7 @@ package android.telecom { method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber(android.telecom.PhoneAccountHandle); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String, android.telecom.PhoneAccountHandle); + method public boolean hasCompanionInCallServiceAccess(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInCall(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInManagedCall(); method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle); @@ -47892,6 +47918,7 @@ package android.telephony { method @NonNull public java.util.List<java.lang.Integer> getAvailableServices(); method @Nullable public android.telephony.CellIdentity getCellIdentity(); method public int getDomain(); + method public int getNrState(); method @Nullable public String getRegisteredPlmn(); method public int getTransportType(); method public boolean isRegistered(); @@ -53763,7 +53790,6 @@ package android.view { } public interface OnReceiveContentCallback<T extends android.view.View> { - method @NonNull public java.util.Set<java.lang.String> getSupportedMimeTypes(@NonNull T); method public boolean onReceiveContent(@NonNull T, @NonNull android.view.OnReceiveContentCallback.Payload); } @@ -54341,7 +54367,7 @@ package android.view { method @IdRes public int getNextFocusRightId(); method @IdRes public int getNextFocusUpId(); method public android.view.View.OnFocusChangeListener getOnFocusChangeListener(); - method @Nullable public android.view.OnReceiveContentCallback<? extends android.view.View> getOnReceiveContentCallback(); + method @Nullable public String[] getOnReceiveContentMimeTypes(); method @ColorInt public int getOutlineAmbientShadowColor(); method public android.view.ViewOutlineProvider getOutlineProvider(); method @ColorInt public int getOutlineSpotShadowColor(); @@ -54536,6 +54562,7 @@ package android.view { method public void onProvideContentCaptureStructure(@NonNull android.view.ViewStructure, int); method public void onProvideStructure(android.view.ViewStructure); method public void onProvideVirtualStructure(android.view.ViewStructure); + method public boolean onReceiveContent(@NonNull android.view.OnReceiveContentCallback.Payload); method public android.view.PointerIcon onResolvePointerIcon(android.view.MotionEvent, int); method @CallSuper protected void onRestoreInstanceState(android.os.Parcelable); method public void onRtlPropertiesChanged(int); @@ -54693,7 +54720,7 @@ package android.view { method public void setOnHoverListener(android.view.View.OnHoverListener); method public void setOnKeyListener(android.view.View.OnKeyListener); method public void setOnLongClickListener(@Nullable android.view.View.OnLongClickListener); - method public void setOnReceiveContentCallback(@Nullable android.view.OnReceiveContentCallback<? extends android.view.View>); + method public void setOnReceiveContentCallback(@Nullable String[], @Nullable android.view.OnReceiveContentCallback); method public void setOnScrollChangeListener(android.view.View.OnScrollChangeListener); method @Deprecated public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener); method public void setOnTouchListener(android.view.View.OnTouchListener); @@ -61523,7 +61550,6 @@ package android.widget { method public int getMinWidth(); method public final android.text.method.MovementMethod getMovementMethod(); method public int getOffsetForPosition(float, float); - method @Nullable public android.view.OnReceiveContentCallback<android.widget.TextView> getOnReceiveContentCallback(); method public android.text.TextPaint getPaint(); method public int getPaintFlags(); method public String getPrivateImeOptions(); @@ -61712,7 +61738,6 @@ package android.widget { public class TextViewOnReceiveContentCallback implements android.view.OnReceiveContentCallback<android.widget.TextView> { ctor public TextViewOnReceiveContentCallback(); - method @NonNull public java.util.Set<java.lang.String> getSupportedMimeTypes(@NonNull android.widget.TextView); method public boolean onReceiveContent(@NonNull android.widget.TextView, @NonNull android.view.OnReceiveContentCallback.Payload); } diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index 872f1f2c0591..8ca290fb1b09 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -185,6 +185,7 @@ package android.provider { public final class DeviceConfig { field public static final String NAMESPACE_ALARM_MANAGER = "alarm_manager"; + field public static final String NAMESPACE_APP_STANDBY = "app_standby"; field public static final String NAMESPACE_DEVICE_IDLE = "device_idle"; } diff --git a/api/system-current.txt b/api/system-current.txt index 98e79827a719..4f74874a7838 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -109,7 +109,8 @@ package android { field public static final String LOCK_DEVICE = "android.permission.LOCK_DEVICE"; field public static final String LOOP_RADIO = "android.permission.LOOP_RADIO"; field public static final String MANAGE_ACCESSIBILITY = "android.permission.MANAGE_ACCESSIBILITY"; - field public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; + field @Deprecated public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; + field public static final String MANAGE_ACTIVITY_TASKS = "android.permission.MANAGE_ACTIVITY_TASKS"; field public static final String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS"; field public static final String MANAGE_APP_PREDICTIONS = "android.permission.MANAGE_APP_PREDICTIONS"; field public static final String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS"; @@ -403,6 +404,7 @@ package android.app { field public static final String OPSTR_LOADER_USAGE_STATS = "android:loader_usage_stats"; field public static final String OPSTR_MANAGE_EXTERNAL_STORAGE = "android:manage_external_storage"; field public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels"; + field public static final String OPSTR_MANAGE_ONGOING_CALLS = "android:manage_ongoing_calls"; field public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone"; field public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells"; field public static final String OPSTR_PLAY_AUDIO = "android:play_audio"; @@ -917,6 +919,7 @@ package android.app.admin { field public static final int PROVISIONING_TRIGGER_QR_CODE = 2; // 0x2 field public static final int PROVISIONING_TRIGGER_UNSPECIFIED = 0; // 0x0 field public static final int STATE_USER_PROFILE_COMPLETE = 4; // 0x4 + field public static final int STATE_USER_PROFILE_FINALIZED = 5; // 0x5 field public static final int STATE_USER_SETUP_COMPLETE = 2; // 0x2 field public static final int STATE_USER_SETUP_FINALIZED = 3; // 0x3 field public static final int STATE_USER_SETUP_INCOMPLETE = 1; // 0x1 @@ -2199,6 +2202,7 @@ package android.content.pm { method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable String); method @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable android.content.pm.SuspendDialogInfo); method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public void setSyntheticAppDetailsActivityEnabled(@NonNull String, boolean); + method public void setSystemAppState(@NonNull String, int); method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public abstract void setUpdateAvailable(@NonNull String, boolean); method @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public abstract boolean updateIntentVerificationStatusAsUser(@NonNull String, int, int); method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle); @@ -2277,11 +2281,16 @@ package android.content.pm { field @Deprecated public static final int MASK_PERMISSION_FLAGS = 255; // 0xff field public static final int MATCH_ANY_USER = 4194304; // 0x400000 field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000 + field public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 536870912; // 0x20000000 field public static final int MATCH_INSTANT = 8388608; // 0x800000 field public static final int MODULE_APEX_NAME = 1; // 0x1 field public static final int RESTRICTION_HIDE_FROM_SUGGESTIONS = 1; // 0x1 field public static final int RESTRICTION_HIDE_NOTIFICATIONS = 2; // 0x2 field public static final int RESTRICTION_NONE = 0; // 0x0 + field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN = 0; // 0x0 + field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE = 1; // 0x1 + field public static final int SYSTEM_APP_STATE_INSTALLED = 2; // 0x2 + field public static final int SYSTEM_APP_STATE_UNINSTALLED = 3; // 0x3 } public abstract static class PackageManager.DexModuleRegisterCallback { @@ -6694,6 +6703,7 @@ package android.net { method @NonNull public int[] getTransportTypes(); method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities); field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16 + field public static final int NET_CAPABILITY_OEM_PRIVATE = 26; // 0x1a field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18 } @@ -7490,8 +7500,10 @@ package android.net.wifi { public final class SoftApConfiguration implements android.os.Parcelable { method @NonNull public java.util.List<android.net.MacAddress> getAllowedClientList(); method public int getBand(); + method @NonNull public int[] getBands(); method @NonNull public java.util.List<android.net.MacAddress> getBlockedClientList(); method public int getChannel(); + method @NonNull public android.util.SparseIntArray getChannels(); method public int getMacRandomizationSetting(); method public int getMaxNumberOfClients(); method public long getShutdownTimeoutMillis(); @@ -7513,9 +7525,11 @@ package android.net.wifi { method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAllowedClientList(@NonNull java.util.List<android.net.MacAddress>); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAutoShutdownEnabled(boolean); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBand(int); + method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBands(@NonNull int[]); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBlockedClientList(@NonNull java.util.List<android.net.MacAddress>); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBssid(@Nullable android.net.MacAddress); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannel(int, int); + method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannels(@NonNull android.util.SparseIntArray); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setClientControlByUserEnabled(boolean); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setHiddenSsid(boolean); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setMacRandomizationSetting(int); @@ -10024,6 +10038,7 @@ package android.service.autofill { public static final class Dataset.Builder { ctor public Dataset.Builder(@NonNull android.service.autofill.InlinePresentation); + method @NonNull public android.service.autofill.Dataset.Builder setContent(@NonNull android.view.autofill.AutofillId, @Nullable android.content.ClipData); method @NonNull public android.service.autofill.Dataset.Builder setFieldInlinePresentation(@NonNull android.view.autofill.AutofillId, @Nullable android.view.autofill.AutofillValue, @Nullable java.util.regex.Pattern, @NonNull android.service.autofill.InlinePresentation); } @@ -11803,6 +11818,7 @@ package android.telephony { method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMobileDataPolicyEnabled(int); + method public boolean isNrDualConnectivityEnabled(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String); @@ -11836,6 +11852,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabledStatus(int, boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean); + method public int setNrDualConnectivityState(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean); @@ -11875,6 +11892,11 @@ package android.telephony { field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1 field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0 field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE = 4; // 0x4 + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED = 1; // 0x1 + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR = 3; // 0x3 + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE = 2; // 0x2 + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS = 0; // 0x0 field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION"; field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID"; field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE"; @@ -11907,6 +11929,9 @@ package android.telephony { field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L + field public static final int NR_DUAL_CONNECTIVITY_DISABLE = 2; // 0x2 + field public static final int NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE = 3; // 0x3 + field public static final int NR_DUAL_CONNECTIVITY_ENABLE = 1; // 0x1 field public static final int RADIO_POWER_OFF = 0; // 0x0 field public static final int RADIO_POWER_ON = 1; // 0x1 field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2 @@ -12018,7 +12043,8 @@ package android.telephony.data { method public int getMtuV6(); method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses(); method public int getProtocolType(); - method public int getSuggestedRetryTime(); + method public long getRetryIntervalMillis(); + method @Deprecated public int getSuggestedRetryTime(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR; field public static final int HANDOVER_FAILURE_MODE_DO_FALLBACK = 1; // 0x1 @@ -12030,6 +12056,7 @@ package android.telephony.data { field public static final int LINK_STATUS_DORMANT = 1; // 0x1 field public static final int LINK_STATUS_INACTIVE = 0; // 0x0 field public static final int LINK_STATUS_UNKNOWN = -1; // 0xffffffff + field public static final int RETRY_INTERVAL_UNDEFINED = -1; // 0xffffffff } public static final class DataCallResponse.Builder { @@ -12048,7 +12075,8 @@ package android.telephony.data { method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>); method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int); - method @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setRetryIntervalMillis(long); + method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int); } public final class DataProfile implements android.os.Parcelable { diff --git a/api/test-current.txt b/api/test-current.txt index 59020068e342..0a8f7a59d3b1 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -12,7 +12,8 @@ package android { field public static final String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS"; field public static final String CONTROL_DEVICE_LIGHTS = "android.permission.CONTROL_DEVICE_LIGHTS"; field public static final String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES"; - field public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; + field @Deprecated public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; + field public static final String MANAGE_ACTIVITY_TASKS = "android.permission.MANAGE_ACTIVITY_TASKS"; field public static final String MANAGE_CRATES = "android.permission.MANAGE_CRATES"; field public static final String MANAGE_NOTIFICATION_LISTENERS = "android.permission.MANAGE_NOTIFICATION_LISTENERS"; field public static final String MANAGE_ROLLBACKS = "android.permission.MANAGE_ROLLBACKS"; @@ -84,7 +85,7 @@ package android.app { method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener); method public void alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName); method public long getTotalRam(); - method @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) public void holdLock(int); + method public void holdLock(android.os.IBinder, int); method public static boolean isHighEndGfx(); method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void removeHomeVisibilityListener(@NonNull android.app.HomeVisibilityListener); method @RequiresPermission(android.Manifest.permission.RESET_APP_ERRORS) public void resetAppErrors(); @@ -128,19 +129,20 @@ package android.app { } public class ActivityTaskManager { - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void clearLaunchParamsForPackages(java.util.List<java.lang.String>); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void clearLaunchParamsForPackages(java.util.List<java.lang.String>); method public static boolean currentUiModeSupportsErrorDialogs(@NonNull android.content.Context); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void moveTaskToRootTask(int, int, boolean); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean moveTopActivityToPinnedRootTask(int, @NonNull android.graphics.Rect); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeRootTasksInWindowingModes(@NonNull int[]); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeRootTasksWithActivityTypes(@NonNull int[]); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void requestPictureInPictureMode(@NonNull android.os.IBinder); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizePrimarySplitScreen(@NonNull android.graphics.Rect, @NonNull android.graphics.Rect); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeTask(int, android.graphics.Rect); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean setTaskWindowingMode(int, int, boolean) throws java.lang.SecurityException; - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean) throws java.lang.SecurityException; - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void startSystemLockTaskMode(int); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void stopSystemLockTaskMode(); + method public static int getMaxNumPictureInPictureActions(@NonNull android.content.Context); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void moveTaskToRootTask(int, int, boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean moveTopActivityToPinnedRootTask(int, @NonNull android.graphics.Rect); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void removeRootTasksInWindowingModes(@NonNull int[]); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void removeRootTasksWithActivityTypes(@NonNull int[]); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void requestPictureInPictureMode(@NonNull android.os.IBinder); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void resizePrimarySplitScreen(@NonNull android.graphics.Rect, @NonNull android.graphics.Rect); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void resizeTask(int, android.graphics.Rect); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean setTaskWindowingMode(int, int, boolean) throws java.lang.SecurityException; + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean) throws java.lang.SecurityException; + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void startSystemLockTaskMode(int); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void stopSystemLockTaskMode(); method public static boolean supportsMultiWindow(android.content.Context); method public static boolean supportsSplitScreenMultiWindow(android.content.Context); field public static final int DEFAULT_MINIMAL_SPLIT_SCREEN_DISPLAY_SIZE_DP = 440; // 0x1b8 @@ -210,6 +212,7 @@ package android.app { field public static final String KEY_BG_STATE_SETTLE_TIME = "bg_state_settle_time"; field public static final String KEY_FG_SERVICE_STATE_SETTLE_TIME = "fg_service_state_settle_time"; field public static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time"; + field public static final String OPSTR_MANAGE_ONGOING_CALLS = "android:manage_ongoing_calls"; field public static final int OP_COARSE_LOCATION = 0; // 0x0 field public static final int OP_RECORD_AUDIO = 27; // 0x1b field public static final int OP_START_FOREGROUND = 76; // 0x4c @@ -284,6 +287,7 @@ package android.app { public class TaskInfo { method @NonNull public android.content.res.Configuration getConfiguration(); + method @Nullable public android.app.PictureInPictureParams getPictureInPictureParams(); method @NonNull public android.window.WindowContainerToken getToken(); } @@ -533,6 +537,7 @@ package android.content.pm { public abstract class PackageManager { method @Nullable public String getContentCaptureServicePackageName(); method @Nullable public String getDefaultTextClassifierPackageName(); + method @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) public android.os.IBinder getHoldLockToken(); method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle); method @NonNull public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int); method @Nullable public abstract String[] getNamesForUids(int[]); @@ -541,7 +546,7 @@ package android.content.pm { method @NonNull public abstract String getSharedSystemSharedLibraryPackageName(); method @Nullable public String getSystemTextClassifierPackageName(); method @Nullable public String getWellbeingPackageName(); - method @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) public void holdLock(int); + method public void holdLock(android.os.IBinder, int); field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage"; field public static final String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption"; field public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED = 128; // 0x80 @@ -1553,6 +1558,19 @@ package android.service.autofill { method @Nullable public android.util.SparseArray<android.service.autofill.InternalOnClickAction> getActions(); } + public final class Dataset implements android.os.Parcelable { + method @Nullable public android.content.IntentSender getAuthentication(); + method @Nullable public android.content.ClipData getFieldContent(); + method @Nullable public java.util.ArrayList<android.view.autofill.AutofillId> getFieldIds(); + method @Nullable public java.util.ArrayList<android.view.autofill.AutofillValue> getFieldValues(); + method @Nullable public String getId(); + method public boolean isEmpty(); + } + + public static final class Dataset.Builder { + method @NonNull public android.service.autofill.Dataset.Builder setContent(@NonNull android.view.autofill.AutofillId, @Nullable android.content.ClipData); + } + public final class DateTransformation extends android.service.autofill.InternalTransformation implements android.os.Parcelable android.service.autofill.Transformation { method public void apply(@NonNull android.service.autofill.ValueFinder, @NonNull android.widget.RemoteViews, int) throws java.lang.Exception; } @@ -2035,7 +2053,7 @@ package android.view { } public interface WindowManager extends android.view.ViewManager { - method @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) public default void holdLock(int); + method public default void holdLock(android.os.IBinder, int); method public default void setShouldShowIme(int, boolean); method public default void setShouldShowSystemDecors(int, boolean); method public default void setShouldShowWithInsecureKeyguard(int, boolean); @@ -2336,6 +2354,15 @@ package android.widget.inline { package android.window { + public final class DisplayAreaAppearedInfo implements android.os.Parcelable { + ctor public DisplayAreaAppearedInfo(@NonNull android.window.DisplayAreaInfo, @NonNull android.view.SurfaceControl); + method public int describeContents(); + method @NonNull public android.window.DisplayAreaInfo getDisplayAreaInfo(); + method @NonNull public android.view.SurfaceControl getLeash(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.window.DisplayAreaAppearedInfo> CREATOR; + } + public final class DisplayAreaInfo implements android.os.Parcelable { ctor public DisplayAreaInfo(@NonNull android.window.WindowContainerToken, int, int); method public int describeContents(); @@ -2351,7 +2378,7 @@ package android.window { ctor public DisplayAreaOrganizer(); method public void onDisplayAreaAppeared(@NonNull android.window.DisplayAreaInfo, @NonNull android.view.SurfaceControl); method public void onDisplayAreaVanished(@NonNull android.window.DisplayAreaInfo); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void registerOrganizer(int); + method @CallSuper @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.window.DisplayAreaAppearedInfo> registerOrganizer(int); field public static final int FEATURE_DEFAULT_TASK_CONTAINER = 1; // 0x1 field public static final int FEATURE_ONE_HANDED = 3; // 0x3 field public static final int FEATURE_ROOT = 0; // 0x0 @@ -2374,19 +2401,19 @@ package android.window { public class TaskOrganizer extends android.window.WindowOrganizer { ctor public TaskOrganizer(); - method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public android.app.ActivityManager.RunningTaskInfo createRootTask(int, int); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean deleteRootTask(@NonNull android.window.WindowContainerToken); - method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]); - method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public android.window.WindowContainerToken getImeTarget(int); - method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]); + method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void createRootTask(int, int, @Nullable android.os.IBinder); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean deleteRootTask(@NonNull android.window.WindowContainerToken); + method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]); + method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public android.window.WindowContainerToken getImeTarget(int); + method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]); method @BinderThread public void onBackPressedOnTaskRoot(@NonNull android.app.ActivityManager.RunningTaskInfo); method @BinderThread public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo, @NonNull android.view.SurfaceControl); method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo); method @BinderThread public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo); - method @CallSuper @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public java.util.List<android.window.TaskAppearedInfo> registerOrganizer(); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(@NonNull android.window.WindowContainerToken, boolean); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setLaunchRoot(int, @NonNull android.window.WindowContainerToken); - method @CallSuper @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void unregisterOrganizer(); + method @CallSuper @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.window.TaskAppearedInfo> registerOrganizer(); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void setInterceptBackPressedOnTaskRoot(@NonNull android.window.WindowContainerToken, boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void setLaunchRoot(int, @NonNull android.window.WindowContainerToken); + method @CallSuper @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void unregisterOrganizer(); } public final class WindowContainerToken implements android.os.Parcelable { @@ -2421,8 +2448,8 @@ package android.window { public class WindowOrganizer { ctor public WindowOrganizer(); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public int applySyncTransaction(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.WindowContainerTransactionCallback); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void applyTransaction(@NonNull android.window.WindowContainerTransaction); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public int applySyncTransaction(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.WindowContainerTransactionCallback); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void applyTransaction(@NonNull android.window.WindowContainerTransaction); } } diff --git a/api/test-lint-baseline.txt b/api/test-lint-baseline.txt index 0440d1a95065..c0b40931f1e6 100644 --- a/api/test-lint-baseline.txt +++ b/api/test-lint-baseline.txt @@ -539,6 +539,8 @@ InternalField: android.telephony.ims.ImsConferenceState#mParticipants: KotlinOperator: android.os.WorkSource#get(int): +KotlinOperator: android.util.SparseArrayMap#get(int, K): + KotlinOperator: android.util.SparseArrayMap#get(int, String): @@ -594,17 +596,17 @@ MinMaxConstant: android.view.autofill.AutofillManager#MAX_TEMP_AUGMENTED_SERVICE MissingGetterMatchingBuilder: android.app.ActivityView.Builder#setAttributeSet(android.util.AttributeSet): - android.app.ActivityView does not declare a `getAttributeSet()` method matching method android.app.ActivityView.Builder.setAttributeSet(android.util.AttributeSet) + MissingGetterMatchingBuilder: android.app.ActivityView.Builder#setDefaultStyle(int): - android.app.ActivityView does not declare a `getDefaultStyle()` method matching method android.app.ActivityView.Builder.setDefaultStyle(int) + MissingGetterMatchingBuilder: android.app.ActivityView.Builder#setDisableSurfaceViewBackgroundLayer(boolean): - android.app.ActivityView does not declare a `isDisableSurfaceViewBackgroundLayer()` method matching method android.app.ActivityView.Builder.setDisableSurfaceViewBackgroundLayer(boolean) + MissingGetterMatchingBuilder: android.app.ActivityView.Builder#setSingleInstance(boolean): - android.app.ActivityView does not declare a `isSingleInstance()` method matching method android.app.ActivityView.Builder.setSingleInstance(boolean) + MissingGetterMatchingBuilder: android.app.ActivityView.Builder#setUsePublicVirtualDisplay(boolean): - android.app.ActivityView does not declare a `isUsePublicVirtualDisplay()` method matching method android.app.ActivityView.Builder.setUsePublicVirtualDisplay(boolean) + MissingGetterMatchingBuilder: android.app.ActivityView.Builder#setUseTrustedDisplay(boolean): - android.app.ActivityView does not declare a `isUseTrustedDisplay()` method matching method android.app.ActivityView.Builder.setUseTrustedDisplay(boolean) + MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setAttributionTag(String): MissingGetterMatchingBuilder: android.app.AppOpsManager.HistoricalOpsRequest.Builder#setFlags(int): @@ -751,6 +753,8 @@ MissingNullability: android.app.ActivityManager#forceStopPackage(String) paramet MissingNullability: android.app.ActivityManager#getPackageImportance(String) parameter #0: +MissingNullability: android.app.ActivityManager#holdLock(android.os.IBinder, int) parameter #0: + MissingNullability: android.app.ActivityManager#removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener) parameter #0: MissingNullability: android.app.ActivityManager#scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int) parameter #0: @@ -935,8 +939,12 @@ MissingNullability: android.content.pm.LauncherApps#LauncherApps(android.content MissingNullability: android.content.pm.PackageInstaller.SessionParams#setGrantedRuntimePermissions(String[]) parameter #0: +MissingNullability: android.content.pm.PackageManager#getHoldLockToken(): + Missing nullability on method `BINDER` return MissingNullability: android.content.pm.PackageManager#getNamesForUids(int[]) parameter #0: +MissingNullability: android.content.pm.PackageManager#holdLock(android.os.IBinder, int) parameter #0: + MissingNullability: android.content.pm.ShortcutManager#ShortcutManager(android.content.Context) parameter #0: MissingNullability: android.content.res.AssetManager#getOverlayablesToString(String) parameter #0: @@ -2313,6 +2321,8 @@ MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #2: +MissingNullability: android.view.WindowManager#holdLock(android.os.IBinder, int) parameter #0: + MissingNullability: android.view.WindowManager.LayoutParams#accessibilityTitle: MissingNullability: android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener#onAccessibilityServicesStateChanged(android.view.accessibility.AccessibilityManager) parameter #0: @@ -2893,6 +2903,10 @@ SetterReturnsThis: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyS +StartWithLower: android.content.pm.PackageManager#BINDER(): + Method name must start with lowercase char: BINDER + + StaticFinalBuilder: android.content.integrity.RuleSet.Builder: StaticFinalBuilder: android.hardware.display.BrightnessConfiguration.Builder: diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index c9356c55e6a1..a379847f21da 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -59,6 +59,7 @@ import "frameworks/base/core/proto/android/stats/mediaprovider/mediaprovider_enu import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto"; import "frameworks/base/core/proto/android/stats/style/style_enums.proto"; import "frameworks/base/core/proto/android/stats/sysui/notification_enums.proto"; +import "frameworks/base/core/proto/android/stats/tls/enums.proto"; import "frameworks/base/core/proto/android/telecomm/enums.proto"; import "frameworks/base/core/proto/android/telephony/enums.proto"; import "frameworks/base/core/proto/android/view/enums.proto"; @@ -495,9 +496,12 @@ message Atom { HdmiCecMessageReported hdmi_cec_message_reported = 310 [(module) = "framework"]; AirplaneMode airplane_mode = 311 [(module) = "telephony"]; ModemRestart modem_restart = 312 [(module) = "telephony"]; - CarrierIdMismatchEvent carrier_id_mismatch_event = 313 [(module) = "telephony"]; - CarrierIdMatchingTable carrier_id_table_update = 314 [(module) = "telephony"]; + CarrierIdMismatchReported carrier_id_mismatch_reported = 313 [(module) = "telephony"]; + CarrierIdTableUpdated carrier_id_table_updated = 314 [(module) = "telephony"]; DataStallRecoveryReported data_stall_recovery_reported = 315 [(module) = "telephony"]; + MediametricsMediaParserReported mediametrics_mediaparser_reported = 316; + TlsHandshakeReported tls_handshake_reported = 317 [(module) = "conscrypt"]; + TextClassifierApiUsageReported text_classifier_api_usage_reported = 318 [(module) = "textclassifier"]; // StatsdStats tracks platform atoms with ids upto 500. // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value. @@ -605,7 +609,7 @@ message Atom { 10085 [(module) = "mediaprovider"]; IncomingSms incoming_sms = 10086 [(module) = "telephony"]; OutgoingSms outgoing_sms = 10087 [(module) = "telephony"]; - CarrierIdMatchingTable carrier_id_table_version = 10088 [(module) = "telephony"]; + CarrierIdTableVersion carrier_id_table_version = 10088 [(module) = "telephony"]; DataCallSession data_call_session = 10089 [(module) = "telephony"]; CellularServiceState cellular_service_state = 10090 [(module) = "telephony"]; CellularDataServiceSwitch cellular_data_service_switch = 10091 [(module) = "telephony"]; @@ -4659,7 +4663,7 @@ message PrivacyIndicatorsInteracted { UNKNOWN = 0; CHIP_VIEWED = 1; CHIP_CLICKED = 2; - reserved 3; // Used only in beta builds, never shipped + reserved 3; // Used only in beta builds, never shipped DIALOG_DISMISS = 4; DIALOG_LINE_ITEM = 5; } @@ -8197,6 +8201,72 @@ message MediametricsExtractorReported { } /** + * Track MediaParser (parsing video/audio streams from containers) usage + * Logged from: + * + * frameworks/av/services/mediametrics/statsd_mediaparser.cpp + * frameworks/base/apex/media/framework/jni/android_media_MediaParserJNI.cpp + */ +message MediametricsMediaParserReported { + optional int64 timestamp_nanos = 1; + optional string package_name = 2; + optional int64 package_version_code = 3; + + // MediaParser specific data. + /** + * The name of the parser selected for parsing the media, or an empty string + * if no parser was selected. + */ + optional string parser_name = 4; + /** + * Whether the parser was created by name. 1 represents true, and 0 + * represents false. + */ + optional int32 created_by_name = 5; + /** + * The parser names in the sniffing pool separated by "|". + */ + optional string parser_pool = 6; + /** + * The fully qualified name of the last encountered exception, or an empty + * string if no exception was encountered. + */ + optional string last_exception = 7; + /** + * The size of the parsed media in bytes, or -1 if unknown. Note this value + * contains intentional random error to prevent media content + * identification. + */ + optional int64 resource_byte_count = 8; + /** + * The duration of the media in milliseconds, or -1 if unknown. Note this + * value contains intentional random error to prevent media content + * identification. + */ + optional int64 duration_millis = 9; + /** + * The MIME types of the tracks separated by "|". + */ + optional string track_mime_types = 10; + /** + * The tracks' RFC 6381 codec strings separated by "|". + */ + optional string track_codecs = 11; + /** + * Concatenation of the parameters altered by the client, separated by "|". + */ + optional string altered_parameters = 12; + /** + * The video width in pixels, or -1 if unknown or not applicable. + */ + optional int32 video_width = 13; + /** + * The video height in pixels, or -1 if unknown or not applicable. + */ + optional int32 video_height = 14; +} + +/** * Track how we arbitrate between microphone/input requests. * Logged from * frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -10679,7 +10749,7 @@ message OutgoingSms { } /** - * Push information about usage of airplane mode. + * Logs information about usage of airplane mode. * * Logged from: * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/AirplaneModeStats.java @@ -10698,7 +10768,7 @@ message AirplaneMode { } /** - * Push information about modem restarts. + * Logs information about modem restarts. * * Logged from: * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/ModemRestartStats.java @@ -10716,7 +10786,7 @@ message ModemRestart { } /** - * Push the SIM card details when the carrier ID match is not complete. + * Logs the SIM card details when the carrier ID match is not complete. * * The atom is pushed when a SIM card is initialized and the MCC/MNC is not present in the * carrier ID table, or the SIM card contains a GID1 value that is not present in the carrier ID @@ -10725,7 +10795,7 @@ message ModemRestart { * Logged from: * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/CarrierIdMatchStats.java */ -message CarrierIdMismatchEvent { +message CarrierIdMismatchReported { // Matched carrier ID. The value -1 is used if no match is found. optional int32 carrier_id = 1; @@ -10737,17 +10807,30 @@ message CarrierIdMismatchEvent { // SPN value of the SIM card. optional string spn = 4; + + // First record of the PNN in the SIM card. This field is populated only if the SPN is missing + // or empty. + optional string pnn = 5; } /** - * Pulls/pushes the version of the carrier ID matching table. - * - * The atom is pushed when a new version is detected. + * Logs the version of the carrier ID matching table at first power up and when it is updated. * * Logged from: * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/CarrierIdMatchStats.java */ -message CarrierIdMatchingTable { +message CarrierIdTableUpdated { + // Version of the CarrierId matching table. + optional int32 table_version = 1; +} + +/** + * Pulls the version of the carrier ID matching table. + * + * Logged from: + * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java + */ +message CarrierIdTableVersion { // Version of the CarrierId matching table. optional int32 table_version = 1; } @@ -11888,3 +11971,45 @@ message HdmiCecMessageReported { // The reason for the feature abort. optional android.stats.hdmi.FeatureAbortReason feature_abort_reason = 9; } + +/** + * Pushes TLS handshake counters from Conscrypt. + * Pulled from: + * external/conscrypt/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java + * external/conscrypt/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java + */ +message TlsHandshakeReported { + optional bool success = 1; + + optional android.stats.tls.Protocol protocol = 2; + + optional android.stats.tls.CipherSuite cipher_suite = 3; + + optional int32 handshake_duration_millis = 4; +} + +/** + * Logs when a TextClassifier API is invoked. + * + * See frameworks/base/core/java/android/view/textclassifier/TextClassifier.java + * Logged from: external/libtextclassifier/java/ + */ +message TextClassifierApiUsageReported { + enum ApiType { + UNKNOWN_API = 0; + SUGGEST_SELECTION = 1; + CLASSIFY_TEXT = 2; + GENERATE_LINKS = 3; + DETECT_LANGUAGES = 4; + SUGGEST_CONVERSATION_ACTIONS = 5; + } + optional ApiType api_type = 1; + + enum ResultType { + UNKNOWN_RESULT = 0; + SUCCESS = 1; + FAIL = 2; + } + optional ResultType result_type = 2; + optional int64 latency_millis = 3; +} diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp index 3d57cfe318c5..22fdf1604435 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -18,12 +18,14 @@ #include "Log.h" #include "ValueMetricProducer.h" -#include "../guardrail/StatsdStats.h" -#include "../stats_log_util.h" #include <limits.h> #include <stdlib.h> +#include "../guardrail/StatsdStats.h" +#include "../stats_log_util.h" +#include "metrics/parsing_utils/metrics_manager_util.h" + using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_BOOL; using android::util::FIELD_TYPE_DOUBLE; @@ -184,6 +186,48 @@ ValueMetricProducer::~ValueMetricProducer() { } } +bool ValueMetricProducer::onConfigUpdatedLocked( + const StatsdConfig& config, const int configIndex, const int metricIndex, + const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, + const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap, + const unordered_map<int64_t, int>& newAtomMatchingTrackerMap, + const sp<EventMatcherWizard>& matcherWizard, + const vector<sp<ConditionTracker>>& allConditionTrackers, + const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard, + const unordered_map<int64_t, int>& metricToActivationMap, + unordered_map<int, vector<int>>& trackerToMetricMap, + unordered_map<int, vector<int>>& conditionToMetricMap, + unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap, + unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap, + vector<int>& metricsWithActivation) { + if (!MetricProducer::onConfigUpdatedLocked( + config, configIndex, metricIndex, allAtomMatchingTrackers, + oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard, + allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap, + trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap, + deactivationAtomTrackerToMetricMap, metricsWithActivation)) { + return false; + } + + const ValueMetric& metric = config.value_metric(configIndex); + // Update appropriate indices: mWhatMatcherIndex, mConditionIndex and MetricsManager maps. + if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, /*enforceOneAtom=*/false, + allAtomMatchingTrackers, newAtomMatchingTrackerMap, + trackerToMetricMap, mWhatMatcherIndex)) { + return false; + } + + if (metric.has_condition() && + !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, + metric.links(), allConditionTrackers, mConditionTrackerIndex, + conditionToMetricMap)) { + return false; + } + sp<EventMatcherWizard> tmpEventWizard = mEventMatcherWizard; + mEventMatcherWizard = matcherWizard; + return true; +} + void ValueMetricProducer::onStateChanged(int64_t eventTimeNs, int32_t atomId, const HashableDimensionKey& primaryKey, const FieldValue& oldState, const FieldValue& newState) { diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h index 67de214e655c..ebd8fecd55d0 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -47,7 +47,7 @@ struct PastValueBucket { // - a condition change // - an app upgrade // - an alarm set to the end of the bucket -class ValueMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver { +class ValueMetricProducer : public MetricProducer, public virtual PullDataReceiver { public: ValueMetricProducer( const ConfigKey& key, const ValueMetric& valueMetric, const int conditionIndex, @@ -155,7 +155,23 @@ private: // causes the bucket to be invalidated will not notify StatsdStats. void skipCurrentBucket(const int64_t dropTimeNs, const BucketDropReason reason); - const int mWhatMatcherIndex; + bool onConfigUpdatedLocked( + const StatsdConfig& config, const int configIndex, const int metricIndex, + const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, + const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap, + const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap, + const sp<EventMatcherWizard>& matcherWizard, + const std::vector<sp<ConditionTracker>>& allConditionTrackers, + const std::unordered_map<int64_t, int>& conditionTrackerMap, + const sp<ConditionWizard>& wizard, + const std::unordered_map<int64_t, int>& metricToActivationMap, + std::unordered_map<int, std::vector<int>>& trackerToMetricMap, + std::unordered_map<int, std::vector<int>>& conditionToMetricMap, + std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, + std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, + std::vector<int>& metricsWithActivation) override; + + int mWhatMatcherIndex; sp<EventMatcherWizard> mEventMatcherWizard; @@ -370,6 +386,8 @@ private: FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValue); FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse); + FRIEND_TEST(ConfigUpdateTest, TestUpdateValueMetrics); + friend class ValueMetricProducerTestHelper; }; diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp index b6e5d8846fd9..335f7753e5e3 100644 --- a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp +++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp @@ -580,7 +580,6 @@ bool determineAllMetricUpdateStatuses(const StatsdConfig& config, return false; } } - // TODO: determine update status for value metrics. return true; } @@ -644,7 +643,7 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 set<int64_t>& noReportMetricIds, unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap, unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap, - vector<int>& metricsWithActivation) { + vector<int>& metricsWithActivation, set<int64_t>& replacedMetrics) { sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers); sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchingTrackers); const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() + @@ -690,6 +689,8 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 break; } case UPDATE_REPLACE: + replacedMetrics.insert(metric.id()); + [[fallthrough]]; // Intentionally fallthrough to create the new metric producer. case UPDATE_NEW: { producer = createCountMetricProducerAndUpdateMetadata( key, config, timeBaseNs, currentTimeNs, metric, metricIndex, @@ -727,6 +728,8 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 break; } case UPDATE_REPLACE: + replacedMetrics.insert(metric.id()); + [[fallthrough]]; // Intentionally fallthrough to create the new metric producer. case UPDATE_NEW: { producer = createDurationMetricProducerAndUpdateMetadata( key, config, timeBaseNs, currentTimeNs, metric, metricIndex, @@ -749,8 +752,8 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 newMetricProducers.push_back(producer.value()); } for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) { - newMetricProducerMap[config.event_metric(i).id()] = metricIndex; const EventMetric& metric = config.event_metric(i); + newMetricProducerMap[metric.id()] = metricIndex; optional<sp<MetricProducer>> producer; switch (metricsToUpdate[metricIndex]) { case UPDATE_PRESERVE: { @@ -764,6 +767,8 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 break; } case UPDATE_REPLACE: + replacedMetrics.insert(metric.id()); + [[fallthrough]]; // Intentionally fallthrough to create the new metric producer. case UPDATE_NEW: { producer = createEventMetricProducerAndUpdateMetadata( key, config, timeBaseNs, metric, metricIndex, allAtomMatchingTrackers, @@ -784,6 +789,47 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 } newMetricProducers.push_back(producer.value()); } + + for (int i = 0; i < config.value_metric_size(); i++, metricIndex++) { + const ValueMetric& metric = config.value_metric(i); + newMetricProducerMap[metric.id()] = metricIndex; + optional<sp<MetricProducer>> producer; + switch (metricsToUpdate[metricIndex]) { + case UPDATE_PRESERVE: { + producer = updateMetric( + config, i, metricIndex, metric.id(), allAtomMatchingTrackers, + oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard, + allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap, + oldMetricProducers, metricToActivationMap, trackerToMetricMap, + conditionToMetricMap, activationAtomTrackerToMetricMap, + deactivationAtomTrackerToMetricMap, metricsWithActivation); + break; + } + case UPDATE_REPLACE: + replacedMetrics.insert(metric.id()); + [[fallthrough]]; // Intentionally fallthrough to create the new metric producer. + case UPDATE_NEW: { + producer = createValueMetricProducerAndUpdateMetadata( + key, config, timeBaseNs, currentTimeNs, pullerManager, metric, metricIndex, + allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers, + conditionTrackerMap, initialConditionCache, wizard, matcherWizard, + stateAtomIdMap, allStateGroupMaps, metricToActivationMap, + trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap, + deactivationAtomTrackerToMetricMap, metricsWithActivation); + break; + } + default: { + ALOGE("Metric \"%lld\" update state is unknown. This should never happen", + (long long)metric.id()); + return false; + } + } + if (!producer) { + return false; + } + newMetricProducers.push_back(producer.value()); + } + for (int i = 0; i < config.gauge_metric_size(); i++, metricIndex++) { const GaugeMetric& metric = config.gauge_metric(i); newMetricProducerMap[metric.id()] = metricIndex; @@ -800,6 +846,8 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 break; } case UPDATE_REPLACE: + replacedMetrics.insert(metric.id()); + [[fallthrough]]; // Intentionally fallthrough to create the new metric producer. case UPDATE_NEW: { producer = createGaugeMetricProducerAndUpdateMetadata( key, config, timeBaseNs, currentTimeNs, pullerManager, metric, metricIndex, @@ -821,7 +869,6 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 } newMetricProducers.push_back(producer.value()); } - // TODO: perform update for value metric. const set<int> atomsAllowedFromAnyUid(config.whitelisted_atom_ids().begin(), config.whitelisted_atom_ids().end()); @@ -872,6 +919,7 @@ bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const set<int64_t>& noReportMetricIds) { set<int64_t> replacedMatchers; set<int64_t> replacedConditions; + set<int64_t> replacedMetrics; vector<ConditionState> conditionCache; unordered_map<int64_t, int> stateAtomIdMap; unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps; @@ -913,7 +961,7 @@ bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const replacedStates, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds, activationTrackerToMetricMap, - deactivationTrackerToMetricMap, metricsWithActivation)) { + deactivationTrackerToMetricMap, metricsWithActivation, replacedMetrics)) { ALOGE("initMetricProducers failed"); return false; } diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h index 34d7e9c7de9e..3f1c5326b569 100644 --- a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h +++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h @@ -187,7 +187,7 @@ bool updateMetrics( std::set<int64_t>& noReportMetricIds, std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, - std::vector<int>& metricsWithActivation); + std::vector<int>& metricsWithActivation, std::set<int64_t>& replacedMetrics); // Updates the existing MetricsManager from a new StatsdConfig. // Parameters are the members of MetricsManager. See MetricsManager for declaration. diff --git a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp index b7dc2c7fd0de..8fc039a7d6b3 100644 --- a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp @@ -599,6 +599,108 @@ optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata( eventDeactivationMap)}; } +optional<sp<MetricProducer>> createValueMetricProducerAndUpdateMetadata( + const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, + const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, + const ValueMetric& metric, const int metricIndex, + const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, + const unordered_map<int64_t, int>& atomMatchingTrackerMap, + vector<sp<ConditionTracker>>& allConditionTrackers, + const unordered_map<int64_t, int>& conditionTrackerMap, + const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard, + const sp<EventMatcherWizard>& matcherWizard, + const unordered_map<int64_t, int>& stateAtomIdMap, + const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps, + const unordered_map<int64_t, int>& metricToActivationMap, + unordered_map<int, vector<int>>& trackerToMetricMap, + unordered_map<int, vector<int>>& conditionToMetricMap, + unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap, + unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap, + vector<int>& metricsWithActivation) { + if (!metric.has_id() || !metric.has_what()) { + ALOGE("cannot find metric id or \"what\" in ValueMetric \"%lld\"", (long long)metric.id()); + return nullopt; + } + if (!metric.has_value_field()) { + ALOGE("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); + return nullopt; + } + std::vector<Matcher> fieldMatchers; + translateFieldMatcher(metric.value_field(), &fieldMatchers); + if (fieldMatchers.size() < 1) { + ALOGE("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); + return nullopt; + } + + int trackerIndex; + if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, + metric.has_dimensions_in_what(), + allAtomMatchingTrackers, atomMatchingTrackerMap, + trackerToMetricMap, trackerIndex)) { + return nullopt; + } + + sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex); + // If it is pulled atom, it should be simple matcher with one tagId. + if (atomMatcher->getAtomIds().size() != 1) { + return nullopt; + } + int atomTagId = *(atomMatcher->getAtomIds().begin()); + int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1; + + int conditionIndex = -1; + if (metric.has_condition()) { + if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, + metric.links(), allConditionTrackers, conditionIndex, + conditionToMetricMap)) { + return nullopt; + } + } else if (metric.links_size() > 0) { + ALOGE("metrics has a MetricConditionLink but doesn't have a condition"); + return nullopt; + } + + std::vector<int> slicedStateAtoms; + unordered_map<int, unordered_map<int, int64_t>> stateGroupMap; + if (metric.slice_by_state_size() > 0) { + if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap, + allStateGroupMaps, slicedStateAtoms, stateGroupMap)) { + return nullopt; + } + } else if (metric.state_link_size() > 0) { + ALOGE("ValueMetric has a MetricStateLink but doesn't have a sliced state"); + return nullopt; + } + + // Check that all metric state links are a subset of dimensions_in_what fields. + std::vector<Matcher> dimensionsInWhat; + translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat); + for (const auto& stateLink : metric.state_link()) { + if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) { + return nullopt; + } + } + + unordered_map<int, shared_ptr<Activation>> eventActivationMap; + unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap; + if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap, + atomMatchingTrackerMap, activationAtomTrackerToMetricMap, + deactivationAtomTrackerToMetricMap, metricsWithActivation, + eventActivationMap, eventDeactivationMap)) { + return nullopt; + } + + uint64_t metricHash; + if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) { + return nullopt; + } + + return {new ValueMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard, + metricHash, trackerIndex, matcherWizard, pullTagId, timeBaseNs, + currentTimeNs, pullerManager, eventActivationMap, + eventDeactivationMap, slicedStateAtoms, stateGroupMap)}; +} + optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, @@ -911,97 +1013,20 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t // build ValueMetricProducer for (int i = 0; i < config.value_metric_size(); i++) { - const ValueMetric& metric = config.value_metric(i); - if (!metric.has_what()) { - ALOGW("cannot find \"what\" in ValueMetric \"%lld\"", (long long)metric.id()); - return false; - } - if (!metric.has_value_field()) { - ALOGW("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); - return false; - } - std::vector<Matcher> fieldMatchers; - translateFieldMatcher(metric.value_field(), &fieldMatchers); - if (fieldMatchers.size() < 1) { - ALOGW("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); - return false; - } - int metricIndex = allMetricProducers.size(); + const ValueMetric& metric = config.value_metric(i); metricMap.insert({metric.id(), metricIndex}); - int trackerIndex; - if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, - metric.has_dimensions_in_what(), - allAtomMatchingTrackers, atomMatchingTrackerMap, - trackerToMetricMap, trackerIndex)) { - return false; - } - - sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex); - // If it is pulled atom, it should be simple matcher with one tagId. - if (atomMatcher->getAtomIds().size() != 1) { - return false; - } - int atomTagId = *(atomMatcher->getAtomIds().begin()); - int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1; - - int conditionIndex = -1; - if (metric.has_condition()) { - bool good = handleMetricWithConditions( - metric.condition(), metricIndex, conditionTrackerMap, metric.links(), - allConditionTrackers, conditionIndex, conditionToMetricMap); - if (!good) { - return false; - } - } else { - if (metric.links_size() > 0) { - ALOGW("metrics has a MetricConditionLink but doesn't have a condition"); - return false; - } - } - - std::vector<int> slicedStateAtoms; - unordered_map<int, unordered_map<int, int64_t>> stateGroupMap; - if (metric.slice_by_state_size() > 0) { - if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap, - allStateGroupMaps, slicedStateAtoms, stateGroupMap)) { - return false; - } - } else { - if (metric.state_link_size() > 0) { - ALOGW("ValueMetric has a MetricStateLink but doesn't have a sliced state"); - return false; - } - } - - // Check that all metric state links are a subset of dimensions_in_what fields. - std::vector<Matcher> dimensionsInWhat; - translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat); - for (const auto& stateLink : metric.state_link()) { - if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) { - return false; - } - } - - unordered_map<int, shared_ptr<Activation>> eventActivationMap; - unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap; - bool success = handleMetricActivation( - config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap, + optional<sp<MetricProducer>> producer = createValueMetricProducerAndUpdateMetadata( + key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex, + allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers, + conditionTrackerMap, initialConditionCache, wizard, matcherWizard, stateAtomIdMap, + allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - metricsWithActivation, eventActivationMap, eventDeactivationMap); - if (!success) return false; - - uint64_t metricHash; - if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) { + metricsWithActivation); + if (!producer) { return false; } - - sp<MetricProducer> valueProducer = new ValueMetricProducer( - key, metric, conditionIndex, initialConditionCache, wizard, metricHash, - trackerIndex, matcherWizard, pullTagId, timeBaseTimeNs, currentTimeNs, - pullerManager, eventActivationMap, eventDeactivationMap, slicedStateAtoms, - stateGroupMap); - allMetricProducers.push_back(valueProducer); + allMetricProducers.push_back(producer.value()); } // Gauge metrics. diff --git a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h index 6d1e6dde7e89..e4585cd578f8 100644 --- a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h +++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h @@ -148,6 +148,27 @@ optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata( std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, std::vector<int>& metricsWithActivation); +// Creates a CountMetricProducer and updates the vectors/maps used by MetricsManager with +// the appropriate indices. Returns an sp to the producer, or nullopt if there was an error. +optional<sp<MetricProducer>> createValueMetricProducerAndUpdateMetadata( + const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, + const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, + const ValueMetric& metric, const int metricIndex, + const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, + const std::unordered_map<int64_t, int>& atomMatchingTrackerMap, + std::vector<sp<ConditionTracker>>& allConditionTrackers, + const std::unordered_map<int64_t, int>& conditionTrackerMap, + const std::vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard, + const sp<EventMatcherWizard>& matcherWizard, + const std::unordered_map<int64_t, int>& stateAtomIdMap, + const std::unordered_map<int64_t, std::unordered_map<int, int64_t>>& allStateGroupMaps, + const std::unordered_map<int64_t, int>& metricToActivationMap, + std::unordered_map<int, std::vector<int>>& trackerToMetricMap, + std::unordered_map<int, std::vector<int>>& conditionToMetricMap, + std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, + std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, + std::vector<int>& metricsWithActivation); + // Creates a GaugeMetricProducer and updates the vectors/maps used by MetricsManager with // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error. optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata( diff --git a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp index 0066030ade54..4fa9bf6ffc01 100644 --- a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp +++ b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp @@ -29,6 +29,7 @@ #include "src/matchers/CombinationAtomMatchingTracker.h" #include "src/metrics/DurationMetricProducer.h" #include "src/metrics/GaugeMetricProducer.h" +#include "src/metrics/ValueMetricProducer.h" #include "src/metrics/parsing_utils/metrics_manager_util.h" #include "tests/statsd_test_util.h" @@ -1811,6 +1812,7 @@ TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) { unordered_map<int, vector<int>> activationAtomTrackerToMetricMap; unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap; vector<int> metricsWithActivation; + set<int64_t> replacedMetrics; EXPECT_TRUE(updateMetrics( key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(), oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers, @@ -1819,13 +1821,14 @@ TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) { /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - metricsWithActivation)); + metricsWithActivation, replacedMetrics)); unordered_map<int64_t, int> expectedMetricProducerMap = { {event1Id, event1Index}, {event2Id, event2Index}, {event3Id, event3Index}, {event4Id, event4Index}, {event6Id, event6Index}, }; EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap)); + EXPECT_EQ(replacedMetrics, set<int64_t>({event2Id, event3Id, event4Id})); // Make sure preserved metrics are the same. ASSERT_EQ(newMetricProducers.size(), 5); @@ -2040,6 +2043,7 @@ TEST_F(ConfigUpdateTest, TestUpdateCountMetrics) { unordered_map<int, vector<int>> activationAtomTrackerToMetricMap; unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap; vector<int> metricsWithActivation; + set<int64_t> replacedMetrics; EXPECT_TRUE(updateMetrics( key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(), oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers, @@ -2048,13 +2052,14 @@ TEST_F(ConfigUpdateTest, TestUpdateCountMetrics) { oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - metricsWithActivation)); + metricsWithActivation, replacedMetrics)); unordered_map<int64_t, int> expectedMetricProducerMap = { {count1Id, count1Index}, {count2Id, count2Index}, {count3Id, count3Index}, {count4Id, count4Index}, {count6Id, count6Index}, }; EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap)); + EXPECT_EQ(replacedMetrics, set<int64_t>({count2Id, count3Id, count4Id})); // Make sure preserved metrics are the same. ASSERT_EQ(newMetricProducers.size(), 5); @@ -2249,6 +2254,7 @@ TEST_F(ConfigUpdateTest, TestUpdateGaugeMetrics) { unordered_map<int, vector<int>> activationAtomTrackerToMetricMap; unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap; vector<int> metricsWithActivation; + set<int64_t> replacedMetrics; EXPECT_TRUE(updateMetrics( key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(), oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers, @@ -2257,13 +2263,14 @@ TEST_F(ConfigUpdateTest, TestUpdateGaugeMetrics) { /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - metricsWithActivation)); + metricsWithActivation, replacedMetrics)); unordered_map<int64_t, int> expectedMetricProducerMap = { {gauge1Id, gauge1Index}, {gauge2Id, gauge2Index}, {gauge3Id, gauge3Index}, {gauge4Id, gauge4Index}, {gauge6Id, gauge6Index}, }; EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap)); + EXPECT_EQ(replacedMetrics, set<int64_t>({gauge2Id, gauge3Id, gauge4Id})); // Make sure preserved metrics are the same. ASSERT_EQ(newMetricProducers.size(), 5); @@ -2566,6 +2573,7 @@ TEST_F(ConfigUpdateTest, TestUpdateDurationMetrics) { unordered_map<int, vector<int>> activationAtomTrackerToMetricMap; unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap; vector<int> metricsWithActivation; + set<int64_t> replacedMetrics; EXPECT_TRUE(updateMetrics( key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(), oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, /*replacedMatchers=*/{}, @@ -2574,7 +2582,7 @@ TEST_F(ConfigUpdateTest, TestUpdateDurationMetrics) { oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - metricsWithActivation)); + metricsWithActivation, replacedMetrics)); unordered_map<int64_t, int> expectedMetricProducerMap = { {duration1Id, duration1Index}, {duration2Id, duration2Index}, @@ -2582,7 +2590,7 @@ TEST_F(ConfigUpdateTest, TestUpdateDurationMetrics) { {duration6Id, duration6Index}, }; EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap)); - + EXPECT_EQ(replacedMetrics, set<int64_t>({duration2Id, duration3Id, duration4Id})); // Make sure preserved metrics are the same. ASSERT_EQ(newMetricProducers.size(), 5); EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(duration1Id)], @@ -2685,6 +2693,245 @@ TEST_F(ConfigUpdateTest, TestUpdateDurationMetrics) { EXPECT_EQ(oldConditionWizard->getStrongCount(), 1); } +TEST_F(ConfigUpdateTest, TestUpdateValueMetrics) { + StatsdConfig config; + + // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig. + AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher(); + int64_t matcher1Id = matcher1.id(); + *config.add_atom_matcher() = matcher1; + + AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher(); + int64_t matcher2Id = matcher2.id(); + *config.add_atom_matcher() = matcher2; + + AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher(); + int64_t matcher3Id = matcher3.id(); + *config.add_atom_matcher() = matcher3; + + AtomMatcher matcher4 = CreateTemperatureAtomMatcher(); + int64_t matcher4Id = matcher4.id(); + *config.add_atom_matcher() = matcher4; + + AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE); + int64_t matcher5Id = matcher5.id(); + *config.add_atom_matcher() = matcher5; + + Predicate predicate1 = CreateScreenIsOnPredicate(); + int64_t predicate1Id = predicate1.id(); + *config.add_predicate() = predicate1; + + Predicate predicate2 = CreateScreenIsOffPredicate(); + int64_t predicate2Id = predicate2.id(); + *config.add_predicate() = predicate2; + + State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321); + int64_t state1Id = state1.id(); + *config.add_state() = state1; + + State state2 = CreateScreenState(); + int64_t state2Id = state2.id(); + *config.add_state() = state2; + + // Add a few value metrics. + // Note that these will not work as "real" metrics since the value field is always 2. + // Will be preserved. + ValueMetric value1 = createValueMetric("VALUE1", matcher4, predicate1Id, {state1Id}); + int64_t value1Id = value1.id(); + *config.add_value_metric() = value1; + + // Will be replaced - definition change. + ValueMetric value2 = createValueMetric("VALUE2", matcher1, nullopt, {}); + int64_t value2Id = value2.id(); + *config.add_value_metric() = value2; + + // Will be replaced - condition change. + ValueMetric value3 = createValueMetric("VALUE3", matcher5, predicate2Id, {}); + int64_t value3Id = value3.id(); + *config.add_value_metric() = value3; + + // Will be replaced - state change. + ValueMetric value4 = createValueMetric("VALUE4", matcher3, nullopt, {state2Id}); + int64_t value4Id = value4.id(); + *config.add_value_metric() = value4; + + // Will be deleted. + ValueMetric value5 = createValueMetric("VALUE5", matcher2, nullopt, {}); + int64_t value5Id = value5.id(); + *config.add_value_metric() = value5; + + EXPECT_TRUE(initConfig(config)); + + // Used later to ensure the condition wizard is replaced. Get it before doing the update. + sp<EventMatcherWizard> oldMatcherWizard = + static_cast<ValueMetricProducer*>(oldMetricProducers[0].get())->mEventMatcherWizard; + EXPECT_EQ(oldMatcherWizard->getStrongCount(), 6); + + // Change value2, causing it to be replaced. + value2.set_aggregation_type(ValueMetric::AVG); + + // Mark predicate 2 as replaced. Causes value3 to be replaced. + set<int64_t> replacedConditions = {predicate2Id}; + + // Mark state 2 as replaced. Causes value4 to be replaced. + set<int64_t> replacedStates = {state2Id}; + + // New value metric. + ValueMetric value6 = createValueMetric("VALUE6", matcher5, predicate1Id, {state1Id}); + int64_t value6Id = value6.id(); + + // Map the matchers and predicates in reverse order to force the indices to change. + std::unordered_map<int64_t, int> newAtomMatchingTrackerMap; + const int matcher5Index = 0; + newAtomMatchingTrackerMap[matcher5Id] = 0; + const int matcher4Index = 1; + newAtomMatchingTrackerMap[matcher4Id] = 1; + const int matcher3Index = 2; + newAtomMatchingTrackerMap[matcher3Id] = 2; + const int matcher2Index = 3; + newAtomMatchingTrackerMap[matcher2Id] = 3; + const int matcher1Index = 4; + newAtomMatchingTrackerMap[matcher1Id] = 4; + // Use the existing matchers. A bit hacky, but saves code and we don't rely on them. + vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5); + std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(), + newAtomMatchingTrackers.begin()); + + std::unordered_map<int64_t, int> newConditionTrackerMap; + const int predicate2Index = 0; + newConditionTrackerMap[predicate2Id] = 0; + const int predicate1Index = 1; + newConditionTrackerMap[predicate1Id] = 1; + // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them. + vector<sp<ConditionTracker>> newConditionTrackers(2); + std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(), + newConditionTrackers.begin()); + // Say that predicate1 & predicate2 is unknown since the initial condition never changed. + vector<ConditionState> conditionCache = {ConditionState::kUnknown, ConditionState::kUnknown}; + + StatsdConfig newConfig; + *newConfig.add_value_metric() = value6; + const int value6Index = 0; + *newConfig.add_value_metric() = value3; + const int value3Index = 1; + *newConfig.add_value_metric() = value1; + const int value1Index = 2; + *newConfig.add_value_metric() = value4; + const int value4Index = 3; + *newConfig.add_value_metric() = value2; + const int value2Index = 4; + + *newConfig.add_state() = state1; + *newConfig.add_state() = state2; + + unordered_map<int64_t, int> stateAtomIdMap; + unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps; + map<int64_t, uint64_t> stateProtoHashes; + EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes)); + + // Output data structures to validate. + unordered_map<int64_t, int> newMetricProducerMap; + vector<sp<MetricProducer>> newMetricProducers; + unordered_map<int, vector<int>> conditionToMetricMap; + unordered_map<int, vector<int>> trackerToMetricMap; + set<int64_t> noReportMetricIds; + unordered_map<int, vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap; + vector<int> metricsWithActivation; + set<int64_t> replacedMetrics; + EXPECT_TRUE(updateMetrics( + key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(), + oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, /*replacedMatchers=*/{}, + newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions, + newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates, + oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers, + conditionToMetricMap, trackerToMetricMap, noReportMetricIds, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, + metricsWithActivation, replacedMetrics)); + + unordered_map<int64_t, int> expectedMetricProducerMap = { + {value1Id, value1Index}, {value2Id, value2Index}, {value3Id, value3Index}, + {value4Id, value4Index}, {value6Id, value6Index}, + }; + EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap)); + EXPECT_EQ(replacedMetrics, set<int64_t>({value2Id, value3Id, value4Id})); + + // Make sure preserved metrics are the same. + ASSERT_EQ(newMetricProducers.size(), 5); + EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(value1Id)], + newMetricProducers[newMetricProducerMap.at(value1Id)]); + + // Make sure replaced metrics are different. + EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value2Id)], + newMetricProducers[newMetricProducerMap.at(value2Id)]); + EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value3Id)], + newMetricProducers[newMetricProducerMap.at(value3Id)]); + EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value4Id)], + newMetricProducers[newMetricProducerMap.at(value4Id)]); + + // Verify the conditionToMetricMap. + ASSERT_EQ(conditionToMetricMap.size(), 2); + const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index]; + EXPECT_THAT(condition1Metrics, UnorderedElementsAre(value1Index, value6Index)); + const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index]; + EXPECT_THAT(condition2Metrics, UnorderedElementsAre(value3Index)); + + // Verify the trackerToMetricMap. + ASSERT_EQ(trackerToMetricMap.size(), 4); + const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index]; + EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(value2Index)); + const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index]; + EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(value4Index)); + const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index]; + EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(value1Index)); + const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index]; + EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(value3Index, value6Index)); + + // Verify event activation/deactivation maps. + ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0); + ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0); + ASSERT_EQ(metricsWithActivation.size(), 0); + + // Verify tracker indices/ids/conditions/states are correct. + ValueMetricProducer* valueProducer1 = + static_cast<ValueMetricProducer*>(newMetricProducers[value1Index].get()); + EXPECT_EQ(valueProducer1->getMetricId(), value1Id); + EXPECT_EQ(valueProducer1->mConditionTrackerIndex, predicate1Index); + EXPECT_EQ(valueProducer1->mCondition, ConditionState::kUnknown); + EXPECT_EQ(valueProducer1->mWhatMatcherIndex, matcher4Index); + ValueMetricProducer* valueProducer2 = + static_cast<ValueMetricProducer*>(newMetricProducers[value2Index].get()); + EXPECT_EQ(valueProducer2->getMetricId(), value2Id); + EXPECT_EQ(valueProducer2->mConditionTrackerIndex, -1); + EXPECT_EQ(valueProducer2->mCondition, ConditionState::kTrue); + EXPECT_EQ(valueProducer2->mWhatMatcherIndex, matcher1Index); + ValueMetricProducer* valueProducer3 = + static_cast<ValueMetricProducer*>(newMetricProducers[value3Index].get()); + EXPECT_EQ(valueProducer3->getMetricId(), value3Id); + EXPECT_EQ(valueProducer3->mConditionTrackerIndex, predicate2Index); + EXPECT_EQ(valueProducer3->mCondition, ConditionState::kUnknown); + EXPECT_EQ(valueProducer3->mWhatMatcherIndex, matcher5Index); + ValueMetricProducer* valueProducer4 = + static_cast<ValueMetricProducer*>(newMetricProducers[value4Index].get()); + EXPECT_EQ(valueProducer4->getMetricId(), value4Id); + EXPECT_EQ(valueProducer4->mConditionTrackerIndex, -1); + EXPECT_EQ(valueProducer4->mCondition, ConditionState::kTrue); + EXPECT_EQ(valueProducer4->mWhatMatcherIndex, matcher3Index); + ValueMetricProducer* valueProducer6 = + static_cast<ValueMetricProducer*>(newMetricProducers[value6Index].get()); + EXPECT_EQ(valueProducer6->getMetricId(), value6Id); + EXPECT_EQ(valueProducer6->mConditionTrackerIndex, predicate1Index); + EXPECT_EQ(valueProducer6->mCondition, ConditionState::kUnknown); + EXPECT_EQ(valueProducer6->mWhatMatcherIndex, matcher5Index); + + sp<EventMatcherWizard> newMatcherWizard = valueProducer1->mEventMatcherWizard; + EXPECT_NE(newMatcherWizard, oldMatcherWizard); + EXPECT_EQ(newMatcherWizard->getStrongCount(), 6); + oldMetricProducers.clear(); + // Only reference to the old wizard should be the one in the test. + EXPECT_EQ(oldMatcherWizard->getStrongCount(), 1); +} + TEST_F(ConfigUpdateTest, TestUpdateMetricActivations) { StatsdConfig config; // Add atom matchers @@ -2767,6 +3014,7 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricActivations) { unordered_map<int, vector<int>> activationAtomTrackerToMetricMap; unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap; vector<int> metricsWithActivation; + set<int64_t> replacedMetrics; EXPECT_TRUE(updateMetrics( key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(), oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers, @@ -2775,7 +3023,7 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricActivations) { /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - metricsWithActivation)); + metricsWithActivation, replacedMetrics)); // Verify event activation/deactivation maps. ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 3); @@ -2850,6 +3098,11 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { *config.add_gauge_metric() = gaugeMetric; // Preserved. + ValueMetric valueMetric = createValueMetric("VALUE1", matcher3, predicate1Id, {}); + int64_t valueMetricId = valueMetric.id(); + *config.add_value_metric() = valueMetric; + + // Preserved. DurationMetric durationMetric = createDurationMetric("DURATION1", predicate1Id, nullopt, {}); int64_t durationMetricId = durationMetric.id(); *config.add_duration_metric() = durationMetric; @@ -2858,7 +3111,7 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { // Used later to ensure the condition wizard is replaced. Get it before doing the update. sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard; - EXPECT_EQ(oldConditionWizard->getStrongCount(), 5); + EXPECT_EQ(oldConditionWizard->getStrongCount(), 6); // Mark matcher 2 as replaced. Causes eventMetric to be replaced. set<int64_t> replacedMatchers; @@ -2889,6 +3142,7 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { newConditionTrackers.begin()); vector<ConditionState> conditionCache = {ConditionState::kUnknown}; + // The order matters. we parse in the order of: count, duration, event, value, gauge. StatsdConfig newConfig; *newConfig.add_count_metric() = countMetric; const int countMetricIndex = 0; @@ -2896,8 +3150,10 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { const int durationMetricIndex = 1; *newConfig.add_event_metric() = eventMetric; const int eventMetricIndex = 2; + *newConfig.add_value_metric() = valueMetric; + const int valueMetricIndex = 3; *newConfig.add_gauge_metric() = gaugeMetric; - const int gaugeMetricIndex = 3; + const int gaugeMetricIndex = 4; // Add the predicate since duration metric needs it. *newConfig.add_predicate() = predicate1; @@ -2911,6 +3167,7 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { unordered_map<int, vector<int>> activationAtomTrackerToMetricMap; unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap; vector<int> metricsWithActivation; + set<int64_t> replacedMetrics; EXPECT_TRUE(updateMetrics( key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(), oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers, @@ -2919,22 +3176,25 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - metricsWithActivation)); + metricsWithActivation, replacedMetrics)); unordered_map<int64_t, int> expectedMetricProducerMap = { - {countMetricId, countMetricIndex}, - {durationMetricId, durationMetricIndex}, - {eventMetricId, eventMetricIndex}, + {countMetricId, countMetricIndex}, {durationMetricId, durationMetricIndex}, + {eventMetricId, eventMetricIndex}, {valueMetricId, valueMetricIndex}, {gaugeMetricId, gaugeMetricIndex}, }; EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap)); + EXPECT_EQ(replacedMetrics, set<int64_t>({eventMetricId, gaugeMetricId})); + // Make sure preserved metrics are the same. - ASSERT_EQ(newMetricProducers.size(), 4); + ASSERT_EQ(newMetricProducers.size(), 5); EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(countMetricId)], newMetricProducers[newMetricProducerMap.at(countMetricId)]); EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(durationMetricId)], newMetricProducers[newMetricProducerMap.at(durationMetricId)]); + EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(valueMetricId)], + newMetricProducers[newMetricProducerMap.at(valueMetricId)]); // Make sure replaced metrics are different. EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(eventMetricId)], @@ -2945,7 +3205,8 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { // Verify the conditionToMetricMap. ASSERT_EQ(conditionToMetricMap.size(), 1); const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index]; - EXPECT_THAT(condition1Metrics, UnorderedElementsAre(countMetricIndex, gaugeMetricIndex)); + EXPECT_THAT(condition1Metrics, + UnorderedElementsAre(countMetricIndex, gaugeMetricIndex, valueMetricIndex)); // Verify the trackerToMetricMap. ASSERT_EQ(trackerToMetricMap.size(), 3); @@ -2954,7 +3215,7 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index]; EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(eventMetricIndex, durationMetricIndex)); const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index]; - EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(gaugeMetricIndex)); + EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(gaugeMetricIndex, valueMetricIndex)); // Verify event activation/deactivation maps. ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0); @@ -2977,7 +3238,7 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard; EXPECT_NE(newConditionWizard, oldConditionWizard); - EXPECT_EQ(newConditionWizard->getStrongCount(), 5); + EXPECT_EQ(newConditionWizard->getStrongCount(), 6); oldMetricProducers.clear(); // Only reference to the old wizard should be the one in the test. EXPECT_EQ(oldConditionWizard->getStrongCount(), 1); diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index f953da48c217..b1b9f4161ee5 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -888,7 +888,7 @@ public class AccessibilityServiceInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCapabilities(int capabilities) { mCapabilities = capabilities; } diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java index b960a7f835d8..0d6a07938e95 100644 --- a/core/java/android/accounts/Account.java +++ b/core/java/android/accounts/Account.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; @@ -38,7 +39,7 @@ import java.util.Set; * suitable for use as the key of a {@link java.util.Map} */ public class Account implements Parcelable { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final String TAG = "Account"; @GuardedBy("sAccessedAccounts") @@ -47,7 +48,7 @@ public class Account implements Parcelable { public final String name; public final String type; private String mSafeName; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final @Nullable String accessId; public boolean equals(@Nullable Object o) { diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 9bb02cdcce73..007b0a8ab960 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -546,7 +546,7 @@ public class AccountManager { /** * @hide used for testing only */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public AccountManager(Context context, IAccountManager service, Handler handler) { mContext = context; mService = service; @@ -831,7 +831,7 @@ public class AccountManager { /** @hide Same as {@link #getAccountsByType(String)} but for a specific user. */ @NonNull - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Account[] getAccountsByTypeAsUser(String type, UserHandle userHandle) { try { return mService.getAccountsAsUser(type, userHandle.getIdentifier(), @@ -2122,7 +2122,7 @@ public class AccountManager { * Same as {@link #confirmCredentials(Account, Bundle, Activity, AccountManagerCallback, Handler)} * but for the specified user. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public AccountManagerFuture<Bundle> confirmCredentialsAsUser(final Account account, final Bundle options, final Activity activity, diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java index 3cdd691fd5dd..eb525d301986 100644 --- a/core/java/android/animation/Animator.java +++ b/core/java/android/animation/Animator.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.ConstantState; +import android.os.Build; import java.util.ArrayList; @@ -461,7 +462,7 @@ public abstract class Animator implements Cloneable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void reverse() { throw new IllegalStateException("Reverse is not supported"); } diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 8c0b4387c27f..2ac345d2560a 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -757,7 +757,7 @@ public class Activity extends ContextThemeWrapper */ public static final int FINISH_TASK_WITH_ACTIVITY = 2; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static final String FRAGMENTS_TAG = "android:fragments"; private static final String LAST_AUTOFILL_ID = "android:lastAutofillId"; @@ -2883,11 +2883,7 @@ public class Activity extends ContextThemeWrapper * but will always be at least three. */ public int getMaxNumPictureInPictureActions() { - try { - return ActivityTaskManager.getService().getMaxNumPictureInPictureActions(mToken); - } catch (RemoteException e) { - return 0; - } + return ActivityTaskManager.getMaxNumPictureInPictureActions(this); } /** @@ -2941,7 +2937,7 @@ public class Activity extends ContextThemeWrapper * @see View#onMovedToDisplay(int, Configuration) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public void onMovedToDisplay(int displayId, Configuration config) { } @@ -3211,7 +3207,7 @@ public class Activity extends ContextThemeWrapper * @deprecated Use {@link CursorLoader} instead. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final Cursor managedQuery(Uri uri, String[] projection, String selection, String sortOrder) { Cursor c = getContentResolver().query(uri, projection, selection, null, sortOrder); @@ -6019,7 +6015,7 @@ public class Activity extends ContextThemeWrapper * @hide */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void startActivityForResult( String who, Intent intent, int requestCode, @Nullable Bundle options) { Uri referrer = onProvideReferrer(); @@ -6351,7 +6347,7 @@ public class Activity extends ContextThemeWrapper * Finishes the current activity and specifies whether to remove the task associated with this * activity. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void finish(int finishTask) { if (mParent == null) { int resultCode; @@ -7881,7 +7877,7 @@ public class Activity extends ContextThemeWrapper mParent = parent; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, @@ -7977,7 +7973,7 @@ public class Activity extends ContextThemeWrapper performCreate(icicle, null); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final void performCreate(Bundle icicle, PersistableBundle persistentState) { dispatchActivityPreCreated(icicle); mCanEnterPictureInPicture = true; @@ -8292,7 +8288,7 @@ public class Activity extends ContextThemeWrapper } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void dispatchActivityResult(String who, int requestCode, int resultCode, Intent data, String reason) { if (false) Log.v( diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 250f2f0b2dc9..ec287fe10634 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -503,23 +503,22 @@ public class ActivityManager { @UnsupportedAppUsage public static final int PROCESS_STATE_TOP = 2; - /** @hide Process is bound to a TOP app. This is ranked below SERVICE_LOCATION so that - * it doesn't get the capability of location access while-in-use. */ + /** @hide Process is bound to a TOP app. */ public static final int PROCESS_STATE_BOUND_TOP = 3; /** @hide Process is hosting a foreground service. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; /** @hide Process is hosting a foreground service due to a system binding. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 5; /** @hide Process is important to the user, and something they are aware of. */ public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6; /** @hide Process is important to the user, but not something they are aware of. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7; /** @hide Process is in the background transient so we will try to keep running. */ @@ -531,14 +530,14 @@ public class ActivityManager { /** @hide Process is in the background running a service. Unlike oom_adj, this level * is used for both the normal running in background state and the executing * operations state. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROCESS_STATE_SERVICE = 10; /** @hide Process is in the background running a receiver. Note that from the * perspective of oom_adj, receivers run at a higher foreground level, but for our * prioritization here that is not necessary and putting them below services means * many fewer changes in some process states as they receive broadcasts. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROCESS_STATE_RECEIVER = 11; /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */ @@ -549,14 +548,14 @@ public class ActivityManager { public static final int PROCESS_STATE_HEAVY_WEIGHT = 13; /** @hide Process is in the background but hosts the home activity. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROCESS_STATE_HOME = 14; /** @hide Process is in the background but hosts the last shown activity. */ public static final int PROCESS_STATE_LAST_ACTIVITY = 15; /** @hide Process is being cached for later use and contains activities. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROCESS_STATE_CACHED_ACTIVITY = 16; /** @hide Process is being cached for later use and is a client of another cached @@ -2198,7 +2197,7 @@ public class ActivityManager { /** * @return The size of the task at the point this snapshot was taken. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Point getTaskSize() { return mTaskSize; } @@ -2740,13 +2739,13 @@ public class ActivityManager { public boolean lowMemory; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long hiddenAppThreshold; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long secondaryServerThreshold; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long visibleAppThreshold; /** @hide */ @UnsupportedAppUsage @@ -3037,7 +3036,7 @@ public class ActivityManager { * persistent system app. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int FLAG_PERSISTENT = 1<<1; /** @@ -3045,7 +3044,7 @@ public class ActivityManager { * persistent system app. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int FLAG_HAS_ACTIVITIES = 1<<2; /** @@ -3149,7 +3148,7 @@ public class ActivityManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final int IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170; @@ -3209,7 +3208,7 @@ public class ActivityManager { * will be passed to a client, use {@link #procStateToImportanceForClient}. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static @Importance int procStateToImportance(int procState) { if (procState == PROCESS_STATE_NONEXISTENT) { return IMPORTANCE_GONE; @@ -4168,7 +4167,7 @@ public class ActivityManager { * @param userid the user's id. Zero indicates the default user. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean switchUser(int userid) { try { return getService().switchUser(userid); @@ -4812,13 +4811,14 @@ public class ActivityManager { /** * Holds the AM lock for the specified amount of milliseconds. * This is intended for use by the tests that need to imitate lock contention. + * The token should be obtained by + * {@link android.content.pm.PackageManager#getHoldLockToken()}. * @hide */ @TestApi - @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) - public void holdLock(int durationMs) { + public void holdLock(IBinder token, int durationMs) { try { - getService().holdLock(durationMs); + getService().holdLock(token, durationMs); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java index 9edf81e8f651..c7b90897c8e7 100644 --- a/core/java/android/app/ActivityTaskManager.java +++ b/core/java/android/app/ActivityTaskManager.java @@ -173,7 +173,7 @@ public class ActivityTaskManager { * @param toTop If the task should be moved to the top once the windowing mode changes. * @return Whether the task was successfully put into the specified windowing mode. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) throws SecurityException { try { @@ -200,7 +200,7 @@ public class ActivityTaskManager { * going into split-screen mode. * @return Whether the task was successfully put into splitscreen. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) throws SecurityException { try { @@ -214,7 +214,7 @@ public class ActivityTaskManager { * Removes root tasks in the windowing modes from the system if they are of activity type * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void removeRootTasksInWindowingModes(@NonNull int[] windowingModes) { try { getService().removeRootTasksInWindowingModes(windowingModes); @@ -224,7 +224,7 @@ public class ActivityTaskManager { } /** Removes root tasks of the activity types from the system. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void removeRootTasksWithActivityTypes(@NonNull int[] activityTypes) { try { getService().removeRootTasksWithActivityTypes(activityTypes); @@ -315,7 +315,7 @@ public class ActivityTaskManager { * @param bounds Bounds to use for pinned root task. * @return True if the top activity of root task was successfully moved to the pinned root task. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean moveTopActivityToPinnedRootTask(int rootTaskId, @NonNull Rect bounds) { try { return getService().moveTopActivityToPinnedRootTask(rootTaskId, bounds); @@ -328,7 +328,7 @@ public class ActivityTaskManager { * Start to enter lock task mode for given task by system(UI). * @param taskId Id of task to lock. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void startSystemLockTaskMode(int taskId) { try { getService().startSystemLockTaskMode(taskId); @@ -340,7 +340,7 @@ public class ActivityTaskManager { /** * Stop lock task mode by system(UI). */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void stopSystemLockTaskMode() { try { getService().stopSystemLockTaskMode(); @@ -355,7 +355,7 @@ public class ActivityTaskManager { * @param rootTaskId Id of the rootTask for task moving. * @param toTop Whether the given task should shown to top of stack. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop) { try { getService().moveTaskToRootTask(taskId, rootTaskId, toTop); @@ -369,7 +369,7 @@ public class ActivityTaskManager { * @param taskId Id of task to resize. * @param bounds Bounds to resize task. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void resizeTask(int taskId, Rect bounds) { try { getService().resizeTask(taskId, bounds, RESIZE_MODE_SYSTEM); @@ -383,7 +383,7 @@ public class ActivityTaskManager { * @param rootTaskBounds Bounds to resize stack. * @param taskBounds Bounds to resize task. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void resizePrimarySplitScreen(@NonNull Rect rootTaskBounds, @NonNull Rect taskBounds) { try { getService().resizePrimarySplitScreen(rootTaskBounds, taskBounds, null, null, null); @@ -396,7 +396,7 @@ public class ActivityTaskManager { * Clears launch params for the given package. * @param packageNames the names of the packages of which the launch params are to be cleared */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void clearLaunchParamsForPackages(List<String> packageNames) { try { getService().clearLaunchParamsForPackages(packageNames); @@ -410,7 +410,7 @@ public class ActivityTaskManager { * @hide */ @TestApi - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void requestPictureInPictureMode(@NonNull IBinder token) { try { getService().requestPictureInPictureMode(token); @@ -437,6 +437,12 @@ public class ActivityTaskManager { return currentUiModeSupportsErrorDialogs(config); } + /** @return max allowed number of actions in picture-in-picture mode. */ + public static int getMaxNumPictureInPictureActions(@NonNull Context context) { + return context.getResources().getInteger( + com.android.internal.R.integer.config_pictureInPictureMaxNumberOfActions); + } + /** * Information you can retrieve about a root task in the system. * @hide diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 87c729b20c71..b68194792db1 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -346,7 +346,7 @@ public final class ActivityThread extends ClientTransactionHandler { @UnsupportedAppUsage AppBindData mBoundApplication; Profiler mProfiler; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int mCurDefaultDisplayDpi; @UnsupportedAppUsage boolean mDensityCompatMode; @@ -821,7 +821,7 @@ public final class ActivityThread extends ClientTransactionHandler { boolean trackAllocation; @UnsupportedAppUsage boolean restrictedBackupMode; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean persistent; Configuration config; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @@ -2288,7 +2288,7 @@ public final class ActivityThread extends ClientTransactionHandler { return null; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo, int flags) { boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0; @@ -3036,7 +3036,7 @@ public final class ActivityThread extends ClientTransactionHandler { proto.end(asToken); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void registerOnActivityPausedListener(Activity activity, OnActivityPausedListener listener) { synchronized (mOnPauseListeners) { @@ -3049,7 +3049,7 @@ public final class ActivityThread extends ClientTransactionHandler { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void unregisterOnActivityPausedListener(Activity activity, OnActivityPausedListener listener) { synchronized (mOnPauseListeners) { diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index f3b37891876d..e20ef7f70954 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -797,7 +797,7 @@ public class AppOpsManager { // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app) /** @hide No operation specified. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int OP_NONE = AppProtoEnums.APP_OP_NONE; /** @hide Access to coarse location information. */ @UnsupportedAppUsage @@ -865,6 +865,8 @@ public class AppOpsManager { @UnsupportedAppUsage public static final int OP_SEND_SMS = AppProtoEnums.APP_OP_SEND_SMS; /** @hide */ + public static final int OP_MANAGE_ONGOING_CALLS = AppProtoEnums.APP_OP_MANAGE_ONGOING_CALLS; + /** @hide */ @UnsupportedAppUsage public static final int OP_READ_ICC_SMS = AppProtoEnums.APP_OP_READ_ICC_SMS; /** @hide */ @@ -1154,8 +1156,8 @@ public class AppOpsManager { public static final int OP_RECORD_AUDIO_HOTWORD = 102; /** @hide */ - @UnsupportedAppUsage - public static final int _NUM_OP = 103; + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + public static final int _NUM_OP = 104; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -1466,6 +1468,15 @@ public class AppOpsManager { public static final String OPSTR_LOADER_USAGE_STATS = "android:loader_usage_stats"; /** + * Grants an app access to the {@link android.telecom.InCallService} API to see + * information about ongoing calls and to enable control of calls. + * @hide + */ + @SystemApi + @TestApi + public static final String OPSTR_MANAGE_ONGOING_CALLS = "android:manage_ongoing_calls"; + + /** * AppOp granted to apps that we are started via {@code am instrument -e --no-isolated-storage} * * <p>MediaProvider is the only component (outside of system server) that should care about this @@ -1574,6 +1585,7 @@ public class AppOpsManager { OP_MANAGE_EXTERNAL_STORAGE, OP_INTERACT_ACROSS_PROFILES, OP_LOADER_USAGE_STATS, + OP_MANAGE_ONGOING_CALLS, }; /** @@ -1688,6 +1700,7 @@ public class AppOpsManager { OP_PHONE_CALL_MICROPHONE, // OP_PHONE_CALL_MICROPHONE OP_PHONE_CALL_CAMERA, // OP_PHONE_CALL_CAMERA OP_RECORD_AUDIO_HOTWORD, // RECORD_AUDIO_HOTWORD + OP_MANAGE_ONGOING_CALLS, // MANAGE_ONGOING_CALLS }; /** @@ -1797,6 +1810,7 @@ public class AppOpsManager { OPSTR_PHONE_CALL_MICROPHONE, OPSTR_PHONE_CALL_CAMERA, OPSTR_RECORD_AUDIO_HOTWORD, + OPSTR_MANAGE_ONGOING_CALLS, }; /** @@ -1907,6 +1921,7 @@ public class AppOpsManager { "PHONE_CALL_MICROPHONE", "PHONE_CALL_CAMERA", "RECORD_AUDIO_HOTWORD", + "MANAGE_ONGOING_CALLS", }; /** @@ -2018,6 +2033,7 @@ public class AppOpsManager { null, // no permission for OP_PHONE_CALL_MICROPHONE null, // no permission for OP_PHONE_CALL_CAMERA null, // no permission for OP_RECORD_AUDIO_HOTWORD + Manifest.permission.MANAGE_ONGOING_CALLS, }; /** @@ -2129,6 +2145,7 @@ public class AppOpsManager { null, // PHONE_CALL_MICROPHONE null, // PHONE_CALL_MICROPHONE null, // RECORD_AUDIO_HOTWORD + null, // MANAGE_ONGOING_CALLS }; /** @@ -2239,6 +2256,7 @@ public class AppOpsManager { null, // PHONE_CALL_MICROPHONE null, // PHONE_CALL_CAMERA null, // RECORD_AUDIO_HOTWORD + null, // MANAGE_ONGOING_CALLS }; /** @@ -2348,6 +2366,7 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, // PHONE_CALL_MICROPHONE AppOpsManager.MODE_ALLOWED, // PHONE_CALL_CAMERA AppOpsManager.MODE_ALLOWED, // OP_RECORD_AUDIO_HOTWORD + AppOpsManager.MODE_DEFAULT, // MANAGE_ONGOING_CALLS }; /** @@ -2461,6 +2480,7 @@ public class AppOpsManager { false, // PHONE_CALL_MICROPHONE false, // PHONE_CALL_CAMERA false, // RECORD_AUDIO_HOTWORD + true, // MANAGE_ONGOING_CALLS }; /** @@ -2572,7 +2592,7 @@ public class AppOpsManager { * Retrieve a non-localized name for the operation, for debugging output. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String opToName(int op) { if (op == OP_NONE) return "NONE"; return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")"); @@ -2603,7 +2623,7 @@ public class AppOpsManager { * Retrieve the permission associated with an operation, or null if there is not one. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static String opToPermission(int op) { return sOpPerms[op]; @@ -6817,7 +6837,7 @@ public class AppOpsManager { /** @hide */ @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void resetAllModes() { try { mService.resetAllModes(mContext.getUserId(), null); diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java index 941467fad736..146d648fe65a 100644 --- a/core/java/android/app/Application.java +++ b/core/java/android/app/Application.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.res.Configuration; +import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.autofill.AutofillManager; @@ -352,7 +353,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { mLoadedApk = ContextImpl.getImpl(context).mPackageInfo; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPreCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { Object[] callbacks = collectActivityLifecycleCallbacks(); @@ -376,7 +377,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPostCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { Object[] callbacks = collectActivityLifecycleCallbacks(); @@ -388,7 +389,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPreStarted(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { @@ -408,7 +409,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPostStarted(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { @@ -418,7 +419,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPreResumed(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { @@ -438,7 +439,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPostResumed(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { @@ -448,7 +449,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPrePaused(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { @@ -468,7 +469,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPostPaused(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { @@ -478,7 +479,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPreStopped(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { @@ -498,7 +499,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPostStopped(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { @@ -508,7 +509,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPreSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) { Object[] callbacks = collectActivityLifecycleCallbacks(); @@ -532,7 +533,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPostSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) { Object[] callbacks = collectActivityLifecycleCallbacks(); @@ -544,7 +545,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPreDestroyed(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { @@ -564,7 +565,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void dispatchActivityPostDestroyed(@NonNull Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index c6b52c1ea705..7cef93fe7547 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1309,7 +1309,7 @@ public class ApplicationPackageManager extends PackageManager { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Override public boolean setInstantAppCookie(@NonNull byte[] cookie) { try { @@ -2422,7 +2422,7 @@ public class ApplicationPackageManager extends PackageManager { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) { final StorageManager storage = mContext.getSystemService(StorageManager.class); return getPackageCurrentVolume(app, storage); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index e94fd452b7f8..5c3be316f924 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -2700,7 +2700,7 @@ class ContextImpl extends Context { return context; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static ContextImpl createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration) { diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java index e4c84d7e7997..9fea3f75c2c2 100644 --- a/core/java/android/app/DialogFragment.java +++ b/core/java/android/app/DialogFragment.java @@ -19,6 +19,7 @@ package android.app; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.DialogInterface; +import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -183,11 +184,11 @@ public class DialogFragment extends Fragment int mTheme = 0; boolean mCancelable = true; boolean mShowsDialog = true; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int mBackStackId = -1; Dialog mDialog; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean mViewDestroyed; @UnsupportedAppUsage boolean mDismissed; diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 0719422632d1..355092378279 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -351,7 +351,7 @@ public class DownloadManager { * columns to request from DownloadProvider. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String[] UNDERLYING_COLUMNS = new String[] { DownloadManager.COLUMN_ID, DownloadManager.COLUMN_LOCAL_FILENAME, @@ -1646,7 +1646,7 @@ public class DownloadManager { /** * Get a parameterized SQL WHERE clause to select a bunch of IDs. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static String getWhereClauseForIds(long[] ids) { StringBuilder whereClause = new StringBuilder(); whereClause.append("("); @@ -1664,7 +1664,7 @@ public class DownloadManager { /** * Get the selection args for a clause returned by {@link #getWhereClauseForIds(long[])}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static String[] getWhereArgsForIds(long[] ids) { String[] whereArgs = new String[ids.length]; return getWhereArgsForIds(ids, whereArgs); diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index ce4109cd44a3..93381cf82764 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -306,7 +306,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene int mTargetRequestCode; // True if the fragment is in the list of added fragments. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean mAdded; // If set this fragment is being removed from its activity. diff --git a/core/java/android/app/FragmentController.java b/core/java/android/app/FragmentController.java index f021f7690283..150b7a56a36d 100644 --- a/core/java/android/app/FragmentController.java +++ b/core/java/android/app/FragmentController.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; +import android.os.Build; import android.os.Bundle; import android.os.Parcelable; import android.util.ArrayMap; @@ -44,7 +45,7 @@ import java.util.List; */ @Deprecated public class FragmentController { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final FragmentHostCallback<?> mHost; /** diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 904c4735e0ff..5435558b3be5 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -1101,7 +1101,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Animator loadAnimator(Fragment fragment, int transit, boolean enter, int transitionStyle) { Animator animObj = fragment.onCreateAnimator(transit, enter, fragment.getNextAnim()); diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 357b26c3083d..879d4373f964 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -112,7 +112,7 @@ interface IActivityManager { in String callingFeatureId, in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void unhandledBack(); @UnsupportedAppUsage boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask); @@ -171,12 +171,12 @@ interface IActivityManager { @UnsupportedAppUsage boolean unbindService(in IServiceConnection connection); void publishService(in IBinder token, in Intent intent, in IBinder service); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setDebugApp(in String packageName, boolean waitForDebugger, boolean persistent); void setAgentApp(in String packageName, @nullable String agent); @UnsupportedAppUsage void setAlwaysFinish(boolean enabled); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean startInstrumentation(in ComponentName className, in String profileFile, int flags, in Bundle arguments, in IInstrumentationWatcher watcher, in IUiAutomationConnection connection, int userId, @@ -198,7 +198,7 @@ interface IActivityManager { * @throws RemoteException * @return Returns true if the configuration was updated. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean updateConfiguration(in Configuration values); /** * Updates mcc mnc configuration and applies changes to the entire system. @@ -223,7 +223,7 @@ interface IActivityManager { int mode, int userId); void revokeUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri, int mode, int userId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setActivityController(in IActivityController watcher, boolean imAMonkey); void showWaitingForDebugger(in IApplicationThread who, boolean waiting); /* @@ -277,7 +277,7 @@ interface IActivityManager { List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses(); IBinder peekService(in Intent service, in String resolvedType, in String callingPackage); // Turn on/off profiling in a particular process. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean profileControl(in String process, int userId, boolean start, in ProfilerInfo profilerInfo, int profileType); @UnsupportedAppUsage @@ -309,7 +309,7 @@ interface IActivityManager { // Retrieve info of applications installed on external media that are currently // running. List<ApplicationInfo> getRunningExternalApplications(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void finishHeavyWeightApp(); // A StrictMode violation to be handled. @UnsupportedAppUsage @@ -331,7 +331,7 @@ interface IActivityManager { in RemoteCallback finishCallback); @UnsupportedAppUsage boolean isUserRunning(int userid, int flags); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setPackageScreenCompatMode(in String packageName, int mode); @UnsupportedAppUsage boolean switchUser(int userid); @@ -349,12 +349,12 @@ interface IActivityManager { @UnsupportedAppUsage long[] getProcessPss(in int[] pids); void showBootMessage(in CharSequence msg, boolean always); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void killAllBackgroundProcesses(); ContentProviderHolder getContentProviderExternal(in String name, int userId, in IBinder token, String tag); /** @deprecated - Use {@link #removeContentProviderExternalAsUser} which takes a user ID. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void removeContentProviderExternal(in String name, in IBinder token); void removeContentProviderExternalAsUser(in String name, in IBinder token, int userId); // Get memory information about the calling process. @@ -382,7 +382,7 @@ interface IActivityManager { in String callingFeatureId, in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options, int userId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int stopUser(int userid, boolean force, in IStopUserCallback callback); /** * Check {@link com.android.server.am.ActivityManagerService#stopUserWithDelayedLocking(int, boolean, IStopUserCallback)} @@ -443,20 +443,20 @@ interface IActivityManager { String getLaunchedFromPackage(in IBinder activityToken); void killUid(int appId, int userId, in String reason); void setUserIsMonkey(boolean monkey); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void hang(in IBinder who, boolean allowRestart); List<ActivityTaskManager.RootTaskInfo> getAllRootTaskInfos(); void moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop); void setFocusedRootTask(int taskId); ActivityTaskManager.RootTaskInfo getFocusedRootTaskInfo(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void restart(); void performIdleMaintenance(); void appNotRespondingViaProvider(in IBinder connection); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Rect getTaskBounds(int taskId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean setProcessMemoryTrimLevel(in String process, int userId, int level); @@ -464,13 +464,13 @@ interface IActivityManager { String getTagForIntentSender(in IIntentSender sender, in String prefix); @UnsupportedAppUsage boolean startUserInBackground(int userid); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isInLockTaskMode(); @UnsupportedAppUsage int startActivityFromRecents(int taskId, in Bundle options); @UnsupportedAppUsage void startSystemLockTaskMode(int taskId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isTopOfTask(in IBinder token); void bootAnimationComplete(); int checkPermissionWithToken(in String permission, int pid, int uid, @@ -481,11 +481,11 @@ interface IActivityManager { void notifyCleartextNetwork(int uid, in byte[] firstPacket); @UnsupportedAppUsage void setTaskResizeable(int taskId, int resizeableMode); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void resizeTask(int taskId, in Rect bounds, int resizeMode); @UnsupportedAppUsage int getLockTaskModeState(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setDumpHeapDebugLimit(in String processName, int uid, long maxMemSize, in String reportPackage); void dumpHeapFinished(in String path); @@ -498,17 +498,17 @@ interface IActivityManager { // Start of N transactions // Start Binder transaction tracking for all applications. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean startBinderTracking(); // Stop Binder transaction tracking for all applications and dump trace data to the given file // descriptor. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean stopBinderTrackingAndDump(in ParcelFileDescriptor fd); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void suppressResizeConfigChanges(boolean suppress); boolean moveTopActivityToPinnedRootTask(int rootTaskId, in Rect bounds); boolean isAppStartModeDisabled(int uid, in String packageName); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean unlockUser(int userid, in byte[] token, in byte[] secret, in IProgressListener listener); void killPackageDependents(in String packageName, int userId); @@ -517,7 +517,7 @@ interface IActivityManager { boolean isVrModePackageEnabled(in ComponentName packageName); void notifyLockedProfile(int userId); void startConfirmDeviceCredentialIntent(in Intent intent, in Bundle options); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void sendIdleJobTrigger(); int sendIntentSender(in IIntentSender target, in IBinder whitelistToken, int code, in Intent intent, in String resolvedType, in IIntentReceiver finishedReceiver, @@ -689,6 +689,8 @@ interface IActivityManager { /** * Holds the AM lock for the specified amount of milliseconds. * This is intended for use by the tests that need to imitate lock contention. + * The token should be obtained by + * {@link android.content.pm.PackageManager#getHoldLockToken()}. */ - void holdLock(in int durationMs); + void holdLock(in IBinder token, in int durationMs); } diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index 8a03fcc33d51..bd5913efdecb 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -303,7 +303,6 @@ interface IActivityTaskManager { boolean enterPictureInPictureMode(in IBinder token, in PictureInPictureParams params); void setPictureInPictureParams(in IBinder token, in PictureInPictureParams params); void requestPictureInPictureMode(in IBinder token); - int getMaxNumPictureInPictureActions(in IBinder token); IBinder getUriPermissionOwnerForActivity(in IBinder activityToken); /** diff --git a/core/java/android/app/IAppTask.aidl b/core/java/android/app/IAppTask.aidl index f41d705e2ba7..d3046c590c4f 100644 --- a/core/java/android/app/IAppTask.aidl +++ b/core/java/android/app/IAppTask.aidl @@ -24,7 +24,7 @@ import android.os.Bundle; /** @hide */ interface IAppTask { void finishAndRemoveTask(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) ActivityManager.RecentTaskInfo getTaskInfo(); void moveToFront(in IApplicationThread appThread, in String callingPackage); int startActivity(IBinder whoThread, String callingPackage, String callingFeatureId, diff --git a/core/java/android/app/IAssistDataReceiver.aidl b/core/java/android/app/IAssistDataReceiver.aidl index 0d69838e4329..d67fbff4548b 100644 --- a/core/java/android/app/IAssistDataReceiver.aidl +++ b/core/java/android/app/IAssistDataReceiver.aidl @@ -21,8 +21,8 @@ import android.os.Bundle; /** @hide */ oneway interface IAssistDataReceiver { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onHandleAssistData(in Bundle resultData); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onHandleAssistScreenshot(in Bitmap screenshot); } diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 66a7f4df03bb..c052186bb974 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -126,7 +126,7 @@ interface INotificationManager StatusBarNotification[] getActiveNotifications(String callingPkg); StatusBarNotification[] getActiveNotificationsWithAttribution(String callingPkg, String callingAttributionTag); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count, boolean includeSnoozed); StatusBarNotification[] getHistoricalNotificationsWithAttribution(String callingPkg, String callingAttributionTag, int count, boolean includeSnoozed); diff --git a/core/java/android/app/IStopUserCallback.aidl b/core/java/android/app/IStopUserCallback.aidl index d3c2ff776128..c99734259f57 100644 --- a/core/java/android/app/IStopUserCallback.aidl +++ b/core/java/android/app/IStopUserCallback.aidl @@ -22,7 +22,7 @@ package android.app; */ interface IStopUserCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void userStopped(int userId); void userStopAborted(int userId); } diff --git a/core/java/android/app/ITransientNotification.aidl b/core/java/android/app/ITransientNotification.aidl index 09a3ba045fc2..537a8f2acdc5 100644 --- a/core/java/android/app/ITransientNotification.aidl +++ b/core/java/android/app/ITransientNotification.aidl @@ -19,7 +19,7 @@ package android.app; /** @hide */ oneway interface ITransientNotification { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void show(IBinder windowToken); void hide(); } diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 4cb8d936aa9c..101917bc2e07 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -83,7 +83,7 @@ interface IWallpaperManager { * information about that wallpaper. Otherwise, if it is a static image, * simply return null. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) WallpaperInfo getWallpaperInfo(int userId); /** diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index f2a9daafb4ce..9e967958c9cb 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1416,7 +1416,7 @@ public class Instrumentation { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void callActivityOnNewIntent(Activity activity, ReferrerIntent intent) { final String oldReferrer = activity.mReferrer; try { @@ -1762,7 +1762,7 @@ public class Instrumentation { * * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int execStartActivitiesAsUser(Context who, IBinder contextThread, IBinder token, Activity target, Intent[] intents, Bundle options, int userId) { @@ -1945,7 +1945,7 @@ public class Instrumentation { * Special version! * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ActivityResult execStartActivityAsCaller( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options, IBinder permissionToken, @@ -1993,7 +1993,7 @@ public class Instrumentation { * Special version! * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void execStartActivityFromAppTask( Context who, IBinder contextThread, IAppTask appTask, Intent intent, Bundle options) { diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index 2122e92ba5b5..545c3f70d466 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -531,7 +531,7 @@ public class KeyguardManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isDeviceSecure(int userId) { try { return mTrustManager.isDeviceSecure(userId); diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 202b6152d2ea..b6094627d1f6 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -117,7 +117,7 @@ public final class LoadedApk { private String[] mOverlayDirs; @UnsupportedAppUsage private String mDataDir; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String mLibDir; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private File mDataDirFile; @@ -286,7 +286,7 @@ public final class LoadedApk { return mSecurityViolation; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CompatibilityInfo getCompatibilityInfo() { return mDisplayAdjustments.getCompatibilityInfo(); } @@ -1739,7 +1739,7 @@ public final class LoadedApk { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public IServiceConnection lookupServiceDispatcher(ServiceConnection c, Context context) { synchronized (mServices) { @@ -1805,7 +1805,7 @@ public final class LoadedApk { static final class ServiceDispatcher { private final ServiceDispatcher.InnerConnection mIServiceConnection; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final ServiceConnection mConnection; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final Context mContext; @@ -1824,7 +1824,7 @@ public final class LoadedApk { } private static class InnerConnection extends IServiceConnection.Stub { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher; InnerConnection(LoadedApk.ServiceDispatcher sd) { @@ -1843,7 +1843,7 @@ public final class LoadedApk { private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) ServiceDispatcher(ServiceConnection conn, Context context, Handler activityThread, int flags) { mIServiceConnection = new InnerConnection(this); @@ -1908,7 +1908,7 @@ public final class LoadedApk { return mConnection; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) IServiceConnection getIServiceConnection() { return mIServiceConnection; } diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java index 74bc9e215106..12d16049d1c3 100644 --- a/core/java/android/app/NativeActivity.java +++ b/core/java/android/app/NativeActivity.java @@ -71,7 +71,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, private NativeContentView mNativeContentView; private InputMethodManager mIMM; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeHandle; private InputQueue mCurInputQueue; @@ -87,7 +87,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, private boolean mDestroyed; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private native long loadNativeCode(String path, String funcname, MessageQueue queue, String internalDataPath, String obbPath, String externalDataPath, int sdkVersion, AssetManager assetMgr, byte[] savedState, ClassLoader classLoader, String libraryPath); @@ -315,22 +315,22 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void setWindowFlags(int flags, int mask) { getWindow().setFlags(flags, mask); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void setWindowFormat(int format) { getWindow().setFormat(format); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void showIme(int mode) { mIMM.showSoftInput(mNativeContentView, mode); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void hideIme(int mode) { mIMM.hideSoftInputFromWindow(mNativeContentView.getWindowToken(), mode); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 5e50b96a23d5..a1abe3d8190b 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -5266,7 +5266,7 @@ public class Notification implements Parcelable /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String loadHeaderAppName() { CharSequence name = null; final PackageManager pm = mContext.getPackageManager(); diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index f3bd04cd132e..27cd78acb35f 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1112,7 +1112,7 @@ public class NotificationManager { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ZenModeConfig getZenModeConfig() { INotificationManager service = getService(); try { diff --git a/core/java/android/app/PackageDeleteObserver.java b/core/java/android/app/PackageDeleteObserver.java index d8803aa13e42..4ff6f2a5133b 100644 --- a/core/java/android/app/PackageDeleteObserver.java +++ b/core/java/android/app/PackageDeleteObserver.java @@ -19,11 +19,12 @@ package android.app; import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.pm.IPackageDeleteObserver2; +import android.os.Build; /** {@hide} */ public class PackageDeleteObserver { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PackageDeleteObserver() { } diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 861e4378c68e..21dfbbd6f15d 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -130,6 +130,7 @@ public final class PendingIntent implements Parcelable { FLAG_UPDATE_CURRENT, FLAG_IMMUTABLE, FLAG_MUTABLE, + FLAG_MUTABLE_UNAUDITED, Intent.FILL_IN_ACTION, Intent.FILL_IN_DATA, @@ -205,6 +206,13 @@ public final class PendingIntent implements Parcelable { public static final int FLAG_MUTABLE = 1<<25; /** + * @deprecated Use {@link #FLAG_IMMUTABLE} or {@link #FLAG_MUTABLE} instead. + * @hide + */ + @Deprecated + public static final int FLAG_MUTABLE_UNAUDITED = FLAG_MUTABLE; + + /** * Exception thrown when trying to send through a PendingIntent that * has been canceled or is otherwise no longer able to execute the request. */ @@ -311,7 +319,7 @@ public final class PendingIntent implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void setOnMarshaledListener(OnMarshaledListener listener) { sOnMarshaledListener.set(listener); } @@ -397,6 +405,7 @@ public final class PendingIntent implements Parcelable { * parameters. May return null only if {@link #FLAG_NO_CREATE} has been * supplied. */ + @SuppressWarnings("AndroidFrameworkPendingIntentMutability") public static PendingIntent getActivity(Context context, int requestCode, @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) { // Some tests only mock Context.getUserId(), so fallback to the id Context.getUser() is null @@ -528,6 +537,7 @@ public final class PendingIntent implements Parcelable { * parameters. May return null only if {@link #FLAG_NO_CREATE} has been * supplied. */ + @SuppressWarnings("AndroidFrameworkPendingIntentMutability") public static PendingIntent getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) { // Some tests only mock Context.getUserId(), so fallback to the id Context.getUser() is null diff --git a/core/java/android/app/QueuedWork.java b/core/java/android/app/QueuedWork.java index a1fcf53a2c37..edf0a46b1433 100644 --- a/core/java/android/app/QueuedWork.java +++ b/core/java/android/app/QueuedWork.java @@ -17,6 +17,7 @@ package android.app; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -217,7 +218,7 @@ public class QueuedWork { * @param work The new runnable to process * @param shouldDelay If the message should be delayed */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void queue(Runnable work, boolean shouldDelay) { Handler handler = getHandler(); diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index dcb53505227a..7dd7c901ff84 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -31,6 +31,7 @@ import android.content.res.Configuration; import android.database.Cursor; import android.graphics.Rect; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.RemoteException; @@ -778,7 +779,7 @@ public class SearchManager * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isVisible() { return mSearchDialog == null? false : mSearchDialog.isShowing(); } diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java index 3df164822f32..bc1bcbc4f80e 100644 --- a/core/java/android/app/SharedPreferencesImpl.java +++ b/core/java/android/app/SharedPreferencesImpl.java @@ -130,7 +130,7 @@ final class SharedPreferencesImpl implements SharedPreferences { startLoadFromDisk(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void startLoadFromDisk() { synchronized (mLock) { mLoaded = false; diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index 864db2722d53..b8fae6755bfd 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -26,6 +26,7 @@ import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; @@ -54,7 +55,7 @@ public class StatusBarManager { /** @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int DISABLE_NOTIFICATION_TICKER = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER; /** @hide */ @@ -313,7 +314,7 @@ public class StatusBarManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void expandSettingsPanel(@Nullable String subPanel) { try { final IStatusBarService svc = getService(); @@ -326,7 +327,7 @@ public class StatusBarManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setIcon(String slot, int iconId, int iconLevel, String contentDescription) { try { final IStatusBarService svc = getService(); @@ -340,7 +341,7 @@ public class StatusBarManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void removeIcon(String slot) { try { final IStatusBarService svc = getService(); @@ -353,7 +354,7 @@ public class StatusBarManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setIconVisibility(String slot, boolean visible) { try { final IStatusBarService svc = getService(); diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index 849f679c9439..45e9c49c5322 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -24,6 +24,9 @@ import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.Configuration; +import android.graphics.Point; +import android.graphics.Rect; +import android.os.Build; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; @@ -43,7 +46,7 @@ public class TaskInfo { * running user of the system otherwise. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int userId; /** @@ -181,6 +184,20 @@ public class TaskInfo { public boolean isResizeable; /** + * Activity bounds if this task or its top activity is presented in letterbox mode and + * {@code null} otherwise. + * @hide + */ + @Nullable + public Rect letterboxActivityBounds; + + /** + * Relative position of the task's top left corner in the parent container. + * @hide + */ + public Point positionInParent; + + /** * The launch cookies associated with activities in this task if any. * @see ActivityOptions#setLaunchCookie(IBinder) * @hide @@ -224,7 +241,15 @@ public class TaskInfo { } /** @hide */ + @Nullable + @TestApi + public PictureInPictureParams getPictureInPictureParams() { + return pictureInPictureParams; + } + + /** @hide */ public void addLaunchCookie(IBinder cookie) { + if (cookie == null || launchCookies.contains(cookie)) return; launchCookies.add(cookie); } @@ -256,6 +281,8 @@ public class TaskInfo { topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR); isResizeable = source.readBoolean(); source.readBinderList(launchCookies); + letterboxActivityBounds = source.readTypedObject(Rect.CREATOR); + positionInParent = source.readTypedObject(Point.CREATOR); } /** @@ -287,6 +314,8 @@ public class TaskInfo { dest.writeTypedObject(topActivityInfo, flags); dest.writeBoolean(isResizeable); dest.writeBinderList(launchCookies); + dest.writeTypedObject(letterboxActivityBounds, flags); + dest.writeTypedObject(positionInParent, flags); } @Override @@ -306,6 +335,9 @@ public class TaskInfo { + " topActivityType=" + topActivityType + " pictureInPictureParams=" + pictureInPictureParams + " topActivityInfo=" + topActivityInfo - + " launchCookies" + launchCookies; + + " launchCookies" + launchCookies + + " letterboxActivityBounds=" + letterboxActivityBounds + + " positionInParent=" + positionInParent + + "}"; } } diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java index e77d7ac6a4ad..70ad9af8a037 100644 --- a/core/java/android/app/TaskStackListener.java +++ b/core/java/android/app/TaskStackListener.java @@ -21,6 +21,7 @@ import android.app.ActivityManager.TaskSnapshot; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; @@ -37,35 +38,35 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onTaskStackChanged() throws RemoteException { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onActivityPinned(String packageName, int userId, int taskId, int stackId) throws RemoteException { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onActivityUnpinned() throws RemoteException { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) throws RemoteException { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onActivityForcedResizable(String packageName, int taskId, int reason) throws RemoteException { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onActivityDismissingDockedStack() throws RemoteException { } @@ -80,12 +81,12 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub { * #onActivityLaunchOnSecondaryDisplayFailed(RunningTaskInfo, int)} */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onActivityLaunchOnSecondaryDisplayFailed() throws RemoteException { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onActivityLaunchOnSecondaryDisplayRerouted(RunningTaskInfo taskInfo, int requestedDisplayId) throws RemoteException { } @@ -95,7 +96,7 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onTaskRemoved(int taskId) throws RemoteException { } @@ -109,7 +110,7 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub { * @deprecated see {@link #onTaskMovedToFront(RunningTaskInfo)} */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onTaskMovedToFront(int taskId) throws RemoteException { } @@ -141,18 +142,18 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) throws RemoteException { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onTaskProfileLocked(int taskId, int userId) throws RemoteException { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException { if (Binder.getCallingPid() != android.os.Process.myPid() && snapshot != null && snapshot.getHardwareBuffer() != null) { @@ -162,7 +163,7 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken) throws RemoteException { } diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index 255b93f79811..290e12191de8 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -25,6 +25,7 @@ import android.graphics.Bitmap; import android.graphics.Rect; import android.hardware.input.InputManager; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.Process; @@ -88,7 +89,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { private int mOwningUid; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public UiAutomationConnection() { } diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java index 08a210b069b9..42b4c5c389bb 100644 --- a/core/java/android/app/VrManager.java +++ b/core/java/android/app/VrManager.java @@ -9,6 +9,7 @@ import android.annotation.SystemService; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; +import android.os.Build; import android.os.RemoteException; import android.service.vr.IPersistentVrStateCallbacks; import android.service.vr.IVrManager; @@ -51,7 +52,7 @@ public class VrManager { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final IVrManager mService; private Map<VrStateCallback, CallbackEntry> mCallbackMap = new ArrayMap<>(); diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 54f3209e17be..ab0901da632f 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -1977,7 +1977,7 @@ public class WallpaperManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static InputStream openDefaultWallpaper(Context context, @SetWallpaperFlags int which) { final String whichProp; final int defaultResId; diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java index 4ae1670e9041..c4af4edb467b 100644 --- a/core/java/android/app/WindowConfiguration.java +++ b/core/java/android/app/WindowConfiguration.java @@ -796,6 +796,9 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu /** * Returns {@code true} if the windowingMode represents a window in multi-window mode. * I.e. sharing the screen with another activity. + * + * TODO(b/171672645): This API could be misleading - in 'undefined' mode it's determined by the + * parent's mode * @hide */ public static boolean inMultiWindowMode(int windowingMode) { diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java index 3cc7f1e5df42..1ee8e4fce58b 100644 --- a/core/java/android/app/admin/DeviceAdminInfo.java +++ b/core/java/android/app/admin/DeviceAdminInfo.java @@ -55,22 +55,6 @@ public final class DeviceAdminInfo implements Parcelable { static final String TAG = "DeviceAdminInfo"; /** - * A type of policy that this device admin can use: device owner meta-policy - * for an admin that is designated as owner of the device. - * - * @hide - */ - public static final int USES_POLICY_DEVICE_OWNER = -2; - - /** - * A type of policy that this device admin can use: profile owner meta-policy - * for admins that have been installed as owner of some user profile. - * - * @hide - */ - public static final int USES_POLICY_PROFILE_OWNER = -1; - - /** * A type of policy that this device admin can use: limit the passwords * that the user can select, via {@link DevicePolicyManager#setPasswordQuality} * and {@link DevicePolicyManager#setPasswordMinimumLength}. @@ -475,7 +459,7 @@ public final class DeviceAdminInfo implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ArrayList<PolicyInfo> getUsedPolicies() { ArrayList<PolicyInfo> res = new ArrayList<PolicyInfo>(); for (int i=0; i<sPoliciesDisplayOrder.size(); i++) { diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index ad902a028f13..224e3a8df5ef 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -525,7 +525,7 @@ public class DevicePolicyManager { * @hide */ public static final String ACTION_REMOTE_BUGREPORT_DISPATCH = - "android.intent.action.REMOTE_BUGREPORT_DISPATCH"; + "com.android.server.action.REMOTE_BUGREPORT_DISPATCH"; /** * Extra for shared bugreport's SHA-256 hash. @@ -1396,7 +1396,7 @@ public class DevicePolicyManager { * sent to the parent user. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED = "android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED"; @@ -1830,6 +1830,15 @@ public class DevicePolicyManager { public static final int STATE_USER_PROFILE_COMPLETE = 4; /** + * Management setup on a managed profile. + * <p>This is used as an intermediate state after {@link #STATE_USER_PROFILE_COMPLETE} once the + * work profile has been created. + * @hide + */ + @SystemApi + public static final int STATE_USER_PROFILE_FINALIZED = 5; + + /** * @hide */ @IntDef(prefix = { "STATE_USER_" }, value = { @@ -1837,7 +1846,8 @@ public class DevicePolicyManager { STATE_USER_SETUP_INCOMPLETE, STATE_USER_SETUP_COMPLETE, STATE_USER_SETUP_FINALIZED, - STATE_USER_PROFILE_COMPLETE + STATE_USER_PROFILE_COMPLETE, + STATE_USER_PROFILE_FINALIZED }) @Retention(RetentionPolicy.SOURCE) public @interface UserProvisioningState {} @@ -4122,7 +4132,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getMaximumTimeToLock(@Nullable ComponentName admin, int userHandle) { if (mService != null) { try { @@ -4204,7 +4214,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN) public long getRequiredStrongAuthTimeout(@Nullable ComponentName admin, @UserIdInt int userId) { if (mService != null) { @@ -4506,7 +4516,7 @@ public class DevicePolicyManager { * of the device admin that sets the proxy. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable ComponentName setGlobalProxy(@NonNull ComponentName admin, Proxy proxySpec, List<String> exclusionList ) { throwIfParentInstance("setGlobalProxy"); @@ -6308,7 +6318,7 @@ public class DevicePolicyManager { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setActiveAdmin(@NonNull ComponentName policyReceiver, boolean refreshing, int userHandle) { if (mService != null) { @@ -7022,7 +7032,7 @@ public class DevicePolicyManager { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable ComponentName getProfileOwnerAsUser(final int userId) { if (mService != null) { try { @@ -7437,7 +7447,7 @@ public class DevicePolicyManager { } /** @hide per-user version */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN) public @Nullable List<PersistableBundle> getTrustAgentConfiguration( @Nullable ComponentName admin, @NonNull ComponentName agent, int userHandle) { @@ -10623,7 +10633,7 @@ public class DevicePolicyManager { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void throwIfParentInstance(String functionName) { if (mParentInstance) { throw new SecurityException(functionName + " cannot be called on the parent instance"); diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java index 5a4ab48f3823..86f91d79ad2b 100644 --- a/core/java/android/app/admin/SecurityLog.java +++ b/core/java/android/app/admin/SecurityLog.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemProperties; @@ -524,7 +525,7 @@ public class SecurityLog { * Constructor used by native classes to generate SecurityEvent instances. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ SecurityEvent(byte[] data) { this(0, data); } diff --git a/core/java/android/app/backup/BackupDataOutput.java b/core/java/android/app/backup/BackupDataOutput.java index fb161d41acd2..50d7cec0bc71 100644 --- a/core/java/android/app/backup/BackupDataOutput.java +++ b/core/java/android/app/backup/BackupDataOutput.java @@ -18,6 +18,7 @@ package android.app.backup; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.ParcelFileDescriptor; import java.io.FileDescriptor; @@ -68,7 +69,7 @@ public class BackupDataOutput { private final long mQuota; private final int mTransportFlags; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) long mBackupWriter; /** diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java index 587e883edaf2..c854abac291e 100644 --- a/core/java/android/app/backup/FullBackup.java +++ b/core/java/android/app/backup/FullBackup.java @@ -20,6 +20,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.XmlResourceParser; +import android.os.Build; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.storage.StorageManager; @@ -91,7 +92,7 @@ public class FullBackup { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static public native int backupToTar(String packageName, String domain, String linkdomain, String rootpath, String path, FullBackupDataOutput output); diff --git a/core/java/android/app/backup/FullBackupDataOutput.java b/core/java/android/app/backup/FullBackupDataOutput.java index d8fa0f586b7a..a47478cc66a7 100644 --- a/core/java/android/app/backup/FullBackupDataOutput.java +++ b/core/java/android/app/backup/FullBackupDataOutput.java @@ -1,6 +1,7 @@ package android.app.backup; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.ParcelFileDescriptor; /** @@ -77,7 +78,7 @@ public class FullBackupDataOutput { public BackupDataOutput getData() { return mData; } /** @hide - used for measurement pass */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addSize(long size) { if (size > 0) { mSize += size; diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl index e177a74915ee..e1bbc08e72f3 100644 --- a/core/java/android/app/backup/IBackupManager.aidl +++ b/core/java/android/app/backup/IBackupManager.aidl @@ -74,7 +74,7 @@ interface IBackupManager { /** * {@link android.app.backup.IBackupManager.clearBackupDataForUser} for the calling user id. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void clearBackupData(String transportName, String packageName); /** @@ -157,7 +157,7 @@ interface IBackupManager { /** * {@link android.app.backup.IBackupManager.setBackupEnabledForUser} for the calling user id. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setBackupEnabled(boolean isEnabled); /** @@ -181,7 +181,7 @@ interface IBackupManager { /** * {@link android.app.backup.IBackupManager.setAutoRestoreForUser} for the calling user id. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setAutoRestore(boolean doAutoRestore); /** @@ -198,7 +198,7 @@ interface IBackupManager { /** * {@link android.app.backup.IBackupManager.isBackupEnabledForUser} for the calling user id. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isBackupEnabled(); /** @@ -327,7 +327,7 @@ interface IBackupManager { * {@link android.app.backup.IBackupManager.acknowledgeFullBackupOrRestoreForUser} for the * calling user id. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void acknowledgeFullBackupOrRestore(int token, boolean allow, in String curPassword, in String encryptionPassword, IFullBackupRestoreObserver observer); @@ -404,7 +404,7 @@ interface IBackupManager { /** * {@link android.app.backup.IBackupManager.listAllTransportsForUser} for the calling user id. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String[] listAllTransports(); /** @@ -442,7 +442,7 @@ interface IBackupManager { * {@link android.app.backup.IBackupManager.selectBackupTransportForUser} for the calling user * id. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String selectBackupTransport(String transport); /** @@ -595,7 +595,7 @@ interface IBackupManager { * @param whichUser User handle of the defined user whose backup active state * is being queried. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isBackupServiceActive(int whichUser); /** diff --git a/core/java/android/app/servertransaction/ActivityResultItem.java b/core/java/android/app/servertransaction/ActivityResultItem.java index 8320f49f132f..e059f177e344 100644 --- a/core/java/android/app/servertransaction/ActivityResultItem.java +++ b/core/java/android/app/servertransaction/ActivityResultItem.java @@ -24,6 +24,7 @@ import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.app.ResultInfo; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.Trace; @@ -37,7 +38,7 @@ import java.util.Objects; */ public class ActivityResultItem extends ActivityTransactionItem { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private List<ResultInfo> mResultInfoList; /* TODO(b/78294732) diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java index ac57f2bf80e0..723fa012c902 100644 --- a/core/java/android/app/servertransaction/NewIntentItem.java +++ b/core/java/android/app/servertransaction/NewIntentItem.java @@ -24,6 +24,7 @@ import android.annotation.Nullable; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.Trace; @@ -39,7 +40,7 @@ import java.util.Objects; */ public class NewIntentItem extends ActivityTransactionItem { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private List<ReferrerIntent> mIntents; private boolean mResume; diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl index ed6ba0c5efa4..2c1e951b6128 100644 --- a/core/java/android/app/usage/IUsageStatsManager.aidl +++ b/core/java/android/app/usage/IUsageStatsManager.aidl @@ -28,10 +28,10 @@ import java.util.Map; * {@hide} */ interface IUsageStatsManager { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) ParceledListSlice queryUsageStats(int bucketType, long beginTime, long endTime, String callingPackage); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) ParceledListSlice queryConfigurationStats(int bucketType, long beginTime, long endTime, String callingPackage); ParceledListSlice queryEventStats(int bucketType, long beginTime, long endTime, @@ -40,9 +40,9 @@ interface IUsageStatsManager { UsageEvents queryEventsForPackage(long beginTime, long endTime, String callingPackage); UsageEvents queryEventsForUser(long beginTime, long endTime, int userId, String callingPackage); UsageEvents queryEventsForPackageForUser(long beginTime, long endTime, int userId, String pkg, String callingPackage); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setAppInactive(String packageName, boolean inactive, int userId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isAppInactive(String packageName, int userId, String callingPackage); void onCarrierPrivilegedAppsChanged(); void reportChooserSelection(String packageName, int userId, String contentType, diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index fc8248e1012a..1ddfe0d2479a 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -34,6 +34,7 @@ import android.net.NetworkTemplate; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.netstats.provider.NetworkStatsProvider; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -129,7 +130,7 @@ public class NetworkStatsManager { /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkStatsManager(Context context) throws ServiceNotFoundException { this(context, INetworkStatsService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE))); @@ -153,7 +154,7 @@ public class NetworkStatsManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public void setPollForce(boolean pollForce) { if (pollForce) { diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index 467b2fba1102..565e4cd7fea0 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -25,6 +25,7 @@ import android.content.Context; import android.content.IntentSender; import android.content.pm.PackageManager; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -54,7 +55,7 @@ public class AppWidgetHost { static final int HANDLE_UPDATE = 1; static final int HANDLE_PROVIDER_CHANGED = 2; static final int HANDLE_PROVIDERS_CHANGED = 3; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static final int HANDLE_VIEW_DATA_CHANGED = 4; static final int HANDLE_APP_WIDGET_REMOVED = 5; @@ -173,7 +174,7 @@ public class AppWidgetHost { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public AppWidgetHost(Context context, int hostId, OnClickHandler handler, Looper looper) { mContextOpPackageName = context.getOpPackageName(); mHostId = hostId; diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 3fef92b203b6..a3c3a0e106a3 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -30,6 +30,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; +import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Parcelable; @@ -286,7 +287,7 @@ public class AppWidgetHostView extends FrameLayout { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void updateAppWidgetSize(Bundle newOptions, int minWidth, int minHeight, int maxWidth, int maxHeight, boolean ignorePadding) { if (newOptions == null) { diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index 009ec522e436..37093a10b2f0 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -34,6 +34,7 @@ import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.RemoteException; @@ -943,7 +944,7 @@ public class AppWidgetManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) { if (mService == null) { return; @@ -1114,7 +1115,7 @@ public class AppWidgetManager { * @see Context#getServiceDispatcher(ServiceConnection, Handler, int) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean bindRemoteViewsService(Context context, int appWidgetId, Intent intent, IServiceConnection connection, @Context.BindServiceFlags int flags) { if (mService == null) { diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 5374d6d55ee3..c0cb32346821 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -118,7 +118,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_ACTIVE_DEVICE_CHANGED = "android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED"; @@ -139,7 +139,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_CODEC_CONFIG_CHANGED = "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED"; @@ -409,7 +409,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @hide */ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean setActiveDevice(@Nullable BluetoothDevice device) { if (DBG) log("setActiveDevice(" + device + ")"); try { @@ -433,7 +433,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * is active * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Nullable @RequiresPermission(Manifest.permission.BLUETOOTH) public BluetoothDevice getActiveDevice() { @@ -651,7 +651,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @return the current codec status * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Nullable @RequiresPermission(Manifest.permission.BLUETOOTH) public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) { @@ -680,7 +680,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @param codecConfig the codec configuration preference * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH) public void setCodecConfigPreference(@NonNull BluetoothDevice device, @NonNull BluetoothCodecConfig codecConfig) { @@ -710,7 +710,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * active A2DP Bluetooth device. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH) public void enableOptionalCodecs(@NonNull BluetoothDevice device) { if (DBG) Log.d(TAG, "enableOptionalCodecs(" + device + ")"); @@ -725,7 +725,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * active A2DP Bluetooth device. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH) public void disableOptionalCodecs(@NonNull BluetoothDevice device) { if (DBG) Log.d(TAG, "disableOptionalCodecs(" + device + ")"); @@ -766,7 +766,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * OPTIONAL_CODECS_SUPPORTED. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) @OptionalCodecsSupportStatus public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) { @@ -792,7 +792,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * OPTIONAL_CODECS_PREF_DISABLED. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) @OptionalCodecsPreferenceStatus public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) { @@ -819,7 +819,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * OPTIONAL_CODECS_PREF_DISABLED. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public void setOptionalCodecsEnabled(@NonNull BluetoothDevice device, @OptionalCodecsPreferenceStatus int value) { diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java index 53f87e6bc05b..67f3d7b5d717 100755 --- a/core/java/android/bluetooth/BluetoothA2dpSink.java +++ b/core/java/android/bluetooth/BluetoothA2dpSink.java @@ -24,6 +24,7 @@ import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -158,7 +159,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile { * @return false on immediate error, true otherwise * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnect(BluetoothDevice device) { if (DBG) log("disconnect(" + device + ")"); diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 573892bcf014..475be121b735 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -40,6 +40,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.BatteryStats; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.ParcelUuid; import android.os.RemoteException; @@ -1170,7 +1171,7 @@ public final class BluetoothAdapter { * @return true to indicate adapter shutdown has begun, or false on immediate error * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean disable(boolean persist) { try { @@ -1219,7 +1220,7 @@ public final class BluetoothAdapter { * @return true to indicate that the config file was successfully cleared * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset() { try { @@ -2625,7 +2626,7 @@ public final class BluetoothAdapter { * permissions, or channel in use. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public BluetoothServerSocket listenUsingEncryptedRfcommWithServiceRecord(String name, UUID uuid) throws IOException { return createNewRfcommSocketAndRecord(name, uuid, false, true); diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java index 7764ebeb2e33..3a65aaa0d16c 100644 --- a/core/java/android/bluetooth/BluetoothCodecStatus.java +++ b/core/java/android/bluetooth/BluetoothCodecStatus.java @@ -18,6 +18,7 @@ package android.bluetooth; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -39,7 +40,7 @@ public final class BluetoothCodecStatus implements Parcelable { * This extra represents the current codec status of the A2DP * profile. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_CODEC_STATUS = "android.bluetooth.extra.CODEC_STATUS"; @@ -198,7 +199,7 @@ public final class BluetoothCodecStatus implements Parcelable { * * @return the current codec configuration */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable BluetoothCodecConfig getCodecConfig() { return mCodecConfig; } @@ -208,7 +209,7 @@ public final class BluetoothCodecStatus implements Parcelable { * * @return an array with the codecs local capabilities */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable BluetoothCodecConfig[] getCodecsLocalCapabilities() { return mCodecsLocalCapabilities; } @@ -218,7 +219,7 @@ public final class BluetoothCodecStatus implements Parcelable { * * @return an array with the codecs selectable capabilities */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable BluetoothCodecConfig[] getCodecsSelectableCapabilities() { return mCodecsSelectableCapabilities; } diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 1b0fe9dc2d78..3b8dec7bf955 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -28,6 +28,7 @@ import android.annotation.SystemApi; import android.app.PropertyInvalidatedCache; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.Handler; import android.os.Parcel; import android.os.ParcelUuid; @@ -369,7 +370,7 @@ public final class BluetoothDevice implements Parcelable { /** @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_SDP_RECORD = "android.bluetooth.device.action.SDP_RECORD"; @@ -665,7 +666,7 @@ public final class BluetoothDevice implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int UNBOND_REASON_AUTH_FAILED = 1; /** @@ -674,7 +675,7 @@ public final class BluetoothDevice implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int UNBOND_REASON_AUTH_REJECTED = 2; /** @@ -689,7 +690,7 @@ public final class BluetoothDevice implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4; /** @@ -697,7 +698,7 @@ public final class BluetoothDevice implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5; /** @@ -705,7 +706,7 @@ public final class BluetoothDevice implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int UNBOND_REASON_AUTH_TIMEOUT = 6; /** @@ -713,7 +714,7 @@ public final class BluetoothDevice implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7; /** @@ -722,7 +723,7 @@ public final class BluetoothDevice implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8; /** @@ -801,7 +802,7 @@ public final class BluetoothDevice implements Parcelable { "android.bluetooth.device.extra.SDP_RECORD"; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_SDP_SEARCH_STATUS = "android.bluetooth.device.extra.SDP_SEARCH_STATUS"; @@ -1134,7 +1135,7 @@ public final class BluetoothDevice implements Parcelable { * @return true on success, false on error * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH) public boolean setAlias(@NonNull String alias) { final IBluetooth service = sService; @@ -1573,7 +1574,7 @@ public final class BluetoothDevice implements Parcelable { * @return true pin has been set false for error * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean setPin(@NonNull String pin) { byte[] pinBytes = convertPinToBytes(pin); @@ -2187,7 +2188,7 @@ public final class BluetoothDevice implements Parcelable { * operations. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public BluetoothGatt connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback, int transport, boolean opportunistic, int phy, Handler handler) { diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java index 6d22eb93fd02..7a6ff79623af 100644 --- a/core/java/android/bluetooth/BluetoothGatt.java +++ b/core/java/android/bluetooth/BluetoothGatt.java @@ -58,9 +58,9 @@ public final class BluetoothGatt implements BluetoothProfile { private int mConnState; private final Object mStateLock = new Object(); private final Object mDeviceBusyLock = new Object(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Boolean mDeviceBusy = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mTransport; private int mPhy; private boolean mOpportunistic; @@ -881,7 +881,7 @@ public final class BluetoothGatt implements BluetoothProfile { * automatically connect as soon as the remote device becomes available (true). * @return true, if the connection attempt was initiated successfully */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback, Handler handler) { if (DBG) { diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java index e7809aeb1bb5..23dc7c830855 100644 --- a/core/java/android/bluetooth/BluetoothGattService.java +++ b/core/java/android/bluetooth/BluetoothGattService.java @@ -16,6 +16,7 @@ package android.bluetooth; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.ParcelUuid; import android.os.Parcelable; @@ -385,7 +386,7 @@ public class BluetoothGattService implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setAdvertisePreferred(boolean advertisePreferred) { mAdvertisePreferred = advertisePreferred; } diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java index e6d6e7ac5dda..57d1411aa68a 100644 --- a/core/java/android/bluetooth/BluetoothHeadset.java +++ b/core/java/android/bluetooth/BluetoothHeadset.java @@ -27,6 +27,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -112,7 +113,7 @@ public final class BluetoothHeadset implements BluetoothProfile { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_ACTIVE_DEVICE_CHANGED = "android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED"; @@ -635,7 +636,7 @@ public final class BluetoothHeadset implements BluetoothProfile { * @return priority of the device * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); @@ -782,7 +783,7 @@ public final class BluetoothHeadset implements BluetoothProfile { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getAudioState(BluetoothDevice device) { if (VDBG) log("getAudioState"); final IBluetoothHeadset service = mService; @@ -1030,7 +1031,7 @@ public final class BluetoothHeadset implements BluetoothProfile { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type, String name) { final IBluetoothHeadset service = mService; @@ -1129,7 +1130,7 @@ public final class BluetoothHeadset implements BluetoothProfile { * @hide */ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean setActiveDevice(@Nullable BluetoothDevice device) { if (DBG) { Log.d(TAG, "setActiveDevice: " + device); @@ -1155,7 +1156,7 @@ public final class BluetoothHeadset implements BluetoothProfile { * is active. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Nullable @RequiresPermission(Manifest.permission.BLUETOOTH) public BluetoothDevice getActiveDevice() { diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java index 28363250ebda..e5b2a1e23cc1 100644 --- a/core/java/android/bluetooth/BluetoothHeadsetClient.java +++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java @@ -22,6 +22,7 @@ import android.annotation.RequiresPermission; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; @@ -445,7 +446,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean connect(BluetoothDevice device) { if (DBG) log("connect(" + device + ")"); final IBluetoothHeadsetClient service = @@ -471,7 +472,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean disconnect(BluetoothDevice device) { if (DBG) log("disconnect(" + device + ")"); final IBluetoothHeadsetClient service = @@ -780,7 +781,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * @return <code>true</code> if command has been issued successfully; <code>false</code> * otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean acceptCall(BluetoothDevice device, int flag) { if (DBG) log("acceptCall()"); final IBluetoothHeadsetClient service = @@ -829,7 +830,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * #EXTRA_AG_FEATURE_REJECT_CALL}. This method invocation will fail silently when feature is not * supported.</p> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean rejectCall(BluetoothDevice device) { if (DBG) log("rejectCall()"); final IBluetoothHeadsetClient service = @@ -1014,7 +1015,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * * Note: This is an internal function and shouldn't be exposed */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getAudioState(BluetoothDevice device) { if (VDBG) log("getAudioState"); final IBluetoothHeadsetClient service = diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java index d1a096e605dd..219d1596fbf3 100644 --- a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java +++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java @@ -17,6 +17,7 @@ package android.bluetooth; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -144,7 +145,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable { * * @return call id. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getId() { return mId; } @@ -164,7 +165,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable { * * @return state of this particular phone call. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getState() { return mState; } @@ -174,7 +175,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable { * * @return string representing phone number. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getNumber() { return mNumber; } @@ -193,7 +194,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable { * * @return <code>true</code> if call is a multi party call, <code>false</code> otherwise. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isMultiParty() { return mMultiParty; } @@ -203,7 +204,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable { * * @return <code>true</code> if its outgoing call, <code>false</code> otherwise. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isOutgoing() { return mOutgoing; } diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java index fa62a02499e0..ff78825e0f96 100644 --- a/core/java/android/bluetooth/BluetoothHearingAid.java +++ b/core/java/android/bluetooth/BluetoothHearingAid.java @@ -26,6 +26,7 @@ import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -85,7 +86,7 @@ public final class BluetoothHearingAid implements BluetoothProfile { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_ACTIVE_DEVICE_CHANGED = "android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED"; @@ -302,7 +303,7 @@ public final class BluetoothHearingAid implements BluetoothProfile { * @return false on immediate error, true otherwise * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean setActiveDevice(@Nullable BluetoothDevice device) { if (DBG) log("setActiveDevice(" + device + ")"); final IBluetoothHearingAid service = getService(); @@ -328,7 +329,7 @@ public final class BluetoothHearingAid implements BluetoothProfile { * is not active, it will be null on that position. Returns empty list on error. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(Manifest.permission.BLUETOOTH) public @NonNull List<BluetoothDevice> getActiveDevices() { if (VDBG) log("getActiveDevices()"); diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java index 14a71c44673b..35549954007e 100644 --- a/core/java/android/bluetooth/BluetoothMap.java +++ b/core/java/android/bluetooth/BluetoothMap.java @@ -24,6 +24,7 @@ import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.util.CloseGuard; @@ -209,7 +210,7 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean disconnect(BluetoothDevice device) { if (DBG) log("disconnect(" + device + ")"); final IBluetoothMap service = getService(); diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java index df11d3adac01..ff6cffb272a5 100644 --- a/core/java/android/bluetooth/BluetoothMapClient.java +++ b/core/java/android/bluetooth/BluetoothMapClient.java @@ -24,6 +24,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -388,7 +389,7 @@ public final class BluetoothMapClient implements BluetoothProfile { * @param deliveredIntent intent issued when message is delivered * @return true if the message is enqueued, false on error */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message, PendingIntent sentIntent, PendingIntent deliveredIntent) { if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message); diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java index ce3c7d25a108..ecd718cec32b 100644 --- a/core/java/android/bluetooth/BluetoothPan.java +++ b/core/java/android/bluetooth/BluetoothPan.java @@ -27,6 +27,7 @@ import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -234,7 +235,7 @@ public final class BluetoothPan implements BluetoothProfile { * @return false on immediate error, true otherwise * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean connect(BluetoothDevice device) { if (DBG) log("connect(" + device + ")"); final IBluetoothPan service = getService(); diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java index d58a89350195..6e5c45f3d129 100644 --- a/core/java/android/bluetooth/BluetoothPbap.java +++ b/core/java/android/bluetooth/BluetoothPbap.java @@ -27,6 +27,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; @@ -322,7 +323,7 @@ public class BluetoothPbap implements BluetoothProfile { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean disconnect(BluetoothDevice device) { log("disconnect()"); final IBluetoothPbap service = mService; diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java index 7538df8bbe5f..db851c4f33b9 100644 --- a/core/java/android/bluetooth/BluetoothProfile.java +++ b/core/java/android/bluetooth/BluetoothProfile.java @@ -23,6 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -219,7 +220,7 @@ public interface BluetoothProfile { * * @hide **/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int PRIORITY_AUTO_CONNECT = 1000; /** diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java index 48e8c1ada255..0d70dbdd8427 100644 --- a/core/java/android/bluetooth/BluetoothSap.java +++ b/core/java/android/bluetooth/BluetoothSap.java @@ -21,6 +21,7 @@ import android.annotation.RequiresPermission; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -219,7 +220,7 @@ public final class BluetoothSap implements BluetoothProfile { * @return false on error, true otherwise * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean disconnect(BluetoothDevice device) { if (DBG) log("disconnect(" + device + ")"); final IBluetoothSap service = getService(); diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index d41a6d064d1f..65381dbb2372 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -18,6 +18,7 @@ package android.bluetooth; import android.compat.annotation.UnsupportedAppUsage; import android.net.LocalSocket; +import android.os.Build; import android.os.ParcelFileDescriptor; import android.os.ParcelUuid; import android.os.RemoteException; @@ -111,7 +112,7 @@ public final class BluetoothSocket implements Closeable { public static final int TYPE_L2CAP_LE = 4; /*package*/ static final int EBADFD = 77; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /*package*/ static final int EADDRINUSE = 98; /*package*/ static final int SEC_FLAG_ENCRYPT = 1; diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java index c55f0ff7da93..8170bf92ae1e 100644 --- a/core/java/android/companion/AssociationRequest.java +++ b/core/java/android/companion/AssociationRequest.java @@ -19,6 +19,7 @@ package android.companion; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.provider.OneTimeUseBuilder; @@ -46,6 +47,7 @@ public final class AssociationRequest implements Parcelable { private final boolean mSingleDevice; private final List<DeviceFilter<?>> mDeviceFilters; + private String mCallingPackage; private AssociationRequest( boolean singleDevice, @Nullable List<DeviceFilter<?>> deviceFilters) { @@ -57,47 +59,61 @@ public final class AssociationRequest implements Parcelable { this( in.readByte() != 0, in.readParcelableList(new ArrayList<>(), AssociationRequest.class.getClassLoader())); + setCallingPackage(in.readString()); } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isSingleDevice() { return mSingleDevice; } /** @hide */ @NonNull - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public List<DeviceFilter<?>> getDeviceFilters() { return mDeviceFilters; } + /** @hide */ + public String getCallingPackage() { + return mCallingPackage; + } + + /** @hide */ + public void setCallingPackage(String pkg) { + mCallingPackage = pkg; + } + @Override public boolean equals(@Nullable Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AssociationRequest that = (AssociationRequest) o; - return mSingleDevice == that.mSingleDevice && - Objects.equals(mDeviceFilters, that.mDeviceFilters); + return mSingleDevice == that.mSingleDevice + && Objects.equals(mDeviceFilters, that.mDeviceFilters) + && Objects.equals(mCallingPackage, that.mCallingPackage); } @Override public int hashCode() { - return Objects.hash(mSingleDevice, mDeviceFilters); + return Objects.hash(mSingleDevice, mDeviceFilters, mCallingPackage); } @Override public String toString() { - return "AssociationRequest{" + - "mSingleDevice=" + mSingleDevice + - ", mDeviceFilters=" + mDeviceFilters + - '}'; + return "AssociationRequest{" + + "mSingleDevice=" + mSingleDevice + + ", mDeviceFilters=" + mDeviceFilters + + ", mCallingPackage=" + mCallingPackage + + '}'; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeByte((byte) (mSingleDevice ? 1 : 0)); dest.writeParcelableList(mDeviceFilters, flags); + dest.writeString(mCallingPackage); } @Override diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java index 48dab3b264fd..be663f7bdc1d 100644 --- a/core/java/android/companion/BluetoothDeviceFilter.java +++ b/core/java/android/companion/BluetoothDeviceFilter.java @@ -27,6 +27,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.bluetooth.BluetoothDevice; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.ParcelUuid; import android.provider.OneTimeUseBuilder; @@ -100,7 +101,7 @@ public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice /** @hide */ @Nullable - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getAddress() { return mAddress; } diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java index 8e687413b7e1..5e2340cee0f9 100644 --- a/core/java/android/companion/BluetoothDeviceFilterUtils.java +++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java @@ -25,6 +25,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.le.ScanFilter; import android.compat.annotation.UnsupportedAppUsage; import android.net.wifi.ScanResult; +import android.os.Build; import android.os.ParcelUuid; import android.os.Parcelable; import android.util.Log; @@ -120,17 +121,17 @@ public class BluetoothDeviceFilterUtils { Log.i(LOG_TAG, getDeviceDisplayNameInternal(device) + (result ? " ~ " : " !~ ") + criteria); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String getDeviceDisplayNameInternal(@NonNull BluetoothDevice device) { return firstNotEmpty(device.getAlias(), device.getAddress()); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String getDeviceDisplayNameInternal(@NonNull ScanResult device) { return firstNotEmpty(device.SSID, device.BSSID); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String getDeviceMacAddress(@NonNull Parcelable device) { if (device instanceof BluetoothDevice) { return ((BluetoothDevice) device).getAddress(); diff --git a/core/java/android/companion/BluetoothLeDeviceFilter.java b/core/java/android/companion/BluetoothLeDeviceFilter.java index 784e3a045bf4..828d482a0e6a 100644 --- a/core/java/android/companion/BluetoothLeDeviceFilter.java +++ b/core/java/android/companion/BluetoothLeDeviceFilter.java @@ -30,6 +30,7 @@ import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.provider.OneTimeUseBuilder; import android.text.TextUtils; @@ -94,7 +95,7 @@ public final class BluetoothLeDeviceFilter implements DeviceFilter<ScanResult> { /** @hide */ @NonNull - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ScanFilter getScanFilter() { return mScanFilter; } diff --git a/core/java/android/companion/DeviceFilter.java b/core/java/android/companion/DeviceFilter.java index c9cb072904b4..37191a246f00 100644 --- a/core/java/android/companion/DeviceFilter.java +++ b/core/java/android/companion/DeviceFilter.java @@ -20,6 +20,7 @@ package android.companion; import android.annotation.IntDef; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcelable; import java.lang.annotation.Retention; @@ -45,11 +46,11 @@ public interface DeviceFilter<D extends Parcelable> extends Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean matches(D device); /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) String getDeviceDisplayName(D device); /** @hide */ diff --git a/core/java/android/companion/IFindDeviceCallback.aidl b/core/java/android/companion/IFindDeviceCallback.aidl index 405277b50f5b..a3a47a9fc857 100644 --- a/core/java/android/companion/IFindDeviceCallback.aidl +++ b/core/java/android/companion/IFindDeviceCallback.aidl @@ -20,7 +20,7 @@ import android.app.PendingIntent; /** @hide */ interface IFindDeviceCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) oneway void onSuccess(in PendingIntent launcher); oneway void onFailure(in CharSequence reason); } diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java index 78eb8591a3e9..c4d98671a598 100644 --- a/core/java/android/content/ClipData.java +++ b/core/java/android/content/ClipData.java @@ -651,45 +651,57 @@ public class ClipData implements Parcelable { StringBuilder b = new StringBuilder(128); b.append("ClipData.Item { "); - toShortString(b); + toShortString(b, true); b.append(" }"); return b.toString(); } - /** @hide */ - public void toShortString(StringBuilder b) { + /** + * Appends this item to the given builder. + * @param redactContent If true, redacts common forms of PII; otherwise appends full + * details. + * @hide + */ + public void toShortString(StringBuilder b, boolean redactContent) { + boolean first = true; if (mHtmlText != null) { - b.append("H:"); - b.append(mHtmlText); - } else if (mText != null) { - b.append("T:"); - b.append(mText); - } else if (mUri != null) { - b.append("U:"); - b.append(mUri); - } else if (mIntent != null) { - b.append("I:"); - mIntent.toShortString(b, true, true, true, true); - } else { - b.append("NULL"); + first = false; + if (redactContent) { + b.append("H(").append(mHtmlText.length()).append(')'); + } else { + b.append("H:").append(mHtmlText); + } } - } - - /** @hide */ - public void toShortSummaryString(StringBuilder b) { - if (mHtmlText != null) { - b.append("HTML"); - } else if (mText != null) { - b.append("TEXT"); - } else if (mUri != null) { - b.append("U:"); - b.append(mUri); - } else if (mIntent != null) { + if (mText != null) { + if (!first) { + b.append(' '); + } + first = false; + if (redactContent) { + b.append("T(").append(mText.length()).append(')'); + } else { + b.append("T:").append(mText); + } + } + if (mUri != null) { + if (!first) { + b.append(' '); + } + first = false; + if (redactContent) { + b.append("U(").append(mUri.getScheme()).append(')'); + } else { + b.append("U:").append(mUri); + } + } + if (mIntent != null) { + if (!first) { + b.append(' '); + } + first = false; b.append("I:"); - mIntent.toShortString(b, true, true, true, true); - } else { - b.append("NULL"); + mIntent.toShortString(b, redactContent, true, true, true); } } @@ -1040,17 +1052,21 @@ public class ClipData implements Parcelable { StringBuilder b = new StringBuilder(128); b.append("ClipData { "); - toShortString(b); + toShortString(b, true); b.append(" }"); return b.toString(); } - /** @hide */ - public void toShortString(StringBuilder b) { + /** + * Appends this clip to the given builder. + * @param redactContent If true, redacts common forms of PII; otherwise appends full details. + * @hide + */ + public void toShortString(StringBuilder b, boolean redactContent) { boolean first; if (mClipDescription != null) { - first = !mClipDescription.toShortString(b); + first = !mClipDescription.toShortString(b, redactContent); } else { first = true; } @@ -1064,26 +1080,21 @@ public class ClipData implements Parcelable { b.append('x'); b.append(mIcon.getHeight()); } - for (int i=0; i<mItems.size(); i++) { + if (mItems.size() != 1) { if (!first) { b.append(' '); } first = false; - b.append('{'); - mItems.get(i).toShortString(b); - b.append('}'); + b.append(mItems.size()).append(" items:"); } - } - - /** @hide */ - public void toShortStringShortItems(StringBuilder b, boolean first) { - if (mItems.size() > 0) { + for (int i = 0; i < mItems.size(); i++) { if (!first) { b.append(' '); } - for (int i=0; i<mItems.size(); i++) { - b.append("{...}"); - } + first = false; + b.append('{'); + mItems.get(i).toShortString(b, redactContent); + b.append('}'); } } diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java index dedfce6f6b96..73becb1c0f1c 100644 --- a/core/java/android/content/ClipDescription.java +++ b/core/java/android/content/ClipDescription.java @@ -16,6 +16,7 @@ package android.content; +import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; @@ -64,12 +65,29 @@ public class ClipDescription implements Parcelable { public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent"; /** - * The MIME type for an activity. + * The MIME type for an activity. The ClipData must include intents with required extras + * {@link #EXTRA_PENDING_INTENT} and {@link Intent#EXTRA_USER}, and an optional + * {@link #EXTRA_ACTIVITY_OPTIONS}. * @hide */ public static final String MIMETYPE_APPLICATION_ACTIVITY = "application/vnd.android.activity"; /** + * The MIME type for a shortcut. The ClipData must include intents with required extras + * {@link #EXTRA_PENDING_INTENT} and {@link Intent#EXTRA_USER}, and an optional + * {@link #EXTRA_ACTIVITY_OPTIONS}. + * @hide + */ + public static final String MIMETYPE_APPLICATION_SHORTCUT = "application/vnd.android.shortcut"; + + /** + * The MIME type for a task. The ClipData must include an intent with a required extra + * {@link Intent#EXTRA_TASK_ID} of the task to launch. + * @hide + */ + public static final String MIMETYPE_APPLICATION_TASK = "application/vnd.android.task"; + + /** * The MIME type for data whose type is otherwise unknown. * <p> * Per RFC 2046, the "application" media type is to be used for discrete @@ -200,6 +218,24 @@ public class ClipDescription implements Parcelable { } /** + * Check whether the clip description contains any of the given MIME types. + * + * @param targetMimeTypes The target MIME types. May use patterns. + * @return Returns true if at least one of the MIME types in the clip description matches at + * least one of the target MIME types, else false. + * + * @hide + */ + public boolean hasMimeType(@NonNull String[] targetMimeTypes) { + for (String targetMimeType : targetMimeTypes) { + if (hasMimeType(targetMimeType)) { + return true; + } + } + return false; + } + + /** * Filter the clip description MIME types by the given MIME type. Returns * all MIME types in the clip that match the given MIME type. * @@ -294,30 +330,45 @@ public class ClipDescription implements Parcelable { StringBuilder b = new StringBuilder(128); b.append("ClipDescription { "); - toShortString(b); + toShortString(b, true); b.append(" }"); return b.toString(); } - /** @hide */ - public boolean toShortString(StringBuilder b) { + /** + * Appends this description to the given builder. + * @param redactContent If true, redacts common forms of PII; otherwise appends full details. + * @hide + */ + public boolean toShortString(StringBuilder b, boolean redactContent) { boolean first = !toShortStringTypesOnly(b); if (mLabel != null) { if (!first) { b.append(' '); } first = false; - b.append('"'); - b.append(mLabel); - b.append('"'); + if (redactContent) { + b.append("hasLabel(").append(mLabel.length()).append(')'); + } else { + b.append('"').append(mLabel).append('"'); + } } if (mExtras != null) { if (!first) { b.append(' '); } first = false; - b.append(mExtras.toString()); + if (redactContent) { + if (mExtras.isParcelled()) { + // We don't want this toString function to trigger un-parcelling. + b.append("hasExtras"); + } else { + b.append("hasExtras(").append(mExtras.size()).append(')'); + } + } else { + b.append(mExtras.toString()); + } } if (mTimeStamp > 0) { if (!first) { diff --git a/core/java/android/content/ComponentName.java b/core/java/android/content/ComponentName.java index b1cee0cb00e0..5f859846a5c1 100644 --- a/core/java/android/content/ComponentName.java +++ b/core/java/android/content/ComponentName.java @@ -19,6 +19,7 @@ package android.content; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -241,14 +242,14 @@ public final class ComponentName implements Parcelable, Cloneable, Comparable<Co } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void appendShortString(StringBuilder sb, String packageName, String className) { sb.append(packageName).append('/'); appendShortClassName(sb, packageName, className); } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void printShortString(PrintWriter pw, String packageName, String className) { pw.print(packageName); pw.print('/'); diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 6cb5b92abb37..49248b51a5c7 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -129,7 +129,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall // performance. @UnsupportedAppUsage private String mAuthority; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String[] mAuthorities; @UnsupportedAppUsage private String mReadPermission; @@ -624,6 +624,20 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } @Override + public void uncanonicalizeAsync(String callingPkg, @Nullable String attributionTag, Uri uri, + RemoteCallback callback) { + final Bundle result = new Bundle(); + try { + result.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, + uncanonicalize(callingPkg, attributionTag, uri)); + } catch (Exception e) { + result.putParcelable(ContentResolver.REMOTE_CALLBACK_ERROR, + new ParcelableException(e)); + } + callback.sendResult(result); + } + + @Override public boolean refresh(String callingPkg, String attributionTag, Uri uri, Bundle extras, ICancellationSignal cancellationSignal) throws RemoteException { uri = validateIncomingUri(uri); @@ -2342,7 +2356,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * when directly instantiating the provider for testing. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void attachInfoForTesting(Context context, ProviderInfo info) { attachInfo(context, info, true); } diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java index 7bc59013bcfe..7d121d56c86d 100644 --- a/core/java/android/content/ContentProviderNative.java +++ b/core/java/android/content/ContentProviderNative.java @@ -382,6 +382,16 @@ abstract public class ContentProviderNative extends Binder implements IContentPr return true; } + case UNCANONICALIZE_ASYNC_TRANSACTION: { + data.enforceInterface(IContentProvider.descriptor); + String callingPkg = data.readString(); + String featureId = data.readString(); + Uri uri = Uri.CREATOR.createFromParcel(data); + RemoteCallback callback = RemoteCallback.CREATOR.createFromParcel(data); + uncanonicalizeAsync(callingPkg, featureId, uri, callback); + return true; + } + case REFRESH_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); String callingPkg = data.readString(); @@ -875,6 +885,25 @@ final class ContentProviderProxy implements IContentProvider } @Override + /* oneway */ public void uncanonicalizeAsync(String callingPkg, @Nullable String featureId, + Uri uri, RemoteCallback callback) throws RemoteException { + Parcel data = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); + + data.writeString(callingPkg); + data.writeString(featureId); + uri.writeToParcel(data, 0); + callback.writeToParcel(data, 0); + + mRemote.transact(IContentProvider.UNCANONICALIZE_ASYNC_TRANSACTION, data, null, + Binder.FLAG_ONEWAY); + } finally { + data.recycle(); + } + } + + @Override public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle extras, ICancellationSignal signal) throws RemoteException { Parcel data = Parcel.obtain(); diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index fd7074c29891..422d3f7c6784 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -49,6 +49,7 @@ import android.graphics.Point; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.DeadObjectException; @@ -567,7 +568,7 @@ public abstract class ContentResolver implements ContentInterface { public static final String MIME_TYPE_DEFAULT = ClipDescription.MIMETYPE_UNKNOWN; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1; /** @hide */ public static final int SYNC_ERROR_AUTHENTICATION = 2; @@ -624,7 +625,7 @@ public abstract class ContentResolver implements ContentInterface { public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; /** @hide */ public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; @@ -1337,7 +1338,14 @@ public abstract class ContentResolver implements ContentInterface { } try { - return provider.uncanonicalize(mPackageName, mAttributionTag, url); + final UriResultListener resultListener = new UriResultListener(); + provider.uncanonicalizeAsync(mPackageName, mAttributionTag, url, + new RemoteCallback(resultListener)); + resultListener.waitForResult(CONTENT_PROVIDER_TIMEOUT_MILLIS); + if (resultListener.exception != null) { + throw resultListener.exception; + } + return resultListener.result; } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity // Manager will kill this process shortly anyway. @@ -3538,7 +3546,7 @@ public abstract class ContentResolver implements ContentInterface { * @see #getSyncStatus(Account, String) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static SyncStatusInfo getSyncStatusAsUser(Account account, String authority, @UserIdInt int userId) { try { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 42fe0e1c465d..1d7a54c3021c 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1927,7 +1927,7 @@ public abstract class Context { * {@link #startActivityForResult(String, Intent, int, Bundle)}. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean canStartActivityForResult() { return false; } @@ -2427,7 +2427,7 @@ public abstract class Context { * @hide */ @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public abstract void sendBroadcastAsUser(@RequiresPermission Intent intent, UserHandle user, @Nullable String receiverPermission, int appOp); @@ -2473,7 +2473,7 @@ public abstract class Context { * @hide */ @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, @Nullable String receiverPermission, int appOp, BroadcastReceiver resultReceiver, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, @@ -5272,7 +5272,7 @@ public abstract class Context { /** @hide */ @PackageManager.PermissionResult - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public abstract int checkPermission(@NonNull String permission, int pid, int uid, IBinder callerToken); diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 5fe094d082ae..387ae193c74e 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -35,6 +35,7 @@ import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -741,7 +742,7 @@ public class ContextWrapper extends Context { /** @hide */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) { return mBase.startForegroundServiceAsUser(service, user); } @@ -944,7 +945,7 @@ public class ContextWrapper extends Context { /** @hide */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Context createApplicationContext(ApplicationInfo application, int flags) throws PackageManager.NameNotFoundException { return mBase.createApplicationContext(application, flags); diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java index 4ff5ccabbcb7..fda646c7f99c 100644 --- a/core/java/android/content/CursorLoader.java +++ b/core/java/android/content/CursorLoader.java @@ -19,6 +19,7 @@ package android.content; import android.compat.annotation.UnsupportedAppUsage; import android.database.Cursor; import android.net.Uri; +import android.os.Build; import android.os.CancellationSignal; import android.os.OperationCanceledException; @@ -45,7 +46,7 @@ import java.util.Arrays; */ @Deprecated public class CursorLoader extends AsyncTaskLoader<Cursor> { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final ForceLoadContentObserver mObserver; Uri mUri; @@ -55,7 +56,7 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> { String mSortOrder; Cursor mCursor; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) CancellationSignal mCancellationSignal; /* Runs on a worker thread */ diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java index 84b0f0e80bab..9210b132c75a 100644 --- a/core/java/android/content/IContentProvider.java +++ b/core/java/android/content/IContentProvider.java @@ -137,6 +137,14 @@ public interface IContentProvider extends IInterface { public Uri uncanonicalize(String callingPkg, @Nullable String attributionTag, Uri uri) throws RemoteException; + /** + * A oneway version of uncanonicalize. The functionality is exactly the same, except that the + * call returns immediately, and the resulting type is returned when available via + * a binder callback. + */ + void uncanonicalizeAsync(String callingPkg, @Nullable String attributionTag, Uri uri, + RemoteCallback callback) throws RemoteException; + public boolean refresh(String callingPkg, @Nullable String attributionTag, Uri url, @Nullable Bundle extras, ICancellationSignal cancellationSignal) throws RemoteException; @@ -152,7 +160,7 @@ public interface IContentProvider extends IInterface { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) static final String descriptor = "android.content.IContentProvider"; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static final int QUERY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION; static final int GET_TYPE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1; static final int INSERT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 2; @@ -172,4 +180,5 @@ public interface IContentProvider extends IInterface { static final int CHECK_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 27; int GET_TYPE_ASYNC_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 28; int CANONICALIZE_ASYNC_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 29; + int UNCANONICALIZE_ASYNC_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 30; } diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl index 03c99e1a2344..2044fc02a7e5 100644 --- a/core/java/android/content/IContentService.aidl +++ b/core/java/android/content/IContentService.aidl @@ -61,7 +61,7 @@ interface IContentService { */ void sync(in SyncRequest request, String callingPackage); void syncAsUser(in SyncRequest request, int userId, String callingPackage); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void cancelSync(in Account account, String authority, in ComponentName cname); void cancelSyncAsUser(in Account account, String authority, in ComponentName cname, int userId); @@ -159,7 +159,7 @@ interface IContentService { * @param cname component to identify sync service, must be null if account/providerName are * non-null. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isSyncActive(in Account account, String authority, in ComponentName cname); /** diff --git a/core/java/android/content/ISyncAdapter.aidl b/core/java/android/content/ISyncAdapter.aidl index 9242d0289cfa..55210d4aa119 100644 --- a/core/java/android/content/ISyncAdapter.aidl +++ b/core/java/android/content/ISyncAdapter.aidl @@ -32,7 +32,7 @@ oneway interface ISyncAdapter { * * @param cb If called back with {@code false} accounts are not synced. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onUnsyncableAccount(ISyncAdapterUnsyncableAccountCallback cb); /** diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 9216a0871870..782f0cd04dfc 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2338,7 +2338,7 @@ public class Intent implements Parcelable, Cloneable { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED"; /** @@ -3724,7 +3724,7 @@ public class Intent implements Parcelable, Cloneable { * {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED"; @@ -7444,7 +7444,7 @@ public class Intent implements Parcelable, Cloneable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @SuppressWarnings("AndroidFrameworkEfficientCollections") public static Intent parseCommandArgs(ShellCommand cmd, CommandOptionHandler optionHandler) throws URISyntaxException { @@ -7836,7 +7836,7 @@ public class Intent implements Parcelable, Cloneable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void printIntentArgsHelp(PrintWriter pw, String prefix) { final String[] lines = new String[] { "<INTENT> specifications include these flags and arguments:", @@ -8126,7 +8126,7 @@ public class Intent implements Parcelable, Cloneable { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setAllowFds(boolean allowFds) { if (mExtras != null) { mExtras.setAllowFds(allowFds); @@ -10473,7 +10473,7 @@ public class Intent implements Parcelable, Cloneable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String toInsecureString() { StringBuilder b = new StringBuilder(128); @@ -10485,17 +10485,6 @@ public class Intent implements Parcelable, Cloneable { } /** @hide */ - public String toInsecureStringWithClip() { - StringBuilder b = new StringBuilder(128); - - b.append("Intent { "); - toShortString(b, false, true, true, true); - b.append(" }"); - - return b.toString(); - } - - /** @hide */ public String toShortString(boolean secure, boolean comp, boolean extras, boolean clip) { StringBuilder b = new StringBuilder(128); toShortString(b, secure, comp, extras, clip); @@ -10581,16 +10570,7 @@ public class Intent implements Parcelable, Cloneable { b.append(' '); } b.append("clip={"); - if (clip) { - mClipData.toShortString(b); - } else { - if (mClipData.getDescription() != null) { - first = !mClipData.getDescription().toShortStringTypesOnly(b); - } else { - first = true; - } - mClipData.toShortStringShortItems(b, first); - } + mClipData.toShortString(b, !clip || secure); first = false; b.append('}'); } @@ -10668,11 +10648,7 @@ public class Intent implements Parcelable, Cloneable { } if (mClipData != null) { StringBuilder b = new StringBuilder(); - if (clip) { - mClipData.toShortString(b); - } else { - mClipData.toShortStringShortItems(b, false); - } + mClipData.toShortString(b, !clip || secure); proto.write(IntentProto.CLIP_DATA, b.toString()); } if (extras && mExtras != null) { @@ -11156,7 +11132,7 @@ public class Intent implements Parcelable, Cloneable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void prepareToLeaveProcess(Context context) { final boolean leavingPackage = (mComponent == null) || !Objects.equals(mComponent.getPackageName(), context.getPackageName()); diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java index 5240ab4e476f..f0633591f16c 100644 --- a/core/java/android/content/IntentFilter.java +++ b/core/java/android/content/IntentFilter.java @@ -570,7 +570,7 @@ public class IntentFilter implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final void setAutoVerify(boolean autoVerify) { mVerifyState &= ~STATE_VERIFY_AUTO; if (autoVerify) mVerifyState |= STATE_VERIFY_AUTO; @@ -950,7 +950,7 @@ public class IntentFilter implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final boolean hasExactDataType(String type) { return mDataTypes != null && mDataTypes.contains(type); } @@ -1295,7 +1295,7 @@ public class IntentFilter implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final boolean hasDataSchemeSpecificPart(PatternMatcher ssp) { if (mDataSchemeSpecificParts == null) { return false; @@ -1379,7 +1379,7 @@ public class IntentFilter implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final boolean hasDataAuthority(AuthorityEntry auth) { if (mDataAuthorities == null) { return false; @@ -1488,7 +1488,7 @@ public class IntentFilter implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final boolean hasDataPath(PatternMatcher path) { if (mDataPaths == null) { return false; diff --git a/core/java/android/content/SyncAdapterType.java b/core/java/android/content/SyncAdapterType.java index ffcdf53ca84d..1c21b2aa73a5 100644 --- a/core/java/android/content/SyncAdapterType.java +++ b/core/java/android/content/SyncAdapterType.java @@ -35,11 +35,11 @@ public class SyncAdapterType implements Parcelable { private final boolean userVisible; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final boolean supportsUploading; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final boolean isAlwaysSyncable; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final boolean allowParallelSyncs; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final String settingsActivity; private final String packageName; diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java index ed9cd86927ae..87afbf874b37 100644 --- a/core/java/android/content/UndoManager.java +++ b/core/java/android/content/UndoManager.java @@ -17,6 +17,7 @@ package android.content; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.text.TextUtils; import android.util.ArrayMap; @@ -85,11 +86,11 @@ public class UndoManager { */ public static final int MERGE_MODE_ANY = 2; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public UndoManager() { } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public UndoOwner getOwner(String tag, Object data) { if (tag == null) { throw new NullPointerException("tag can't be null"); @@ -126,7 +127,7 @@ public class UndoManager { * Flatten the current undo state into a Parcel object, which can later be restored * with {@link #restoreInstanceState(android.os.Parcel, java.lang.ClassLoader)}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void saveInstanceState(Parcel p) { if (mUpdateCount > 0) { throw new IllegalStateException("Can't save state while updating"); @@ -175,7 +176,7 @@ public class UndoManager { * associated with each {@link UndoOwner}, which requires separate calls to * {@link #getOwner(String, Object)} to re-associate the owner with its data. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void restoreInstanceState(Parcel p, ClassLoader loader) { if (mUpdateCount > 0) { throw new IllegalStateException("Can't save state while updating"); @@ -236,7 +237,7 @@ public class UndoManager { * @param count Number of undo states to pop. * @return Returns the number of undo states that were actually popped. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int undo(UndoOwner[] owners, int count) { if (mWorking != null) { throw new IllegalStateException("Can't be called during an update"); @@ -274,7 +275,7 @@ public class UndoManager { * @param count Number of undo states to pop. * @return Returns the number of undo states that were actually redone. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int redo(UndoOwner[] owners, int count) { if (mWorking != null) { throw new IllegalStateException("Can't be called during an update"); @@ -303,12 +304,12 @@ public class UndoManager { * useful for editors to know whether they should be generating new undo state * when they see edit operations happening. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isInUndo() { return mInUndo; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int forgetUndos(UndoOwner[] owners, int count) { if (count < 0) { count = mUndos.size(); @@ -330,7 +331,7 @@ public class UndoManager { return removed; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int forgetRedos(UndoOwner[] owners, int count) { if (count < 0) { count = mRedos.size(); @@ -357,7 +358,7 @@ public class UndoManager { * @param owners If non-null, only those states containing an operation with one of * the owners supplied here will be counted. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int countUndos(UndoOwner[] owners) { if (owners == null) { return mUndos.size(); @@ -377,7 +378,7 @@ public class UndoManager { * @param owners If non-null, only those states containing an operation with one of * the owners supplied here will be counted. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int countRedos(UndoOwner[] owners) { if (owners == null) { return mRedos.size(); @@ -417,7 +418,7 @@ public class UndoManager { * they are all matched by a later call to {@link #endUpdate}. * @param label Optional user-visible label for this new undo state. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void beginUpdate(CharSequence label) { if (mInUndo) { throw new IllegalStateException("Can't being update while performing undo/redo"); @@ -450,7 +451,7 @@ public class UndoManager { * Forcibly set a new for the new undo state being built within a {@link #beginUpdate}. * Any existing label will be replaced with this one. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setUndoLabel(CharSequence label) { if (mWorking == null) { throw new IllegalStateException("Must be called during an update"); @@ -525,7 +526,7 @@ public class UndoManager { * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE}, * or {@link #MERGE_MODE_ANY}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public <T extends UndoOperation> T getLastOperation(Class<T> clazz, UndoOwner owner, int mergeMode) { if (mWorking == null) { @@ -555,7 +556,7 @@ public class UndoManager { * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE}, * or {@link #MERGE_MODE_ANY}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addOperation(UndoOperation<?> op, int mergeMode) { if (mWorking == null) { throw new IllegalStateException("Must be called during an update"); @@ -582,7 +583,7 @@ public class UndoManager { * Finish the creation of an undo state, matching a previous call to * {@link #beginUpdate}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void endUpdate() { if (mWorking == null) { throw new IllegalStateException("Must be called during an update"); @@ -631,7 +632,7 @@ public class UndoManager { * @return Returns an integer identifier for the committed undo state, which * can later be used to try to uncommit the state to perform further edits on it. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int commitState(UndoOwner owner) { if (mWorking != null && mWorking.hasData()) { if (owner == null || mWorking.hasOperation(owner)) { diff --git a/core/java/android/content/UndoOperation.java b/core/java/android/content/UndoOperation.java index 235d72123ff6..25aeca3290f3 100644 --- a/core/java/android/content/UndoOperation.java +++ b/core/java/android/content/UndoOperation.java @@ -17,6 +17,7 @@ package android.content; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -35,7 +36,7 @@ public abstract class UndoOperation<DATA> implements Parcelable { * @param owner Who owns the data being modified by this undo state; must be * returned by {@link UndoManager#getOwner(String, Object) UndoManager.getOwner}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public UndoOperation(UndoOwner owner) { mOwner = owner; } @@ -43,7 +44,7 @@ public abstract class UndoOperation<DATA> implements Parcelable { /** * Construct from a Parcel. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected UndoOperation(Parcel src, ClassLoader loader) { } diff --git a/core/java/android/content/om/IOverlayManager.aidl b/core/java/android/content/om/IOverlayManager.aidl index 3d7e3befd9f1..44b5c4482599 100644 --- a/core/java/android/content/om/IOverlayManager.aidl +++ b/core/java/android/content/om/IOverlayManager.aidl @@ -37,7 +37,7 @@ interface IOverlayManager { * mapped to lists of overlays; if no overlays exist for the * requested user, an empty map is returned. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Map getAllOverlays(in int userId); /** @@ -61,7 +61,7 @@ interface IOverlayManager { * @return The OverlayInfo for the overlay package; or null if no such * overlay package exists. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) OverlayInfo getOverlayInfo(in String packageName, in int userId); /** diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java index 62815ddcfc19..517e4bda68d7 100644 --- a/core/java/android/content/om/OverlayInfo.java +++ b/core/java/android/content/om/OverlayInfo.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.UserIdInt; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -174,7 +175,7 @@ public final class OverlayInfo implements Parcelable { * The state of this OverlayInfo as defined by the STATE_* constants in this class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final @State int state; /** diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index b371141ca9c1..9c4e6aa3e17f 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -24,6 +24,7 @@ import android.content.Intent; import android.content.res.Configuration; import android.content.res.Configuration.NativeConfig; import android.content.res.TypedArray; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.Printer; @@ -373,7 +374,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * {@link android.R.attr#showForAllUsers} attribute. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int FLAG_SHOW_FOR_ALL_USERS = 0x0400; /** * Bit in {@link #flags} corresponding to an immersive activity @@ -502,7 +503,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * this activity is launched into such a container a SecurityException will be * thrown. Set from the {@link android.R.attr#allowEmbedded} attribute. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int FLAG_ALLOW_EMBEDDED = 0x80000000; /** @@ -869,7 +870,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static @NativeConfig int activityInfoConfigJavaToNative(@Config int input) { int output = 0; for (int i = 0; i < CONFIG_NATIVE_BITS.length; i++) { diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 8f4fc261df37..1cca53f369fa 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -128,7 +128,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int fullBackupContent = 0; /** @@ -2236,7 +2236,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** {@hide} */ public void setGwpAsanMode(@GwpAsanMode int value) { gwpAsanMode = value; } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getCodePath() { return scanSourceDir; } /** {@hide} */ public String getBaseCodePath() { return sourceDir; } /** {@hide} */ public String[] getSplitCodePaths() { return splitSourceDirs; } diff --git a/core/java/android/content/pm/BaseParceledListSlice.java b/core/java/android/content/pm/BaseParceledListSlice.java index bd847bfdb719..5c7a5488076b 100644 --- a/core/java/android/content/pm/BaseParceledListSlice.java +++ b/core/java/android/content/pm/BaseParceledListSlice.java @@ -18,6 +18,7 @@ package android.content.pm; import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -133,7 +134,7 @@ abstract class BaseParceledListSlice<T> implements Parcelable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public List<T> getList() { return mList; } @@ -207,7 +208,7 @@ abstract class BaseParceledListSlice<T> implements Parcelable { protected abstract void writeElement(T parcelable, Parcel reply, int callFlags); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected abstract void writeParcelableCreator(T parcelable, Parcel dest); protected abstract Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader); diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java index 628bcd70cdf6..c67d00e88707 100644 --- a/core/java/android/content/pm/ComponentInfo.java +++ b/core/java/android/content/pm/ComponentInfo.java @@ -19,6 +19,7 @@ package android.content.pm; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Parcel; import android.util.Printer; @@ -158,7 +159,7 @@ public class ComponentInfo extends PackageItemInfo { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ComponentName getComponentName() { return new ComponentName(packageName, name); } diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl index d9ecf46069cd..d688614f6caa 100644 --- a/core/java/android/content/pm/ILauncherApps.aidl +++ b/core/java/android/content/pm/ILauncherApps.aidl @@ -17,6 +17,7 @@ package android.content.pm; import android.app.IApplicationThread; +import android.app.PendingIntent; import android.content.ComponentName; import android.content.Intent; import android.content.IntentSender; @@ -55,6 +56,8 @@ interface ILauncherApps { void startActivityAsUser(in IApplicationThread caller, String callingPackage, String callingFeatureId, in ComponentName component, in Rect sourceBounds, in Bundle opts, in UserHandle user); + PendingIntent getActivityLaunchIntent(in ComponentName component, in Bundle opts, + in UserHandle user); void showAppDetailsAsUser(in IApplicationThread caller, String callingPackage, String callingFeatureId, in ComponentName component, in Rect sourceBounds, in Bundle opts, in UserHandle user); diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl index 2147c397725b..d7c257affd43 100644 --- a/core/java/android/content/pm/IPackageInstaller.aidl +++ b/core/java/android/content/pm/IPackageInstaller.aidl @@ -48,7 +48,7 @@ interface IPackageInstaller { void registerCallback(IPackageInstallerCallback callback, int userId); void unregisterCallback(IPackageInstallerCallback callback); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void uninstall(in VersionedPackage versionedPackage, String callerPackageName, int flags, in IntentSender statusReceiver, int userId); diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index c32d34457889..d66a42a6232a 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -64,7 +64,7 @@ import android.content.IntentSender; */ interface IPackageManager { void checkPackageStartable(String packageName, int userId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isPackageAvailable(String packageName, int userId); @UnsupportedAppUsage PackageInfo getPackageInfo(String packageName, int flags, int userId); @@ -137,7 +137,7 @@ interface IPackageManager { boolean canForwardTo(in Intent intent, String resolvedType, int sourceUserId, int targetUserId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) ParceledListSlice queryIntentActivities(in Intent intent, String resolvedType, int flags, int userId); @@ -182,7 +182,7 @@ interface IPackageManager { * limit that kicks in when flags are included that bloat up the data * returned. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) ParceledListSlice getInstalledApplications(int flags, int userId); /** @@ -203,7 +203,7 @@ interface IPackageManager { * @param outInfo Filled in with a list of the ProviderInfo for each * name in 'outNames'. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void querySyncProviders(inout List<String> outNames, inout List<ProviderInfo> outInfo); @@ -214,7 +214,7 @@ interface IPackageManager { InstrumentationInfo getInstrumentationInfo( in ComponentName className, int flags); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) ParceledListSlice queryInstrumentation( String targetPackage, int flags); @@ -649,7 +649,7 @@ interface IPackageManager { void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden); boolean setSystemAppInstallState(String packageName, boolean installed, int userId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) IPackageInstaller getPackageInstaller(); boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId); @@ -661,7 +661,7 @@ interface IPackageManager { boolean isPackageSignedByKeySet(String packageName, in KeySet ks); boolean isPackageSignedByKeySetExactly(String packageName, in KeySet ks); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String getPermissionControllerPackageName(); ParceledListSlice getInstantApps(int userId); @@ -678,9 +678,9 @@ interface IPackageManager { */ void setUpdateAvailable(String packageName, boolean updateAvaialble); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String getServicesSystemSharedLibraryPackageName(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String getSharedSystemSharedLibraryPackageName(); ChangedPackages getChangedPackages(int sequenceNumber, int userId); @@ -758,7 +758,7 @@ interface IPackageManager { //------------------------------------------------------------------------ // We need to keep these in IPackageManager for app compatibility //------------------------------------------------------------------------ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String[] getAppOpPermissionPackages(String permissionName); @UnsupportedAppUsage @@ -773,10 +773,10 @@ interface IPackageManager { @UnsupportedAppUsage void removePermission(String name); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int checkPermission(String permName, String pkgName, int userId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void grantRuntimePermission(String packageName, String permissionName, int userId); //------------------------------------------------------------------------ @@ -794,5 +794,7 @@ interface IPackageManager { void grantImplicitAccess(int queryingUid, String visibleAuthority); - void holdLock(in int durationMs); + IBinder getHoldLockToken(); + + void holdLock(in IBinder token, in int durationMs); } diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index b7af397cd36a..2909d66d72ff 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -17,6 +17,7 @@ package android.content.pm; import static android.Manifest.permission; +import static android.app.PendingIntent.FLAG_IMMUTABLE; import android.annotation.CallbackExecutor; import android.annotation.IntDef; @@ -716,6 +717,29 @@ public class LauncherApps { } /** + * Returns a PendingIntent that would start the same activity started from + * {@link #startMainActivity(ComponentName, UserHandle, Rect, Bundle)}. + * + * @param component The ComponentName of the activity to launch + * @param startActivityOptions Options to pass to startActivity + * @param user The UserHandle of the profile + * @hide + */ + @Nullable + public PendingIntent getMainActivityLaunchIntent(@NonNull ComponentName component, + @Nullable Bundle startActivityOptions, @NonNull UserHandle user) { + logErrorForInvalidProfileAccess(user); + if (DEBUG) { + Log.i(TAG, "GetMainActivityLaunchIntent " + component + " " + user); + } + try { + return mService.getActivityLaunchIntent(component, startActivityOptions, user); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** * Returns the activity info for a given intent and user handle, if it resolves. Otherwise it * returns null. * diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index e2f85282948a..596d39b50848 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1497,13 +1497,13 @@ public class PackageInstaller { /** {@hide} */ public @InstallReason int installReason = PackageManager.INSTALL_REASON_UNKNOWN; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long sizeBytes = -1; /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public String appPackageName; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Bitmap appIcon; /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @@ -1513,7 +1513,7 @@ public class PackageInstaller { /** {@hide} */ public Uri originatingUri; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int originatingUid = UID_UNKNOWN; /** {@hide} */ public Uri referrerUri; @@ -2148,13 +2148,13 @@ public class PackageInstaller { /** {@hide} */ public String installerAttributionTag; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String resolvedBaseCodePath; /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public float progress; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean sealed; /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @@ -2227,7 +2227,7 @@ public class PackageInstaller { public int rollbackDataPolicy; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public SessionInfo() { } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 3fb9a9e924e7..c0f581717641 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -63,6 +63,7 @@ import android.net.wifi.WifiManager; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.UserHandle; @@ -566,9 +567,11 @@ public abstract class PackageManager { public static final int MATCH_DEBUG_TRIAGED_MISSING = MATCH_DIRECT_BOOT_AUTO; /** - * Internal {@link PackageInfo} flag used to indicate that a package is a hidden system app. + * {@link PackageInfo} flag: include system apps that are in the uninstalled state and have + * been set to be hidden until installed via {@link #setSystemAppState}. * @hide */ + @SystemApi public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 0x20000000; /** @@ -1791,7 +1794,7 @@ public abstract class PackageManager { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int MOVE_INTERNAL = 0x00000001; /** @@ -1800,7 +1803,7 @@ public abstract class PackageManager { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int MOVE_EXTERNAL_MEDIA = 0x00000002; /** {@hide} */ @@ -3660,7 +3663,7 @@ public abstract class PackageManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String SYSTEM_SHARED_LIBRARY_SERVICES = "android.ext.services"; @@ -3673,7 +3676,7 @@ public abstract class PackageManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared"; @@ -3767,27 +3770,34 @@ public abstract class PackageManager { public @interface SystemAppState {} /** - * Constant for noting system app state as hidden before installation + * Constant for use with {@link #setSystemAppState} to mark a system app as hidden until + * installation. * @hide */ + @SystemApi public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN = 0; /** - * Constant for noting system app state as visible before installation + * Constant for use with {@link #setSystemAppState} to mark a system app as not hidden until + * installation. * @hide */ + @SystemApi public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE = 1; /** - * Constant for noting system app state as installed + * Constant for use with {@link #setSystemAppState} to change a system app's state to installed. * @hide */ + @SystemApi public static final int SYSTEM_APP_STATE_INSTALLED = 2; /** - * Constant for noting system app state as not installed + * Constant for use with {@link #setSystemAppState} to change a system app's state to + * uninstalled. * @hide */ + @SystemApi public static final int SYSTEM_APP_STATE_UNINSTALLED = 3; /** @@ -7091,11 +7101,18 @@ public abstract class PackageManager { @NonNull UserHandle userHandle); /** - * Sets system app state + * Sets the state of a system app. + * + * This method can be used to change a system app's hidden-until-installed state (via + * {@link #SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN} and + * {@link #SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE} or its installation state (via + * {@link #SYSTEM_APP_STATE_INSTALLED} and {@link #SYSTEM_APP_STATE_UNINSTALLED}. + * * @param packageName Package name of the app. * @param state State of the app. * @hide */ + @SystemApi public void setSystemAppState(@NonNull String packageName, @SystemAppState int state) { throw new RuntimeException("Not implemented. Must override in a subclass"); } @@ -7483,14 +7500,14 @@ public abstract class PackageManager { public abstract void unregisterMoveCallback(@NonNull MoveCallback callback); /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public abstract int movePackage(@NonNull String packageName, @NonNull VolumeInfo vol); /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public abstract @Nullable VolumeInfo getPackageCurrentVolume(@NonNull ApplicationInfo app); /** {@hide} */ @NonNull - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public abstract List<VolumeInfo> getPackageCandidateVolumes( @NonNull ApplicationInfo app); @@ -7581,7 +7598,7 @@ public abstract class PackageManager { /** {@hide} */ @NonNull - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String installStatusToString(int status, @Nullable String msg) { final String str = installStatusToString(status); if (msg != null) { @@ -8462,15 +8479,30 @@ public abstract class PackageManager { } /** + * Returns the token to be used by the subsequent calls to holdLock(). + * @hide + */ + @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) + @TestApi + public IBinder getHoldLockToken() { + try { + return ActivityThread.getPackageManager().getHoldLockToken(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Holds the PM lock for the specified amount of milliseconds. * Intended for use by the tests that need to imitate lock contention. + * The token should be obtained by + * {@link android.content.pm.PackageManager#getHoldLockToken()}. * @hide */ @TestApi - @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) - public void holdLock(int durationMs) { + public void holdLock(IBinder token, int durationMs) { try { - ActivityThread.getPackageManager().holdLock(durationMs); + ActivityThread.getPackageManager().holdLock(token, durationMs); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 177f691a97c1..118524d494de 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -288,7 +288,7 @@ public class PackageParser { public String[] mSeparateProcesses; private boolean mOnlyCoreApps; private DisplayMetrics mMetrics; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Callback mCallback; private File mCacheDir; @@ -1364,7 +1364,7 @@ public class PackageParser { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void collectCertificates(Package pkg, File apkFile, boolean skipVerify) throws PackageParserException { final String apkPath = apkFile.getAbsolutePath(); @@ -6539,7 +6539,7 @@ public class PackageParser { } /** set the signing certificates by which the APK proved it can be authenticated */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Builder setPastSigningCertificates(Signature[] pastSigningCertificates) { mPastSigningCertificates = pastSigningCertificates; return this; @@ -6753,9 +6753,9 @@ public class PackageParser { /** * Data used to feed the KeySetManagerService */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ArraySet<String> mUpgradeKeySets; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ArrayMap<String, ArraySet<PublicKey>> mKeySetMapping; /** diff --git a/core/java/android/content/pm/ParceledListSlice.java b/core/java/android/content/pm/ParceledListSlice.java index 73119e05095b..b54bc5daf31f 100644 --- a/core/java/android/content/pm/ParceledListSlice.java +++ b/core/java/android/content/pm/ParceledListSlice.java @@ -62,7 +62,7 @@ public class ParceledListSlice<T extends Parcelable> extends BaseParceledListSli } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void writeParcelableCreator(T parcelable, Parcel dest) { dest.writeParcelableCreator((Parcelable) parcelable); } diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 0f9e8e59ec94..c6450ffdf91c 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -23,6 +23,7 @@ import android.annotation.StringRes; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -451,7 +452,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static @NonNull String protectionToString(int level) { final StringBuilder protLevel = new StringBuilder(); switch (level & PROTECTION_MASK_BASE) { diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java index 4f2bf65adfca..fe8e4d7b1bb2 100644 --- a/core/java/android/content/pm/ResolveInfo.java +++ b/core/java/android/content/pm/ResolveInfo.java @@ -21,6 +21,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.IntentFilter; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; @@ -183,7 +184,7 @@ public class ResolveInfo implements Parcelable { public boolean handleAllWebDataURI; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ComponentInfo getComponentInfo() { if (activityInfo != null) return activityInfo; if (serviceInfo != null) return serviceInfo; diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java index 7ed803f78260..5855de1109bd 100644 --- a/core/java/android/content/pm/ShortcutInfo.java +++ b/core/java/android/content/pm/ShortcutInfo.java @@ -1212,8 +1212,12 @@ public final class ShortcutInfo implements Parcelable { } /** - * Sets categories for a shortcut. Launcher apps may use this information to - * categorize shortcuts. + * Sets categories for a shortcut. + * <ul> + * <li>Launcher apps may use this information to categorize shortcuts + * <li>Used to filter shortcuts that can handle share intents or actions + * and required for shortcuts that are meant to be used as share targets. + * </ul> * * @see #SHORTCUT_CATEGORY_CONVERSATION * @see ShortcutInfo#getCategories() diff --git a/core/java/android/content/pm/VerifierInfo.java b/core/java/android/content/pm/VerifierInfo.java index 5f8855572ef0..3e69ff555946 100644 --- a/core/java/android/content/pm/VerifierInfo.java +++ b/core/java/android/content/pm/VerifierInfo.java @@ -17,6 +17,7 @@ package android.content.pm; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -44,7 +45,7 @@ public class VerifierInfo implements Parcelable { * not be {@code null} or empty. * @throws IllegalArgumentException if either argument is null or empty. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public VerifierInfo(String packageName, PublicKey publicKey) { if (packageName == null || packageName.length() == 0) { throw new IllegalArgumentException("packageName must not be null or empty"); diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 69dd25fa41d7..13433dc7979f 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -28,6 +28,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.res.Configuration.NativeConfig; import android.content.res.loader.ResourcesLoader; +import android.os.Build; import android.os.ParcelFileDescriptor; import android.util.ArraySet; import android.util.Log; @@ -955,7 +956,7 @@ public final class AssetManager implements AutoCloseable { * @see #open(String, int) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @NonNull InputStream openNonAsset(@NonNull String fileName, int accessMode) throws IOException { return openNonAsset(0, fileName, accessMode); @@ -968,7 +969,7 @@ public final class AssetManager implements AutoCloseable { * @param fileName Name of the asset to retrieve. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @NonNull InputStream openNonAsset(int cookie, @NonNull String fileName) throws IOException { return openNonAsset(cookie, fileName, ACCESS_STREAMING); @@ -1105,7 +1106,7 @@ public final class AssetManager implements AutoCloseable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void applyStyle(long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes, @Nullable XmlBlock.Parser parser, @NonNull int[] inAttrs, long outValuesAddress, long outIndicesAddress) { @@ -1128,7 +1129,7 @@ public final class AssetManager implements AutoCloseable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean resolveAttrs(long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes, @Nullable int[] inValues, @NonNull int[] inAttrs, @NonNull int[] outValues, @NonNull int[] outIndices) { @@ -1144,7 +1145,7 @@ public final class AssetManager implements AutoCloseable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean retrieveAttributes(@NonNull XmlBlock.Parser parser, @NonNull int[] inAttrs, @NonNull int[] outValues, @NonNull int[] outIndices) { Objects.requireNonNull(parser, "parser"); @@ -1186,7 +1187,7 @@ public final class AssetManager implements AutoCloseable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void setThemeTo(long dstThemePtr, @NonNull AssetManager srcAssetManager, long srcThemePtr) { synchronized (this) { ensureValidLocked(); diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java index f23c802d98e2..921c63025a57 100644 --- a/core/java/android/content/res/ColorStateList.java +++ b/core/java/android/content/res/ColorStateList.java @@ -23,6 +23,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo.Config; import android.content.res.Resources.Theme; import android.graphics.Color; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; @@ -480,7 +481,7 @@ public class ColorStateList extends ComplexColor implements Parcelable { * @hide only for resource preloading */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ColorStateList obtainForTheme(Theme t) { if (t == null || !canApplyTheme()) { return this; @@ -643,7 +644,7 @@ public class ColorStateList extends ComplexColor implements Parcelable { /** * Updates the default color and opacity. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void onColorsChanged() { int defaultColor = DEFAULT_COLOR; boolean isOpaque = true; diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index f8ed27a6646b..f6edb2edc5ff 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -514,7 +514,7 @@ public class CompatibilityInfo implements Parcelable { * @param outDm If non-null the width and height will be set to their scaled values. * @return Returns the scaling factor for the window. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static float computeCompatibleScaling(DisplayMetrics dm, DisplayMetrics outDm) { final int width = dm.noncompatWidthPixels; final int height = dm.noncompatHeightPixels; diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 9f3634443d62..ce4ed8edec11 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -839,7 +839,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration * {@link ActivityInfo#CONFIG_ASSETS_PATHS}. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public int assetsSeq; @@ -2336,7 +2336,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String resourceQualifierString(Configuration config) { return resourceQualifierString(config, null); } diff --git a/core/java/android/content/res/DrawableCache.java b/core/java/android/content/res/DrawableCache.java index 5497e61fa2e9..d0ebe3304065 100644 --- a/core/java/android/content/res/DrawableCache.java +++ b/core/java/android/content/res/DrawableCache.java @@ -18,6 +18,7 @@ package android.content.res; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.drawable.Drawable; +import android.os.Build; /** * Class which can be used to cache Drawable resources against a theme. @@ -37,7 +38,7 @@ class DrawableCache extends ThemedResourceCache<Drawable.ConstantState> { * @return a new instance of the resource, or {@code null} if not in * the cache */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Drawable getInstance(long key, Resources resources, Resources.Theme theme) { final Drawable.ConstantState entry = get(key, theme); if (entry != null) { diff --git a/core/java/android/content/res/ObbInfo.java b/core/java/android/content/res/ObbInfo.java index c477abcea8ba..6cafb3196735 100644 --- a/core/java/android/content/res/ObbInfo.java +++ b/core/java/android/content/res/ObbInfo.java @@ -17,6 +17,7 @@ package android.content.res; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -54,7 +55,7 @@ public class ObbInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public byte[] salt; // Only allow things in this package to instantiate. diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index c1f0a5f778b9..260f03bab7e4 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -317,7 +317,7 @@ public class Resources { * class loader * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Resources(@Nullable ClassLoader classLoader) { mClassLoader = classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader; } @@ -394,7 +394,7 @@ public class Resources { * @return the inflater used to create drawable objects * @hide Pending API finalization. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final DrawableInflater getDrawableInflater() { if (mDrawableInflater == null) { mDrawableInflater = new DrawableInflater(this, mClassLoader); @@ -987,7 +987,7 @@ public class Resources { } @NonNull - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Drawable loadDrawable(@NonNull TypedValue value, int id, int density, @Nullable Theme theme) throws NotFoundException { return mResourcesImpl.loadDrawable(this, value, id, density, theme); @@ -2057,7 +2057,7 @@ public class Resources { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public DisplayAdjustments getDisplayAdjustments() { final DisplayAdjustments overrideDisplayAdjustments = mOverrideDisplayAdjustments; if (overrideDisplayAdjustments != null) { diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index bbcacefb02c9..78cea15ea33e 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -78,9 +78,9 @@ public class ResourcesImpl { private static final boolean DEBUG_LOAD = false; private static final boolean DEBUG_CONFIG = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final boolean TRACE_FOR_PRELOAD = false; // Do we still need it? - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final boolean TRACE_FOR_MISS_PRELOAD = false; // Do we still need it? private static final int ID_OTHER = 0x01000004; @@ -88,7 +88,7 @@ public class ResourcesImpl { private static final Object sSync = new Object(); private static boolean sPreloaded; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mPreloading; // Information about preloaded resources. Note that they are not @@ -146,7 +146,7 @@ public class ResourcesImpl { private PluralRules mPluralRule; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final Configuration mConfiguration = new Configuration(); static { @@ -166,7 +166,7 @@ public class ResourcesImpl { * @param displayAdjustments this resource's Display override and compatibility info. * Must not be null. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics, @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments) { mAssets = assets; @@ -185,7 +185,7 @@ public class ResourcesImpl { return mAssets; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) DisplayMetrics getDisplayMetrics() { if (DEBUG_CONFIG) Slog.v(TAG, "Returning DisplayMetrics: " + mMetrics.widthPixels + "x" + mMetrics.heightPixels + " " + mMetrics.density); @@ -213,7 +213,7 @@ public class ResourcesImpl { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void getValue(@AnyRes int id, TypedValue outValue, boolean resolveRefs) throws NotFoundException { boolean found = mAssets.getResourceValue(id, 0, outValue, resolveRefs); diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index 29c5c935c1bf..5eaa7662b250 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -25,6 +25,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; import android.graphics.Typeface; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.StrictMode; import android.util.AttributeSet; import android.util.DisplayMetrics; @@ -75,17 +76,17 @@ public class TypedArray { @UnsupportedAppUsage private final Resources mResources; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private DisplayMetrics mMetrics; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private AssetManager mAssets; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mRecycled; @UnsupportedAppUsage /*package*/ XmlBlock.Parser mXml; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /*package*/ Resources.Theme mTheme; /** * mData is used to hold the value/id and other metadata about each attribute. diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java index fcbe36246273..b0291ce6d842 100644 --- a/core/java/android/content/res/XmlBlock.java +++ b/core/java/android/content/res/XmlBlock.java @@ -21,6 +21,7 @@ import static android.content.res.Resources.ID_NULL; import android.annotation.AnyRes; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.util.TypedValue; import com.android.internal.annotations.VisibleForTesting; @@ -480,7 +481,7 @@ public final class XmlBlock implements AutoCloseable { return mStrings.get(id); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /*package*/ long mParseState; @UnsupportedAppUsage private final XmlBlock mBlock; diff --git a/core/java/android/database/AbstractWindowedCursor.java b/core/java/android/database/AbstractWindowedCursor.java index daf7d2b1e908..18562034e38c 100644 --- a/core/java/android/database/AbstractWindowedCursor.java +++ b/core/java/android/database/AbstractWindowedCursor.java @@ -17,6 +17,7 @@ package android.database; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * A base class for Cursors that store their data in {@link CursorWindow}s. @@ -181,7 +182,7 @@ public abstract class AbstractWindowedCursor extends AbstractCursor { * Closes the cursor window and sets {@link #mWindow} to null. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void closeWindow() { if (mWindow != null) { mWindow.close(); diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java index edb7b715e944..1db948aba7c6 100644 --- a/core/java/android/database/CursorWindow.java +++ b/core/java/android/database/CursorWindow.java @@ -23,6 +23,7 @@ import android.content.res.Resources; import android.database.sqlite.SQLiteClosable; import android.database.sqlite.SQLiteException; import android.os.Binder; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; @@ -767,7 +768,7 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String printStats() { StringBuilder buff = new StringBuilder(); int myPid = Process.myPid(); diff --git a/core/java/android/database/sqlite/SQLiteCustomFunction.java b/core/java/android/database/sqlite/SQLiteCustomFunction.java index 1ace40d7e913..4a15f7010d54 100644 --- a/core/java/android/database/sqlite/SQLiteCustomFunction.java +++ b/core/java/android/database/sqlite/SQLiteCustomFunction.java @@ -27,7 +27,7 @@ import android.os.Build; public final class SQLiteCustomFunction { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public final String name; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int numArgs; public final SQLiteDatabase.CustomFunction callback; @@ -52,7 +52,7 @@ public final class SQLiteCustomFunction { // Called from native. @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void dispatchCallback(String[] args) { callback.callback(args); } diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index a2cbdd3829ff..9684ece5d9c1 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -31,6 +31,7 @@ import android.database.DatabaseUtils; import android.database.DefaultDatabaseErrorHandler; import android.database.SQLException; import android.database.sqlite.SQLiteDebug.DbStats; +import android.os.Build; import android.os.CancellationSignal; import android.os.Looper; import android.os.OperationCanceledException; @@ -103,7 +104,7 @@ public final class SQLiteDatabase extends SQLiteClosable { // Thread-local for database sessions that belong to this database. // Each thread has its own database session. // INVARIANT: Immutable. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final ThreadLocal<SQLiteSession> mThreadSession = ThreadLocal .withInitial(this::createSession); diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java index 165f863ccde7..1afa0f8d7090 100644 --- a/core/java/android/database/sqlite/SQLiteDebug.java +++ b/core/java/android/database/sqlite/SQLiteDebug.java @@ -135,7 +135,7 @@ public final class SQLiteDebug { * that overflowed because no space was left in the page cache. * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int pageCacheOverflow; /** records the largest memory allocation request handed to sqlite3. diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java index de1c54321985..cd4131ce2abb 100644 --- a/core/java/android/database/sqlite/SQLiteProgram.java +++ b/core/java/android/database/sqlite/SQLiteProgram.java @@ -18,6 +18,7 @@ package android.database.sqlite; import android.compat.annotation.UnsupportedAppUsage; import android.database.DatabaseUtils; +import android.os.Build; import android.os.CancellationSignal; import java.util.Arrays; @@ -37,7 +38,7 @@ public abstract class SQLiteProgram extends SQLiteClosable { private final boolean mReadOnly; private final String[] mColumnNames; private final int mNumParameters; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final Object[] mBindArgs; SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs, diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java index 9fda8b011e52..d33eadcfd11b 100644 --- a/core/java/android/database/sqlite/SQLiteStatement.java +++ b/core/java/android/database/sqlite/SQLiteStatement.java @@ -17,6 +17,7 @@ package android.database.sqlite; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.ParcelFileDescriptor; /** @@ -28,7 +29,7 @@ import android.os.ParcelFileDescriptor; * </p> */ public final class SQLiteStatement extends SQLiteProgram { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) SQLiteStatement(SQLiteDatabase db, String sql, Object[] bindArgs) { super(db, sql, bindArgs, null); } diff --git a/core/java/android/ddm/DdmHandleAppName.java b/core/java/android/ddm/DdmHandleAppName.java index 4f55921b0488..35da062329b3 100644 --- a/core/java/android/ddm/DdmHandleAppName.java +++ b/core/java/android/ddm/DdmHandleAppName.java @@ -17,6 +17,7 @@ package android.ddm; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.util.Log; import org.apache.harmony.dalvik.ddmc.Chunk; @@ -80,7 +81,7 @@ public class DdmHandleAppName extends ChunkHandler { * before or after DDMS connects. For the latter we need to send up * an APNM message. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void setAppName(String appName, String pkgName, int userId) { if (appName == null || appName.isEmpty() || pkgName == null || pkgName.isEmpty()) return; @@ -90,7 +91,7 @@ public class DdmHandleAppName extends ChunkHandler { sendAPNM(appName, pkgName, userId); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static Names getNames() { return sNames; } diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 86031dd918f5..3bdd39f5d7d7 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -245,7 +245,7 @@ public class Camera { * Camera HAL device API version 1.0 * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int CAMERA_HAL_API_VERSION_1_0 = 0x100; /** @@ -1221,7 +1221,7 @@ public class Camera { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void postEventFromNative(Object camera_ref, int what, int arg1, int arg2, Object obj) { @@ -4415,7 +4415,7 @@ public class Camera { // Splits a comma delimited string to an ArrayList of Area objects. // Example string: "(-10,-10,0,0,300),(0,0,10,10,700)". Return null if // the passing string is null or the size is 0 or (0,0,0,0,0). - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private ArrayList<Area> splitArea(String str) { if (str == null || str.charAt(0) != '(' || str.charAt(str.length() - 1) != ')') { diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java index a9b613228070..cad30dda9034 100644 --- a/core/java/android/hardware/HardwareBuffer.java +++ b/core/java/android/hardware/HardwareBuffer.java @@ -97,7 +97,7 @@ public final class HardwareBuffer implements Parcelable, AutoCloseable { public static final int S_UI8 = 0x35; // Note: do not rename, this field is used by native code - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeObject; // Invoked on destruction diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java index 0f3cdfca70f5..e913986ae792 100644 --- a/core/java/android/hardware/Sensor.java +++ b/core/java/android/hardware/Sensor.java @@ -509,7 +509,7 @@ public final class Sensor { * * @hide Expected to be used internally for always on display. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int TYPE_PICK_UP_GESTURE = 25; /** @@ -549,7 +549,7 @@ public final class Sensor { * @hide Expected to be used internally for auto-rotate and speaker rotation. * */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int TYPE_DEVICE_ORIENTATION = 27; /** diff --git a/core/java/android/hardware/SerialManager.java b/core/java/android/hardware/SerialManager.java index b51382e01ccd..26e5129b1fb3 100644 --- a/core/java/android/hardware/SerialManager.java +++ b/core/java/android/hardware/SerialManager.java @@ -19,6 +19,7 @@ package android.hardware; import android.annotation.SystemService; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -47,7 +48,7 @@ public class SerialManager { * * @return names of available serial ports */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String[] getSerialPorts() { try { return mService.getSerialPorts(); @@ -67,7 +68,7 @@ public class SerialManager { * @param speed at which to open the serial port * @return the serial port */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public SerialPort openSerialPort(String name, int speed) throws IOException { try { ParcelFileDescriptor pfd = mService.openSerialPort(name); diff --git a/core/java/android/hardware/SerialPort.java b/core/java/android/hardware/SerialPort.java index 0fcaa4989210..2578dd67746e 100644 --- a/core/java/android/hardware/SerialPort.java +++ b/core/java/android/hardware/SerialPort.java @@ -17,6 +17,7 @@ package android.hardware; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.ParcelFileDescriptor; import java.io.FileDescriptor; @@ -31,7 +32,7 @@ public class SerialPort { private static final String TAG = "SerialPort"; // used by the JNI code - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mNativeContext; private final String mName; private ParcelFileDescriptor mFileDescriptor; @@ -60,7 +61,7 @@ public class SerialPort { /** * Closes the serial port */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void close() throws IOException { if (mFileDescriptor != null) { mFileDescriptor.close(); @@ -104,7 +105,7 @@ public class SerialPort { * @param buffer to write * @param length number of bytes to write */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void write(ByteBuffer buffer, int length) throws IOException { if (buffer.isDirect()) { native_write_direct(buffer, length); diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 974913b290b1..376503e79cfc 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -21,6 +21,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.MemoryFile; @@ -759,13 +760,13 @@ public class SystemSensorManager extends SensorManager { if (sensor == null) throw new NullPointerException(); return nativeDisableSensor(mNativeSensorEventQueue, sensor.getHandle()); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected abstract void dispatchFlushCompleteEvent(int handle); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void dispatchAdditionalInfoEvent( int handle, int type, int serial, float[] floatValues, int[] intValues) { // default implementation is do nothing diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java index bed9a0640693..76d50bdf414c 100644 --- a/core/java/android/hardware/biometrics/BiometricConstants.java +++ b/core/java/android/hardware/biometrics/BiometricConstants.java @@ -20,6 +20,7 @@ import static android.hardware.biometrics.BiometricManager.Authenticators; import android.annotation.IntDef; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -153,7 +154,7 @@ public interface BiometricConstants { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int BIOMETRIC_ERROR_VENDOR_BASE = 1000; @IntDef({BIOMETRIC_SUCCESS, diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java index c7b554b3aafc..01f0e71a7c33 100644 --- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java +++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java @@ -21,6 +21,7 @@ import android.app.KeyguardManager; import android.compat.annotation.UnsupportedAppUsage; import android.hardware.biometrics.BiometricManager.Authenticators; import android.hardware.fingerprint.FingerprintManager; +import android.os.Build; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -167,7 +168,7 @@ public interface BiometricFingerprintConstants { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int FINGERPRINT_ERROR_VENDOR_BASE = 1000; // diff --git a/core/java/android/hardware/biometrics/BiometricTestSession.java b/core/java/android/hardware/biometrics/BiometricTestSession.java index 802655b0d364..2b689899af01 100644 --- a/core/java/android/hardware/biometrics/BiometricTestSession.java +++ b/core/java/android/hardware/biometrics/BiometricTestSession.java @@ -46,7 +46,7 @@ public class BiometricTestSession implements AutoCloseable { mContext = context; mTestSession = testSession; mTestedUsers = new ArraySet<>(); - enableTestHal(true); + setTestHalEnabled(true); } /** @@ -56,12 +56,12 @@ public class BiometricTestSession implements AutoCloseable { * secure pathways such as HAT/Keystore are not testable, since they depend on the TEE or its * equivalent for the secret key. * - * @param enableTestHal If true, enable testing with a fake HAL instead of the real HAL. + * @param enabled If true, enable testing with a fake HAL instead of the real HAL. */ @RequiresPermission(TEST_BIOMETRIC) - private void enableTestHal(boolean enableTestHal) { + private void setTestHalEnabled(boolean enabled) { try { - mTestSession.enableTestHal(enableTestHal); + mTestSession.setTestHalEnabled(enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -178,10 +178,12 @@ public class BiometricTestSession implements AutoCloseable { @Override @RequiresPermission(TEST_BIOMETRIC) public void close() { + // Disable the test HAL first, so that enumerate is run on the real HAL, which should have + // no enrollments. Test-only framework enrollments will be deleted. + setTestHalEnabled(false); + for (int user : mTestedUsers) { cleanupInternalState(user); } - - enableTestHal(false); } } diff --git a/core/java/android/hardware/biometrics/ITestSession.aidl b/core/java/android/hardware/biometrics/ITestSession.aidl index 6112f17949d7..fa7a62c53531 100644 --- a/core/java/android/hardware/biometrics/ITestSession.aidl +++ b/core/java/android/hardware/biometrics/ITestSession.aidl @@ -27,7 +27,7 @@ interface ITestSession { // portion of the framework code that would otherwise require human interaction. Note that // secure pathways such as HAT/Keystore are not testable, since they depend on the TEE or its // equivalent for the secret key. - void enableTestHal(boolean enableTestHal); + void setTestHalEnabled(boolean enableTestHal); // Starts the enrollment process. This should generally be used when the test HAL is enabled. void startEnroll(int userId); diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 2efec3fa2ec1..232056cb13d4 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -26,6 +26,7 @@ import android.hardware.camera2.params.RecommendedStreamConfigurationMap; import android.hardware.camera2.params.SessionConfiguration; import android.hardware.camera2.utils.ArrayUtils; import android.hardware.camera2.utils.TypeReference; +import android.os.Build; import android.util.Rational; import java.util.ArrayList; @@ -79,7 +80,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Key(String name, Class<T> type, long vendorId) { mKey = new CameraMetadataNative.Key<T>(name, type, vendorId); } @@ -193,7 +194,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final CameraMetadataNative mProperties; private List<CameraCharacteristics.Key<?>> mKeys; private List<CameraCharacteristics.Key<?>> mKeysNeedingPermission; @@ -1180,7 +1181,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <p>The list of extended scene modes for {@link CaptureRequest#CONTROL_EXTENDED_SCENE_MODE android.control.extendedSceneMode} that * are supported by this camera device, and each extended scene mode's capabilities such * as maximum streaming size, and supported zoom ratio ranges.</p> - * <p>For DISABLED mode, the camera behaves normally with no extended scene mdoe enabled.</p> + * <p>For DISABLED mode, the camera behaves normally with no extended scene mode enabled.</p> * <p>For BOKEH_STILL_CAPTURE mode, the maximum streaming dimension specifies the limit * under which bokeh is effective when capture intent is PREVIEW. Note that when capture * intent is PREVIEW, the bokeh effect may not be as high quality compared to STILL_CAPTURE @@ -3164,7 +3165,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * rectangle, and cropping to the rectangle given in {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p> * <p>E.g. to calculate position of a pixel, (x,y), in a processed YUV output image with the * dimensions in {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} given the position of a pixel, - * (x', y'), in the raw pixel array with dimensions give in + * (x', y'), in the raw pixel array with dimensions given in * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}:</p> * <ol> * <li>Choose a pixel (x', y') within the active array region of the raw buffer given in diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 47dafa0c61a8..d931789a7005 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -26,6 +26,7 @@ import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.utils.HashCodeHelpers; import android.hardware.camera2.utils.SurfaceUtils; import android.hardware.camera2.utils.TypeReference; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.ArraySet; @@ -108,7 +109,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Key(String name, Class<T> type, long vendorId) { mKey = new CameraMetadataNative.Key<T>(name, type, vendorId); } @@ -229,7 +230,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> private static final ArraySet<Surface> mEmptySurfaceSet = new ArraySet<Surface>(); private String mLogicalCameraId; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private CameraMetadataNative mLogicalCameraSettings; private final HashMap<String, CameraMetadataNative> mPhysicalCameraSettings = new HashMap<String, CameraMetadataNative>(); diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index 8cfa0866f13a..cd69788f1924 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -24,6 +24,7 @@ import android.hardware.camera2.impl.CaptureResultExtras; import android.hardware.camera2.impl.PublicKey; import android.hardware.camera2.impl.SyntheticKey; import android.hardware.camera2.utils.TypeReference; +import android.os.Build; import android.util.Log; import android.util.Rational; @@ -79,7 +80,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Key(String name, Class<T> type, long vendorId) { mKey = new CameraMetadataNative.Key<T>(name, type, vendorId); } @@ -190,6 +191,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { } } + private final String mCameraId; @UnsupportedAppUsage private final CameraMetadataNative mResults; private final CaptureRequest mRequest; @@ -202,7 +204,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <p>For internal use only</p> * @hide */ - public CaptureResult(CameraMetadataNative results, CaptureRequest parent, + public CaptureResult(String cameraId, CameraMetadataNative results, CaptureRequest parent, CaptureResultExtras extras) { if (results == null) { throw new IllegalArgumentException("results was null"); @@ -221,6 +223,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { throw new AssertionError("Results must not be empty"); } setNativeInstance(mResults); + mCameraId = cameraId; mRequest = parent; mSequenceId = extras.getRequestId(); mFrameNumber = extras.getFrameNumber(); @@ -251,12 +254,27 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { } setNativeInstance(mResults); + mCameraId = "none"; mRequest = null; mSequenceId = sequenceId; mFrameNumber = -1; } /** + * Get the camera ID of the camera that produced this capture result. + * + * For a logical multi-camera, the ID may be the logical or the physical camera ID, depending on + * whether the capture result was obtained from + * {@link TotalCaptureResult#getPhysicalCameraResults} or not. + * + * @return The camera ID for the camera that produced this capture result. + */ + @NonNull + public String getCameraId() { + return mCameraId; + } + + /** * Get a capture result field value. * * <p>The field definitions can be found in {@link CaptureResult}.</p> diff --git a/core/java/android/hardware/camera2/TotalCaptureResult.java b/core/java/android/hardware/camera2/TotalCaptureResult.java index 7cc2623a29ba..da65f71ce02c 100644 --- a/core/java/android/hardware/camera2/TotalCaptureResult.java +++ b/core/java/android/hardware/camera2/TotalCaptureResult.java @@ -70,10 +70,10 @@ public final class TotalCaptureResult extends CaptureResult { * @param partials a list of partial results; {@code null} will be substituted for an empty list * @hide */ - public TotalCaptureResult(CameraMetadataNative results, CaptureRequest parent, - CaptureResultExtras extras, List<CaptureResult> partials, int sessionId, - PhysicalCaptureResultInfo physicalResults[]) { - super(results, parent, extras); + public TotalCaptureResult(String logicalCameraId, CameraMetadataNative results, + CaptureRequest parent, CaptureResultExtras extras, List<CaptureResult> partials, + int sessionId, PhysicalCaptureResultInfo[] physicalResults) { + super(logicalCameraId, results, parent, extras); if (partials == null) { mPartialResults = new ArrayList<>(); @@ -85,7 +85,7 @@ public final class TotalCaptureResult extends CaptureResult { mPhysicalCaptureResults = new HashMap<String, CaptureResult>(); for (PhysicalCaptureResultInfo onePhysicalResult : physicalResults) { - CaptureResult physicalResult = new CaptureResult( + CaptureResult physicalResult = new CaptureResult(onePhysicalResult.getCameraId(), onePhysicalResult.getCameraMetadata(), parent, extras); mPhysicalCaptureResults.put(onePhysicalResult.getCameraId(), physicalResult); diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index 48ec3fd808fe..819d966e3bfe 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -1980,7 +1980,7 @@ public class CameraDeviceImpl extends CameraDevice // Either send a partial result or the final capture completed result if (isPartialResult) { final CaptureResult resultAsCapture = - new CaptureResult(result, request, resultExtras); + new CaptureResult(getId(), result, request, resultExtras); // Partial result resultDispatch = new Runnable() { @Override @@ -1992,7 +1992,7 @@ public class CameraDeviceImpl extends CameraDevice for (int i = 0; i < holder.getRequestCount(); i++) { CameraMetadataNative resultLocal = new CameraMetadataNative(resultCopy); - CaptureResult resultInBatch = new CaptureResult( + CaptureResult resultInBatch = new CaptureResult(getId(), resultLocal, holder.getRequest(i), resultExtras); holder.getCallback().onCaptureProgressed( @@ -2019,8 +2019,8 @@ public class CameraDeviceImpl extends CameraDevice final Range<Integer> fpsRange = request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE); final int subsequenceId = resultExtras.getSubsequenceId(); - final TotalCaptureResult resultAsCapture = new TotalCaptureResult(result, - request, resultExtras, partialResults, holder.getSessionId(), + final TotalCaptureResult resultAsCapture = new TotalCaptureResult(getId(), + result, request, resultExtras, partialResults, holder.getSessionId(), physicalResults); // Final capture result resultDispatch = new Runnable() { @@ -2038,9 +2038,9 @@ public class CameraDeviceImpl extends CameraDevice new CameraMetadataNative(resultCopy); // No logical multi-camera support for batched output mode. TotalCaptureResult resultInBatch = new TotalCaptureResult( - resultLocal, holder.getRequest(i), resultExtras, - partialResults, holder.getSessionId(), - new PhysicalCaptureResultInfo[0]); + getId(), resultLocal, holder.getRequest(i), + resultExtras, partialResults, holder.getSessionId(), + new PhysicalCaptureResultInfo[0]); holder.getCallback().onCaptureCompleted( CameraDeviceImpl.this, diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java index 9d4ab0b08e92..19f4cd6e991a 100644 --- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java +++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java @@ -64,6 +64,7 @@ import android.hardware.camera2.params.TonemapCurve; import android.hardware.camera2.utils.TypeReference; import android.location.Location; import android.location.LocationManager; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.ServiceSpecificException; @@ -261,7 +262,7 @@ public class CameraMetadataNative implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final boolean hasTag() { return mHasTag; } @@ -271,7 +272,7 @@ public class CameraMetadataNative implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final void cacheTag(int tag) { mHasTag = true; mTag = tag; @@ -1709,7 +1710,7 @@ public class CameraMetadataNative implements Parcelable { mDisplaySize = displaySize; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mMetadataPtr; // native std::shared_ptr<CameraMetadata>* @FastNative @@ -1734,7 +1735,7 @@ public class CameraMetadataNative implements Parcelable { @FastNative private static synchronized native long nativeGetBufferSize(long ptr); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @FastNative private static synchronized native byte[] nativeReadValues(int tag, long ptr); @FastNative @@ -1743,11 +1744,11 @@ public class CameraMetadataNative implements Parcelable { @FastNative private static synchronized native ArrayList nativeGetAllVendorKeys(long ptr, Class keyClass); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @FastNative private static synchronized native int nativeGetTagFromKeyLocal(long ptr, String keyName) throws IllegalArgumentException; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @FastNative private static synchronized native int nativeGetTypeFromTagLocal(long ptr, int tag) throws IllegalArgumentException; diff --git a/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java index 1d8b2a123c6a..eb2ff88ec1b2 100644 --- a/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java @@ -334,7 +334,7 @@ public class CameraOfflineSessionImpl extends CameraOfflineSession // Either send a partial result or the final capture completed result if (isPartialResult) { final CaptureResult resultAsCapture = - new CaptureResult(result, request, resultExtras); + new CaptureResult(mCameraId, result, request, resultExtras); // Partial result resultDispatch = new Runnable() { @Override @@ -349,7 +349,8 @@ public class CameraOfflineSessionImpl extends CameraOfflineSession CameraMetadataNative resultLocal = new CameraMetadataNative(resultCopy); final CaptureResult resultInBatch = new CaptureResult( - resultLocal, holder.getRequest(i), resultExtras); + mCameraId, resultLocal, holder.getRequest(i), + resultExtras); final CaptureRequest cbRequest = holder.getRequest(i); callback.onCaptureProgressed(CameraOfflineSessionImpl.this, @@ -372,8 +373,8 @@ public class CameraOfflineSessionImpl extends CameraOfflineSession final Range<Integer> fpsRange = request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE); final int subsequenceId = resultExtras.getSubsequenceId(); - final TotalCaptureResult resultAsCapture = new TotalCaptureResult(result, - request, resultExtras, partialResults, holder.getSessionId(), + final TotalCaptureResult resultAsCapture = new TotalCaptureResult(mCameraId, + result, request, resultExtras, partialResults, holder.getSessionId(), physicalResults); // Final capture result resultDispatch = new Runnable() { @@ -393,9 +394,9 @@ public class CameraOfflineSessionImpl extends CameraOfflineSession new CameraMetadataNative(resultCopy); // No logical multi-camera support for batched output mode. TotalCaptureResult resultInBatch = new TotalCaptureResult( - resultLocal, holder.getRequest(i), resultExtras, - partialResults, holder.getSessionId(), - new PhysicalCaptureResultInfo[0]); + mCameraId, resultLocal, holder.getRequest(i), + resultExtras, partialResults, holder.getSessionId(), + new PhysicalCaptureResultInfo[0]); final CaptureRequest cbRequest = holder.getRequest(i); callback.onCaptureCompleted(CameraOfflineSessionImpl.this, diff --git a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java index 16f3f2ab2023..064d4b31363b 100644 --- a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java +++ b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java @@ -17,6 +17,7 @@ package android.hardware.camera2.utils; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * Provide hashing functions using the Modified Bernstein hash @@ -32,7 +33,7 @@ public final class HashCodeHelpers { * * @return the numeric hash code */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int hashCode(int... array) { if (array == null) { return 0; diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 68b9d5227746..32900225d887 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -31,6 +31,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Point; import android.media.projection.MediaProjection; +import android.os.Build; import android.os.Handler; import android.util.Pair; import android.util.SparseArray; @@ -66,7 +67,7 @@ public final class DisplayManager { * </p> * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_WIFI_DISPLAY_STATUS_CHANGED = "android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED"; @@ -74,7 +75,7 @@ public final class DisplayManager { * Contains a {@link WifiDisplayStatus} object. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_WIFI_DISPLAY_STATUS = "android.hardware.display.extra.WIFI_DISPLAY_STATUS"; @@ -326,6 +327,15 @@ public final class DisplayManager { @TestApi public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10; + /** + * Virtual display flags: Indicates that the display should not be a part of the default + * DisplayGroup and instead be part of a new DisplayGroup. + * + * @see #createVirtualDisplay + * @hide + */ + public static final int VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP = 1 << 11; + /** @hide */ public DisplayManager(Context context) { mContext = context; diff --git a/core/java/android/hardware/display/WifiDisplayStatus.java b/core/java/android/hardware/display/WifiDisplayStatus.java index e2a825fd990a..0004b39e54e8 100644 --- a/core/java/android/hardware/display/WifiDisplayStatus.java +++ b/core/java/android/hardware/display/WifiDisplayStatus.java @@ -17,6 +17,7 @@ package android.hardware.display; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -35,9 +36,9 @@ public final class WifiDisplayStatus implements Parcelable { private final int mFeatureState; private final int mScanState; private final int mActiveDisplayState; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final WifiDisplay mActiveDisplay; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final WifiDisplay[] mDisplays; /** Session info needed for Miracast Certification */ @@ -50,23 +51,23 @@ public final class WifiDisplayStatus implements Parcelable { /** Feature state: Wifi display is turned off in settings. */ public static final int FEATURE_STATE_OFF = 2; /** Feature state: Wifi display is turned on in settings. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int FEATURE_STATE_ON = 3; /** Scan state: Not currently scanning. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int SCAN_STATE_NOT_SCANNING = 0; /** Scan state: Currently scanning. */ public static final int SCAN_STATE_SCANNING = 1; /** Display state: Not connected. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int DISPLAY_STATE_NOT_CONNECTED = 0; /** Display state: Connecting to active display. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int DISPLAY_STATE_CONNECTING = 1; /** Display state: Connected to active display. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int DISPLAY_STATE_CONNECTED = 2; public static final @android.annotation.NonNull Creator<WifiDisplayStatus> CREATOR = new Creator<WifiDisplayStatus>() { diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index 2aefb1da4783..63397c05edc2 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -41,6 +41,7 @@ import android.hardware.biometrics.BiometricTestSession; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.SensorProperties; import android.os.Binder; +import android.os.Build; import android.os.CancellationSignal; import android.os.CancellationSignal.OnCancelListener; import android.os.Handler; @@ -761,7 +762,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing * @hide */ @RequiresPermission(USE_FINGERPRINT) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public List<Fingerprint> getEnrolledFingerprints(int userId) { if (mService != null) try { return mService.getEnrolledFingerprints(userId, mContext.getOpPackageName()); diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java index 1f896cdf4298..9a9e47868b85 100644 --- a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java +++ b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java @@ -28,12 +28,41 @@ import android.os.Parcel; * @hide */ public class FingerprintSensorPropertiesInternal extends SensorPropertiesInternal { + /** + * See {@link FingerprintSensorProperties.SensorType}. + */ public final @FingerprintSensorProperties.SensorType int sensorType; - // IBiometricsFingerprint@2.1 does not manage timeout below the HAL, so the Gatekeeper HAT - // cannot be checked + + /** + * IBiometricsFingerprint@2.1 does not manage timeout below the HAL, so the Gatekeeper HAT + * cannot be checked + */ public final boolean resetLockoutRequiresHardwareAuthToken; /** + * The location of the center of the sensor if applicable. For example, sensors of type + * {@link FingerprintSensorProperties#TYPE_UDFPS_OPTICAL} would report this value as the + * distance in pixels, measured from the left edge of the screen. + * TODO: Value should be provided from the HAL + */ + public final int sensorLocationX = 540; + + /** + * The location of the center of the sensor if applicable. For example, sensors of type + * {@link FingerprintSensorProperties#TYPE_UDFPS_OPTICAL} would report this value as the + * distance in pixels, measured from the top edge of the screen. + * TODO: Value should be provided from the HAL + */ + public final int sensorLocationY = 1636; + + /** + * The radius of the sensor if applicable. For example, sensors of type + * {@link FingerprintSensorProperties#TYPE_UDFPS_OPTICAL} would report this value as the radius + * of the sensor, in pixels. + */ + public final int sensorRadius = 130; + + /** * Initializes SensorProperties with specified values */ public FingerprintSensorPropertiesInternal(int sensorId, diff --git a/core/java/android/hardware/location/GeofenceHardware.java b/core/java/android/hardware/location/GeofenceHardware.java index a1866af43706..313d8efc19be 100644 --- a/core/java/android/hardware/location/GeofenceHardware.java +++ b/core/java/android/hardware/location/GeofenceHardware.java @@ -169,7 +169,7 @@ public final class GeofenceHardware { GeofenceHardwareMonitorCallbackWrapper>(); /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public GeofenceHardware(IGeofenceHardware service) { mService = service; } diff --git a/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl b/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl index 2dfaf601c6f5..b32b7e555622 100644 --- a/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl +++ b/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl @@ -32,6 +32,6 @@ oneway interface IActivityRecognitionHardwareClient { * @param isSupported whether the platform has hardware support for the feature * @param instance the available instance to provide access to the feature */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onAvailabilityChanged(in boolean isSupported, in IActivityRecognitionHardware instance); } diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java index e58403fe387d..11f3e4582ac2 100644 --- a/core/java/android/hardware/soundtrigger/SoundTrigger.java +++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java @@ -45,6 +45,7 @@ import android.media.soundtrigger_middleware.ISoundTriggerMiddlewareService; import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor; import android.media.soundtrigger_middleware.Status; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -1174,7 +1175,7 @@ public class SoundTrigger { /** @hide */ @TestApi - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable, int captureSession, int captureDelayMs, int capturePreambleMs, boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data) { @@ -1380,7 +1381,7 @@ public class SoundTrigger { public static class RecognitionConfig implements Parcelable { /** True if the DSP should capture the trigger sound and make it available for further * capture. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final boolean captureRequested; /** * True if the service should restart listening after the DSP triggers. @@ -1389,12 +1390,12 @@ public class SoundTrigger { public final boolean allowMultipleTriggers; /** List of all keyphrases in the sound model for which recognition should be performed with * options for each keyphrase. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @NonNull public final KeyphraseRecognitionExtra keyphrases[]; /** Opaque data for use by system applications who know about voice engine internals, * typically during enrollment. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @NonNull public final byte[] data; @@ -1560,7 +1561,7 @@ public class SoundTrigger { public final int id; /** Recognition modes matched for this event */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int recognitionModes; /** Confidence level for mode RECOGNITION_MODE_VOICE_TRIGGER when user identification @@ -1667,7 +1668,7 @@ public class SoundTrigger { @NonNull public final KeyphraseRecognitionExtra[] keyphraseExtras; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeyphraseRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable, int captureSession, int captureDelayMs, int capturePreambleMs, boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data, @@ -1789,7 +1790,7 @@ public class SoundTrigger { * @hide */ public static class GenericRecognitionEvent extends RecognitionEvent implements Parcelable { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public GenericRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable, int captureSession, int captureDelayMs, int capturePreambleMs, boolean triggerInData, @NonNull AudioFormat captureFormat, @@ -1860,7 +1861,7 @@ public class SoundTrigger { @NonNull public final byte[] data; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) SoundModelEvent(int status, int soundModelHandle, @Nullable byte[] data) { this.status = status; this.soundModelHandle = soundModelHandle; diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java index 05823bf14b63..431c99dbdc1f 100644 --- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java +++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java @@ -29,6 +29,7 @@ import android.media.soundtrigger_middleware.PhraseRecognitionEvent; import android.media.soundtrigger_middleware.PhraseSoundModel; import android.media.soundtrigger_middleware.RecognitionEvent; import android.media.soundtrigger_middleware.SoundModel; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -48,7 +49,7 @@ public class SoundTriggerModule { private static final int EVENT_RECOGNITION = 1; private static final int EVENT_SERVICE_DIED = 2; private static final int EVENT_SERVICE_STATE_CHANGE = 3; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mId; private EventHandlerDelegate mEventHandlerDelegate; private ISoundTriggerModule mService; diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java index 53a5785f7c76..21634cc544e7 100644 --- a/core/java/android/hardware/usb/UsbDeviceConnection.java +++ b/core/java/android/hardware/usb/UsbDeviceConnection.java @@ -47,7 +47,7 @@ public class UsbDeviceConnection { private Context mContext; // used by the JNI code - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeContext; private final CloseGuard mCloseGuard = CloseGuard.get(); diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index ef305e2c1867..62a5782cb55d 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -209,7 +209,7 @@ public class UsbManager { * * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String USB_DATA_UNLOCKED = "unlocked"; /** @@ -771,7 +771,7 @@ public class UsbManager { * {@hide} */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isFunctionEnabled(String function) { try { return mService.isFunctionEnabled(function); diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java index 473df712e3f9..d1c6465d62c8 100644 --- a/core/java/android/hardware/usb/UsbRequest.java +++ b/core/java/android/hardware/usb/UsbRequest.java @@ -49,7 +49,7 @@ public class UsbRequest { static final int MAX_USBFS_BUFFER_SIZE = 16384; // used by the JNI code - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeContext; private UsbEndpoint mEndpoint; diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java index 0512305e71a2..bb2357e24617 100644 --- a/core/java/android/inputmethodservice/IInputMethodWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java @@ -280,7 +280,7 @@ class IInputMethodWrapper extends IInputMethod.Stub } CountDownLatch latch = new CountDownLatch(1); - mCaller.executeOrSendMessage(mCaller.obtainMessageOOOO(DO_DUMP, + mCaller.getHandler().sendMessageAtFrontOfQueue(mCaller.obtainMessageOOOO(DO_DUMP, fd, fout, args, latch)); try { if (!latch.await(5, TimeUnit.SECONDS)) { diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 78cc71a782a5..070bec11b93a 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1139,7 +1139,7 @@ public class InputMethodService extends AbstractInputMethodService { mService.getContentResolver().unregisterContentObserver(this); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean shouldShowImeWithHardKeyboard() { // Lazily initialize as needed. if (mShowImeWithHardKeyboard == ShowImeWithHardKeyboardType.UNKNOWN) { @@ -1179,7 +1179,7 @@ public class InputMethodService extends AbstractInputMethodService { return "SettingsObserver{mShowImeWithHardKeyboard=" + mShowImeWithHardKeyboard + "}"; } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private SettingsObserver mSettingsObserver; /** diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 1012f47f8c0a..224113fc29cb 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -354,7 +354,7 @@ public class ConnectivityManager { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_TETHER_STATE_CHANGED = TetheringManager.ACTION_TETHER_STATE_CHANGED; @@ -363,7 +363,7 @@ public class ConnectivityManager { * gives a String[] listing all the interfaces configured for * tethering and currently available for tethering. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_AVAILABLE_TETHER = TetheringManager.EXTRA_AVAILABLE_TETHER; /** @@ -378,7 +378,7 @@ public class ConnectivityManager { * gives a String[] listing all the interfaces currently tethered * (ie, has DHCPv4 support and packets potentially forwarded/NATed) */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_ACTIVE_TETHER = TetheringManager.EXTRA_ACTIVE_TETHER; /** @@ -387,7 +387,7 @@ public class ConnectivityManager { * failed. Use {@link #getLastTetherError} to find the error code * for any interfaces listed here. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_ERRORED_TETHER = TetheringManager.EXTRA_ERRORED_TETHER; /** @@ -850,7 +850,7 @@ public class ConnectivityManager { * {@hide} */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String getNetworkTypeName(int type) { switch (type) { case TYPE_NONE: @@ -1173,7 +1173,7 @@ public class ConnectivityManager { * {@hide} */ @RequiresPermission(android.Manifest.permission.NETWORK_STACK) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkInfo getActiveNetworkInfoForUid(int uid) { return getActiveNetworkInfoForUid(uid, false); } @@ -1520,7 +1520,7 @@ public class ConnectivityManager { return 1; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) { if (networkType == TYPE_MOBILE) { switch (feature) { @@ -1606,7 +1606,7 @@ public class ConnectivityManager { }; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests = new HashMap<>(); @@ -1635,7 +1635,7 @@ public class ConnectivityManager { Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) { int delay = -1; int type = legacyTypeForNetworkCapabilities(netCap); @@ -1665,7 +1665,7 @@ public class ConnectivityManager { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean removeRequestForFeature(NetworkCapabilities netCap) { final LegacyRequest l; synchronized (sLegacyRequests) { @@ -1732,17 +1732,17 @@ public class ConnectivityManager { /** @hide */ public static class PacketKeepaliveCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PacketKeepaliveCallback() { } /** The requested keepalive was successfully started. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onStarted() {} /** The keepalive was successfully stopped. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onStopped() {} /** An error occurred. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onError(int error) {} } @@ -1806,7 +1806,7 @@ public class ConnectivityManager { private volatile Integer mSlot; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void stop() { try { mExecutor.execute(() -> { @@ -1875,7 +1875,7 @@ public class ConnectivityManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PacketKeepalive startNattKeepalive( Network network, int intervalSeconds, PacketKeepaliveCallback callback, InetAddress srcAddr, int srcPort, InetAddress dstAddr) { @@ -2110,7 +2110,7 @@ public class ConnectivityManager { /** {@hide} */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkQuotaInfo getActiveNetworkQuotaInfo() { try { return mService.getActiveNetworkQuotaInfo(); @@ -2408,7 +2408,7 @@ public class ConnectivityManager { * * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Deprecated public int tether(String iface) { return mTetheringManager.tether(iface); @@ -2849,7 +2849,7 @@ public class ConnectivityManager { * {@hide} */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Deprecated public int getLastTetherError(String iface) { int error = mTetheringManager.getLastTetherError(iface); @@ -4659,7 +4659,7 @@ public class ConnectivityManager { * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean setProcessDefaultNetworkForHostResolution(Network network) { return NetworkUtils.bindProcessToNetworkForHostResolution( (network == null) ? NETID_UNSET : network.getNetIdForResolv()); diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java index 6819c349d20a..82ba156b08d0 100644 --- a/core/java/android/net/DhcpResults.java +++ b/core/java/android/net/DhcpResults.java @@ -18,6 +18,7 @@ package android.net; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -40,30 +41,30 @@ import java.util.Objects; public final class DhcpResults implements Parcelable { private static final String TAG = "DhcpResults"; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public LinkAddress ipAddress; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public InetAddress gateway; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final ArrayList<InetAddress> dnsServers = new ArrayList<>(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String domains; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Inet4Address serverAddress; /** Vendor specific information (from RFC 2132). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String vendorInfo; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int leaseDuration; /** Link MTU option. 0 means unset. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mtu; public String serverHostName; diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java index 5860e20ad3b4..84a8e1c3dcc1 100644 --- a/core/java/android/net/EthernetManager.java +++ b/core/java/android/net/EthernetManager.java @@ -23,6 +23,7 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.Handler; import android.os.Message; import android.os.RemoteException; @@ -76,7 +77,7 @@ public class EthernetManager { * @param isAvailable {@code true} if Ethernet port exists. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void onAvailabilityChanged(String iface, boolean isAvailable); } @@ -97,7 +98,7 @@ public class EthernetManager { * @return the Ethernet Configuration, contained in {@link IpConfiguration}. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public IpConfiguration getConfiguration(String iface) { try { return mService.getConfiguration(iface); @@ -110,7 +111,7 @@ public class EthernetManager { * Set Ethernet configuration. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setConfiguration(String iface, IpConfiguration config) { try { mService.setConfiguration(iface, config); @@ -123,7 +124,7 @@ public class EthernetManager { * Indicates whether the system currently has one or more Ethernet interfaces. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isAvailable() { return getAvailableInterfaces().length > 0; } @@ -134,7 +135,7 @@ public class EthernetManager { * @param iface Ethernet interface name * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isAvailable(String iface) { try { return mService.isAvailable(iface); @@ -149,7 +150,7 @@ public class EthernetManager { * @throws IllegalArgumentException If the listener is null. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addListener(Listener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); @@ -168,7 +169,7 @@ public class EthernetManager { * Returns an array of available Ethernet interface names. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String[] getAvailableInterfaces() { try { return mService.getAvailableInterfaces(); @@ -183,7 +184,7 @@ public class EthernetManager { * @throws IllegalArgumentException If the listener is null. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void removeListener(Listener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 059ec28298f9..41732008b4ee 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -73,7 +73,7 @@ interface IConnectivityManager NetworkCapabilities getNetworkCapabilities(in Network network, String callingPackageName); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) NetworkState[] getAllNetworkState(); NetworkQuotaInfo getActiveNetworkQuotaInfo(); @@ -134,7 +134,7 @@ interface IConnectivityManager VpnConfig getVpnConfig(int userId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void startLegacyVpn(in VpnProfile profile); LegacyVpnInfo getLegacyVpnInfo(int userId); diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl index 72a6b397a30c..e486052e0e53 100644 --- a/core/java/android/net/INetworkPolicyManager.aidl +++ b/core/java/android/net/INetworkPolicyManager.aidl @@ -67,7 +67,7 @@ interface INetworkPolicyManager { void setDeviceIdleMode(boolean enabled); void setWifiMeteredOverride(String networkId, int meteredOverride); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) NetworkQuotaInfo getNetworkQuotaInfo(in NetworkState state); SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage); diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index 5fa515a14343..1a3dc974480c 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -42,7 +42,7 @@ interface INetworkStatsService { * PACKAGE_USAGE_STATS permission is always checked. If PACKAGE_USAGE_STATS is not granted * READ_NETWORK_USAGE_STATS is checked for. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage); /** Return data layer snapshot of UID network usage. */ diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java index fa31b806ba9f..d5f8b2edb6bb 100644 --- a/core/java/android/net/IpConfiguration.java +++ b/core/java/android/net/IpConfiguration.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -98,7 +99,7 @@ public final class IpConfiguration implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public IpConfiguration(IpAssignment ipAssignment, ProxySettings proxySettings, StaticIpConfiguration staticIpConfiguration, diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 25a76f43553a..209a3fa839c0 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -111,7 +111,7 @@ public final class LinkProperties implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static ProvisioningChange compareProvisioning( LinkProperties before, LinkProperties after) { if (before.isProvisioned() && after.isProvisioned()) { @@ -849,7 +849,7 @@ public final class LinkProperties implements Parcelable { * Returns all the links stacked on top of this link. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @NonNull List<LinkProperties> getStackedLinks() { if (mStackedLinks.isEmpty()) { return Collections.emptyList(); @@ -1448,7 +1448,7 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if both are identical, {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isIdenticalStackedLinks(@NonNull LinkProperties target) { if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) { return false; diff --git a/core/java/android/net/LinkQualityInfo.java b/core/java/android/net/LinkQualityInfo.java index aa56cff50f63..2bf1fbc848f7 100644 --- a/core/java/android/net/LinkQualityInfo.java +++ b/core/java/android/net/LinkQualityInfo.java @@ -17,6 +17,7 @@ package android.net; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -190,7 +191,7 @@ public class LinkQualityInfo implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setPacketCount(long packetCount) { mPacketCount = packetCount; } @@ -206,7 +207,7 @@ public class LinkQualityInfo implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setPacketErrorCount(long packetErrorCount) { mPacketErrorCount = packetErrorCount; } @@ -268,7 +269,7 @@ public class LinkQualityInfo implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setLastDataSampleTime(long lastDataSampleTime) { mLastDataSampleTime = lastDataSampleTime; } @@ -284,7 +285,7 @@ public class LinkQualityInfo implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDataSampleDuration(int dataSampleDuration) { mDataSampleDuration = dataSampleDuration; } diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java index e80e3a6f93ec..e01e5aecc7e6 100644 --- a/core/java/android/net/LocalSocketImpl.java +++ b/core/java/android/net/LocalSocketImpl.java @@ -17,6 +17,7 @@ package android.net; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.system.ErrnoException; import android.system.Int32Ref; import android.system.Os; @@ -51,7 +52,7 @@ class LocalSocketImpl @UnsupportedAppUsage FileDescriptor[] inboundFileDescriptors; /** file descriptor array that should be written during next write */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) FileDescriptor[] outboundFileDescriptors; /** diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java index 6949bf2a7807..049e9bcc2509 100644 --- a/core/java/android/net/MacAddress.java +++ b/core/java/android/net/MacAddress.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.net.util.MacAddressUtils; import android.net.wifi.WifiInfo; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -58,7 +59,7 @@ public final class MacAddress implements Parcelable { * <p>Not publicly exposed or treated specially since the OUI 00:00:00 is registered. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final MacAddress ALL_ZEROS_ADDRESS = new MacAddress(0); /** @hide */ diff --git a/core/java/android/net/MobileLinkQualityInfo.java b/core/java/android/net/MobileLinkQualityInfo.java index a65de6bb2908..f51c4df2d6b5 100644 --- a/core/java/android/net/MobileLinkQualityInfo.java +++ b/core/java/android/net/MobileLinkQualityInfo.java @@ -17,6 +17,7 @@ package android.net; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; /** @@ -40,7 +41,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { private int mLteRssnr = UNKNOWN_INT; private int mLteCqi = UNKNOWN_INT; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public MobileLinkQualityInfo() { } @@ -98,7 +99,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { * returns mobile network type as defined by {@link android.telephony.TelephonyManager} * @return network type or {@link android.net.LinkQualityInfo#UNKNOWN_INT} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getMobileNetworkType() { return mMobileNetworkType; } @@ -106,7 +107,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setMobileNetworkType(int mobileNetworkType) { mMobileNetworkType = mobileNetworkType; } @@ -122,7 +123,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRssi(int Rssi) { mRssi = Rssi; } @@ -138,7 +139,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setGsmErrorRate(int gsmErrorRate) { mGsmErrorRate = gsmErrorRate; } @@ -154,7 +155,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCdmaDbm(int cdmaDbm) { mCdmaDbm = cdmaDbm; } @@ -170,7 +171,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCdmaEcio(int cdmaEcio) { mCdmaEcio = cdmaEcio; } @@ -186,7 +187,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setEvdoDbm(int evdoDbm) { mEvdoDbm = evdoDbm; } @@ -202,7 +203,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setEvdoEcio(int evdoEcio) { mEvdoEcio = evdoEcio; } @@ -218,7 +219,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setEvdoSnr(int evdoSnr) { mEvdoSnr = evdoSnr; } @@ -234,7 +235,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setLteSignalStrength(int lteSignalStrength) { mLteSignalStrength = lteSignalStrength; } @@ -250,7 +251,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setLteRsrp(int lteRsrp) { mLteRsrp = lteRsrp; } @@ -266,7 +267,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setLteRsrq(int lteRsrq) { mLteRsrq = lteRsrq; } @@ -282,7 +283,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setLteRssnr(int lteRssnr) { mLteRssnr = lteRssnr; } @@ -298,7 +299,7 @@ public class MobileLinkQualityInfo extends LinkQualityInfo { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setLteCqi(int lteCqi) { mLteCqi = lteCqi; } diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index 3e4f73555e58..53996a5fc503 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.system.ErrnoException; @@ -110,7 +111,7 @@ public class Network implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Network(int netId) { this(netId, false); } diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 327e42bdd2f7..44ebff99f3e9 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -353,10 +353,11 @@ public abstract class NetworkAgent { private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) { // The subtype can be changed with (TODO) setLegacySubtype, but it starts - // with the type and an empty description. + // with 0 (TelephonyManager.NETWORK_TYPE_UNKNOWN) and an empty description. final NetworkInfo ni = new NetworkInfo(config.legacyType, 0, config.legacyTypeName, ""); ni.setIsAvailable(true); - ni.setExtraInfo(config.getLegacyExtraInfo()); + ni.setDetailedState(NetworkInfo.DetailedState.CONNECTING, null /* reason */, + config.getLegacyExtraInfo()); return ni; } diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index be33f4edb5d1..f806b565b127 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -133,7 +133,7 @@ public final class NetworkCapabilities implements Parcelable { * Represents the network's capabilities. If any are specified they will be satisfied * by any Network that matches all of them. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNetworkCapabilities; /** @@ -170,6 +170,7 @@ public final class NetworkCapabilities implements Parcelable { NET_CAPABILITY_MCX, NET_CAPABILITY_PARTIAL_CONNECTIVITY, NET_CAPABILITY_TEMPORARILY_NOT_METERED, + NET_CAPABILITY_OEM_PRIVATE, }) public @interface NetCapability { } @@ -345,8 +346,15 @@ public final class NetworkCapabilities implements Parcelable { */ public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25; + /** + * Indicates that this network is private to the OEM and meant only for OEM use. + * @hide + */ + @SystemApi + public static final int NET_CAPABILITY_OEM_PRIVATE = 26; + private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; - private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_TEMPORARILY_NOT_METERED; + private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_OEM_PRIVATE; /** * Network capabilities that are expected to be mutable, i.e., can change while a particular @@ -404,7 +412,8 @@ public final class NetworkCapabilities implements Parcelable { * {@see #maybeMarkCapabilitiesRestricted}. */ private static final long FORCE_RESTRICTED_CAPABILITIES = - (1 << NET_CAPABILITY_OEM_PAID); + (1 << NET_CAPABILITY_OEM_PAID) + | (1 << NET_CAPABILITY_OEM_PRIVATE); /** * Capabilities that suggest that a network is unrestricted. @@ -1279,7 +1288,7 @@ public final class NetworkCapabilities implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean hasSignalStrength() { return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED; } @@ -1910,6 +1919,7 @@ public final class NetworkCapabilities implements Parcelable { case NET_CAPABILITY_MCX: return "MCX"; case NET_CAPABILITY_PARTIAL_CONNECTIVITY: return "PARTIAL_CONNECTIVITY"; case NET_CAPABILITY_TEMPORARILY_NOT_METERED: return "TEMPORARILY_NOT_METERED"; + case NET_CAPABILITY_OEM_PRIVATE: return "OEM_PRIVATE"; default: return Integer.toString(capability); } } @@ -1917,7 +1927,7 @@ public final class NetworkCapabilities implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static @NonNull String transportNamesOf(@Nullable @Transport int[] types) { StringJoiner joiner = new StringJoiner("|"); if (types != null) { diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index e9e242e2b08a..a643d09eef49 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -253,7 +253,7 @@ public class NetworkPolicyManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getUidPolicy(int uid) { try { return mService.getUidPolicy(uid); @@ -339,7 +339,7 @@ public class NetworkPolicyManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRestrictBackground(boolean restrictBackground) { try { mService.setRestrictBackground(restrictBackground); @@ -349,7 +349,7 @@ public class NetworkPolicyManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean getRestrictBackground() { try { return mService.getRestrictBackground(); diff --git a/core/java/android/net/NetworkQuotaInfo.java b/core/java/android/net/NetworkQuotaInfo.java index 2e52d9cd19ab..d39bf29a4ef1 100644 --- a/core/java/android/net/NetworkQuotaInfo.java +++ b/core/java/android/net/NetworkQuotaInfo.java @@ -17,6 +17,7 @@ package android.net; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -37,17 +38,17 @@ public class NetworkQuotaInfo implements Parcelable { public NetworkQuotaInfo(Parcel in) { } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getEstimatedBytes() { return 0; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getSoftLimitBytes() { return NO_LIMIT; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getHardLimitBytes() { return NO_LIMIT; } diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java index 1d6e50710df1..6209718e8788 100644 --- a/core/java/android/net/NetworkRequest.java +++ b/core/java/android/net/NetworkRequest.java @@ -43,7 +43,7 @@ public class NetworkRequest implements Parcelable { * The {@link NetworkCapabilities} that define this request. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final @NonNull NetworkCapabilities networkCapabilities; /** @@ -52,7 +52,7 @@ public class NetworkRequest implements Parcelable { * the request. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int requestId; /** diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index cbee01024622..d42beae601ed 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -219,11 +220,11 @@ public final class NetworkStats implements Parcelable { * generated. */ private long elapsedRealtime; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int size; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int capacity; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String[] iface; @UnsupportedAppUsage private int[] uid; @@ -231,21 +232,21 @@ public final class NetworkStats implements Parcelable { private int[] set; @UnsupportedAppUsage private int[] tag; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int[] metered; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int[] roaming; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int[] defaultNetwork; @UnsupportedAppUsage private long[] rxBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long[] rxPackets; @UnsupportedAppUsage private long[] txBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long[] txPackets; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long[] operations; /** @@ -258,7 +259,7 @@ public final class NetworkStats implements Parcelable { @SystemApi public static class Entry { /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String iface; /** @hide */ @UnsupportedAppUsage @@ -267,7 +268,7 @@ public final class NetworkStats implements Parcelable { @UnsupportedAppUsage public int set; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int tag; /** * Note that this is only populated w/ the default value when read from /proc or written @@ -294,20 +295,20 @@ public final class NetworkStats implements Parcelable { @UnsupportedAppUsage public long rxBytes; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long rxPackets; /** @hide */ @UnsupportedAppUsage public long txBytes; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long txPackets; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long operations; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Entry() { this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); } @@ -454,7 +455,7 @@ public final class NetworkStats implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkStats(Parcel parcel) { elapsedRealtime = parcel.readLong(); size = parcel.readInt(); diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index 51f09a0103ff..fba75614342d 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -32,6 +32,7 @@ import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.internal.util.ArrayUtils.total; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.service.NetworkStatsHistoryBucketProto; @@ -91,18 +92,18 @@ public class NetworkStatsHistory implements Parcelable { public static class Entry { public static final long UNKNOWN = -1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long bucketDuration; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long bucketStart; public long activeTime; @UnsupportedAppUsage public long rxBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long rxPackets; @UnsupportedAppUsage public long txBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long txPackets; public long operations; } @@ -134,7 +135,7 @@ public class NetworkStatsHistory implements Parcelable { recordEntireHistory(existing); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkStatsHistory(Parcel in) { bucketDuration = in.readLong(); bucketStart = readLongArray(in); @@ -220,7 +221,7 @@ public class NetworkStatsHistory implements Parcelable { return 0; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int size() { return bucketCount; } @@ -258,7 +259,7 @@ public class NetworkStatsHistory implements Parcelable { * Return index of bucket that contains or is immediately before the * requested time. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getIndexBefore(long time) { int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time); if (index < 0) { @@ -286,7 +287,7 @@ public class NetworkStatsHistory implements Parcelable { /** * Return specific stats entry. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Entry getValues(int i, Entry recycle) { final Entry entry = recycle != null ? recycle : new Entry(); entry.bucketStart = bucketStart[i]; diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index a95ba12f6544..dc33cc7b614d 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -37,6 +37,7 @@ import static android.net.wifi.WifiInfo.sanitizeSsid; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.NetworkType; @@ -159,7 +160,7 @@ public class NetworkTemplate implements Parcelable { * Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks, * regardless of IMSI. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static NetworkTemplate buildTemplateMobileWildcard() { return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null); } diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index 1e5b6d5ab5c0..a0faafa779a8 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -98,7 +98,7 @@ public class NetworkUtils { * this socket will go directly to the underlying network, so its traffic will not be * forwarded through the VPN. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean protectFromVpn(FileDescriptor fd) { return protectFromVpn(fd.getInt$()); } @@ -223,7 +223,7 @@ public class NetworkUtils { * @hide * @deprecated use {@link Inet4AddressUtils#netmaskToPrefixLength(Inet4Address)} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Deprecated public static int netmaskToPrefixLength(Inet4Address netmask) { // This is only here because some apps seem to be using it (@UnsupportedAppUsage). @@ -290,7 +290,7 @@ public class NetworkUtils { /** * Returns the implicit netmask of an IPv4 address, as was the custom before 1993. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int getImplicitNetmask(Inet4Address address) { // Only here because it seems to be used by apps return Inet4AddressUtils.getImplicitNetmask(address); diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java index 4ba7394a4bb2..f1d9669a8309 100644 --- a/core/java/android/net/Proxy.java +++ b/core/java/android/net/Proxy.java @@ -20,6 +20,7 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.text.TextUtils; import android.util.Log; @@ -241,7 +242,7 @@ public final class Proxy { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final void setHttpProxySystemProperty(ProxyInfo p) { String host = null; String port = null; diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index 93ad41f7c524..2543aa3ab48a 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -232,7 +232,7 @@ public final class RouteInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway, @Nullable String iface) { this(destination, gateway, iface, RTN_UNICAST); @@ -501,7 +501,7 @@ public final class RouteInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Nullable public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) { return NetUtils.selectBestRoute(routes, dest); diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java index e51145800cc7..f3d3c6560fc2 100644 --- a/core/java/android/net/SSLCertificateSocketFactory.java +++ b/core/java/android/net/SSLCertificateSocketFactory.java @@ -115,20 +115,20 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory { private SSLSocketFactory mInsecureFactory = null; @UnsupportedAppUsage private SSLSocketFactory mSecureFactory = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private TrustManager[] mTrustManagers = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private KeyManager[] mKeyManagers = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private byte[] mNpnProtocols = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private byte[] mAlpnProtocols = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private PrivateKey mChannelIdPrivateKey = null; @UnsupportedAppUsage private final int mHandshakeTimeoutMillis; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final SSLClientSessionCache mSessionCache; @UnsupportedAppUsage private final boolean mSecure; @@ -249,7 +249,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private SSLSocketFactory makeSocketFactory( KeyManager[] keyManagers, TrustManager[] trustManagers) { try { @@ -343,7 +343,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory { * must be non-empty and of length less than 256. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setAlpnProtocols(byte[][] protocols) { this.mAlpnProtocols = toLengthPrefixedList(protocols); } @@ -464,13 +464,13 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSoWriteTimeout(Socket socket, int writeTimeoutMilliseconds) throws SocketException { castToOpenSSLSocket(socket).setSoWriteTimeout(writeTimeoutMilliseconds); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static OpenSSLSocketImpl castToOpenSSLSocket(Socket socket) { if (!(socket instanceof OpenSSLSocketImpl)) { throw new IllegalArgumentException("Socket not created by this factory: " diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java index f56d656f07ed..ce545974f5cb 100644 --- a/core/java/android/net/StaticIpConfiguration.java +++ b/core/java/android/net/StaticIpConfiguration.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -53,19 +54,19 @@ import java.util.Objects; @SystemApi public final class StaticIpConfiguration implements Parcelable { /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Nullable public LinkAddress ipAddress; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Nullable public InetAddress gateway; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @NonNull public final ArrayList<InetAddress> dnsServers; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Nullable public String domains; diff --git a/core/java/android/net/TEST_MAPPING b/core/java/android/net/TEST_MAPPING index abac81117deb..8c13ef98bedb 100644 --- a/core/java/android/net/TEST_MAPPING +++ b/core/java/android/net/TEST_MAPPING @@ -17,4 +17,4 @@ "path": "frameworks/opt/net/wifi" } ] -}
\ No newline at end of file +} diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index e7bba69dbb84..a985e934ed3c 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -565,7 +565,7 @@ public class TrafficStats { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static long getMobileTcpRxPackets() { long total = 0; for (String iface : getMobileIfaces()) { @@ -581,7 +581,7 @@ public class TrafficStats { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static long getMobileTcpTxPackets() { long total = 0; for (String iface : getMobileIfaces()) { diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java index aa3777d55342..77fb18411546 100644 --- a/core/java/android/net/WebAddress.java +++ b/core/java/android/net/WebAddress.java @@ -161,7 +161,7 @@ public class WebAddress { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setHost(String host) { mHost = host; } @@ -201,7 +201,7 @@ public class WebAddress { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getAuthInfo() { return mAuthInfo; } diff --git a/core/java/android/net/metrics/ApfProgramEvent.java b/core/java/android/net/metrics/ApfProgramEvent.java index c50bae90488b..ab12cdd22685 100644 --- a/core/java/android/net/metrics/ApfProgramEvent.java +++ b/core/java/android/net/metrics/ApfProgramEvent.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -55,22 +56,22 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { public @interface Flags {} /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final long lifetime; // Maximum computed lifetime of the program in seconds /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final long actualLifetime; // Effective program lifetime in seconds /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int filteredRas; // Number of RAs filtered by the APF program /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int currentRas; // Total number of current RAs at generation time /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int programLength; // Length of the APF program in bytes /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int flags; // Bitfield compound of FLAG_* constants private ApfProgramEvent(long lifetime, long actualLifetime, int filteredRas, int currentRas, @@ -217,7 +218,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { }; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static @Flags int flagsFor(boolean hasIPv4, boolean multicastFilterOn) { int bitfield = 0; if (hasIPv4) { diff --git a/core/java/android/net/metrics/ApfStats.java b/core/java/android/net/metrics/ApfStats.java index 2a601b273ef4..fcafb7ebd676 100644 --- a/core/java/android/net/metrics/ApfStats.java +++ b/core/java/android/net/metrics/ApfStats.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -34,61 +35,61 @@ public final class ApfStats implements IpConnectivityLog.Event { * time interval in milliseconds these stastistics covers. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final long durationMs; /** * number of received RAs. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int receivedRas; /** * number of received RAs matching a known RA. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int matchingRas; /** * number of received RAs ignored due to the MAX_RAS limit. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int droppedRas; /** * number of received RAs with a minimum lifetime of 0. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int zeroLifetimeRas; /** * number of received RAs that could not be parsed. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int parseErrors; /** * number of APF program updates from receiving RAs. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int programUpdates; /** * total number of APF program updates. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int programUpdatesAll; /** * number of APF program updates from allowing multicast traffic. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int programUpdatesAllowingMulticast; /** * maximum APF program size advertised by hardware. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int maxProgramSize; private ApfStats(Parcel in) { diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java index e0a93dd1c18f..8de427de1dab 100644 --- a/core/java/android/net/metrics/DhcpClientEvent.java +++ b/core/java/android/net/metrics/DhcpClientEvent.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -38,7 +39,7 @@ public final class DhcpClientEvent implements IpConnectivityLog.Event { /** @hide */ public final int durationMs; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private DhcpClientEvent(String msg, int durationMs) { this.msg = msg; this.durationMs = durationMs; diff --git a/core/java/android/net/nsd/INsdManager.aidl b/core/java/android/net/nsd/INsdManager.aidl index 9484c74bcb23..e9e8935a19b2 100644 --- a/core/java/android/net/nsd/INsdManager.aidl +++ b/core/java/android/net/nsd/INsdManager.aidl @@ -25,7 +25,7 @@ import android.os.Messenger; */ interface INsdManager { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Messenger getMessenger(); void setEnabled(boolean enable); } diff --git a/core/java/android/nfc/INfcAdapterExtras.aidl b/core/java/android/nfc/INfcAdapterExtras.aidl index dd260bc6f2f6..cde57c58ca1f 100644 --- a/core/java/android/nfc/INfcAdapterExtras.aidl +++ b/core/java/android/nfc/INfcAdapterExtras.aidl @@ -23,18 +23,18 @@ import android.os.Bundle; * {@hide} */ interface INfcAdapterExtras { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Bundle open(in String pkg, IBinder b); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Bundle close(in String pkg, IBinder b); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Bundle transceive(in String pkg, in byte[] data_in); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int getCardEmulationRoute(in String pkg); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setCardEmulationRoute(in String pkg, int route); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void authenticate(in String pkg, in byte[] token); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String getDriverName(in String pkg); } diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java index 421eb33392db..7bf4355d5b35 100644 --- a/core/java/android/nfc/NdefRecord.java +++ b/core/java/android/nfc/NdefRecord.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.net.Uri; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.proto.ProtoOutputStream; @@ -282,7 +283,7 @@ public final class NdefRecord implements Parcelable { private final short mTnf; private final byte[] mType; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final byte[] mId; private final byte[] mPayload; diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index c61f10f50c93..90e01ebe6205 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -35,6 +35,7 @@ import android.nfc.tech.MifareClassic; import android.nfc.tech.Ndef; import android.nfc.tech.NfcA; import android.nfc.tech.NfcF; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -2077,7 +2078,7 @@ public final class NfcAdapter { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public INfcAdapterExtras getNfcAdapterExtrasInterface() { if (mContext == null) { throw new UnsupportedOperationException("You need a context on NfcAdapter to use the " diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index b9e6ff4a5a9e..398ec63a931b 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -29,6 +29,7 @@ import android.nfc.tech.NfcBarcode; import android.nfc.tech.NfcF; import android.nfc.tech.NfcV; import android.nfc.tech.TagTechnology; +import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -111,7 +112,7 @@ import java.util.HashMap; * <p> */ public final class Tag implements Parcelable { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final byte[] mId; final int[] mTechList; final String[] mTechStringList; diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java index 1d28489d2ac8..1692921f4a8f 100644 --- a/core/java/android/os/BaseBundle.java +++ b/core/java/android/os/BaseBundle.java @@ -315,7 +315,7 @@ public class BaseBundle { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isParcelled() { return mParcelledData != null; } diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java index 9a16d3fee600..6d4593a2ce87 100644 --- a/core/java/android/os/BatteryManager.java +++ b/core/java/android/os/BatteryManager.java @@ -120,7 +120,7 @@ public class BatteryManager { * Int value set to the maximum charging current supported by the charger in micro amperes. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_MAX_CHARGING_CURRENT = "max_charging_current"; /** @@ -128,7 +128,7 @@ public class BatteryManager { * Int value set to the maximum charging voltage supported by the charger in micro volts. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_MAX_CHARGING_VOLTAGE = "max_charging_voltage"; /** @@ -136,7 +136,7 @@ public class BatteryManager { * integer containing the charge counter present in the battery. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_CHARGE_COUNTER = "charge_counter"; /** diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index b550c7d4ba81..00023a5caf75 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -87,7 +87,7 @@ public abstract class BatteryStats implements Parcelable { /** * A constant indicating a partial wake lock timer. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int WAKE_TYPE_PARTIAL = 0; /** @@ -790,7 +790,7 @@ public abstract class BatteryStats implements Parcelable { * Returns the timer keeping track of background wifi scans. */ public abstract Timer getWifiScanBackgroundTimer(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which); public abstract int getWifiBatchedScanCount(int csphBin, int which); @UnsupportedAppUsage diff --git a/core/java/android/os/Broadcaster.java b/core/java/android/os/Broadcaster.java index d1a953f23f7f..88760b0b6828 100644 --- a/core/java/android/os/Broadcaster.java +++ b/core/java/android/os/Broadcaster.java @@ -21,7 +21,7 @@ import android.compat.annotation.UnsupportedAppUsage; /** @hide */ public class Broadcaster { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Broadcaster() { } @@ -32,7 +32,7 @@ public class Broadcaster * When this broadcaster pushes a message with senderWhat in the what field, * target will be sent a copy of that message with targetWhat in the what field. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void request(int senderWhat, Handler target, int targetWhat) { synchronized (this) { @@ -100,7 +100,7 @@ public class Broadcaster /** * Unregister for notifications for this senderWhat/target/targetWhat tuple. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void cancelRequest(int senderWhat, Handler target, int targetWhat) { synchronized (this) { @@ -173,7 +173,7 @@ public class Broadcaster * Send out msg. Anyone who has registered via the request() method will be * sent the message. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void broadcast(Message msg) { synchronized (this) { diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index f8f8bf746afd..1c1f5c034cd9 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -174,7 +174,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static Bundle forPair(String key, String value) { Bundle b = new Bundle(1); b.putString(key, value); @@ -306,7 +306,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getSize() { if (mParcelledData != null) { return mParcelledData.dataSize(); @@ -389,7 +389,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * Filter values in Bundle to only basic types. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Bundle filterValues() { unparcel(); Bundle bundle = this; diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 4fed93204f59..a4af0dbed0bd 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -88,7 +88,7 @@ public final class Debug // set/cleared by waitForDebugger() private static volatile boolean mWaiting = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Debug() {} /* @@ -120,7 +120,7 @@ public final class Debug @UnsupportedAppUsage public int dalvikSwappablePss; /** @hide The resident set size for dalvik heap. (Without other Dalvik overhead.) */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int dalvikRss; /** The private dirty pages used by dalvik heap. */ public int dalvikPrivateDirty; @@ -140,7 +140,7 @@ public final class Debug public int dalvikSwappedOut; /** The dirty dalvik pages that have been swapped out, proportional. */ /** @hide We may want to expose this, eventually. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int dalvikSwappedOutPss; /** The proportional set size for the native heap. */ @@ -150,7 +150,7 @@ public final class Debug @UnsupportedAppUsage public int nativeSwappablePss; /** @hide The resident set size for the native heap. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int nativeRss; /** The private dirty pages used by the native heap. */ public int nativePrivateDirty; @@ -170,7 +170,7 @@ public final class Debug public int nativeSwappedOut; /** The dirty native pages that have been swapped out, proportional. */ /** @hide We may want to expose this, eventually. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int nativeSwappedOutPss; /** The proportional set size for everything else. */ @@ -180,7 +180,7 @@ public final class Debug @UnsupportedAppUsage public int otherSwappablePss; /** @hide The resident set size for everything else. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int otherRss; /** The private dirty pages used by everything else. */ public int otherPrivateDirty; @@ -200,12 +200,12 @@ public final class Debug public int otherSwappedOut; /** The dirty pages used by anyting else that have been swapped out, proportional. */ /** @hide We may want to expose this, eventually. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int otherSwappedOutPss; /** Whether the kernel reports proportional swap usage */ /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean hasSwappedOutPss; /** @hide */ @@ -2042,7 +2042,7 @@ public final class Debug * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static native void dumpNativeHeap(FileDescriptor fd); /** diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 5745187fcbb9..518e29d51091 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -719,7 +719,7 @@ public class Environment { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static File getLegacyExternalStorageObbDirectory() { return buildPath(getLegacyExternalStorageDirectory(), DIR_ANDROID, DIR_OBB); } @@ -1040,7 +1040,7 @@ public class Environment { * Generates the raw path to an application's OBB files * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static File[] buildExternalStorageAppObbDirs(String packageName) { throwIfUserRequired(); return sCurrentUser.buildExternalStorageAppObbDirs(packageName); diff --git a/core/java/android/os/FileObserver.java b/core/java/android/os/FileObserver.java index 25bffbc9e8d5..6f44b20a0ff4 100644 --- a/core/java/android/os/FileObserver.java +++ b/core/java/android/os/FileObserver.java @@ -145,7 +145,7 @@ public abstract class FileObserver { stopWatching(m_fd, descriptors); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onEvent(int wfd, @NotifyEventType int mask, String path) { // look up our observer, fixing up the map if necessary... FileObserver observer = null; diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index bbafc7b0875a..d151c16061d9 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -189,7 +189,7 @@ public final class FileUtils { * @return 0 on success, otherwise errno. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int setPermissions(FileDescriptor fd, int mode, int uid, int gid) { try { Os.fchmod(fd, mode); @@ -672,7 +672,7 @@ public final class FileUtils { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void stringToFile(File file, String string) throws IOException { stringToFile(file.getAbsolutePath(), string); } @@ -721,7 +721,7 @@ public final class FileUtils { * to its potential for collision. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Deprecated public static long checksumCrc32(File file) throws FileNotFoundException, IOException { CRC32 checkSummer = new CRC32(); @@ -808,7 +808,7 @@ public final class FileUtils { * @return if any files were deleted. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean deleteOlderFiles(File dir, int minCount, long minAgeMs) { if (minCount < 0 || minAgeMs < 0) { throw new IllegalArgumentException("Constraints must be positive or 0"); @@ -917,7 +917,7 @@ public final class FileUtils { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean deleteContents(File dir) { File[] files = dir.listFiles(); boolean success = true; diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index 24aaa583f542..d310d6e7530d 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -189,7 +189,7 @@ public class Handler { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Handler(boolean async) { this(null, async); } @@ -297,7 +297,7 @@ public class Handler { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @NonNull public static Handler getMain() { if (MAIN_THREAD_HANDLER == null) { diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java index 0d2bfdf04905..feed20800fd4 100644 --- a/core/java/android/os/HwBinder.java +++ b/core/java/android/os/HwBinder.java @@ -159,7 +159,7 @@ public abstract class HwBinder implements IHwBinder { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) public static void reportSyspropChanged() { native_report_sysprop_change(); } diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 8a8a6af09e5f..d91c458a474b 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -150,7 +150,7 @@ public interface IBinder { int LIKE_TRANSACTION = ('_'<<24)|('L'<<16)|('I'<<8)|'K'; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int SYSPROPS_TRANSACTION = ('_'<<24)|('S'<<16)|('P'<<8)|'R'; /** diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 8f8d451bbe8e..e1d900528f07 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -68,7 +68,7 @@ interface INetworkManagementService /** * Clear all IP addresses on the specified interface */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void clearInterfaceAddresses(String iface); /** @@ -84,26 +84,26 @@ interface INetworkManagementService /** * Set interface IPv6 privacy extensions */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable); /** * Disable IPv6 on an interface */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void disableIpv6(String iface); /** * Enable IPv6 on an interface */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void enableIpv6(String iface); /** * Set IPv6 autoconf address generation mode. * This is a no-op if an unsupported mode is requested. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setIPv6AddrGenMode(String iface, int mode); /** @@ -117,11 +117,6 @@ interface INetworkManagementService void removeRoute(int netId, in RouteInfo route); /** - * Set the specified MTU size - */ - void setMtu(String iface, int mtu); - - /** * Shuts down the service */ void shutdown(); @@ -296,7 +291,7 @@ interface INetworkManagementService /** * Return status of bandwidth control module. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isBandwidthControlEnabled(); /** @@ -350,28 +345,8 @@ interface INetworkManagementService */ boolean isNetworkActive(); - /** - * Add an interface to a network. - */ - void addInterfaceToNetwork(String iface, int netId); - - /** - * Remove an Interface from a network. - */ - void removeInterfaceFromNetwork(String iface, int netId); - void addLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid); - void setDefaultNetId(int netId); - void clearDefaultNetId(); - - /** - * Set permission for a network. - * @param permission PERMISSION_NONE to clear permissions. - * PERMISSION_NETWORK or PERMISSION_SYSTEM to set permission. - */ - void setNetworkPermission(int netId, int permission); - /** * Allow UID to call protect(). */ diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index e996809f1299..90cbac50b391 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -45,7 +45,7 @@ interface IPowerManager @UnsupportedAppUsage void userActivity(long time, int event, int flags); void wakeUp(long time, int reason, String details, String opPackageName); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void goToSleep(long time, int reason, int flags); @UnsupportedAppUsage(maxTargetSdk = 28) void nap(long time); diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index ee64551df226..cfa823cffe86 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -546,7 +546,7 @@ public final class LocaleList implements Parcelable { * * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void setDefault(@NonNull @Size(min=1) LocaleList locales, int localeIndex) { if (locales == null) { throw new NullPointerException("locales is null"); diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index c39fd4d1bc43..8c98362fa909 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -44,7 +44,7 @@ import android.util.proto.ProtoOutputStream; * public void run() { * Looper.prepare(); * - * mHandler = new Handler() { + * mHandler = new Handler(Looper.myLooper()) { * public void handleMessage(Message msg) { * // process incoming messages here * } diff --git a/core/java/android/os/MemoryFile.java b/core/java/android/os/MemoryFile.java index f84f9f05b13e..95337f6a1b1e 100644 --- a/core/java/android/os/MemoryFile.java +++ b/core/java/android/os/MemoryFile.java @@ -41,7 +41,7 @@ public class MemoryFile { private static String TAG = "MemoryFile"; // Returns 'true' if purged, 'false' otherwise - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native boolean native_pin(FileDescriptor fd, boolean pin) throws IOException; @UnsupportedAppUsage private static native int native_get_size(FileDescriptor fd) throws IOException; diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index 7213b067a691..87c4f331e93f 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -266,7 +266,7 @@ public final class MessageQueue { } // Called from native code. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int dispatchEvents(int fd, int events) { // Get the file descriptor record and any state that might change. final FileDescriptorRecord record; @@ -635,7 +635,7 @@ public final class MessageQueue { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean hasMessages(Handler h, Runnable r, Object object) { if (h == null) { return false; diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 765ef48308ae..a04fcb580e63 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -514,11 +514,11 @@ public final class Parcel { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static native long getGlobalAllocSize(); /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static native long getGlobalAllocCount(); /** @@ -742,7 +742,7 @@ public final class Parcel { * {@hide} * {@SystemApi} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final void writeBlob(@Nullable byte[] b) { writeBlob(b, 0, (b != null) ? b.length : 0); } @@ -1014,7 +1014,7 @@ public final class Parcel { /** * @hide For testing only. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void writeArrayMap(@Nullable ArrayMap<String, Object> val) { writeArrayMapInternal(val); } @@ -1053,7 +1053,7 @@ public final class Parcel { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void writeArraySet(@Nullable ArraySet<? extends Object> val) { final int size = (val != null) ? val.size() : -1; writeInt(size); @@ -2719,7 +2719,7 @@ public final class Parcel { * {@hide} * {@SystemApi} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Nullable public final byte[] readBlob() { return nativeReadBlob(mNativePtr); @@ -3633,7 +3633,7 @@ public final class Parcel { /** * @hide For testing only. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void readArrayMap(@NonNull ArrayMap outVal, @Nullable ClassLoader loader) { final int N = readInt(); if (N < 0) { diff --git a/core/java/android/os/ParcelableParcel.java b/core/java/android/os/ParcelableParcel.java index 38d980ecb0f1..3be630f2b382 100644 --- a/core/java/android/os/ParcelableParcel.java +++ b/core/java/android/os/ParcelableParcel.java @@ -27,7 +27,7 @@ public class ParcelableParcel implements Parcelable { final Parcel mParcel; final ClassLoader mClassLoader; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ParcelableParcel(ClassLoader loader) { mParcel = Parcel.obtain(); mClassLoader = loader; @@ -46,13 +46,13 @@ public class ParcelableParcel implements Parcelable { mParcel.appendFrom(src, pos, size); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Parcel getParcel() { mParcel.setDataPosition(0); return mParcel; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ClassLoader getClassLoader() { return mClassLoader; } @@ -68,7 +68,7 @@ public class ParcelableParcel implements Parcelable { dest.appendFrom(mParcel, 0, mParcel.dataSize()); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Parcelable.ClassLoaderCreator<ParcelableParcel> CREATOR = new Parcelable.ClassLoaderCreator<ParcelableParcel>() { public ParcelableParcel createFromParcel(Parcel in) { diff --git a/core/java/android/os/PerformanceCollector.java b/core/java/android/os/PerformanceCollector.java index 27de48d40188..e6471ae1c00a 100644 --- a/core/java/android/os/PerformanceCollector.java +++ b/core/java/android/os/PerformanceCollector.java @@ -364,7 +364,7 @@ public class PerformanceCollector { * @param label description of code block between startTiming and * stopTiming, used to label output */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void startTiming(String label) { if (mPerfWriter != null) mPerfWriter.writeStartTiming(label); @@ -414,7 +414,7 @@ public class PerformanceCollector { * between calls to startTiming and stopTiming. List of iterations * is keyed by {@link #METRIC_KEY_ITERATIONS iterations}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Bundle stopTiming(String label) { addIteration(label); if (mPerfWriter != null) diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index e736e30b51e5..d130bc5d37e7 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1014,7 +1014,7 @@ public final class PowerManager { * Gets a float screen brightness setting. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public float getBrightnessConstraint(int constraint) { try { return mService.getBrightnessConstraint(constraint); @@ -2304,7 +2304,7 @@ public final class PowerManager { * This broadcast is only sent to registered receivers. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED = "android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED"; diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index e62ad1fa9052..8048b9df6097 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -71,7 +71,7 @@ public class Process { * Defines the UID/GID for the log group. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int LOG_UID = 1007; /** @@ -84,14 +84,14 @@ public class Process { * Defines the UID/GID for the mediaserver process. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int MEDIA_UID = 1013; /** * Defines the UID/GID for the DRM process. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int DRM_UID = 1019; /** @@ -104,7 +104,7 @@ public class Process { * Defines the UID/GID for the group that controls VPN services. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int VPN_UID = 1016; /** @@ -123,7 +123,7 @@ public class Process { * Defines the UID/GID for the NFC service process. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int NFC_UID = 1027; /** @@ -277,7 +277,7 @@ public class Process { * First uid used for fully isolated sandboxed processes (with no permissions of their own) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final int FIRST_ISOLATED_UID = 99000; @@ -285,7 +285,7 @@ public class Process { * Last uid used for fully isolated sandboxed processes (with no permissions of their own) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final int LAST_ISOLATED_UID = 99999; @@ -725,7 +725,7 @@ public class Process { * Returns the identifier of this process' parent. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(trackingBug = 171962076) public static final int myPpid() { return Os.getppid(); } @@ -1165,38 +1165,38 @@ public class Process { public static final native int[] getPids(String path, int[] lastArray); /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_TERM_MASK = 0xff; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_ZERO_TERM = 0; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_SPACE_TERM = (int)' '; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_TAB_TERM = (int)'\t'; /** @hide */ public static final int PROC_NEWLINE_TERM = (int) '\n'; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_COMBINE = 0x100; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_PARENS = 0x200; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_QUOTES = 0x400; /** @hide */ public static final int PROC_CHAR = 0x800; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_OUT_STRING = 0x1000; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_OUT_LONG = 0x2000; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROC_OUT_FLOAT = 0x4000; /** diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 8cdcd49cb2cc..13b30f43ff7a 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -908,7 +908,11 @@ public class RecoverySystem { Intent intent = new Intent(ACTION_EUICC_FACTORY_RESET); intent.setPackage(packageName); PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser( - context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM); + context, + 0, + intent, + PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT, + UserHandle.SYSTEM); IntentFilter filterConsent = new IntentFilter(); filterConsent.addAction(ACTION_EUICC_FACTORY_RESET); HandlerThread euiccHandlerThread = new HandlerThread("euiccWipeFinishReceiverThread"); @@ -1002,7 +1006,11 @@ public class RecoverySystem { Intent intent = new Intent(ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS); intent.setPackage(PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK); PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser( - context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM); + context, + 0, + intent, + PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT, + UserHandle.SYSTEM); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS); HandlerThread euiccHandlerThread = diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java index 35e7bad83736..71344f90de75 100644 --- a/core/java/android/os/ServiceManager.java +++ b/core/java/android/os/ServiceManager.java @@ -190,7 +190,7 @@ public final class ServiceManager { * @param dumpPriority supported dump priority levels as a bitmask * to access this service */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) { try { diff --git a/core/java/android/os/ShellCommand.java b/core/java/android/os/ShellCommand.java index 0be3d681c80a..3358ce13ed52 100644 --- a/core/java/android/os/ShellCommand.java +++ b/core/java/android/os/ShellCommand.java @@ -98,7 +98,7 @@ public abstract class ShellCommand extends BasicShellCommandHandler { return super.handleDefaultCommands(cmd); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String peekNextArg() { return super.peekNextArg(); } diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java index 6d1a1164abb4..eb8e71761294 100644 --- a/core/java/android/os/StatFs.java +++ b/core/java/android/os/StatFs.java @@ -26,7 +26,7 @@ import android.system.StructStatVfs; * wrapper for Unix statvfs(). */ public class StatFs { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private StructStatVfs mStat; /** diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 0fba8950cf15..c89adadfbf2d 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -2381,7 +2381,7 @@ public final class StrictMode { * Binder for its current (native) thread-local policy value and synchronize it to libcore's * (Java) thread-local policy value. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void onBinderStrictModePolicyChange(@ThreadPolicyMask int newPolicy) { setBlockGuardPolicy(newPolicy); } @@ -2621,7 +2621,7 @@ public final class StrictMode { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void incrementExpectedActivityCount(Class klass) { if (klass == null) { return; diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java index 26f3af0c68bb..e29d75611856 100644 --- a/core/java/android/os/SystemClock.java +++ b/core/java/android/os/SystemClock.java @@ -247,7 +247,7 @@ public final class SystemClock { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @CriticalNative public static native long currentThreadTimeMicro(); diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java index a16452705efc..ded9be5eb74a 100644 --- a/core/java/android/os/SystemProperties.java +++ b/core/java/android/os/SystemProperties.java @@ -60,7 +60,7 @@ public class SystemProperties { * uses reflection to read this whenever text is selected (http://b/36095274). * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int PROP_NAME_MAX = Integer.MAX_VALUE; /** @hide */ @@ -256,7 +256,7 @@ public class SystemProperties { * @param callback The {@link Runnable} that should be removed. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void removeChangeCallback(@NonNull Runnable callback) { synchronized (sChangeCallbacks) { if (sChangeCallbacks.contains(callback)) { diff --git a/core/java/android/os/SystemService.java b/core/java/android/os/SystemService.java index 5871d2d9b58f..9b0ac8fdeb7a 100644 --- a/core/java/android/os/SystemService.java +++ b/core/java/android/os/SystemService.java @@ -66,7 +66,7 @@ public class SystemService { } /** Request that the init daemon stop a named service. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void stop(String name) { SystemProperties.set("ctl.stop", name); } diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java index 58c8efa3a972..9c9e4995d673 100644 --- a/core/java/android/os/Trace.java +++ b/core/java/android/os/Trace.java @@ -52,7 +52,7 @@ public final class Trace { /** @hide */ public static final long TRACE_TAG_INPUT = 1L << 2; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final long TRACE_TAG_VIEW = 1L << 3; /** @hide */ public static final long TRACE_TAG_WEBVIEW = 1L << 4; diff --git a/core/java/android/os/UpdateLock.java b/core/java/android/os/UpdateLock.java index 036d0951c19a..5aa9401ddb27 100644 --- a/core/java/android/os/UpdateLock.java +++ b/core/java/android/os/UpdateLock.java @@ -51,7 +51,7 @@ public class UpdateLock { * locker releases theirs. The broadcast is sticky but is sent only to * registered receivers. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String UPDATE_LOCK_CHANGED = "android.os.UpdateLock.UPDATE_LOCK_CHANGED"; /** @@ -60,7 +60,7 @@ public class UpdateLock { * update operation. True means that updates are okay right now; false indicates * that perhaps later would be a better time. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String NOW_IS_CONVENIENT = "nowisconvenient"; /** @@ -69,7 +69,7 @@ public class UpdateLock { * in the System.currentTimeMillis() time base, which may be non-monotonic especially * around reboots. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String TIMESTAMP = "timestamp"; /** @@ -94,7 +94,7 @@ public class UpdateLock { /** * Is this lock currently held? */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isHeld() { synchronized (mToken) { return mHeld; @@ -104,7 +104,7 @@ public class UpdateLock { /** * Acquire an update lock. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void acquire() { if (DEBUG) { Log.v(TAG, "acquire() : " + this, new RuntimeException("here")); @@ -131,7 +131,7 @@ public class UpdateLock { /** * Release this update lock. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void release() { if (DEBUG) Log.v(TAG, "release() : " + this, new RuntimeException("here")); checkService(); diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index d39c5328e330..d6720248720a 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -100,7 +100,7 @@ public final class UserHandle implements Parcelable { public static final @UserIdInt int USER_SYSTEM = 0; /** @hide A user serial constant to indicate the "system" user of the device */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int USER_SERIAL_SYSTEM = 0; /** @hide A user handle to indicate the "system" user of the device */ @@ -136,22 +136,22 @@ public final class UserHandle implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int ERR_GID = -1; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int AID_ROOT = android.os.Process.ROOT_UID; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int AID_APP_START = android.os.Process.FIRST_APPLICATION_UID; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int AID_APP_END = android.os.Process.LAST_APPLICATION_UID; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int AID_SHARED_GID_START = android.os.Process.FIRST_SHARED_APPLICATION_GID; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int AID_CACHE_GID_START = android.os.Process.FIRST_APPLICATION_CACHE_GID; /** The userId represented by this UserHandle. */ diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index b0e76e3ea851..2edd3227cf36 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -67,7 +67,7 @@ import java.util.Set; /** * Manages users and user details on a multi-user system. There are two major categories of - * users: fully customizable users with their own login, and managed profiles that share a workspace + * users: fully customizable users with their own login, and profiles that share a workspace * with a related user. * <p> * Users are different from accounts, which are managed by @@ -1020,7 +1020,7 @@ public class UserManager { * @see #getUserRestrictions() * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String DISALLOW_RECORD_AUDIO = "no_record_audio"; /** @@ -1704,7 +1704,7 @@ public class UserManager { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean canSwitchUsers() { boolean allowUserSwitchingWhenSystemUserLocked = Settings.Global.getInt( mContext.getContentResolver(), @@ -2066,7 +2066,7 @@ public class UserManager { * @return whether user is a guest user. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS}) public boolean isGuestUser(@UserIdInt int userId) { @@ -2298,7 +2298,7 @@ public class UserManager { * private app data storage is available. * <p>Requires {@code android.permission.MANAGE_USERS} or * {@code android.permission.INTERACT_ACROSS_USERS}, otherwise specified {@link UserHandle user} - * must be the calling user or a managed profile associated with it. + * must be the calling user or a profile associated with it. * * @param user to retrieve the unlocked state for. * @see Intent#ACTION_USER_UNLOCKED @@ -2397,7 +2397,7 @@ public class UserManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getUserStartRealtime() { try { return mService.getUserStartRealtime(); @@ -2412,7 +2412,7 @@ public class UserManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getUserUnlockRealtime() { try { return mService.getUserUnlockRealtime(); @@ -2496,7 +2496,7 @@ public class UserManager { * * <p>Requires {@code android.permission.MANAGE_USERS} or * {@code android.permission.INTERACT_ACROSS_USERS}, otherwise specified {@link UserHandle user} - * must be the calling user or a managed profile associated with it. + * must be the calling user or a profile associated with it. */ @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_USERS, @@ -2620,7 +2620,7 @@ public class UserManager { * * <p>Requires {@code android.permission.MANAGE_USERS} or * {@code android.permission.INTERACT_ACROSS_USERS}, otherwise specified {@link UserHandle user} - * must be the calling user or a managed profile associated with it. + * must be the calling user or a profile associated with it. * * @hide */ @@ -3429,6 +3429,7 @@ public class UserManager { * Returns list of the profiles of userId including userId itself. * Note that this returns both enabled and not enabled profiles. See * {@link #getEnabledProfiles(int)} if you need only the enabled ones. + * <p>Note that this includes all profile types (not including Restricted profiles). * * <p>Requires {@link android.Manifest.permission#MANAGE_USERS}. * {@link android.Manifest.permission#CREATE_USERS} suffices if userId is the calling user. @@ -3481,6 +3482,7 @@ public class UserManager { /** * Returns list of the profiles of userId including userId itself. * Note that this returns only enabled. + * <p>Note that this includes all profile types (not including Restricted profiles). * * <p>Requires {@link android.Manifest.permission#MANAGE_USERS}. * {@link android.Manifest.permission#CREATE_USERS} suffices if userId is the calling user. @@ -3502,6 +3504,7 @@ public class UserManager { /** * Returns a list of UserHandles for profiles associated with the user that the calling process * is running on, including the user itself. + * <p>Note that this includes all profile types (not including Restricted profiles). * * @return A non-empty list of UserHandles associated with the calling user. */ @@ -3517,6 +3520,7 @@ public class UserManager { /** * Returns a list of ids for enabled profiles associated with the context user including the * user itself. + * <p>Note that this includes all profile types (not including Restricted profiles). * * @return A non-empty list of UserHandles associated with the calling user. * @hide @@ -3532,6 +3536,7 @@ public class UserManager { /** * Returns a list of ids for all profiles associated with the context user including the user * itself. + * <p>Note that this includes all profile types (not including Restricted profiles). * * @return A non-empty list of UserHandles associated with the calling user. * @hide @@ -3547,6 +3552,7 @@ public class UserManager { /** * Returns a list of ids for profiles associated with the context user including the user * itself. + * <p>Note that this includes all profile types (not including Restricted profiles). * * @param enabledOnly whether to return only {@link UserInfo#isEnabled() enabled} profiles * @return A non-empty list of UserHandles associated with the calling user. @@ -3566,6 +3572,7 @@ public class UserManager { /** * Returns a list of ids for profiles associated with the specified user including the user * itself. + * <p>Note that this includes all profile types (not including Restricted profiles). * * @param userId id of the user to return profiles for * @param enabledOnly whether return only {@link UserInfo#isEnabled() enabled} profiles @@ -4220,7 +4227,7 @@ public class UserManager { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isDeviceInDemoMode(Context context) { return Settings.Global.getInt(context.getContentResolver(), Settings.Global.DEVICE_DEMO_MODE, 0) > 0; @@ -4355,8 +4362,9 @@ public class UserManager { } /** - * Returns creation time of the user or of a managed profile associated with the calling user. - * @param userHandle user handle of the user or a managed profile associated with the + * Returns creation time of the given user. The given user must be the calling user or + * a profile associated with it. + * @param userHandle user handle of the calling user or a profile associated with the * calling user. * @return creation time in milliseconds since Epoch time. */ diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java index 21ad38b0e371..f82cc22bd764 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -85,7 +85,7 @@ public abstract class VibrationEffect implements Parcelable { * @see #get(int) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final int EFFECT_THUD = Effect.THUD; @@ -94,7 +94,7 @@ public abstract class VibrationEffect implements Parcelable { * @see #get(int) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final int EFFECT_POP = Effect.POP; @@ -135,7 +135,7 @@ public abstract class VibrationEffect implements Parcelable { * @see #get(Uri, Context) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final int[] RINGTONES = { Effect.RINGTONE_1, @@ -567,7 +567,7 @@ public abstract class VibrationEffect implements Parcelable { out.writeInt(mAmplitude); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Parcelable.Creator<OneShot> CREATOR = new Parcelable.Creator<OneShot>() { @Override diff --git a/core/java/android/os/health/HealthStatsParceler.java b/core/java/android/os/health/HealthStatsParceler.java index f28a9747bc44..eb864a4c3d3f 100644 --- a/core/java/android/os/health/HealthStatsParceler.java +++ b/core/java/android/os/health/HealthStatsParceler.java @@ -18,6 +18,7 @@ package android.os.health; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -38,7 +39,7 @@ public class HealthStatsParceler implements Parcelable { private HealthStatsWriter mWriter; private HealthStats mHealthStats; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Parcelable.Creator<HealthStatsParceler> CREATOR = new Parcelable.Creator<HealthStatsParceler>() { public HealthStatsParceler createFromParcel(Parcel in) { diff --git a/core/java/android/os/health/SystemHealthManager.java b/core/java/android/os/health/SystemHealthManager.java index 6e259ea2642c..8181911ec783 100644 --- a/core/java/android/os/health/SystemHealthManager.java +++ b/core/java/android/os/health/SystemHealthManager.java @@ -52,7 +52,7 @@ public class SystemHealthManager { * Construct a new SystemHealthManager object. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public SystemHealthManager() { this(IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME))); } diff --git a/core/java/android/os/storage/StorageEventListener.java b/core/java/android/os/storage/StorageEventListener.java index 9fd9e4e4067d..694ff19f7dad 100644 --- a/core/java/android/os/storage/StorageEventListener.java +++ b/core/java/android/os/storage/StorageEventListener.java @@ -17,6 +17,7 @@ package android.os.storage; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * Used for receiving notifications from the StorageManager @@ -47,23 +48,23 @@ public class StorageEventListener { public void onStorageStateChanged(String path, String oldState, String newState) { } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onVolumeRecordChanged(VolumeRecord rec) { } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onVolumeForgotten(String fsUuid) { } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onDiskScanned(DiskInfo disk, int volumeCount) { } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onDiskDestroyed(DiskInfo disk) { } } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 270115beb09b..5d3c66cc3f34 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -60,6 +60,7 @@ import android.content.res.ObbScanner; import android.database.Cursor; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Environment; import android.os.FileUtils; import android.os.Handler; @@ -287,7 +288,7 @@ public class StorageManager { public static final int FSTRIM_FLAG_DEEP = IVold.FSTRIM_FLAG_DEEP_TRIM; /** @hide The volume is not encrypted. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int ENCRYPTION_STATE_NONE = IVold.ENCRYPTION_STATE_NONE; @@ -627,7 +628,7 @@ public class StorageManager { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void enableUsbMassStorage() { } @@ -637,7 +638,7 @@ public class StorageManager { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void disableUsbMassStorage() { } @@ -648,7 +649,7 @@ public class StorageManager { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isUsbMassStorageConnected() { return false; } @@ -804,7 +805,7 @@ public class StorageManager { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable VolumeInfo findVolumeById(String id) { Preconditions.checkNotNull(id); // TODO; go directly to service to make this faster @@ -1025,7 +1026,7 @@ public class StorageManager { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void format(String volId) { try { mStorageManager.format(volId); @@ -1067,7 +1068,7 @@ public class StorageManager { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void partitionPublic(String diskId) { try { mStorageManager.partitionPublic(diskId); @@ -1229,7 +1230,7 @@ public class StorageManager { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static @Nullable StorageVolume getStorageVolume(StorageVolume[] volumes, File file) { if (file == null) { return null; @@ -1477,7 +1478,7 @@ public class StorageManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getStorageFullBytes(File path) { return Settings.Global.getLong(mResolver, Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES, DEFAULT_FULL_THRESHOLD_BYTES); @@ -1594,7 +1595,7 @@ public class StorageManager { * @return true for file encrypted. (Implies isEncrypted() == true) * false not encrypted or block encrypted */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isFileEncryptedNativeOnly() { if (!isEncrypted()) { return false; @@ -2676,10 +2677,10 @@ public class StorageManager { /// Consts to match the password types in cryptfs.h /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int CRYPT_TYPE_PASSWORD = IVold.PASSWORD_TYPE_PASSWORD; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int CRYPT_TYPE_DEFAULT = IVold.PASSWORD_TYPE_DEFAULT; /** @hide */ public static final int CRYPT_TYPE_PATTERN = IVold.PASSWORD_TYPE_PATTERN; diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index eed36d714653..a52eeccaca64 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -327,7 +327,7 @@ public final class StorageVolume implements Parcelable { * parse or UUID is unknown. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getFatVolumeId() { if (mFsUuid == null || mFsUuid.length() != 9) { return -1; diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index 74c0ecb2ecc3..901494b845b0 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.net.Uri; +import android.os.Build; import android.os.Environment; import android.os.IVold; import android.os.Parcel; @@ -179,7 +180,7 @@ public class VolumeInfo implements Parcelable { this.partGuid = partGuid; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public VolumeInfo(Parcel parcel) { id = parcel.readString8(); type = parcel.readInt(); @@ -312,7 +313,7 @@ public class VolumeInfo implements Parcelable { * Returns {@code true} if this volume is the primary emulated volume for {@code userId}, * {@code false} otherwise. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isPrimaryEmulatedForUser(int userId) { return id.equals(ID_EMULATED_INTERNAL + ";" + userId); } @@ -321,7 +322,7 @@ public class VolumeInfo implements Parcelable { return isVisibleForUser(userId); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isVisibleForWrite(int userId) { return isVisibleForUser(userId); } @@ -331,7 +332,7 @@ public class VolumeInfo implements Parcelable { return (path != null) ? new File(path) : null; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public File getInternalPath() { return (internalPath != null) ? new File(internalPath) : null; } @@ -533,7 +534,7 @@ public class VolumeInfo implements Parcelable { return id.hashCode(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Creator<VolumeInfo> CREATOR = new Creator<VolumeInfo>() { @Override public VolumeInfo createFromParcel(Parcel in) { diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java index 0f58a714749b..ee67ca6b7cd0 100644 --- a/core/java/android/os/storage/VolumeRecord.java +++ b/core/java/android/os/storage/VolumeRecord.java @@ -19,6 +19,7 @@ package android.os.storage; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; @@ -60,7 +61,7 @@ public class VolumeRecord implements Parcelable { this.fsUuid = Preconditions.checkNotNull(fsUuid); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public VolumeRecord(Parcel parcel) { type = parcel.readInt(); fsUuid = parcel.readString(); @@ -163,7 +164,7 @@ public class VolumeRecord implements Parcelable { return fsUuid.hashCode(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Creator<VolumeRecord> CREATOR = new Creator<VolumeRecord>() { @Override public VolumeRecord createFromParcel(Parcel in) { diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java index ae4a626cdd5d..53b1dab9f760 100644 --- a/core/java/android/preference/PreferenceActivity.java +++ b/core/java/android/preference/PreferenceActivity.java @@ -31,6 +31,7 @@ import android.content.Intent; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -728,7 +729,7 @@ public abstract class PreferenceActivity extends ListActivity implements * Returns the Header list * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public List<Header> getHeaders() { return mHeaders; } diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java index 3f6e5051a3f8..22399f517908 100644 --- a/core/java/android/preference/PreferenceFragment.java +++ b/core/java/android/preference/PreferenceFragment.java @@ -24,6 +24,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.TypedArray; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -103,7 +104,7 @@ public abstract class PreferenceFragment extends Fragment implements private static final String PREFERENCES_TAG = "android:preferences"; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private PreferenceManager mPreferenceManager; private ListView mList; private boolean mHavePrefs; diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java index 01fe2f3f6b3a..6b813b0c04f6 100644 --- a/core/java/android/preference/PreferenceScreen.java +++ b/core/java/android/preference/PreferenceScreen.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -102,7 +103,7 @@ public final class PreferenceScreen extends PreferenceGroup implements AdapterVi private Dialog mDialog; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private ListView mListView; private int mLayoutResId = com.android.internal.R.layout.preference_list_fragment; diff --git a/core/java/android/preference/SeekBarPreference.java b/core/java/android/preference/SeekBarPreference.java index a2852bc2cce3..e31165e6adcc 100644 --- a/core/java/android/preference/SeekBarPreference.java +++ b/core/java/android/preference/SeekBarPreference.java @@ -19,6 +19,7 @@ package android.preference; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; @@ -73,7 +74,7 @@ public class SeekBarPreference extends Preference this(context, attrs, com.android.internal.R.attr.seekBarPreferenceStyle); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public SeekBarPreference(Context context) { this(context, null); } diff --git a/core/java/android/preference/SwitchPreference.java b/core/java/android/preference/SwitchPreference.java index baa023e41aad..57fefda35de3 100644 --- a/core/java/android/preference/SwitchPreference.java +++ b/core/java/android/preference/SwitchPreference.java @@ -20,6 +20,7 @@ import android.annotation.StringRes; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; +import android.os.Build; import android.util.AttributeSet; import android.view.View; import android.widget.Checkable; @@ -45,7 +46,7 @@ import android.widget.Switch; */ @Deprecated public class SwitchPreference extends TwoStatePreference { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final Listener mListener = new Listener(); // Switch text for on and off states diff --git a/core/java/android/provider/BrowserContract.java b/core/java/android/provider/BrowserContract.java index 5083b8b254ab..7d77d37e117b 100644 --- a/core/java/android/provider/BrowserContract.java +++ b/core/java/android/provider/BrowserContract.java @@ -27,6 +27,7 @@ import android.content.Context; import android.database.Cursor; import android.graphics.BitmapFactory; import android.net.Uri; +import android.os.Build; import android.os.RemoteException; import android.util.Pair; @@ -47,7 +48,7 @@ public class BrowserContract { public static final String AUTHORITY = "com.android.browser"; /** A content:// style uri to the authority for the browser provider */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY); /** @@ -303,7 +304,7 @@ public class BrowserContract { * The content:// style URI for the default folder * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Uri CONTENT_URI_DEFAULT_FOLDER = Uri.withAppendedPath(CONTENT_URI, "folder"); @@ -324,7 +325,7 @@ public class BrowserContract { * @param folderId the ID of the folder to point to * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Uri buildFolderUri(long folderId) { return ContentUris.withAppendedId(CONTENT_URI_DEFAULT_FOLDER, folderId); } @@ -412,7 +413,7 @@ public class BrowserContract { /** * Directory under {@link Bookmarks#CONTENT_URI} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Uri CONTENT_URI = AUTHORITY_URI.buildUpon().appendPath("accounts").build(); @@ -450,7 +451,7 @@ public class BrowserContract { /** * The content:// style URI for this table */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "history"); /** @@ -580,7 +581,7 @@ public class BrowserContract { /** * The content:// style URI for this table */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "images"); /** @@ -681,7 +682,7 @@ public class BrowserContract { /** * The content:// style URI for this table */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "combined"); /** diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java index 8ac1d84e04e4..1ee2f19038db 100644 --- a/core/java/android/provider/CalendarContract.java +++ b/core/java/android/provider/CalendarContract.java @@ -38,6 +38,7 @@ import android.content.Intent; import android.database.Cursor; import android.database.DatabaseUtils; import android.net.Uri; +import android.os.Build; import android.os.RemoteException; import android.text.format.DateUtils; import android.text.format.TimeMigrationUtils; @@ -1825,7 +1826,7 @@ public final class CalendarContract { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String[] PROVIDER_WRITABLE_COLUMNS = new String[] { ACCOUNT_NAME, ACCOUNT_TYPE, @@ -1860,7 +1861,7 @@ public final class CalendarContract { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String[] SYNC_WRITABLE_COLUMNS = new String[] { _SYNC_ID, @@ -2512,7 +2513,7 @@ public final class CalendarContract { * if no such alarm exists. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final long findNextAlarmTime(ContentResolver cr, long millis) { String selection = ALARM_TIME + ">=" + millis; // TODO: construct an explicit SQL query so that we can add @@ -2546,7 +2547,7 @@ public final class CalendarContract { * @param manager the AlarmManager * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final void rescheduleMissedAlarms(ContentResolver cr, Context context, AlarmManager manager) { // Get all the alerts that have been scheduled but have not fired @@ -2603,7 +2604,7 @@ public final class CalendarContract { * epoch * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void scheduleAlarm(Context context, AlarmManager manager, long alarmTime) { if (DEBUG) { String schedTime = TimeMigrationUtils.formatMillisWithFixedFormat(alarmTime); diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index c3b6d8e2cfe3..105ffaa4718e 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -17,6 +17,7 @@ package android.provider; +import android.annotation.LongDef; import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentProvider; import android.content.ContentResolver; @@ -43,6 +44,8 @@ import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.util.Log; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.List; /** @@ -611,6 +614,144 @@ public class CallLog { */ public static final String BLOCK_REASON = "block_reason"; + /** @hide */ + @LongDef(flag = true, value = { + MISSED_REASON_NOT_MISSED, + AUTO_MISSED_EMERGENCY_CALL, + AUTO_MISSED_MAXIMUM_RINGING, + AUTO_MISSED_MAXIMUM_DIALING, + USER_MISSED_NO_ANSWER, + USER_MISSED_SHORT_RING, + USER_MISSED_DND_MODE, + USER_MISSED_LOW_RING_VOLUME, + USER_MISSED_NO_VIBRATE, + USER_MISSED_CALL_SCREENING_SERVICE_SILENCED, + USER_MISSED_CALL_FILTERS_TIMEOUT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface MissedReason {} + + /** + * Value for {@link CallLog.Calls#MISSED_REASON}, set as the default value when a call was + * not missed. + */ + public static final long MISSED_REASON_NOT_MISSED = 0; + + /** + * Value for {@link CallLog.Calls#MISSED_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#MISSED_TYPE} to indicate that a call was automatically rejected by + * system because an ongoing emergency call. + */ + public static final long AUTO_MISSED_EMERGENCY_CALL = 1 << 0; + + /** + * Value for {@link CallLog.Calls#MISSED_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#MISSED_TYPE} to indicate that a call was automatically rejected by + * system because the system cannot support any more ringing calls. + */ + public static final long AUTO_MISSED_MAXIMUM_RINGING = 1 << 1; + + /** + * Value for {@link CallLog.Calls#MISSED_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#MISSED_TYPE} to indicate that a call was automatically rejected by + * system because the system cannot support any more dialing calls. + */ + public static final long AUTO_MISSED_MAXIMUM_DIALING = 1 << 2; + + /** + * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when + * the call was missed just because user didn't answer it. + */ + public static final long USER_MISSED_NO_ANSWER = 1 << 16; + + /** + * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when + * this call rang for a short period of time. + */ + public static final long USER_MISSED_SHORT_RING = 1 << 17; + + /** + * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, when this call + * rings less than this defined time in millisecond, set + * {@link CallLog.Calls#USER_MISSED_SHORT_RING} bit. + * @hide + */ + public static final long SHORT_RING_THRESHOLD = 5000L; + + /** + * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when + * this call is silenced because the phone is in 'do not disturb mode'. + */ + public static final long USER_MISSED_DND_MODE = 1 << 18; + + /** + * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when + * this call rings with a low ring volume. + */ + public static final long USER_MISSED_LOW_RING_VOLUME = 1 << 19; + + /** + * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, when this call + * rings in volume less than this defined volume threshold, set + * {@link CallLog.Calls#USER_MISSED_LOW_RING_VOLUME} bit. + * @hide + */ + public static final int LOW_RING_VOLUME = 0; + + /** + * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE} set this bit when + * this call rings without vibration. + */ + public static final long USER_MISSED_NO_VIBRATE = 1 << 20; + + /** + * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when + * this call is silenced by the call screening service. + */ + public static final long USER_MISSED_CALL_SCREENING_SERVICE_SILENCED = 1 << 21; + + /** + * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when + * the call filters timed out. + */ + public static final long USER_MISSED_CALL_FILTERS_TIMEOUT = 1 << 22; + + /** + * Where the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, + * indicates factors which may have lead the user to miss the call. + * <P>Type: INTEGER</P> + * + * <p> + * There are two main cases. Auto missed cases and user missed cases. Default value is: + * <ul> + * <li>{@link CallLog.Calls#MISSED_REASON_NOT_MISSED}</li> + * </ul> + * </p> + * <P> + * Auto missed cases are those where a call was missed because it was not possible for the + * incoming call to be presented to the user at all. Possible values are: + * <ul> + * <li>{@link CallLog.Calls#AUTO_MISSED_EMERGENCY_CALL}</li> + * <li>{@link CallLog.Calls#AUTO_MISSED_MAXIMUM_RINGING}</li> + * <li>{@link CallLog.Calls#AUTO_MISSED_MAXIMUM_DIALING}</li> + * </ul> + * </P> + * <P> + * User missed cases are those where the incoming call was presented to the user, but + * factors such as a low ringing volume may have contributed to the call being missed. + * Following bits can be set to indicate possible reasons for this: + * <ul> + * <li>{@link CallLog.Calls#USER_MISSED_SHORT_RING}</li> + * <li>{@link CallLog.Calls#USER_MISSED_DND_MODE}</li> + * <li>{@link CallLog.Calls#USER_MISSED_LOW_RING_VOLUME}</li> + * <li>{@link CallLog.Calls#USER_MISSED_NO_VIBRATE}</li> + * <li>{@link CallLog.Calls#USER_MISSED_CALL_SCREENING_SERVICE_SILENCED}</li> + * <li>{@link CallLog.Calls#USER_MISSED_CALL_FILTERS_TIMEOUT}</li> + * </ul> + * </P> + */ + public static final String MISSED_REASON = "missed_reason"; + /** * Adds a call to the call log. * @@ -635,12 +776,13 @@ public class CallLog { public static Uri addCall(CallerInfo ci, Context context, String number, int presentation, int callType, int features, PhoneAccountHandle accountHandle, - long start, int duration, Long dataUsage) { + long start, int duration, Long dataUsage, long missedReason) { return addCall(ci, context, number, "" /* postDialDigits */, "" /* viaNumber */, presentation, callType, features, accountHandle, start, duration, dataUsage, false /* addForAllUsers */, null /* userToBeInsertedTo */, false /* isRead */, Calls.BLOCK_REASON_NOT_BLOCKED /* callBlockReason */, - null /* callScreeningAppName */, null /* callScreeningComponentName */); + null /* callScreeningAppName */, null /* callScreeningComponentName */, + missedReason); } @@ -675,12 +817,13 @@ public class CallLog { public static Uri addCall(CallerInfo ci, Context context, String number, String postDialDigits, String viaNumber, int presentation, int callType, int features, PhoneAccountHandle accountHandle, long start, int duration, - Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo) { + Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo, + long missedReason) { return addCall(ci, context, number, postDialDigits, viaNumber, presentation, callType, features, accountHandle, start, duration, dataUsage, addForAllUsers, userToBeInsertedTo, false /* isRead */ , Calls.BLOCK_REASON_NOT_BLOCKED /* callBlockReason */, null /* callScreeningAppName */, - null /* callScreeningComponentName */); + null /* callScreeningComponentName */, missedReason); } /** @@ -714,6 +857,7 @@ public class CallLog { * @param callBlockReason The reason why the call is blocked. * @param callScreeningAppName The call screening application name which block the call. * @param callScreeningComponentName The call screening component name which block the call. + * @param missedReason The encoded missed information of the call. * * @result The URI of the call log entry belonging to the user that made or received this * call. This could be of the shadow provider. Do not return it to non-system apps, @@ -726,7 +870,7 @@ public class CallLog { int features, PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo, boolean isRead, int callBlockReason, CharSequence callScreeningAppName, - String callScreeningComponentName) { + String callScreeningComponentName, long missedReason) { if (VERBOSE_LOG) { Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s", number, userToBeInsertedTo, addForAllUsers)); @@ -779,6 +923,7 @@ public class CallLog { values.put(BLOCK_REASON, callBlockReason); values.put(CALL_SCREENING_APP_NAME, charSequenceToString(callScreeningAppName)); values.put(CALL_SCREENING_COMPONENT_NAME, callScreeningComponentName); + values.put(MISSED_REASON, Long.valueOf(missedReason)); if ((ci != null) && (ci.getContactId() > 0)) { // Update usage information for the number associated with the contact ID. @@ -1114,5 +1259,19 @@ public class CallLog { } return countryIso; } + + /** + * Check if the missedReason code indicate that the call was user missed or automatically + * rejected by system. + * + * @param missedReason + * The result is true if the call was user missed, false if the call was automatically + * rejected by system. + * + * @hide + */ + public static boolean isUserMissed(long missedReason) { + return missedReason >= (USER_MISSED_NO_ANSWER); + } } } diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 24cde0667444..bbd838db68c3 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -46,6 +46,7 @@ import android.database.CursorWrapper; import android.database.DatabaseUtils; import android.graphics.Rect; import android.net.Uri; +import android.os.Build; import android.os.RemoteException; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; @@ -129,7 +130,7 @@ public final class ContactsContract { * Prefix for column names that are not visible to client apps. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String HIDDEN_COLUMN_PREFIX = "x_"; @@ -6140,7 +6141,7 @@ public final class ContactsContract { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final Uri ENTERPRISE_CONTENT_URI = Uri.withAppendedPath(Data.ENTERPRISE_CONTENT_URI, "phones"); diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 0315b561c120..0a4e867458e0 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -101,6 +101,14 @@ public final class DeviceConfig { public static final String NAMESPACE_APP_COMPAT = "app_compat"; /** + * Namespace for app standby configurations. + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final String NAMESPACE_APP_STANDBY = "app_standby"; + + /** * Namespace for AttentionManagerService related features. * * @hide diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 062d92900643..0fea48442941 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -842,7 +842,7 @@ public final class DocumentsContract { public static final String EXTRA_RESULT = "result"; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String METHOD_CREATE_DOCUMENT = "android:createDocument"; /** {@hide} */ public static final String METHOD_RENAME_DOCUMENT = "android:renameDocument"; @@ -877,11 +877,11 @@ public final class DocumentsContract { private static final String PATH_ROOT = "root"; private static final String PATH_RECENT = "recent"; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final String PATH_DOCUMENT = "document"; private static final String PATH_CHILDREN = "children"; private static final String PATH_SEARCH = "search"; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final String PATH_TREE = "tree"; private static final String PARAM_QUERY = "query"; diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java index 48410a748766..0829d85801ac 100644 --- a/core/java/android/provider/Downloads.java +++ b/core/java/android/provider/Downloads.java @@ -21,6 +21,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.NetworkPolicyManager; import android.net.Uri; +import android.os.Build; /** * The Download Manager @@ -138,7 +139,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init/Read</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_URI = "uri"; /** @@ -168,7 +169,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_FILE_NAME_HINT = "hint"; /** @@ -184,7 +185,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init/Read</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_MIME_TYPE = "mimetype"; /** @@ -193,7 +194,7 @@ public final class Downloads { * <P>Type: INTEGER</P> * <P>Owner can Init</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_DESTINATION = "destination"; /** @@ -203,7 +204,7 @@ public final class Downloads { * <P>Type: INTEGER</P> * <P>Owner can Init/Read/Write</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_VISIBILITY = "visibility"; /** @@ -240,7 +241,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init/Read</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_NOTIFICATION_PACKAGE = "notificationpackage"; /** @@ -251,7 +252,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init/Read</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_NOTIFICATION_CLASS = "notificationclass"; /** @@ -260,7 +261,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_NOTIFICATION_EXTRAS = "notificationextras"; /** @@ -270,7 +271,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_COOKIE_DATA = "cookiedata"; /** @@ -287,7 +288,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_REFERER = "referer"; /** @@ -325,7 +326,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init/Read/Write</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_TITLE = "title"; /** @@ -335,7 +336,7 @@ public final class Downloads { * <P>Type: TEXT</P> * <P>Owner can Init/Read/Write</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_DESCRIPTION = "description"; /** @@ -344,7 +345,7 @@ public final class Downloads { * <P>Type: BOOLEAN</P> * <P>Owner can Init/Read</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_IS_PUBLIC_API = "is_public_api"; /** @@ -353,7 +354,7 @@ public final class Downloads { * <P>Type: INTEGER</P> * <P>Owner can Init/Read</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types"; /** @@ -362,7 +363,7 @@ public final class Downloads { * <P>Type: BOOLEAN</P> * <P>Owner can Init/Read</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_ALLOW_ROAMING = "allow_roaming"; /** @@ -379,7 +380,7 @@ public final class Downloads { * <P>Type: INTEGER</P> * <P>Owner can Init/Read</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI = "is_visible_in_downloads_ui"; /** @@ -396,7 +397,7 @@ public final class Downloads { * <P>Type: BOOLEAN</P> * <P>Owner can Read</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_DELETED = "deleted"; /** @@ -425,7 +426,7 @@ public final class Downloads { * * <P>Type: TEXT</P> */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String COLUMN_MEDIA_SCANNED = "scanned"; /** Possible values for column {@link #COLUMN_MEDIA_SCANNED} */ @@ -504,7 +505,7 @@ public final class Downloads { * immediately after they are used, and are kept around by the download * manager as long as space is available. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int DESTINATION_CACHE_PARTITION_PURGEABLE = 2; /** @@ -518,7 +519,7 @@ public final class Downloads { * This download will be saved to the location given by the file URI in * {@link #COLUMN_FILE_NAME_HINT}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int DESTINATION_FILE_URI = 4; /** @@ -599,7 +600,7 @@ public final class Downloads { * @param visibility the value of {@link #COLUMN_VISIBILITY}. * @return true if the notification should be displayed. false otherwise. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isNotificationToBeDisplayed(int visibility) { return visibility == DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED || visibility == DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION; @@ -840,7 +841,7 @@ public final class Downloads { * Prefix for ContentValues keys that contain HTTP header lines, to be passed to * DownloadProvider.insert(). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String INSERT_KEY_PREFIX = "http_header_"; } } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a4c8114159d3..d3820e0490cc 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -60,6 +60,7 @@ import android.net.wifi.WifiManager; import android.net.wifi.p2p.WifiP2pManager; import android.os.BatteryManager; import android.os.Binder; +import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.DropBoxManager; @@ -942,7 +943,7 @@ public final class Settings { * @hide */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACTION_USER_DICTIONARY_INSERT = "com.android.settings.USER_DICTIONARY_INSERT"; @@ -1893,7 +1894,7 @@ public final class Settings { = "android.settings.ACTION_APP_NOTIFICATION_REDACTION"; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String EXTRA_APP_UID = "app_uid"; /** @@ -2421,7 +2422,7 @@ public final class Settings { * This is the only type of reset available to non-system clients. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final int RESET_MODE_PACKAGE_DEFAULTS = 1; @@ -3066,7 +3067,7 @@ public final class Settings { public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/system"); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final ContentProviderHolder sProviderHolder = new ContentProviderHolder(CONTENT_URI); @@ -3115,9 +3116,9 @@ public final class Settings { MOVED_TO_SECURE.add(Secure.INSTALL_NON_MARKET_APPS); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final HashSet<String> MOVED_TO_GLOBAL; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final HashSet<String> MOVED_TO_SECURE_THEN_GLOBAL; static { MOVED_TO_GLOBAL = new HashSet<>(); @@ -4274,7 +4275,7 @@ public final class Settings { * Kept for use by legacy database upgrade code in DatabaseHelper. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String VIBRATE_IN_SILENT = "vibrate_in_silent"; /** @@ -4569,7 +4570,7 @@ public final class Settings { * 3 = HCO * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String TTY_MODE = "tty_mode"; /** @@ -4596,7 +4597,7 @@ public final class Settings { * pending. The value is boolean (1 or 0). * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse"; /** @@ -4605,7 +4606,7 @@ public final class Settings { * 1 = yes * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String POINTER_LOCATION = "pointer_location"; /** @@ -4614,7 +4615,7 @@ public final class Settings { * 1 = yes * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String SHOW_TOUCHES = "show_touches"; /** @@ -4642,14 +4643,14 @@ public final class Settings { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String DOCK_SOUNDS_ENABLED = Global.DOCK_SOUNDS_ENABLED; /** * Whether to play sounds when the keyguard is shown and dismissed. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String LOCKSCREEN_SOUNDS_ENABLED = "lockscreen_sounds_enabled"; /** @@ -4672,7 +4673,7 @@ public final class Settings { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String DESK_DOCK_SOUND = Global.DESK_DOCK_SOUND; /** @@ -4681,7 +4682,7 @@ public final class Settings { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String DESK_UNDOCK_SOUND = Global.DESK_UNDOCK_SOUND; /** @@ -4690,7 +4691,7 @@ public final class Settings { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String CAR_DOCK_SOUND = Global.CAR_DOCK_SOUND; /** @@ -4699,7 +4700,7 @@ public final class Settings { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String CAR_UNDOCK_SOUND = Global.CAR_UNDOCK_SOUND; /** @@ -4708,7 +4709,7 @@ public final class Settings { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String LOCK_SOUND = Global.LOCK_SOUND; /** @@ -4717,7 +4718,7 @@ public final class Settings { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String UNLOCK_SOUND = Global.UNLOCK_SOUND; /** @@ -4766,7 +4767,7 @@ public final class Settings { * +7 = fastest * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String POINTER_SPEED = "pointer_speed"; /** @@ -4824,7 +4825,7 @@ public final class Settings { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Set<String> PUBLIC_SETTINGS = new ArraySet<>(); static { PUBLIC_SETTINGS.add(END_BUTTON_BEHAVIOR); @@ -4883,7 +4884,7 @@ public final class Settings { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Set<String> PRIVATE_SETTINGS = new ArraySet<>(); static { PRIVATE_SETTINGS.add(WIFI_USE_STATIC_IP); @@ -4932,7 +4933,7 @@ public final class Settings { * These entries are considered common between the personal and the managed profile, * since the managed profile doesn't get to change them. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final Set<String> CLONE_TO_MANAGED_PROFILE = new ArraySet<>(); static { CLONE_TO_MANAGED_PROFILE.add(DATE_FORMAT); @@ -5259,7 +5260,7 @@ public final class Settings { public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/secure"); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final ContentProviderHolder sProviderHolder = new ContentProviderHolder(CONTENT_URI); @@ -5499,7 +5500,7 @@ public final class Settings { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean putStringForUser(@NonNull ContentResolver resolver, @NonNull String name, @Nullable String value, @Nullable String tag, boolean makeDefault, @UserIdInt int userHandle, boolean overrideableByRestore) { @@ -5739,7 +5740,7 @@ public final class Settings { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static long getLongForUser(ContentResolver cr, String name, long def, int userHandle) { String valString = getStringForUser(cr, name, userHandle); @@ -5803,7 +5804,7 @@ public final class Settings { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean putLongForUser(ContentResolver cr, String name, long value, int userHandle) { return putStringForUser(cr, name, Long.toString(value), userHandle); @@ -6486,7 +6487,7 @@ public final class Settings { * subject to current DeviceAdmin policy limits. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String LOCK_SCREEN_LOCK_AFTER_TIMEOUT = "lock_screen_lock_after_timeout"; @@ -6528,7 +6529,7 @@ public final class Settings { * @deprecated */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String LOCK_SCREEN_OWNER_INFO_ENABLED = "lock_screen_owner_info_enabled"; @@ -6659,7 +6660,7 @@ public final class Settings { * accessibility feature. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String ACCESSIBILITY_SHORTCUT_TARGET_SERVICE = "accessibility_shortcut_target_service"; @@ -7026,7 +7027,7 @@ public final class Settings { * @see android.graphics.Typeface * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACCESSIBILITY_CAPTIONING_TYPEFACE = "accessibility_captioning_typeface"; @@ -7066,7 +7067,7 @@ public final class Settings { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String ACCESSIBILITY_DISPLAY_DALTONIZER = "accessibility_display_daltonizer"; @@ -7480,7 +7481,7 @@ public final class Settings { * Type: int ( 0 = disabled, 1 = enabled ) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String BACKUP_ENABLED = "backup_enabled"; /** @@ -7489,7 +7490,7 @@ public final class Settings { * Type: int ( 0 = disabled, 1 = enabled ) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String BACKUP_AUTO_RESTORE = "backup_auto_restore"; /** @@ -7497,14 +7498,14 @@ public final class Settings { * Type: int ( 0 = unprovisioned, 1 = fully provisioned ) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String BACKUP_PROVISIONED = "backup_provisioned"; /** * Component of the transport to use for backup/restore. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String BACKUP_TRANSPORT = "backup_transport"; /** @@ -7676,7 +7677,7 @@ public final class Settings { * Also prevents ANRs and crash dialogs from being suppressed. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi @SuppressLint("NoSettingsProvider") public static final String ANR_SHOW_BACKGROUND = "anr_show_background"; @@ -7697,7 +7698,7 @@ public final class Settings { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service"; /** @@ -7706,7 +7707,7 @@ public final class Settings { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi @SuppressLint("NoSettingsProvider") public static final String SELECTED_SPELL_CHECKER = "selected_spell_checker"; @@ -7718,7 +7719,7 @@ public final class Settings { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi @SuppressLint("NoSettingsProvider") public static final String SELECTED_SPELL_CHECKER_SUBTYPE = @@ -8053,7 +8054,7 @@ public final class Settings { * The default NFC payment component * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component"; @@ -8067,14 +8068,14 @@ public final class Settings { * Specifies the package name currently configured to be the primary sms application * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String SMS_DEFAULT_APPLICATION = "sms_default_application"; /** * Specifies the package name currently configured to be the default dialer application * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String DIALER_DEFAULT_APPLICATION = "dialer_default_application"; /** @@ -8212,7 +8213,7 @@ public final class Settings { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String IMMERSIVE_MODE_CONFIRMATIONS = "immersive_mode_confirmations"; @@ -8380,18 +8381,19 @@ public final class Settings { public static final String CAMERA_GESTURE_DISABLED = "camera_gesture_disabled"; /** - * Whether the panic button (emergency sos) gesture should be enabled. + * Whether the emergency gesture should be enabled. * * @hide */ - public static final String PANIC_GESTURE_ENABLED = "panic_gesture_enabled"; + public static final String EMERGENCY_GESTURE_ENABLED = "emergency_gesture_enabled"; /** - * Whether the panic button (emergency sos) sound should be enabled. + * Whether the emergency gesture sound should be enabled. * * @hide */ - public static final String PANIC_SOUND_ENABLED = "panic_sound_enabled"; + public static final String EMERGENCY_GESTURE_SOUND_ENABLED = + "emergency_gesture_sound_enabled"; /** * Whether the camera launch gesture to double tap the power button when the screen is off @@ -8621,7 +8623,7 @@ public final class Settings { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners"; @@ -8790,7 +8792,7 @@ public final class Settings { * The value is boolean (1 or 0). * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String NOTIFICATION_BADGING = "notification_badging"; @@ -9052,12 +9054,6 @@ public final class Settings { public static final String MEDIA_CONTROLS_RESUME_BLOCKED = "qs_media_resumption_blocked"; /** - * Controls if window magnification is enabled. - * @hide - */ - public static final String WINDOW_MAGNIFICATION = "window_magnification"; - - /** * Controls magnification mode when magnification is enabled via a system-wide triple tap * gesture or the accessibility shortcut. * @@ -9896,6 +9892,13 @@ public final class Settings { "hdmi_cec_switch_enabled"; /** + * HDMI CEC version to use. Defaults to v1.4b. + * @hide + */ + public static final String HDMI_CEC_VERSION = + "hdmi_cec_version"; + + /** * Whether TV will automatically turn on upon reception of the CEC command * <Text View On> or <Image View On>. (0 = false, 1 = true) * @@ -9914,13 +9917,19 @@ public final class Settings { "hdmi_control_auto_device_off_enabled"; /** - * Property to decide which devices the playback device can send a <Standby> message to upon - * going to sleep. Supported values are: + * Property to decide which devices the playback device can send a <Standby> message to + * upon going to sleep. It additionally controls whether a playback device attempts to turn + * on the connected Audio system when waking up. Supported values are: * <ul> - * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_TO_TV} to TV only.</li> - * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_BROADCAST} to all devices in the - * network.</li> - * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_NONE} no <Standby> message sent.</li> + * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_TO_TV} Upon going to sleep, device + * sends {@code <Standby>} to TV only. Upon waking up, device does not turn on the Audio + * system via {@code <System Audio Mode Request>}.</li> + * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_BROADCAST} Upon going to sleep, + * device sends {@code <Standby>} to all devices in the network. Upon waking up, device + * attempts to turn on the Audio system via {@code <System Audio Mode Request>}.</li> + * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_NONE} Upon going to sleep, device + * does not send any {@code <Standby>} message. Upon waking up, device does not turn on the + * Audio system via {@code <System Audio Mode Request>}.</li> * </ul> * * @hide @@ -10088,7 +10097,7 @@ public final class Settings { * scorer app, external network scores will neither be requested nor accepted. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String NETWORK_SCORER_APP = "network_scorer_app"; /** @@ -10432,7 +10441,7 @@ public final class Settings { * by the system). * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String WEBVIEW_PROVIDER = "webview_provider"; /** @@ -10824,7 +10833,7 @@ public final class Settings { * the setting needs to be set to 0 to disable it. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED = "wifi_watchdog_poor_network_test_enabled"; @@ -11002,7 +11011,7 @@ public final class Settings { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices"; @@ -11644,7 +11653,7 @@ public final class Settings { * @hide * @see com.android.server.power.batterysaver.BatterySaverPolicy */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants"; @@ -11823,37 +11832,6 @@ public final class Settings { public static final String APP_TIME_LIMIT_USAGE_SOURCE = "app_time_limit_usage_source"; /** - * App standby (app idle) specific settings. - * This is encoded as a key=value list, separated by commas. Ex: - * <p> - * "idle_duration=5000,prediction_timeout=4500,screen_thresholds=0/0/60000/120000" - * <p> - * All durations are in millis. - * Array values are separated by forward slashes - * The following keys are supported: - * - * <pre> - * screen_thresholds (long[4]) - * elapsed_thresholds (long[4]) - * strong_usage_duration (long) - * notification_seen_duration (long) - * system_update_usage_duration (long) - * prediction_timeout (long) - * sync_adapter_duration (long) - * exempted_sync_duration (long) - * system_interaction_duration (long) - * initial_foreground_service_start_duration (long) - * cross_profile_apps_share_standby_buckets (boolean) - * </pre> - * - * <p> - * Type: string - * @hide - * @see com.android.server.usage.AppStandbyController - */ - public static final String APP_IDLE_CONSTANTS = "app_idle_constants"; - - /** * Enable ART bytecode verification verifications for debuggable apps. * 0 = disable, 1 = enable. * @hide @@ -11881,21 +11859,6 @@ public final class Settings { public static final String POWER_MANAGER_CONSTANTS = "power_manager_constants"; /** - * Job scheduler QuotaController specific settings. - * This is encoded as a key=value list, separated by commas. Ex: - * - * "max_job_count_working=5,max_job_count_rare=2" - * - * <p> - * Type: string - * - * @hide - * @see com.android.server.job.JobSchedulerService.Constants - */ - public static final String JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS = - "job_scheduler_quota_controller_constants"; - - /** * ShortcutManager specific settings. * This is encoded as a key=value list, separated by commas. Ex: * @@ -12301,7 +12264,7 @@ public final class Settings { * See RIL_PreferredNetworkType in ril.h * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String PREFERRED_NETWORK_MODE = "preferred_network_mode"; @@ -12908,7 +12871,7 @@ public final class Settings { @UnsupportedAppUsage public static final int ZEN_MODE_NO_INTERRUPTIONS = 2; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int ZEN_MODE_ALARMS = 3; /** @hide */ public static String zenModeToString(int mode) { @@ -12971,15 +12934,15 @@ public final class Settings { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String HEADS_UP_NOTIFICATIONS_ENABLED = "heads_up_notifications_enabled"; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int HEADS_UP_OFF = 0; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int HEADS_UP_ON = 1; /** @@ -13453,7 +13416,7 @@ public final class Settings { public static final String[] LEGACY_RESTORE_SETTINGS = { }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final ContentProviderHolder sProviderHolder = new ContentProviderHolder(CONTENT_URI); @@ -13503,7 +13466,7 @@ public final class Settings { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String getStringForUser(ContentResolver resolver, String name, int userHandle) { if (MOVED_TO_SECURE.contains(name)) { @@ -13653,7 +13616,7 @@ public final class Settings { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean putStringForUser(ContentResolver resolver, String name, String value, int userHandle) { return putStringForUser(resolver, name, value, null, false, userHandle, @@ -14533,6 +14496,15 @@ public final class Settings { public static final String SHOW_NEW_LOCKSCREEN = "show_new_lockscreen"; /** + * Whether to show new notification dismissal. + * Values are: + * 0: Disabled + * 1: Enabled + * @hide + */ + public static final String SHOW_NEW_NOTIF_DISMISS = "show_new_notif_dismiss"; + + /** * Block untrusted touches mode. * * Can be one of: @@ -15219,7 +15191,7 @@ public final class Settings { * callingPackage, a negative result will be returned. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isCallingPackageAllowedToWriteSettings(Context context, int uid, String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index 2c735fd9012f..649c8f353196 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -627,7 +627,7 @@ public final class Telephony { * @return the URI for the new message * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static Uri addMessage(int subId, ContentResolver resolver, String address, String body, String subject, Long date, boolean read) { return addMessageToUri(subId, resolver, CONTENT_URI, address, body, @@ -687,7 +687,7 @@ public final class Telephony { * @return the URI for the new message * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static Uri addMessage(int subId, ContentResolver resolver, String address, String body, String subject, Long date) { return addMessageToUri(subId, resolver, CONTENT_URI, address, body, @@ -734,7 +734,7 @@ public final class Telephony { * @return the URI for the new message * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static Uri addMessage(int subId, ContentResolver resolver, String address, String body, String subject, Long date) { return addMessageToUri(subId, resolver, CONTENT_URI, address, body, @@ -781,7 +781,7 @@ public final class Telephony { * @return the URI for the new message * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static Uri addMessage(ContentResolver resolver, String address, String body, String subject, Long date, boolean deliveryReport, long threadId) { diff --git a/core/java/android/security/KeystoreArguments.java b/core/java/android/security/KeystoreArguments.java index a59c4e04285d..19f78c8500d6 100644 --- a/core/java/android/security/KeystoreArguments.java +++ b/core/java/android/security/KeystoreArguments.java @@ -17,6 +17,7 @@ package android.security; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -28,7 +29,7 @@ import android.os.Parcelable; public class KeystoreArguments implements Parcelable { public byte[][] args; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Parcelable.Creator<KeystoreArguments> CREATOR = new Parcelable.Creator<KeystoreArguments>() { public KeystoreArguments createFromParcel(Parcel in) { @@ -43,7 +44,7 @@ public class KeystoreArguments implements Parcelable { args = null; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeystoreArguments(byte[][] args) { this.args = args; } diff --git a/core/java/android/security/keymaster/ExportResult.java b/core/java/android/security/keymaster/ExportResult.java index 037b85270306..2c382efab1be 100644 --- a/core/java/android/security/keymaster/ExportResult.java +++ b/core/java/android/security/keymaster/ExportResult.java @@ -17,6 +17,7 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -33,7 +34,7 @@ public class ExportResult implements Parcelable { this.exportData = new byte[0]; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Parcelable.Creator<ExportResult> CREATOR = new Parcelable.Creator<ExportResult>() { public ExportResult createFromParcel(Parcel in) { diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java index d8382fa8f969..4f2bad1127e8 100644 --- a/core/java/android/security/keymaster/KeyCharacteristics.java +++ b/core/java/android/security/keymaster/KeyCharacteristics.java @@ -17,6 +17,7 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -45,7 +46,7 @@ public class KeyCharacteristics implements Parcelable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeyCharacteristics() {} protected KeyCharacteristics(Parcel in) { @@ -71,7 +72,7 @@ public class KeyCharacteristics implements Parcelable { hwEnforced.writeToParcel(out, flags); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void readFromParcel(Parcel in) { swEnforced = KeymasterArguments.CREATOR.createFromParcel(in); hwEnforced = KeymasterArguments.CREATOR.createFromParcel(in); diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java index e009e128bfea..7608f3a7b9ef 100644 --- a/core/java/android/security/keymaster/KeymasterArguments.java +++ b/core/java/android/security/keymaster/KeymasterArguments.java @@ -17,6 +17,7 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -41,7 +42,7 @@ public class KeymasterArguments implements Parcelable { private List<KeymasterArgument> mArguments; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Parcelable.Creator<KeymasterArguments> CREATOR = new Parcelable.Creator<KeymasterArguments>() { @Override @@ -55,7 +56,7 @@ public class KeymasterArguments implements Parcelable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeymasterArguments() { mArguments = new ArrayList<KeymasterArgument>(); } @@ -69,7 +70,7 @@ public class KeymasterArguments implements Parcelable { * * @throws IllegalArgumentException if {@code tag} is not an enum tag. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addEnum(int tag, int value) { int tagType = KeymasterDefs.getTagType(tag); if ((tagType != KeymasterDefs.KM_ENUM) && (tagType != KeymasterDefs.KM_ENUM_REP)) { @@ -141,7 +142,7 @@ public class KeymasterArguments implements Parcelable { * @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag or if * {@code value} is outside of the permitted range [0; 2^32). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addUnsignedInt(int tag, long value) { int tagType = KeymasterDefs.getTagType(tag); if ((tagType != KeymasterDefs.KM_UINT) && (tagType != KeymasterDefs.KM_UINT_REP)) { @@ -178,7 +179,7 @@ public class KeymasterArguments implements Parcelable { * @throws IllegalArgumentException if {@code tag} is not an unsigned 64-bit long tag or if * {@code value} is outside of the permitted range [0; 2^64). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addUnsignedLong(int tag, BigInteger value) { int tagType = KeymasterDefs.getTagType(tag); if ((tagType != KeymasterDefs.KM_ULONG) && (tagType != KeymasterDefs.KM_ULONG_REP)) { @@ -364,7 +365,7 @@ public class KeymasterArguments implements Parcelable { out.writeTypedList(mArguments); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void readFromParcel(Parcel in) { in.readTypedList(mArguments, KeymasterArgument.CREATOR); } diff --git a/core/java/android/security/keymaster/KeymasterBlob.java b/core/java/android/security/keymaster/KeymasterBlob.java index 68365bfe603f..18cdecb167db 100644 --- a/core/java/android/security/keymaster/KeymasterBlob.java +++ b/core/java/android/security/keymaster/KeymasterBlob.java @@ -17,6 +17,7 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -29,7 +30,7 @@ public class KeymasterBlob implements Parcelable { public KeymasterBlob(byte[] blob) { this.blob = blob; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Parcelable.Creator<KeymasterBlob> CREATOR = new Parcelable.Creator<KeymasterBlob>() { public KeymasterBlob createFromParcel(Parcel in) { diff --git a/core/java/android/security/keymaster/KeymasterBlobArgument.java b/core/java/android/security/keymaster/KeymasterBlobArgument.java index 81b08c5b5b0a..b4106a6f2bc9 100644 --- a/core/java/android/security/keymaster/KeymasterBlobArgument.java +++ b/core/java/android/security/keymaster/KeymasterBlobArgument.java @@ -17,16 +17,17 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; /** * @hide */ class KeymasterBlobArgument extends KeymasterArgument { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final byte[] blob; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeymasterBlobArgument(int tag, byte[] blob) { super(tag); switch (KeymasterDefs.getTagType(tag)) { @@ -39,7 +40,7 @@ class KeymasterBlobArgument extends KeymasterArgument { this.blob = blob; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeymasterBlobArgument(int tag, Parcel in) { super(tag); blob = in.createByteArray(); diff --git a/core/java/android/security/keymaster/KeymasterBooleanArgument.java b/core/java/android/security/keymaster/KeymasterBooleanArgument.java index 25b2ac409d97..574511c70051 100644 --- a/core/java/android/security/keymaster/KeymasterBooleanArgument.java +++ b/core/java/android/security/keymaster/KeymasterBooleanArgument.java @@ -17,6 +17,7 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; /** @@ -37,7 +38,7 @@ class KeymasterBooleanArgument extends KeymasterArgument { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeymasterBooleanArgument(int tag, Parcel in) { super(tag); } diff --git a/core/java/android/security/keymaster/KeymasterDateArgument.java b/core/java/android/security/keymaster/KeymasterDateArgument.java index 218f4880b289..f6b8fb589b25 100644 --- a/core/java/android/security/keymaster/KeymasterDateArgument.java +++ b/core/java/android/security/keymaster/KeymasterDateArgument.java @@ -17,6 +17,7 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import java.util.Date; @@ -38,7 +39,7 @@ class KeymasterDateArgument extends KeymasterArgument { this.date = date; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeymasterDateArgument(int tag, Parcel in) { super(tag); date = new Date(in.readLong()); diff --git a/core/java/android/security/keymaster/KeymasterIntArgument.java b/core/java/android/security/keymaster/KeymasterIntArgument.java index 01d38c799d9c..6aed8c998d62 100644 --- a/core/java/android/security/keymaster/KeymasterIntArgument.java +++ b/core/java/android/security/keymaster/KeymasterIntArgument.java @@ -17,16 +17,17 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; /** * @hide */ class KeymasterIntArgument extends KeymasterArgument { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int value; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeymasterIntArgument(int tag, int value) { super(tag); switch (KeymasterDefs.getTagType(tag)) { @@ -41,7 +42,7 @@ class KeymasterIntArgument extends KeymasterArgument { this.value = value; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeymasterIntArgument(int tag, Parcel in) { super(tag); value = in.readInt(); diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java index 3ac27ccef295..c0c6f0e518cb 100644 --- a/core/java/android/security/keymaster/KeymasterLongArgument.java +++ b/core/java/android/security/keymaster/KeymasterLongArgument.java @@ -17,16 +17,17 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; /** * @hide */ class KeymasterLongArgument extends KeymasterArgument { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final long value; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeymasterLongArgument(int tag, long value) { super(tag); switch (KeymasterDefs.getTagType(tag)) { @@ -39,7 +40,7 @@ class KeymasterLongArgument extends KeymasterArgument { this.value = value; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public KeymasterLongArgument(int tag, Parcel in) { super(tag); value = in.readLong(); diff --git a/core/java/android/security/keymaster/OperationResult.java b/core/java/android/security/keymaster/OperationResult.java index b4e155a527de..0ace764e435b 100644 --- a/core/java/android/security/keymaster/OperationResult.java +++ b/core/java/android/security/keymaster/OperationResult.java @@ -17,6 +17,7 @@ package android.security.keymaster; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -34,7 +35,7 @@ public class OperationResult implements Parcelable { public final byte[] output; public final KeymasterArguments outParams; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Parcelable.Creator<OperationResult> CREATOR = new Parcelable.Creator<OperationResult>() { @Override diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java index cc3e57859b64..d859b1c33c94 100644 --- a/core/java/android/security/keystore/recovery/RecoveryController.java +++ b/core/java/android/security/keystore/recovery/RecoveryController.java @@ -751,7 +751,7 @@ public class RecoveryController { InternalRecoveryServiceException wrapUnexpectedServiceSpecificException( ServiceSpecificException e) { if (e.errorCode == ERROR_SERVICE_INTERNAL_ERROR) { - return new InternalRecoveryServiceException(e.getMessage()); + return new InternalRecoveryServiceException(e.getMessage(), e); } // Should never happen. If it does, it's a bug, and we need to update how the method that diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java index 18d79927388b..8ae1b6bf702d 100644 --- a/core/java/android/service/autofill/Dataset.java +++ b/core/java/android/service/autofill/Dataset.java @@ -20,7 +20,10 @@ import static android.view.autofill.Helper.sDebug; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.content.ClipData; import android.content.IntentSender; import android.os.Parcel; import android.os.Parcelable; @@ -97,7 +100,6 @@ import java.util.regex.Pattern; * with the lower case value of the view's text are shown. * <li>All other datasets are hidden. * </ol> - * */ public final class Dataset implements Parcelable { @@ -106,6 +108,7 @@ public final class Dataset implements Parcelable { private final ArrayList<RemoteViews> mFieldPresentations; private final ArrayList<InlinePresentation> mFieldInlinePresentations; private final ArrayList<DatasetFieldFilter> mFieldFilters; + @Nullable private final ClipData mFieldContent; private final RemoteViews mPresentation; @Nullable private final InlinePresentation mInlinePresentation; private final IntentSender mAuthentication; @@ -117,6 +120,7 @@ public final class Dataset implements Parcelable { mFieldPresentations = builder.mFieldPresentations; mFieldInlinePresentations = builder.mFieldInlinePresentations; mFieldFilters = builder.mFieldFilters; + mFieldContent = builder.mFieldContent; mPresentation = builder.mPresentation; mInlinePresentation = builder.mInlinePresentation; mAuthentication = builder.mAuthentication; @@ -124,11 +128,15 @@ public final class Dataset implements Parcelable { } /** @hide */ + @TestApi + @SuppressLint("ConcreteCollection") public @Nullable ArrayList<AutofillId> getFieldIds() { return mFieldIds; } /** @hide */ + @TestApi + @SuppressLint("ConcreteCollection") public @Nullable ArrayList<AutofillValue> getFieldValues() { return mFieldValues; } @@ -140,24 +148,37 @@ public final class Dataset implements Parcelable { } /** @hide */ - @Nullable - public InlinePresentation getFieldInlinePresentation(int index) { + public @Nullable InlinePresentation getFieldInlinePresentation(int index) { final InlinePresentation inlinePresentation = mFieldInlinePresentations.get(index); return inlinePresentation != null ? inlinePresentation : mInlinePresentation; } /** @hide */ - @Nullable - public DatasetFieldFilter getFilter(int index) { + public @Nullable DatasetFieldFilter getFilter(int index) { return mFieldFilters.get(index); } + /** + * Returns the content to be filled for a non-text suggestion. This is only applicable to + * augmented autofill. The target field for the content is available via {@link #getFieldIds()} + * (guaranteed to have a single field id set when the return value here is non-null). See + * {@link Builder#setContent(AutofillId, ClipData)} for more info. + * + * @hide + */ + @TestApi + public @Nullable ClipData getFieldContent() { + return mFieldContent; + } + /** @hide */ + @TestApi public @Nullable IntentSender getAuthentication() { return mAuthentication; } /** @hide */ + @TestApi public boolean isEmpty() { return mFieldIds == null || mFieldIds.isEmpty(); } @@ -179,6 +200,9 @@ public final class Dataset implements Parcelable { if (mFieldValues != null) { builder.append(", fieldValues=").append(mFieldValues); } + if (mFieldContent != null) { + builder.append(", fieldContent=").append(mFieldContent); + } if (mFieldPresentations != null) { builder.append(", fieldPresentations=").append(mFieldPresentations.size()); } @@ -207,7 +231,8 @@ public final class Dataset implements Parcelable { * * @hide */ - public String getId() { + @TestApi + public @Nullable String getId() { return mId; } @@ -221,6 +246,7 @@ public final class Dataset implements Parcelable { private ArrayList<RemoteViews> mFieldPresentations; private ArrayList<InlinePresentation> mFieldInlinePresentations; private ArrayList<DatasetFieldFilter> mFieldFilters; + @Nullable private ClipData mFieldContent; private RemoteViews mPresentation; @Nullable private InlinePresentation mInlinePresentation; private IntentSender mAuthentication; @@ -366,6 +392,36 @@ public final class Dataset implements Parcelable { } /** + * Sets the content for a field. + * + * <p>Only called by augmented autofill. + * + * <p>For a given field, either a {@link AutofillValue value} or content can be filled, but + * not both. Furthermore, when filling content, only a single field can be filled. + * + * @param id id returned by + * {@link android.app.assist.AssistStructure.ViewNode#getAutofillId()}. + * @param content content to be autofilled. Pass {@code null} if you do not have the content + * but the target view is a logical part of the dataset. For example, if the dataset needs + * authentication. + * + * @throws IllegalStateException if {@link #build()} was already called. + * + * @return this builder. + * + * @hide + */ + @TestApi + @SystemApi + @SuppressLint("MissingGetterMatchingBuilder") + public @NonNull Builder setContent(@NonNull AutofillId id, @Nullable ClipData content) { + throwIfDestroyed(); + setLifeTheUniverseAndEverything(id, null, null, null, null); + mFieldContent = content; + return this; + } + + /** * Sets the value of a field. * * <b>Note:</b> Prior to Android {@link android.os.Build.VERSION_CODES#P}, this method would @@ -659,6 +715,15 @@ public final class Dataset implements Parcelable { if (mFieldIds == null) { throw new IllegalStateException("at least one value must be set"); } + if (mFieldContent != null) { + if (mFieldIds.size() > 1) { + throw new IllegalStateException( + "when filling content, only one field can be filled"); + } + if (mFieldValues.get(0) != null) { + throw new IllegalStateException("cannot fill both content and values"); + } + } return new Dataset(this); } @@ -687,6 +752,7 @@ public final class Dataset implements Parcelable { parcel.writeTypedList(mFieldPresentations, flags); parcel.writeTypedList(mFieldInlinePresentations, flags); parcel.writeTypedList(mFieldFilters, flags); + parcel.writeParcelable(mFieldContent, flags); parcel.writeParcelable(mAuthentication, flags); parcel.writeString(mId); } @@ -694,18 +760,8 @@ public final class Dataset implements Parcelable { public static final @NonNull Creator<Dataset> CREATOR = new Creator<Dataset>() { @Override public Dataset createFromParcel(Parcel parcel) { - // Always go through the builder to ensure the data ingested by - // the system obeys the contract of the builder to avoid attacks - // using specially crafted parcels. final RemoteViews presentation = parcel.readParcelable(null); final InlinePresentation inlinePresentation = parcel.readParcelable(null); - final Builder builder = presentation != null - ? inlinePresentation == null - ? new Builder(presentation) - : new Builder(presentation).setInlinePresentation(inlinePresentation) - : inlinePresentation == null - ? new Builder() - : new Builder(inlinePresentation); final ArrayList<AutofillId> ids = parcel.createTypedArrayList(AutofillId.CREATOR); final ArrayList<AutofillValue> values = @@ -716,6 +772,21 @@ public final class Dataset implements Parcelable { parcel.createTypedArrayList(InlinePresentation.CREATOR); final ArrayList<DatasetFieldFilter> filters = parcel.createTypedArrayList(DatasetFieldFilter.CREATOR); + final ClipData fieldContent = parcel.readParcelable(null); + final IntentSender authentication = parcel.readParcelable(null); + final String datasetId = parcel.readString(); + + // Always go through the builder to ensure the data ingested by + // the system obeys the contract of the builder to avoid attacks + // using specially crafted parcels. + final Builder builder = (presentation != null) ? new Builder(presentation) + : new Builder(); + if (inlinePresentation != null) { + builder.setInlinePresentation(inlinePresentation); + } + if (fieldContent != null) { + builder.setContent(ids.get(0), fieldContent); + } final int inlinePresentationsSize = inlinePresentations.size(); for (int i = 0; i < ids.size(); i++) { final AutofillId id = ids.get(i); @@ -727,8 +798,8 @@ public final class Dataset implements Parcelable { builder.setLifeTheUniverseAndEverything(id, value, fieldPresentation, fieldInlinePresentation, filter); } - builder.setAuthentication(parcel.readParcelable(null)); - builder.setId(parcel.readString()); + builder.setAuthentication(authentication); + builder.setId(datasetId); return builder.build(); } diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 859bb51607b9..a47c3b188b79 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -771,7 +771,7 @@ public class DreamService extends Service implements Window.Callback { * @see #setDozeScreenBrightness * @hide For use by system UI components only. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getDozeScreenBrightness() { return mDozeScreenBrightness; } diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl index 6496de3e15a0..0ce9cfa7a0bf 100644 --- a/core/java/android/service/dreams/IDreamManager.aidl +++ b/core/java/android/service/dreams/IDreamManager.aidl @@ -27,9 +27,9 @@ interface IDreamManager { void dream(); @UnsupportedAppUsage void awaken(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setDreamComponents(in ComponentName[] componentNames); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) ComponentName[] getDreamComponents(); ComponentName getDefaultDreamComponentForUser(int userId); void testDream(int userId, in ComponentName componentName); diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 25f140f29e00..aa9e289345db 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -311,7 +311,7 @@ public abstract class NotificationListenerService extends Service { private Handler mHandler; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected NotificationListenerWrapper mWrapper = null; private boolean isConnected = false; @@ -1885,7 +1885,7 @@ public abstract class NotificationListenerService extends Service { * <p>This might be null even if the notification is a conversation notification, if * the posting app hasn't opted into the full conversation feature set yet.</p> */ - public @Nullable ShortcutInfo getShortcutInfo() { + public @Nullable ShortcutInfo getConversationShortcutInfo() { return mShortcutInfo; } diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 579a8bfc9d99..8e4a68e52697 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -430,7 +430,7 @@ public class StatusBarNotification implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Context getPackageContext(Context context) { if (mContext == null) { try { diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index a9ab33c0d1de..787a81bac3c0 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -35,6 +35,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.Uri; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; @@ -286,7 +287,7 @@ public class ZenModeConfig implements Parcelable { } StringBuilder buffer = new StringBuilder(automaticRules.size() * 28); - buffer.append('{'); + buffer.append("{\n"); for (int i = 0; i < automaticRules.size(); i++) { if (i > 0) { buffer.append(",\n"); @@ -1743,9 +1744,9 @@ public class ZenModeConfig implements Parcelable { public static class ZenRule implements Parcelable { @UnsupportedAppUsage public boolean enabled; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean snoozing; // user manually disabled this instance - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String name; // required for automatic @UnsupportedAppUsage public int zenMode; // ie: Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS @@ -1755,7 +1756,7 @@ public class ZenModeConfig implements Parcelable { public ComponentName component; // optional public ComponentName configurationActivity; // optional public String id; // required for automatic (unique) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long creationTime; // required for automatic // package name, only used for manual rules when they have turned DND on. public String enabler; @@ -1830,12 +1831,13 @@ public class ZenModeConfig implements Parcelable { public String toString() { return new StringBuilder(ZenRule.class.getSimpleName()).append('[') .append("id=").append(id) + .append(",state=").append(condition == null ? "STATE_FALSE" + : Condition.stateToString(condition.state)) .append(",enabled=").append(String.valueOf(enabled).toUpperCase()) .append(",snoozing=").append(snoozing) .append(",name=").append(name) .append(",zenMode=").append(Global.zenModeToString(zenMode)) .append(",conditionId=").append(conditionId) - .append(",condition=").append(condition) .append(",pkg=").append(pkg) .append(",component=").append(component) .append(",configActivity=").append(configurationActivity) @@ -1843,6 +1845,7 @@ public class ZenModeConfig implements Parcelable { .append(",enabler=").append(enabler) .append(",zenPolicy=").append(zenPolicy) .append(",modified=").append(modified) + .append(",condition=").append(condition) .append(']').toString(); } @@ -2010,6 +2013,10 @@ public class ZenModeConfig implements Parcelable { public Diff addLine(String item, Object from, Object to) { return addLine(item, from + "->" + to); } + + public boolean isEmpty() { + return lines.isEmpty(); + } } /** diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl index a8293b47db30..f8ae08563a52 100644 --- a/core/java/android/service/vr/IVrManager.aidl +++ b/core/java/android/service/vr/IVrManager.aidl @@ -94,7 +94,7 @@ interface IVrManager { * @return {@link android.view.Display.INVALID_DISPLAY} if there is no virtual display * currently, else return the display id of the virtual display */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int getVr2dDisplayId(); /** diff --git a/core/java/android/service/vr/VrListenerService.java b/core/java/android/service/vr/VrListenerService.java index 2758ace8d00b..d92e3b8b6b9b 100644 --- a/core/java/android/service/vr/VrListenerService.java +++ b/core/java/android/service/vr/VrListenerService.java @@ -24,6 +24,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -140,7 +141,7 @@ public abstract class VrListenerService extends Service { * @see android.R.attr#enableVrMode * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onCurrentVrActivityChanged( ComponentName component, boolean running2dInVr, int pid) { // Override to implement. Default to old behaviour of sending null for 2D. diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 4249e5c20d3b..9a76f19f3e41 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -127,7 +127,7 @@ public abstract class WallpaperService extends Service { private static final int MSG_VISIBILITY_CHANGED = 10010; private static final int MSG_WALLPAPER_OFFSETS = 10020; private static final int MSG_WALLPAPER_COMMAND = 10025; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int MSG_WINDOW_RESIZED = 10030; private static final int MSG_WINDOW_MOVED = 10035; private static final int MSG_TOUCH_EVENT = 10040; diff --git a/core/java/android/speech/IRecognitionListener.aidl b/core/java/android/speech/IRecognitionListener.aidl index e77851b0e405..7c79b1ae15de 100644 --- a/core/java/android/speech/IRecognitionListener.aidl +++ b/core/java/android/speech/IRecognitionListener.aidl @@ -83,6 +83,6 @@ oneway interface IRecognitionListener { * @param eventType the type of the occurred event * @param params a Bundle containing the passed parameters */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onEvent(in int eventType, in Bundle params); } diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 6a5d5c63cb4d..479a0c16c747 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -843,7 +843,7 @@ public class PhoneStateListener { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onDataConnectionRealTimeInfoChanged( DataConnectionRealTimeInfo dcRtInfo) { // default implementation empty @@ -1046,7 +1046,7 @@ public class PhoneStateListener { * @param rawData is the byte array of the OEM hook raw data. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onOemHookRawEvent(byte[] rawData) { // default implementation empty } diff --git a/core/java/android/telephony/Rlog.java b/core/java/android/telephony/Rlog.java index 2afdd339e80b..a1c74e69e7a2 100644 --- a/core/java/android/telephony/Rlog.java +++ b/core/java/android/telephony/Rlog.java @@ -53,7 +53,7 @@ public final class Rlog { return Log.println_native(Log.LOG_ID_RADIO, Log.DEBUG, tag, msg); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int d(String tag, String msg, Throwable tr) { return Log.println_native(Log.LOG_ID_RADIO, Log.DEBUG, tag, msg + '\n' + Log.getStackTraceString(tr)); diff --git a/core/java/android/text/AndroidBidi.java b/core/java/android/text/AndroidBidi.java index b9811638b28f..31da79995172 100644 --- a/core/java/android/text/AndroidBidi.java +++ b/core/java/android/text/AndroidBidi.java @@ -18,6 +18,7 @@ package android.text; import android.compat.annotation.UnsupportedAppUsage; import android.icu.text.Bidi; +import android.os.Build; import android.text.Layout.Directions; import com.android.internal.annotations.VisibleForTesting; @@ -32,7 +33,7 @@ public class AndroidBidi { /** * Runs the bidi algorithm on input text. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int bidi(int dir, char[] chs, byte[] chInfo) { if (chs == null || chInfo == null) { throw new NullPointerException(); diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java index c60d446d921d..16b45c30b69f 100644 --- a/core/java/android/text/DynamicLayout.java +++ b/core/java/android/text/DynamicLayout.java @@ -987,7 +987,7 @@ public class DynamicLayout extends Layout { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getIndexFirstChangedBlock() { return mIndexFirstChangedBlock; } @@ -995,7 +995,7 @@ public class DynamicLayout extends Layout { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setIndexFirstChangedBlock(int i) { mIndexFirstChangedBlock = i; } diff --git a/core/java/android/text/Editable.java b/core/java/android/text/Editable.java index 3396bceb75d0..a942f6ce2879 100644 --- a/core/java/android/text/Editable.java +++ b/core/java/android/text/Editable.java @@ -137,7 +137,7 @@ extends CharSequence, GetChars, Spannable, Appendable } /** - * Returns a new SpannedStringBuilder from the specified + * Returns a new SpannableStringBuilder from the specified * CharSequence. You can override this to provide * a different kind of Spanned. */ diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java index b5688a48344e..1878d61c78ac 100644 --- a/core/java/android/text/FontConfig.java +++ b/core/java/android/text/FontConfig.java @@ -24,6 +24,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; import android.net.Uri; +import android.os.Build; import java.lang.annotation.Retention; @@ -44,7 +45,7 @@ public final class FontConfig { /** * Returns the ordered list of families included in the system fonts. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @NonNull Family[] getFamilies() { return mFamilies; } @@ -91,7 +92,7 @@ public final class FontConfig { /** * Returns the index to be used to access this font when accessing a TTC file. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getTtcIndex() { return mTtcIndex; } @@ -99,7 +100,7 @@ public final class FontConfig { /** * Returns the list of axes associated to this font. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @NonNull FontVariationAxis[] getAxes() { return mAxes; } @@ -107,7 +108,7 @@ public final class FontConfig { /** * Returns the weight value for this font. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getWeight() { return mWeight; } @@ -115,7 +116,7 @@ public final class FontConfig { /** * Returns whether this font is italic. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isItalic() { return mIsItalic; } @@ -231,7 +232,7 @@ public final class FontConfig { /** * Returns the name given by the system to this font family. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable String getName() { return mName; } @@ -239,7 +240,7 @@ public final class FontConfig { /** * Returns the list of fonts included in this family. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable Font[] getFonts() { return mFonts; } @@ -254,7 +255,7 @@ public final class FontConfig { /** * Returns the font variant for this family, e.g. "elegant" or "compact". May be null. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Variant int getVariant() { return mVariant; } diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java index ab19fa9a1256..b80b01f5a64a 100644 --- a/core/java/android/text/Html.java +++ b/core/java/android/text/Html.java @@ -23,6 +23,7 @@ import android.content.res.Resources; import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.Drawable; +import android.os.Build; import android.text.style.AbsoluteSizeSpan; import android.text.style.AlignmentSpan; import android.text.style.BackgroundColorSpan; @@ -631,7 +632,7 @@ public class Html { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void withinStyle(StringBuilder out, CharSequence text, int start, int end) { for (int i = start; i < end; i++) { diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index 8a4497a0f0ce..f0f0867d414b 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -24,6 +24,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.graphics.text.LineBreaker; +import android.os.Build; import android.text.method.TextKeyListener; import android.text.style.AlignmentSpan; import android.text.style.LeadingMarginSpan; @@ -414,7 +415,7 @@ public abstract class Layout { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void drawText(Canvas canvas, int firstLine, int lastLine) { int previousLineBottom = getLineTop(firstLine); int previousLineEnd = getLineStart(firstLine); @@ -583,7 +584,7 @@ public abstract class Layout { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void drawBackground(Canvas canvas, Path highlight, Paint highlightPaint, int cursorOffsetVertical, int firstLine, int lastLine) { // First, draw LineBackgroundSpans. @@ -664,7 +665,7 @@ public abstract class Layout { * @return The range of lines that need to be drawn, possibly empty. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getLineRangeForDraw(Canvas canvas) { int dtop, dbottom; @@ -1154,7 +1155,7 @@ public abstract class Layout { * optionally clamp it so that it doesn't exceed the width of the layout. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public float getPrimaryHorizontal(int offset, boolean clamped) { boolean trailing = primaryIsTrailingPrevious(offset); return getHorizontal(offset, trailing, clamped); @@ -1174,7 +1175,7 @@ public abstract class Layout { * optionally clamp it so that it doesn't exceed the width of the layout. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public float getSecondaryHorizontal(int offset, boolean clamped) { boolean trailing = primaryIsTrailingPrevious(offset); return getHorizontal(offset, !trailing, clamped); @@ -1849,7 +1850,7 @@ public abstract class Layout { * only robust for left-aligned displays. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean shouldClampCursor(int line) { // Only clamp cursor position in left-aligned displays. switch (getParagraphAlignment(line)) { diff --git a/core/java/android/text/SpanSet.java b/core/java/android/text/SpanSet.java index 81bdd65974a8..d464278c714c 100644 --- a/core/java/android/text/SpanSet.java +++ b/core/java/android/text/SpanSet.java @@ -17,6 +17,7 @@ package android.text; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.lang.reflect.Array; import java.util.Arrays; @@ -34,7 +35,7 @@ public class SpanSet<E> { private final Class<? extends E> classType; int numberOfSpans; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) E[] spans; int[] spanStarts; int[] spanEnds; diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java index c5f7f581dcd1..0e61eff86c2b 100644 --- a/core/java/android/text/SpannableStringBuilder.java +++ b/core/java/android/text/SpannableStringBuilder.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.BaseCanvas; import android.graphics.Paint; +import android.os.Build; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -863,7 +864,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public <T> T[] getSpans(int queryStart, int queryEnd, @Nullable Class<T> kind, boolean sortByInsertionOrder) { if (kind == null) return (T[]) ArrayUtils.emptyArray(Object.class); diff --git a/core/java/android/text/SpannableStringInternal.java b/core/java/android/text/SpannableStringInternal.java index 0fe9b6afeaea..f2ab1bb31fbc 100644 --- a/core/java/android/text/SpannableStringInternal.java +++ b/core/java/android/text/SpannableStringInternal.java @@ -18,6 +18,7 @@ package android.text; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; @@ -153,7 +154,7 @@ import java.lang.reflect.Array; * * @return True if excluded, false if included. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final boolean isOutOfCopyRange(int start, int end, int spanStart, int spanEnd) { if (spanStart > end || spanEnd < start) return true; if (spanStart != spanEnd && start != end) { @@ -185,12 +186,12 @@ import java.lang.reflect.Array; setSpan(what, start, end, flags, true/*enforceParagraph*/); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean isIndexFollowsNextLine(int index) { return index != 0 && index != length() && charAt(index - 1) != '\n'; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void setSpan(Object what, int start, int end, int flags, boolean enforceParagraph) { int nstart = start; int nend = end; @@ -555,12 +556,12 @@ import java.lang.reflect.Array; * * Due to backward compatibility reasons, we copy even NoCopySpan by default */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void copySpans(Spanned src, int start, int end) { copySpansFromSpanned(src, start, end, false); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void copySpans(SpannableStringInternal src, int start, int end) { copySpansFromInternal(src, start, end, false); } @@ -576,15 +577,15 @@ import java.lang.reflect.Array; @UnsupportedAppUsage private int mSpanCount; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ static final Object[] EMPTY = new Object[0]; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int START = 0; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int END = 1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int FLAGS = 2; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int COLUMNS = 3; } diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 85e2d98e93c0..85911fffc1bf 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -1433,15 +1433,15 @@ public class StaticLayout extends Layout { // Unused, here because of gray list private API accesses. /*package*/ static class LineBreaks { private static final int INITIAL_SIZE = 16; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int[] breaks = new int[INITIAL_SIZE]; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public float[] widths = new float[INITIAL_SIZE]; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public float[] ascents = new float[INITIAL_SIZE]; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public float[] descents = new float[INITIAL_SIZE]; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int[] flags = new int[INITIAL_SIZE]; // hasTab // breaks, widths, and flags should all have the same length } diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 6318c4757bce..1f11d10052fe 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -57,7 +57,7 @@ public class TextLine { private static final char TAB_CHAR = '\t'; private TextPaint mPaint; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private CharSequence mText; private int mStart; private int mLen; @@ -83,13 +83,13 @@ public class TextLine { private final TextPaint mWorkPaint = new TextPaint(); private final TextPaint mActivePaint = new TextPaint(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final SpanSet<MetricAffectingSpan> mMetricAffectingSpanSpanSet = new SpanSet<MetricAffectingSpan>(MetricAffectingSpan.class); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final SpanSet<CharacterStyle> mCharacterStyleSpanSet = new SpanSet<CharacterStyle>(CharacterStyle.class); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final SpanSet<ReplacementSpan> mReplacementSpanSpanSet = new SpanSet<ReplacementSpan>(ReplacementSpan.class); diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java index c2e3a80a5c51..8e6c26ae9f93 100755 --- a/core/java/android/text/format/DateFormat.java +++ b/core/java/android/text/format/DateFormat.java @@ -460,7 +460,7 @@ public class DateFormat { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean hasDesignator(CharSequence inFormat, char designator) { if (inFormat == null) return false; diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java index ff08269a93a4..511c9746c84c 100644 --- a/core/java/android/text/format/DateUtils.java +++ b/core/java/android/text/format/DateUtils.java @@ -25,6 +25,7 @@ import android.icu.text.MeasureFormat; import android.icu.text.MeasureFormat.FormatWidth; import android.icu.util.Measure; import android.icu.util.MeasureUnit; +import android.os.Build; import com.android.internal.R; @@ -395,7 +396,7 @@ public class DateUtils * the briefest form available (e.g. "2h"). * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static CharSequence formatDuration(long millis, int abbrev) { final FormatWidth width; switch (abbrev) { diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java index d766186c13b0..f427e1bd2b72 100644 --- a/core/java/android/text/method/WordIterator.java +++ b/core/java/android/text/method/WordIterator.java @@ -21,6 +21,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.icu.lang.UCharacter; import android.icu.lang.UProperty; import android.icu.text.BreakIterator; +import android.os.Build; import android.text.CharSequenceCharacterIterator; import android.text.Selection; @@ -71,7 +72,7 @@ public class WordIterator implements Selection.PositionIterator { } /** {@inheritDoc} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int preceding(int offset) { checkOffsetIsValid(offset); while (true) { @@ -83,7 +84,7 @@ public class WordIterator implements Selection.PositionIterator { } /** {@inheritDoc} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int following(int offset) { checkOffsetIsValid(offset); while (true) { @@ -95,7 +96,7 @@ public class WordIterator implements Selection.PositionIterator { } /** {@inheritDoc} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isBoundary(int offset) { checkOffsetIsValid(offset); return mIterator.isBoundary(offset); @@ -108,7 +109,7 @@ public class WordIterator implements Selection.PositionIterator { * @param offset the given start position to search from. * @return the position of the last boundary preceding the given offset. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int nextBoundary(int offset) { checkOffsetIsValid(offset); return mIterator.following(offset); @@ -121,7 +122,7 @@ public class WordIterator implements Selection.PositionIterator { * @param offset the given start position to search from. * @return the position of the last boundary preceding the given offset. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int prevBoundary(int offset) { checkOffsetIsValid(offset); return mIterator.preceding(offset); @@ -180,7 +181,7 @@ public class WordIterator implements Selection.PositionIterator { * * @throws IllegalArgumentException is offset is not valid. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getPrevWordBeginningOnTwoWordsBoundary(int offset) { return getBeginning(offset, true); } @@ -199,7 +200,7 @@ public class WordIterator implements Selection.PositionIterator { * * @throws IllegalArgumentException is offset is not valid. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getNextWordEndOnTwoWordBoundary(int offset) { return getEnd(offset, true); } @@ -280,7 +281,7 @@ public class WordIterator implements Selection.PositionIterator { * * @param offset the offset to search from. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getPunctuationBeginning(int offset) { checkOffsetIsValid(offset); while (offset != BreakIterator.DONE && !isPunctuationStartBoundary(offset)) { @@ -297,7 +298,7 @@ public class WordIterator implements Selection.PositionIterator { * * @param offset the offset to search from. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getPunctuationEnd(int offset) { checkOffsetIsValid(offset); while (offset != BreakIterator.DONE && !isPunctuationEndBoundary(offset)) { @@ -314,7 +315,7 @@ public class WordIterator implements Selection.PositionIterator { * @param offset the offset to check from. * @return Whether the offset is after a punctuation character. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isAfterPunctuation(int offset) { if (mStart < offset && offset <= mEnd) { final int codePoint = Character.codePointBefore(mCharSeq, offset); @@ -330,7 +331,7 @@ public class WordIterator implements Selection.PositionIterator { * @param offset the offset to check from. * @return Whether the offset is at a punctuation character. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isOnPunctuation(int offset) { if (mStart <= offset && offset < mEnd) { final int codePoint = Character.codePointAt(mCharSeq, offset); diff --git a/core/java/android/text/style/EasyEditSpan.java b/core/java/android/text/style/EasyEditSpan.java index b23c2b7da6ac..ccccdcf88b69 100644 --- a/core/java/android/text/style/EasyEditSpan.java +++ b/core/java/android/text/style/EasyEditSpan.java @@ -19,6 +19,7 @@ package android.text.style; import android.annotation.NonNull; import android.app.PendingIntent; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextUtils; @@ -116,7 +117,7 @@ public class EasyEditSpan implements ParcelableSpan { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isDeleteEnabled() { return mDeleteEnabled; } @@ -126,7 +127,7 @@ public class EasyEditSpan implements ParcelableSpan { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDeleteEnabled(boolean value) { mDeleteEnabled = value; } @@ -136,7 +137,7 @@ public class EasyEditSpan implements ParcelableSpan { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PendingIntent getPendingIntent() { return mPendingIntent; } diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java index 9378636c24ca..1f15d462b9b1 100644 --- a/core/java/android/text/style/SuggestionSpan.java +++ b/core/java/android/text/style/SuggestionSpan.java @@ -23,6 +23,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -131,9 +132,9 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan { private final String mLanguageTag; private final int mHashCode; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mEasyCorrectUnderlineThickness; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mEasyCorrectUnderlineColor; private float mMisspelledUnderlineThickness; @@ -434,7 +435,7 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan { * @deprecated this is deprecated in {@link android.os.Build.VERSION_CODES#Q}. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Deprecated public void notifySelection(Context context, String original, int index) { Log.w(TAG, "notifySelection() is deprecated. Does nothing."); diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java index a7ddfa93a74e..6e25160de8ac 100644 --- a/core/java/android/text/util/Linkify.java +++ b/core/java/android/text/util/Linkify.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.app.ActivityThread; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.telephony.PhoneNumberUtils; import android.telephony.TelephonyManager; import android.text.Spannable; @@ -660,7 +661,7 @@ public class Linkify { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void gatherTelLinks(ArrayList<LinkSpec> links, Spannable s, @Nullable Context context) { PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java index e5115846013f..a2046307302b 100644 --- a/core/java/android/transition/Transition.java +++ b/core/java/android/transition/Transition.java @@ -25,6 +25,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Path; import android.graphics.Rect; +import android.os.Build; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.Log; @@ -848,7 +849,7 @@ public abstract class Transition implements Cloneable { return false; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() { ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get(); if (runningAnimators == null) { @@ -1913,7 +1914,7 @@ public abstract class Transition implements Cloneable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void end() { --mNumInstances; if (mNumInstances == 0) { @@ -1971,7 +1972,7 @@ public abstract class Transition implements Cloneable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void cancel() { int numAnimators = mCurrentAnimators.size(); for (int i = numAnimators - 1; i >= 0; i--) { diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java index 1b0612e87202..3d5b811f7d9c 100644 --- a/core/java/android/transition/TransitionManager.java +++ b/core/java/android/transition/TransitionManager.java @@ -19,6 +19,7 @@ package android.transition; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.util.ArrayMap; import android.util.Log; import android.view.View; @@ -215,7 +216,7 @@ public class TransitionManager { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() { WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>> runningTransitions = sRunningTransitions.get(); diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java index ee98b65d2444..4654dbfa9531 100644 --- a/core/java/android/util/EventLog.java +++ b/core/java/android/util/EventLog.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.io.BufferedReader; import java.io.FileReader; @@ -64,7 +65,7 @@ public class EventLog { private Exception mLastWtf; // Layout of event log entry received from Android logger. - // see system/core/liblog/include/log/log_read.h + // see system/logging/liblog/include/log/log_read.h private static final int LENGTH_OFFSET = 0; private static final int HEADER_SIZE_OFFSET = 2; private static final int PROCESS_OFFSET = 4; @@ -85,7 +86,7 @@ public class EventLog { private static final byte FLOAT_TYPE = 4; /** @param data containing event, read from the system */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /*package*/ Event(byte[] data) { mBuffer = ByteBuffer.wrap(data); mBuffer.order(ByteOrder.nativeOrder()); diff --git a/core/java/android/util/IconDrawableFactory.java b/core/java/android/util/IconDrawableFactory.java index 5eeb12273661..b5e8dd7ed0af 100644 --- a/core/java/android/util/IconDrawableFactory.java +++ b/core/java/android/util/IconDrawableFactory.java @@ -23,6 +23,7 @@ import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.UserHandle; import android.os.UserManager; @@ -51,7 +52,7 @@ public class IconDrawableFactory { return appInfo.isInstantApp() || mUm.hasBadge(userId); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Drawable getBadgedIcon(ApplicationInfo appInfo) { return getBadgedIcon(appInfo, UserHandle.getUserId(appInfo.uid)); } diff --git a/core/java/android/util/LocalLog.java b/core/java/android/util/LocalLog.java index bf9a8384fe2c..8c4dcb3b28e2 100644 --- a/core/java/android/util/LocalLog.java +++ b/core/java/android/util/LocalLog.java @@ -17,6 +17,7 @@ package android.util; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.SystemClock; import java.io.FileDescriptor; @@ -112,7 +113,7 @@ public final class LocalLog { ReadOnlyLocalLog(LocalLog log) { mLog = log; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { mLog.dump(pw); } @@ -127,7 +128,7 @@ public final class LocalLog { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ReadOnlyLocalLog readOnlyLocalLog() { return new ReadOnlyLocalLog(this); } diff --git a/core/java/android/util/LogWriter.java b/core/java/android/util/LogWriter.java index a674ae166d63..21b366531eac 100644 --- a/core/java/android/util/LogWriter.java +++ b/core/java/android/util/LogWriter.java @@ -17,6 +17,7 @@ package android.util; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.io.Writer; @@ -39,7 +40,7 @@ public class LogWriter extends Writer { * {@link android.util.Log#ERROR Log.ERROR}. * @param tag A string tag to associate with each printed log statement. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public LogWriter(int priority, String tag) { mPriority = priority; mTag = tag; diff --git a/core/java/android/util/LongArray.java b/core/java/android/util/LongArray.java index 93bcd6b8d4a1..53dddeb5ad0b 100644 --- a/core/java/android/util/LongArray.java +++ b/core/java/android/util/LongArray.java @@ -18,6 +18,7 @@ package android.util; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; @@ -45,7 +46,7 @@ public class LongArray implements Cloneable { /** * Creates an empty LongArray with the default initial capacity. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public LongArray() { this(10); } @@ -104,7 +105,7 @@ public class LongArray implements Cloneable { * * @throws IndexOutOfBoundsException when index < 0 || index > size() */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void add(int index, long value) { ensureCapacity(1); int rightSegment = mSize - index; @@ -208,7 +209,7 @@ public class LongArray implements Cloneable { /** * Returns the number of values in this array. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int size() { return mSize; } diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java index 0892c94d5bec..4ac3178ecb4c 100644 --- a/core/java/android/util/NtpTrustedTime.java +++ b/core/java/android/util/NtpTrustedTime.java @@ -26,6 +26,7 @@ import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkInfo; import android.net.SntpClient; +import android.os.Build; import android.os.SystemClock; import android.provider.Settings; import android.text.TextUtils; @@ -138,7 +139,7 @@ public class NtpTrustedTime implements TrustedTime { return sSingleton; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean forceRefresh() { synchronized (this) { NtpConnectionInfo connectionInfo = getNtpConnectionInfo(); @@ -181,7 +182,7 @@ public class NtpTrustedTime implements TrustedTime { * @deprecated Use {@link #getCachedTimeResult()} to obtain a {@link TimeResult} atomically. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean hasCache() { return mTimeResult != null; } @@ -208,7 +209,7 @@ public class NtpTrustedTime implements TrustedTime { * @deprecated Use {@link #getCachedTimeResult()} to obtain a {@link TimeResult} atomically. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long currentTimeMillis() { TimeResult timeResult = mTimeResult; if (timeResult == null) { @@ -227,7 +228,7 @@ public class NtpTrustedTime implements TrustedTime { * @deprecated Use {@link #getCachedTimeResult()} to obtain a {@link TimeResult} atomically. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getCachedNtpTime() { if (LOGD) Log.d(TAG, "getCachedNtpTime() cache hit"); TimeResult timeResult = mTimeResult; @@ -240,7 +241,7 @@ public class NtpTrustedTime implements TrustedTime { * @deprecated Use {@link #getCachedTimeResult()} to obtain a {@link TimeResult} atomically. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getCachedNtpTimeReference() { TimeResult timeResult = mTimeResult; return timeResult == null ? 0 : timeResult.getElapsedRealtimeMillis(); diff --git a/core/java/android/util/PathParser.java b/core/java/android/util/PathParser.java index 1e5ec0b1c5c3..9be17cf75ba7 100644 --- a/core/java/android/util/PathParser.java +++ b/core/java/android/util/PathParser.java @@ -16,6 +16,7 @@ package android.util; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Path; +import android.os.Build; import dalvik.annotation.optimization.FastNative; @@ -29,7 +30,7 @@ public class PathParser { * @param pathString The string representing a path, the same as "d" string in svg file. * @return the generated Path object. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static Path createPathFromPathData(String pathString) { if (pathString == null) { throw new IllegalArgumentException("Path string can not be null."); diff --git a/core/java/android/util/Rational.java b/core/java/android/util/Rational.java index aade6204aff8..d7730f2b0b3f 100644 --- a/core/java/android/util/Rational.java +++ b/core/java/android/util/Rational.java @@ -19,6 +19,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.io.IOException; import java.io.InvalidObjectException; @@ -77,9 +78,9 @@ public final class Rational extends Number implements Comparable<Rational> { * Do not change the order of these fields or add new instance fields to maintain the * Serializable compatibility across API revisions. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mNumerator; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mDenominator; /** diff --git a/core/java/android/util/RecurrenceRule.java b/core/java/android/util/RecurrenceRule.java index 0f2d8bc9e375..39d1f2cbef19 100644 --- a/core/java/android/util/RecurrenceRule.java +++ b/core/java/android/util/RecurrenceRule.java @@ -18,6 +18,7 @@ package android.util; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -51,7 +52,7 @@ public class RecurrenceRule implements Parcelable { @VisibleForTesting public static Clock sClock = Clock.systemDefaultZone(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final ZonedDateTime start; public final ZonedDateTime end; public final Period period; @@ -68,7 +69,7 @@ public class RecurrenceRule implements Parcelable { } @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static RecurrenceRule buildRecurringMonthly(int dayOfMonth, ZoneId zone) { // Assume we started last January, since it has all possible days final ZonedDateTime now = ZonedDateTime.now(sClock).withZoneSameInstant(zone); diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java index 2c8bbbfcf8de..3880131324fc 100644 --- a/core/java/android/util/Slog.java +++ b/core/java/android/util/Slog.java @@ -89,7 +89,7 @@ public final class Slog { * will always be handled asynchronously. Primarily for use by coding running within * the system process. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int wtf(String tag, String msg) { return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, null, false, true); } @@ -130,7 +130,7 @@ public final class Slog { return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, tr, false, true); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int println(int priority, String tag, String msg) { return Log.println_native(Log.LOG_ID_SYSTEM, priority, tag, msg); } diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java index e0b8d52aa132..cd6585cd3fa1 100644 --- a/core/java/android/util/TimeUtils.java +++ b/core/java/android/util/TimeUtils.java @@ -363,7 +363,7 @@ public class TimeUtils { * @return String representation of the time. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String logTimeOfDay(long millis) { Calendar c = Calendar.getInstance(); if (millis >= 0) { diff --git a/core/java/android/util/TrustedTime.java b/core/java/android/util/TrustedTime.java index f41fe85fa8bb..f279bdb79420 100644 --- a/core/java/android/util/TrustedTime.java +++ b/core/java/android/util/TrustedTime.java @@ -17,6 +17,7 @@ package android.util; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * Interface that provides trusted time information, possibly coming from an NTP @@ -52,7 +53,7 @@ public interface TrustedTime { * @deprecated Only kept for UnsupportedAppUsage. Do not use. See {@link NtpTrustedTime} */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getCacheAge(); /** diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java index bee04f4d8036..c41b3cf9fb72 100644 --- a/core/java/android/view/AccessibilityIterators.java +++ b/core/java/android/view/AccessibilityIterators.java @@ -18,6 +18,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Configuration; +import android.os.Build; import java.text.BreakIterator; import java.util.Locale; @@ -46,11 +47,11 @@ public final class AccessibilityIterators { */ public static abstract class AbstractTextSegmentIterator implements TextSegmentIterator { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public AbstractTextSegmentIterator() { } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected String mText; private final int[] mSegment = new int[2]; diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index b5080cdb37aa..3da3184afae1 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -854,7 +854,7 @@ public final class Choreographer { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void scheduleVsyncLocked() { mDisplayEventReceiver.scheduleVsync(); } @@ -994,7 +994,7 @@ public final class Choreographer { public Object action; // Runnable or FrameCallback public Object token; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void run(long frameTimeNanos) { if (token == FRAME_CALLBACK_TOKEN) { ((FrameCallback)action).doFrame(frameTimeNanos); diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 34e8221bc971..237ed729e0b8 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -262,6 +262,15 @@ public final class Display { public static final int FLAG_TRUSTED = 1 << 7; /** + * Flag: Indicates that the display should not be a part of the default DisplayGroup and + * instead be part of a new DisplayGroup. + * + * @hide + * @see #getFlags() + */ + public static final int FLAG_OWN_DISPLAY_GROUP = 1 << 8; + + /** * Display flag: Indicates that the contents of the display should not be scaled * to fit the physical screen dimensions. Used for development only to emulate * devices with smaller physicals screens while preserving density. @@ -289,7 +298,7 @@ public final class Display { * Display type: Physical display connected through an external port. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public static final int TYPE_EXTERNAL = 2; @@ -1400,7 +1409,7 @@ public final class Display { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Mode(int modeId, int width, int height, float refreshRate) { mModeId = modeId; mWidth = width; @@ -1583,7 +1592,7 @@ public final class Display { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public HdrCapabilities(int[] supportedHdrTypes, float maxLuminance, float maxAverageLuminance, float minLuminance) { mSupportedHdrTypes = supportedHdrTypes; diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 467d93ef3aaf..e8a4ed44b7c8 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -18,6 +18,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.FrameInfo; +import android.os.Build; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; @@ -228,7 +229,7 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void dispatchHotplug(long timestampNanos, long physicalDisplayId, boolean connected) { onHotplug(timestampNanos, physicalDisplayId, connected); } diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java index 9d8f7c3c083d..b6b029bdbb44 100644 --- a/core/java/android/view/DragEvent.java +++ b/core/java/android/view/DragEvent.java @@ -19,6 +19,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ClipDescription; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -130,9 +131,9 @@ public class DragEvent implements Parcelable { int mAction; float mX, mY; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) ClipDescription mClipDescription; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) ClipData mClipData; IDragAndDropPermissions mDragAndDropPermissions; @@ -337,7 +338,7 @@ public class DragEvent implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static DragEvent obtain(DragEvent source) { return obtain(source.mAction, source.mX, source.mY, source.mOffsetX, source.mOffsetY, source.mLocalState, source.mClipDescription, source.mClipData, source.mDragSurface, diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java index 387787e3b0be..388096e09631 100644 --- a/core/java/android/view/FrameMetrics.java +++ b/core/java/android/view/FrameMetrics.java @@ -18,6 +18,7 @@ package android.view; import android.annotation.IntDef; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -258,7 +259,7 @@ public final class FrameMetrics { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final long[] mTimingData; /** diff --git a/core/java/android/view/IRecentsAnimationRunner.aidl b/core/java/android/view/IRecentsAnimationRunner.aidl index 925786f82e00..f054b869a9b9 100644 --- a/core/java/android/view/IRecentsAnimationRunner.aidl +++ b/core/java/android/view/IRecentsAnimationRunner.aidl @@ -42,7 +42,7 @@ oneway interface IRecentsAnimationRunner { * * @see {@link RecentsAnimationController#cleanupScreenshot} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onAnimationCanceled(in @nullable ActivityManager.TaskSnapshot taskSnapshot) = 1; /** @@ -52,7 +52,7 @@ oneway interface IRecentsAnimationRunner { * @param minimizedHomeBounds Specifies the bounds of the minimized home app, will be * {@code null} if the device is not currently in split screen */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onAnimationStart(in IRecentsAnimationController controller, in RemoteAnimationTarget[] apps, in RemoteAnimationTarget[] wallpapers, in Rect homeContentInsets, in Rect minimizedHomeBounds) = 2; diff --git a/core/java/android/view/IRemoteAnimationRunner.aidl b/core/java/android/view/IRemoteAnimationRunner.aidl index 7b35aa2d2b45..423e23d2bc08 100644 --- a/core/java/android/view/IRemoteAnimationRunner.aidl +++ b/core/java/android/view/IRemoteAnimationRunner.aidl @@ -33,7 +33,7 @@ oneway interface IRemoteAnimationRunner { * @param apps The list of apps to animate. * @param finishedCallback The callback to invoke when the animation is finished. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onAnimationStart(in RemoteAnimationTarget[] apps, in RemoteAnimationTarget[] wallpapers, in IRemoteAnimationFinishedCallback finishedCallback); @@ -41,6 +41,6 @@ oneway interface IRemoteAnimationRunner { * Called when the animation was cancelled. From this point on, any updates onto the leashes * won't have any effect anymore. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onAnimationCancelled(); } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 43a8992aa74e..11423e6de93e 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -184,7 +184,7 @@ interface IWindowManager * Used by system ui to report that recents has shown itself. * @deprecated to be removed once prebuilts are updated */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void endProlongedAnimations(); void startFreezingScreen(int exitAnim, int enterAnim); @@ -198,7 +198,7 @@ interface IWindowManager void exitKeyguardSecurely(IOnKeyguardExitResult callback); @UnsupportedAppUsage boolean isKeyguardLocked(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isKeyguardSecure(int userId); void dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message); @@ -210,11 +210,11 @@ interface IWindowManager // These can only be called with the SET_ANIMATON_SCALE permission. @UnsupportedAppUsage float getAnimationScale(int which); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) float[] getAnimationScales(); @UnsupportedAppUsage void setAnimationScale(int which, float scale); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setAnimationScales(in float[] scales); float getCurrentAnimatorScale(); @@ -235,7 +235,7 @@ interface IWindowManager // should be enabled. The 'enabled' value is null or blank for // the system default (differs per build variant) or any valid // boolean string as parsed by SystemProperties.getBoolean(). - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setStrictModeVisualIndicatorPreference(String enabled); /** @@ -411,7 +411,7 @@ interface IWindowManager /** * Lock the device immediately with the specified options (can be null). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void lockNow(in Bundle options); /** @@ -755,6 +755,8 @@ interface IWindowManager /** * Holds the WM lock for the specified amount of milliseconds. * Intended for use by the tests that need to imitate lock contention. + * The token should be obtained by + * {@link android.content.pm.PackageManager#getHoldLockToken()}. */ - void holdLock(in int durationMs); + void holdLock(in IBinder token, in int durationMs); } diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 9febc9f09ef3..0089a852a893 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -178,7 +178,7 @@ interface IWindowSession { * @param data Data transferred by drag and drop * @return Token of drag operation which will be passed to cancelDragAndDrop. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) IBinder performDrag(IWindow window, int flags, in SurfaceControl surface, int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY, in ClipData data); diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java index f2d3f5ad08bf..f76b1f89625b 100644 --- a/core/java/android/view/InputChannel.java +++ b/core/java/android/view/InputChannel.java @@ -17,6 +17,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -54,7 +55,7 @@ public final class InputChannel implements Parcelable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mPtr; // used by native code private static native long[] nativeOpenInputChannelPair(String name); diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index 58e5b2dfaa37..22ac4dcd2cfe 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -424,7 +424,7 @@ public final class InputDevice implements Parcelable { }; // Called by native code. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId, int productId, String descriptor, boolean isExternal, int sources, int keyboardType, KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone, @@ -757,7 +757,7 @@ public final class InputDevice implements Parcelable { } // Called from native code. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void addMotionRange(int axis, int source, float min, float max, float flat, float fuzz, float resolution) { mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz, resolution)); diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java index a06a0c68e241..038dff654ba6 100644 --- a/core/java/android/view/InputEventReceiver.java +++ b/core/java/android/view/InputEventReceiver.java @@ -17,6 +17,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.IBinder; import android.os.Looper; import android.os.MessageQueue; @@ -124,7 +125,7 @@ public abstract class InputEventReceiver { * * @param event The input event that was received. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onInputEvent(InputEvent event) { finishInputEvent(event, false); } @@ -216,7 +217,7 @@ public abstract class InputEventReceiver { // Called from native code. @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void dispatchInputEvent(int seq, InputEvent event) { mSeqMap.put(event.getSequenceNumber(), seq); onInputEvent(event); diff --git a/core/java/android/view/InputEventSender.java b/core/java/android/view/InputEventSender.java index 86a309e3ed79..40eb438262a1 100644 --- a/core/java/android/view/InputEventSender.java +++ b/core/java/android/view/InputEventSender.java @@ -17,6 +17,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; @@ -138,7 +139,7 @@ public abstract class InputEventSender { // Called from native code. @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void dispatchInputEventFinished(int seq, boolean handled) { onInputEventFinished(seq, handled); } diff --git a/core/java/android/view/InputFilter.java b/core/java/android/view/InputFilter.java index 36d558630da9..b18c5cdb2aab 100644 --- a/core/java/android/view/InputFilter.java +++ b/core/java/android/view/InputFilter.java @@ -17,6 +17,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -118,7 +119,7 @@ public abstract class InputFilter extends IInputFilter.Stub { * * @param looper The looper to run callbacks on. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public InputFilter(Looper looper) { mH = new H(looper); } @@ -188,7 +189,7 @@ public abstract class InputFilter extends IInputFilter.Stub { * @param event The input event that was received. * @param policyFlags The input event policy flags. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onInputEvent(InputEvent event, int policyFlags) { sendInputEvent(event, policyFlags); } diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java index 74ce6ac02db3..7accb66aa3aa 100644 --- a/core/java/android/view/InputQueue.java +++ b/core/java/android/view/InputQueue.java @@ -17,6 +17,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Looper; import android.os.MessageQueue; import android.util.LongSparseArray; @@ -101,7 +102,7 @@ public final class InputQueue { mActiveEventArray.put(id, event); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void finishInputEvent(long id, boolean handled) { int index = mActiveEventArray.indexOfKey(id); if (index >= 0) { diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java index 90e0f3f89a0f..02a97888cffd 100644 --- a/core/java/android/view/KeyCharacterMap.java +++ b/core/java/android/view/KeyCharacterMap.java @@ -18,6 +18,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; import android.hardware.input.InputManager; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.method.MetaKeyKeyListener; @@ -308,7 +309,7 @@ public class KeyCharacterMap implements Parcelable { } // Called from native - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private KeyCharacterMap(long ptr) { mPtr = ptr; } @@ -750,9 +751,9 @@ public class KeyCharacterMap implements Parcelable { private FallbackAction next; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int keyCode; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int metaState; private FallbackAction() { diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index 0ab1751fbf95..c87e51e35891 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -849,7 +849,7 @@ public class KeyEvent extends InputEvent implements Parcelable { // Symbolic names of all metakeys in bit order from least significant to most significant. // Accordingly there are exactly 32 values in this table. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final String[] META_SYMBOLIC_NAMES = new String[] { "META_SHIFT_ON", "META_ALT_ON", @@ -920,7 +920,7 @@ public class KeyEvent extends InputEvent implements Parcelable { * Reserved for use by {@link MetaKeyKeyListener} for a published constant in its API. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int META_CAP_LOCKED = 0x100; /** @@ -928,7 +928,7 @@ public class KeyEvent extends InputEvent implements Parcelable { * Reserved for use by {@link MetaKeyKeyListener} for a published constant in its API. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int META_ALT_LOCKED = 0x200; /** @@ -936,7 +936,7 @@ public class KeyEvent extends InputEvent implements Parcelable { * Reserved for use by {@link MetaKeyKeyListener} for a published constant in its API. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int META_SYM_LOCKED = 0x400; /** @@ -945,7 +945,7 @@ public class KeyEvent extends InputEvent implements Parcelable { * in its API that is currently being retained for legacy reasons. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int META_SELECTING = 0x800; /** @@ -1266,29 +1266,29 @@ public class KeyEvent extends InputEvent implements Parcelable { private KeyEvent mNext; private int mId; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mDeviceId; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mSource; private int mDisplayId; private @Nullable byte[] mHmac; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mMetaState; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mAction; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mKeyCode; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mScanCode; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mRepeatCount; @UnsupportedAppUsage private int mFlags; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mDownTime; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mEventTime; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String mCharacters; public interface Callback { @@ -1651,7 +1651,7 @@ public class KeyEvent extends InputEvent implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static KeyEvent obtain(long downTime, long eventTime, int action, int code, int repeat, int metaState, int deviceId, int scancode, int flags, int source, String characters) { @@ -2103,7 +2103,7 @@ public class KeyEvent extends InputEvent implements Parcelable { } // Mask of all modifier key meta states. Specifically excludes locked keys like caps lock. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int META_MODIFIER_MASK = META_SHIFT_ON | META_SHIFT_LEFT_ON | META_SHIFT_RIGHT_ON | META_ALT_ON | META_ALT_LEFT_ON | META_ALT_RIGHT_ON @@ -2112,23 +2112,23 @@ public class KeyEvent extends InputEvent implements Parcelable { | META_SYM_ON | META_FUNCTION_ON; // Mask of all lock key meta states. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int META_LOCK_MASK = META_CAPS_LOCK_ON | META_NUM_LOCK_ON | META_SCROLL_LOCK_ON; // Mask of all valid meta states. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int META_ALL_MASK = META_MODIFIER_MASK | META_LOCK_MASK; // Mask of all synthetic meta states that are reserved for API compatibility with // historical uses in MetaKeyKeyListener. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int META_SYNTHETIC_MASK = META_CAP_LOCKED | META_ALT_LOCKED | META_SYM_LOCKED | META_SELECTING; // Mask of all meta states that are not valid use in specifying a modifier key. // These bits are known to be used for purposes other than specifying modifiers. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int META_INVALID_MODIFIER_MASK = META_LOCK_MASK | META_SYNTHETIC_MASK; diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index b925b492c04b..66c514824e35 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -956,7 +956,7 @@ public abstract class LayoutInflater { * argument and should be used for everything except {@code >include>} * tag parsing. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private View createViewFromTag(View parent, String name, Context context, AttributeSet attrs) { return createViewFromTag(parent, name, context, attrs, false); } @@ -976,7 +976,7 @@ public abstract class LayoutInflater { * attribute (if set) for the view being inflated, * {@code false} otherwise */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) View createViewFromTag(View parent, String name, Context context, AttributeSet attrs, boolean ignoreThemeAttr) { if (name.equals("view")) { diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index abb82bc9e16b..a8d261553a8f 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -1484,7 +1484,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { } // Private value for history pos that obtains the current sample. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int HISTORY_CURRENT = -0x80000000; // This is essentially the same as native AMOTION_EVENT_INVALID_CURSOR_POSITION as they're all diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java index 726176568605..2bd3d46d389a 100644 --- a/core/java/android/view/NotificationHeaderView.java +++ b/core/java/android/view/NotificationHeaderView.java @@ -25,6 +25,7 @@ import android.graphics.Canvas; import android.graphics.Outline; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Build; import android.util.AttributeSet; import android.widget.RemoteViews; @@ -68,7 +69,7 @@ public class NotificationHeaderView extends ViewGroup { this(context, null); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NotificationHeaderView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } diff --git a/core/java/android/view/NotificationTopLineView.java b/core/java/android/view/NotificationTopLineView.java index 9443ccfc7553..24748222b3af 100644 --- a/core/java/android/view/NotificationTopLineView.java +++ b/core/java/android/view/NotificationTopLineView.java @@ -19,6 +19,7 @@ package android.view; import android.annotation.Nullable; import android.content.Context; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Rect; import android.util.AttributeSet; import android.widget.RemoteViews; @@ -36,6 +37,7 @@ import java.util.List; */ @RemoteViews.RemoteView public class NotificationTopLineView extends ViewGroup { + private final int mGravityY; private final int mChildMinWidth; private final int mContentEndMargin; private View mAppName; @@ -48,6 +50,9 @@ public class NotificationTopLineView extends ViewGroup { private int mHeaderTextMarginEnd; private List<View> mIconsAtEnd; + private int mMaxAscent; + private int mMaxDescent; + public NotificationTopLineView(Context context) { this(context, null); } @@ -67,6 +72,20 @@ public class NotificationTopLineView extends ViewGroup { Resources res = getResources(); mChildMinWidth = res.getDimensionPixelSize(R.dimen.notification_header_shrink_min_width); mContentEndMargin = res.getDimensionPixelSize(R.dimen.notification_content_margin_end); + + // NOTE: Implementation only supports TOP, BOTTOM, and CENTER_VERTICAL gravities, + // with CENTER_VERTICAL being the default. + int[] attrIds = {android.R.attr.gravity}; + TypedArray ta = context.obtainStyledAttributes(attrs, attrIds, defStyleAttr, defStyleRes); + int gravity = ta.getInt(0, 0); + ta.recycle(); + if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) { + mGravityY = Gravity.BOTTOM; + } else if ((gravity & Gravity.TOP) == Gravity.TOP) { + mGravityY = Gravity.TOP; + } else { + mGravityY = Gravity.CENTER_VERTICAL; + } } @Override @@ -84,12 +103,16 @@ public class NotificationTopLineView extends ViewGroup { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int givenWidth = MeasureSpec.getSize(widthMeasureSpec); final int givenHeight = MeasureSpec.getSize(heightMeasureSpec); + final boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST; int wrapContentWidthSpec = MeasureSpec.makeMeasureSpec(givenWidth, MeasureSpec.AT_MOST); int wrapContentHeightSpec = MeasureSpec.makeMeasureSpec(givenHeight, MeasureSpec.AT_MOST); int totalWidth = getPaddingStart(); int iconWidth = getPaddingEnd(); + int maxChildHeight = -1; + mMaxAscent = -1; + mMaxDescent = -1; for (int i = 0; i < getChildCount(); i++) { final View child = getChildAt(i); if (child.getVisibility() == GONE) { @@ -108,6 +131,13 @@ public class NotificationTopLineView extends ViewGroup { } else { totalWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth(); } + int childBaseline = child.getBaseline(); + int childHeight = child.getMeasuredHeight(); + if (childBaseline != -1) { + mMaxAscent = Math.max(mMaxAscent, childBaseline); + mMaxDescent = Math.max(mMaxDescent, childHeight - childBaseline); + } + maxChildHeight = Math.max(maxChildHeight, childHeight); } // Ensure that there is at least enough space for the icons @@ -125,7 +155,7 @@ public class NotificationTopLineView extends ViewGroup { shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mSecondaryHeaderText, 0); } - setMeasuredDimension(givenWidth, givenHeight); + setMeasuredDimension(givenWidth, wrapHeight ? maxChildHeight : givenHeight); } private int shrinkViewForOverflow(int heightSpec, int overFlow, View targetView, @@ -146,7 +176,13 @@ public class NotificationTopLineView extends ViewGroup { int left = getPaddingStart(); int end = getMeasuredWidth(); int childCount = getChildCount(); - int ownHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); + int ownHeight = b - t; + int childSpace = ownHeight - mPaddingTop - mPaddingBottom; + + // Instead of centering the baseline, pick a baseline that centers views which align to it. + // Only used when mGravityY is CENTER_VERTICAL + int baselineY = mPaddingTop + ((childSpace - (mMaxAscent + mMaxDescent)) / 2) + mMaxAscent; + for (int i = 0; i < childCount; i++) { View child = getChildAt(i); if (child.getVisibility() == GONE) { @@ -156,8 +192,42 @@ public class NotificationTopLineView extends ViewGroup { MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams(); int layoutLeft; int layoutRight; - int top = (int) (getPaddingTop() + (ownHeight - childHeight) / 2.0f); - int bottom = top + childHeight; + + // Calculate vertical alignment of the views, accounting for the view baselines + int childTop; + int childBaseline = child.getBaseline(); + switch (mGravityY) { + case Gravity.TOP: + childTop = mPaddingTop + params.topMargin; + if (childBaseline != -1) { + childTop += mMaxAscent - childBaseline; + } + break; + case Gravity.CENTER_VERTICAL: + if (childBaseline != -1) { + // Align baselines vertically only if the child is smaller than us + if (childSpace - childHeight > 0) { + childTop = baselineY - childBaseline; + } else { + childTop = mPaddingTop + (childSpace - childHeight) / 2; + } + } else { + childTop = mPaddingTop + ((childSpace - childHeight) / 2) + + params.topMargin - params.bottomMargin; + } + break; + case Gravity.BOTTOM: + int childBottom = ownHeight - mPaddingBottom; + childTop = childBottom - childHeight - params.bottomMargin; + if (childBaseline != -1) { + int descent = childHeight - childBaseline; + childTop -= (mMaxDescent - descent); + } + break; + default: + childTop = mPaddingTop; + } + // Icons that should go at the end if (mIconsAtEnd.contains(child)) { if (end == getMeasuredWidth()) { @@ -179,7 +249,7 @@ public class NotificationTopLineView extends ViewGroup { layoutLeft = getWidth() - layoutRight; layoutRight = getWidth() - ltrLeft; } - child.layout(layoutLeft, top, layoutRight, bottom); + child.layout(layoutLeft, childTop, layoutRight, childTop + childHeight); } updateTouchListener(); } diff --git a/core/java/android/view/OnReceiveContentCallback.java b/core/java/android/view/OnReceiveContentCallback.java index a217ff642ab7..d74938c1d1fd 100644 --- a/core/java/android/view/OnReceiveContentCallback.java +++ b/core/java/android/view/OnReceiveContentCallback.java @@ -19,9 +19,7 @@ package android.view; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SuppressLint; import android.content.ClipData; -import android.content.ClipDescription; import android.net.Uri; import android.os.Bundle; @@ -30,11 +28,10 @@ import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; -import java.util.Set; /** - * Callback for apps to implement handling for insertion of content. "Content" here refers to both - * text and non-text (plain/styled text, HTML, images, videos, audio files, etc). + * Callback for apps to implement handling for insertion of content. Content may be both text and + * non-text (plain/styled text, HTML, images, videos, audio files, etc). * * <p>This callback can be attached to different types of UI components using * {@link View#setOnReceiveContentCallback}. @@ -45,32 +42,38 @@ import java.util.Set; * * <p>Example implementation:<br> * <pre class="prettyprint"> + * // (1) Define the callback * public class MyOnReceiveContentCallback implements OnReceiveContentCallback<TextView> { - * - * private static final Set<String> SUPPORTED_MIME_TYPES = Collections.unmodifiableSet( + * public static final Set<String> MIME_TYPES = Collections.unmodifiableSet( * Set.of("image/*", "video/*")); * - * @NonNull - * @Override - * public Set<String> getSupportedMimeTypes() { - * return SUPPORTED_MIME_TYPES; - * } - * * @Override * public boolean onReceiveContent(@NonNull TextView view, @NonNull Payload payload) { * // ... app-specific logic to handle the content in the payload ... * } * } + * + * // (2) Register the callback + * public class MyActivity extends Activity { + * @Override + * public void onCreate(Bundle savedInstanceState) { + * // ... + * + * EditText myInput = findViewById(R.id.my_input); + * myInput.setOnReceiveContentCallback( + * MyOnReceiveContentCallback.MIME_TYPES, + * new MyOnReceiveContentCallback()); + * } * </pre> * - * @param <T> The type of {@link View} with which this receiver can be associated. + * @param <T> The type of {@link View} with which this callback can be associated. */ public interface OnReceiveContentCallback<T extends View> { /** * Receive the given content. * - * <p>This function will only be invoked if the MIME type of the content is in the set of - * types returned by {@link #getSupportedMimeTypes}. + * <p>This method is only invoked for content whose MIME type matches a type specified via + * {@link View#setOnReceiveContentCallback}. * * <p>For text, if the view has a selection, the selection should be overwritten by the clip; if * there's no selection, this method should insert the content at the current cursor position. @@ -81,54 +84,14 @@ public interface OnReceiveContentCallback<T extends View> { * @param view The view where the content insertion was requested. * @param payload The content to insert and related metadata. * - * @return Returns true if some or all of the content is accepted for insertion. If accepted, - * actual insertion may be handled asynchronously in the background and may or may not result in - * successful insertion. For example, the app may not end up inserting an accepted item if it + * @return Returns true if the content was handled in some way, false otherwise. Actual + * insertion may be processed asynchronously in the background and may or may not succeed even + * if this method returns true. For example, an app may not end up inserting an item if it * exceeds the app's size limit for that type of content. */ boolean onReceiveContent(@NonNull T view, @NonNull Payload payload); /** - * Returns the MIME types that can be handled by this callback. - * - * <p>The {@link #onReceiveContent} callback method will only be invoked if the MIME type of the - * content is in the set of supported types returned here. - * - * <p>Different platform features (e.g. pasting from the clipboard, inserting stickers from the - * keyboard, etc) may use this function to conditionally alter their behavior. For example, the - * keyboard may choose to hide its UI for inserting GIFs if the input field that has focus has - * a {@link OnReceiveContentCallback} set and the MIME types returned from this function don't - * include "image/gif". - * - * <p><em>Note: MIME type matching in the Android framework is case-sensitive, unlike formal RFC - * MIME types. As a result, you should always write your MIME types with lower case letters, or - * use {@link android.content.Intent#normalizeMimeType} to ensure that it is converted to lower - * case.</em> - * - * @param view The target view. - * @return An immutable set with the MIME types supported by this callback. The returned MIME - * types may contain wildcards such as "text/*", "image/*", etc. - */ - @SuppressLint("CallbackMethodName") - @NonNull - Set<String> getSupportedMimeTypes(@NonNull T view); - - /** - * Returns true if at least one of the MIME types of the given clip is - * {@link #getSupportedMimeTypes supported} by this receiver. - * - * @hide - */ - default boolean supports(@NonNull T view, @NonNull ClipDescription description) { - for (String supportedMimeType : getSupportedMimeTypes(view)) { - if (description.hasMimeType(supportedMimeType)) { - return true; - } - } - return false; - } - - /** * Holds all the relevant data for a request to {@link OnReceiveContentCallback}. */ final class Payload { diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java index f60d98b2dc23..38ae03db3290 100644 --- a/core/java/android/view/PointerIcon.java +++ b/core/java/android/view/PointerIcon.java @@ -153,17 +153,17 @@ public final class PointerIcon implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final int mType; private int mSystemIconResourceId; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Bitmap mBitmap; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mHotSpotX; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mHotSpotY; // The bitmaps for the additional frame of animated pointer icon. Note that the first frame // will be stored in mBitmap. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Bitmap mBitmapFrames[]; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mDurationPerFrame; /** diff --git a/core/java/android/view/RemoteAnimationAdapter.java b/core/java/android/view/RemoteAnimationAdapter.java index 166d3baa2fdf..a78036fba094 100644 --- a/core/java/android/view/RemoteAnimationAdapter.java +++ b/core/java/android/view/RemoteAnimationAdapter.java @@ -18,6 +18,7 @@ package android.view; import android.app.ActivityOptions; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -65,7 +66,7 @@ public class RemoteAnimationAdapter implements Parcelable { * @param statusBarTransitionDelay The desired delay for all visual animations in the * status bar caused by this app animation in millis. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public RemoteAnimationAdapter(IRemoteAnimationRunner runner, long duration, long statusBarTransitionDelay, boolean changeNeedsSnapshot) { mRunner = runner; diff --git a/core/java/android/view/RemoteAnimationTarget.java b/core/java/android/view/RemoteAnimationTarget.java index e3129b639900..ac5d14e97c85 100644 --- a/core/java/android/view/RemoteAnimationTarget.java +++ b/core/java/android/view/RemoteAnimationTarget.java @@ -38,6 +38,7 @@ import android.app.WindowConfiguration; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Point; import android.graphics.Rect; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.proto.ProtoOutputStream; @@ -98,7 +99,7 @@ public class RemoteAnimationTarget implements Parcelable { * The {@link SurfaceControl} for the starting state of a target if this transition is * MODE_CHANGING, {@code null)} otherwise. This is relative to the app window. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final SurfaceControl startLeash; /** @@ -171,7 +172,7 @@ public class RemoteAnimationTarget implements Parcelable { * should be equivalent to the size of the starting thumbnail. Note that sourceContainerBounds * is the end bounds of a change transition. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final Rect startBounds; /** diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 0847a179c553..5b79174a6cd8 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -34,6 +34,7 @@ import android.graphics.Rect; import android.graphics.RenderNode; import android.graphics.SurfaceTexture; import android.hardware.HardwareBuffer; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; @@ -74,7 +75,7 @@ public class Surface implements Parcelable { throws OutOfResourcesException; private static native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native void nativeRelease(long nativeObject); private static native boolean nativeIsValid(long nativeObject); private static native boolean nativeIsConsumerRunningBehind(long nativeObject); @@ -127,7 +128,7 @@ public class Surface implements Parcelable { private String mName; @UnsupportedAppUsage long mNativeObject; // package scope only for SurfaceControl access - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mLockedObject; private int mGenerationId; // incremented each time mNativeObject changes private final Canvas mCanvas = new CompatibleCanvas(); @@ -264,7 +265,7 @@ public class Surface implements Parcelable { } /* called from android_view_Surface_createFromIGraphicBufferProducer() */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Surface(long nativeObject) { synchronized (mLock) { setNativeObjectLocked(nativeObject); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 6d6fabb16b72..3a15aa26e357 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -309,7 +309,7 @@ public final class SurfaceControl implements Parcelable { * Surface creation flag: Surface is created hidden * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int HIDDEN = 0x00000004; /** @@ -653,12 +653,14 @@ public final class SurfaceControl implements Parcelable { private final Rect mSourceCrop = new Rect(); private final float mFrameScale; private final boolean mCaptureSecureLayers; + private final boolean mAllowProtected; private CaptureArgs(Builder<? extends Builder<?>> builder) { mPixelFormat = builder.mPixelFormat; mSourceCrop.set(builder.mSourceCrop); mFrameScale = builder.mFrameScale; mCaptureSecureLayers = builder.mCaptureSecureLayers; + mAllowProtected = builder.mAllowProtected; } /** @@ -671,6 +673,7 @@ public final class SurfaceControl implements Parcelable { private final Rect mSourceCrop = new Rect(); private float mFrameScale = 1; private boolean mCaptureSecureLayers; + private boolean mAllowProtected; /** * The desired pixel format of the returned buffer. @@ -709,6 +712,17 @@ public final class SurfaceControl implements Parcelable { } /** + * Whether to allow the screenshot of protected (DRM) content. Warning: The screenshot + * cannot be read in unprotected space. + * + * @see HardwareBuffer#USAGE_PROTECTED_CONTENT + */ + public T setAllowProtected(boolean allowProtected) { + mAllowProtected = allowProtected; + return getThis(); + } + + /** * Each sub class should return itself to allow the builder to chain properly */ abstract T getThis(); @@ -1907,16 +1921,23 @@ public final class SurfaceControl implements Parcelable { public float appRequestRefreshRateMin; public float appRequestRefreshRateMax; + /** + * If true this will allow switching between modes in different display configuration + * groups. This way the user may see visual interruptions when the display mode changes. + */ + public boolean allowGroupSwitching; + public DesiredDisplayConfigSpecs() {} public DesiredDisplayConfigSpecs(DesiredDisplayConfigSpecs other) { copyFrom(other); } - public DesiredDisplayConfigSpecs(int defaultConfig, float primaryRefreshRateMin, - float primaryRefreshRateMax, float appRequestRefreshRateMin, - float appRequestRefreshRateMax) { + public DesiredDisplayConfigSpecs(int defaultConfig, boolean allowGroupSwitching, + float primaryRefreshRateMin, float primaryRefreshRateMax, + float appRequestRefreshRateMin, float appRequestRefreshRateMax) { this.defaultConfig = defaultConfig; + this.allowGroupSwitching = allowGroupSwitching; this.primaryRefreshRateMin = primaryRefreshRateMin; this.primaryRefreshRateMax = primaryRefreshRateMax; this.appRequestRefreshRateMin = appRequestRefreshRateMin; @@ -2898,7 +2919,7 @@ public final class SurfaceControl implements Parcelable { * @return Itself. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) { checkPreconditions(sc); nativeSetCornerRadius(mNativeObject, sc.mNativeObject, cornerRadius); diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java index 0f851c1881f5..cbc0479a4c07 100644 --- a/core/java/android/view/SurfaceSession.java +++ b/core/java/android/view/SurfaceSession.java @@ -17,6 +17,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * An instance of this class represents a connection to the surface @@ -26,7 +27,7 @@ import android.compat.annotation.UnsupportedAppUsage; */ public final class SurfaceSession { // Note: This field is accessed by native code. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeClient; // SurfaceComposerClient* private static native long nativeCreate(); diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index a02070a21ac8..fc0ec4c560d4 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.graphics.TextureLayer; import android.graphics.drawable.Drawable; +import android.os.Build; import android.util.AttributeSet; import android.util.Log; @@ -117,7 +118,7 @@ public class TextureView extends View { private SurfaceTextureListener mListener; private boolean mHadSurface; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mOpaque = true; private final Matrix mMatrix = new Matrix(); @@ -125,7 +126,7 @@ public class TextureView extends View { private final Object[] mLock = new Object[0]; private boolean mUpdateLayer; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mUpdateSurface; private Canvas mCanvas; @@ -133,7 +134,7 @@ public class TextureView extends View { private final Object[] mNativeWindowLock = new Object[0]; // Set by native code, do not write! - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeWindow; /** @@ -227,7 +228,7 @@ public class TextureView extends View { /** @hide */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void onDetachedFromWindowInternal() { destroyHardwareLayer(); releaseSurfaceTexture(); @@ -244,7 +245,7 @@ public class TextureView extends View { destroyHardwareLayer(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void destroyHardwareLayer() { if (mLayer != null) { mLayer.detachSurfaceTexture(); @@ -853,9 +854,9 @@ public class TextureView extends View { void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private native void nCreateNativeWindow(SurfaceTexture surface); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private native void nDestroyNativeWindow(); private static native boolean nLockCanvas(long nativeWindow, Canvas canvas, Rect dirty); diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java index 1f71924ca927..e1c4305e8747 100644 --- a/core/java/android/view/VelocityTracker.java +++ b/core/java/android/view/VelocityTracker.java @@ -18,6 +18,7 @@ package android.view; import android.annotation.IntDef; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.SystemProperties; import android.util.ArrayMap; import android.util.Pools.SynchronizedPool; @@ -436,25 +437,25 @@ public final class VelocityTracker { /** * Polynomial coefficients describing motion in X. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final float[] xCoeff = new float[MAX_DEGREE + 1]; /** * Polynomial coefficients describing motion in Y. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final float[] yCoeff = new float[MAX_DEGREE + 1]; /** * Polynomial degree, or zero if only position information is available. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int degree; /** * Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public float confidence; /** diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index ce43922e7a2d..cefddd84ee32 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -47,6 +47,7 @@ import android.annotation.UiThread; import android.compat.annotation.UnsupportedAppUsage; import android.content.AutofillOptions; import android.content.ClipData; +import android.content.ClipDescription; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; @@ -143,6 +144,7 @@ import android.widget.ScrollBarDrawable; import com.android.internal.R; import com.android.internal.util.FrameworkStatsLog; +import com.android.internal.util.Preconditions; import com.android.internal.view.ScrollCaptureInternal; import com.android.internal.view.TooltipPopup; import com.android.internal.view.menu.MenuBuilder; @@ -809,7 +811,7 @@ import java.util.function.Predicate; @UiThread public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final boolean DBG = false; /** @hide */ @@ -2409,7 +2411,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private int mAutofillViewId = NO_ID; // ID for accessibility purposes. This ID must be unique for every window - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mAccessibilityViewId = NO_ID; private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED; @@ -2421,7 +2423,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #setTag(Object) * @see #getTag() */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected Object mTag = null; /* @@ -3888,7 +3890,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Flag to make the status bar not expandable. Unless you also * set {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000; /** @@ -4551,7 +4553,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private LongSparseLongArray mMeasureCache; @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Drawable mBackground; private TintInfo mBackgroundTint; @@ -4669,7 +4671,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * This field should be made private, so it is hidden from the SDK. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected OnCreateContextMenuListener mOnCreateContextMenuListener; @UnsupportedAppUsage @@ -4678,13 +4680,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @UnsupportedAppUsage private OnTouchListener mOnTouchListener; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private OnHoverListener mOnHoverListener; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private OnGenericMotionListener mOnGenericMotionListener; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private OnDragListener mOnDragListener; private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener; @@ -5113,7 +5115,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean mCachingFailed; @UnsupportedAppUsage private Bitmap mDrawingCache; @@ -5243,7 +5245,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int mUnbufferedInputSource = InputDevice.SOURCE_CLASS_NONE; @Nullable - private OnReceiveContentCallback<? extends View> mOnReceiveContentCallback; + private String[] mOnReceiveContentMimeTypes; + @Nullable + private OnReceiveContentCallback mOnReceiveContentCallback; /** * Simple constructor to use when creating a view from code. @@ -6850,7 +6854,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private ScrollabilityCache getScrollCache() { initScrollCache(); return mScrollCache; @@ -9001,36 +9005,78 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Returns the callback used for handling insertion of content into this view. See - * {@link #setOnReceiveContentCallback} for more info. - * - * @return The callback for handling insertion of content. Returns null if no callback has been - * {@link #setOnReceiveContentCallback set}. - */ - @Nullable - public OnReceiveContentCallback<? extends View> getOnReceiveContentCallback() { - return mOnReceiveContentCallback; - } - - /** * Sets the callback to handle insertion of content into this view. * * <p>Depending on the view, this callback may be invoked for scenarios such as content * insertion from the IME, Autofill, etc. * - * <p>The callback will only be invoked if the MIME type of the content is - * {@link OnReceiveContentCallback#getSupportedMimeTypes declared as supported} by the callback. - * If the content type is not supported by the callback, the default platform handling will be - * executed instead. + * <p>This callback is only invoked for content whose MIME type matches a type specified via + * the {code mimeTypes} parameter. If the MIME type is not supported by the callback, the + * default platform handling will be executed instead (no-op for the default {@link View}). * + * <p><em>Note: MIME type matching in the Android framework is case-sensitive, unlike formal RFC + * MIME types. As a result, you should always write your MIME types with lower case letters, or + * use {@link android.content.Intent#normalizeMimeType} to ensure that it is converted to lower + * case.</em> + * + * @param mimeTypes The type of content for which the callback should be invoked. This may use + * wildcards such as "text/*", "image/*", etc. This must not be null or empty if a non-null + * callback is passed in. * @param callback The callback to use. This can be null to reset to the default behavior. */ - public void setOnReceiveContentCallback( - @Nullable OnReceiveContentCallback<? extends View> callback) { + @SuppressWarnings("rawtypes") + public void setOnReceiveContentCallback(@Nullable String[] mimeTypes, + @Nullable OnReceiveContentCallback callback) { + if (callback != null) { + Preconditions.checkArgument(mimeTypes != null && mimeTypes.length > 0, + "When the callback is set, MIME types must also be set"); + } + mOnReceiveContentMimeTypes = mimeTypes; mOnReceiveContentCallback = callback; } /** + * Receives the given content. The default implementation invokes the callback set via + * {@link #setOnReceiveContentCallback}. If no callback is set or if the callback does not + * support the given content (based on the MIME type), returns false. + * + * @param payload The content to insert and related metadata. + * + * @return Returns true if the content was handled in some way, false otherwise. Actual + * insertion may be processed asynchronously in the background and may or may not succeed even + * if this method returns true. For example, an app may not end up inserting an item if it + * exceeds the app's size limit for that type of content. + */ + public boolean onReceiveContent(@NonNull OnReceiveContentCallback.Payload payload) { + ClipDescription description = payload.getClip().getDescription(); + if (mOnReceiveContentCallback != null && mOnReceiveContentMimeTypes != null + && description.hasMimeType(mOnReceiveContentMimeTypes)) { + return mOnReceiveContentCallback.onReceiveContent(this, payload); + } + return false; + } + + /** + * Returns the MIME types that can be handled by {@link #onReceiveContent} for this view, as + * configured via {@link #setOnReceiveContentCallback}. By default returns null. + * + * <p>Different platform features (e.g. pasting from the clipboard, inserting stickers from the + * keyboard, etc) may use this function to conditionally alter their behavior. For example, the + * soft keyboard may choose to hide its UI for inserting GIFs for a particular input field if + * the MIME types returned here for that field don't include "image/gif". + * + * <p>Note: Comparisons of MIME types should be performed using utilities such as + * {@link ClipDescription#compareMimeTypes} rather than simple string equality, in order to + * correctly handle patterns (e.g. "text/*"). + * + * @return The MIME types supported by {@link #onReceiveContent} for this view. The returned + * MIME types may contain wildcards such as "text/*", "image/*", etc. + */ + public @Nullable String[] getOnReceiveContentMimeTypes() { + return mOnReceiveContentMimeTypes; + } + + /** * Automatically fills the content of this view with the {@code value}. * * <p>Views support the Autofill Framework mainly by: @@ -10368,7 +10414,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected boolean isVisibleToUser(Rect boundInView) { if (mAttachInfo != null) { // Attached to invisible window means this view is not visible. @@ -10756,7 +10802,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide pending API council approval */ @CallSuper - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void onFocusLost() { resetPressedState(); } @@ -11648,7 +11694,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean fitsSystemWindows() { return getFitsSystemWindows(); } @@ -13709,7 +13755,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) { if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) { return; @@ -14129,7 +14175,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public TextSegmentIterator getIteratorForGranularity(int granularity) { switch (granularity) { case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER: { @@ -14596,7 +14642,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return True if the event was handled by the view, false otherwise. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final boolean dispatchPointerEvent(MotionEvent event) { if (event.isTouchEvent()) { return dispatchTouchEvent(event); @@ -15916,7 +15962,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isInScrollingContainer() { ViewParent p = getParent(); while (p != null && p instanceof ViewGroup) { @@ -16646,7 +16692,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return The inverse of the current matrix of this view. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final Matrix getInverseMatrix() { ensureTransformationInfo(); if (mTransformationInfo.mInverseMatrix == null) { @@ -18688,7 +18734,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void invalidateParentIfNeeded() { if (isHardwareAccelerated() && mParent instanceof View) { ((View) mParent).invalidate(true); @@ -18795,7 +18841,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ThreadedRenderer getThreadedRenderer() { return mAttachInfo != null ? mAttachInfo.mThreadedRenderer : null; } @@ -19932,7 +19978,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #computeHorizontalScrollOffset() * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) { scrollBar.setBounds(l, t, r, b); @@ -20115,7 +20161,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Return true if the application tag in the AndroidManifest has set "supportRtl" to true */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean hasRtlSupport() { return mContext.getApplicationInfo().hasRtlSupport(); } @@ -20273,7 +20319,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void resolvePadding() { final int resolvedLayoutDirection = getLayoutDirection(); @@ -20371,7 +20417,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ @CallSuper - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void onDetachedFromWindowInternal() { mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT; mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT; @@ -21088,7 +21134,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ @CallSuper - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void destroyHardwareResources() { if (mOverlay != null) { mOverlay.getOverlayView().destroyHardwareResources(); @@ -21224,7 +21270,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ @NonNull - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public RenderNode updateDisplayListIfDirty() { final RenderNode renderNode = mRenderNode; if (!canHaveDisplayList()) { @@ -21295,7 +21341,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return renderNode; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void resetDisplayList() { mRenderNode.discardDisplayList(); if (mBackgroundRenderNode != null) { @@ -24749,7 +24795,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return false if the transformation could not be applied * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean toGlobalMotionEvent(MotionEvent ev) { final AttachInfo info = mAttachInfo; if (info == null) { @@ -24771,7 +24817,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return false if the transformation could not be applied * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean toLocalMotionEvent(MotionEvent ev) { final AttachInfo info = mAttachInfo; if (info == null) { @@ -26193,7 +26239,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDisabledSystemUiVisibility(int flags) { if (mAttachInfo != null) { if (mAttachInfo.mDisabledSystemUiVisibility != flags) { @@ -26242,7 +26288,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * </div> */ public static class DragShadowBuilder { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final WeakReference<View> mView; /** @@ -26443,7 +26489,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, surface.copyFrom(surfaceControl); IBinder token = null; try { - final Canvas canvas = surface.lockCanvas(null); + final Canvas canvas = isHardwareAccelerated() + ? surface.lockHardwareCanvas() + : surface.lockCanvas(null); try { canvas.drawColor(0, PorterDuff.Mode.CLEAR); shadowBuilder.onDrawShadow(canvas); @@ -26534,7 +26582,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } if (mAttachInfo.mDragToken != null) { try { - Canvas canvas = mAttachInfo.mDragSurface.lockCanvas(null); + Canvas canvas = isHardwareAccelerated() + ? mAttachInfo.mDragSurface.lockHardwareCanvas() + : mAttachInfo.mDragSurface.lockCanvas(null); try { canvas.drawColor(0, PorterDuff.Mode.CLEAR); shadowBuilder.onDrawShadow(canvas); @@ -26706,7 +26756,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Drawable that are not transparent. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void applyDrawableToTransparentRegion(Drawable dr, Region region) { if (DBG) { Log.i("View", "Getting transparent region for: " + this); @@ -27274,7 +27324,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @EnumEntry(value = TEXT_DIRECTION_FIRST_STRONG_LTR, name = "firstStrongLtr"), @EnumEntry(value = TEXT_DIRECTION_FIRST_STRONG_RTL, name = "firstStrongRtl"), }) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getRawTextDirection() { return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_MASK) >> PFLAG2_TEXT_DIRECTION_MASK_SHIFT; } @@ -27531,7 +27581,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @EnumEntry(value = TEXT_ALIGNMENT_VIEW_END, name = "viewEnd") }) @TextAlignment - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getRawTextAlignment() { return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT; } @@ -28881,7 +28931,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * constants declared by {@link View} (there are more display states than * screen states). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int mDisplayState = Display.STATE_UNKNOWN; /** @@ -29361,7 +29411,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * The current state of the scrollbars: ON, OFF, or FADING */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int state = OFF; private int mLastColor; @@ -29813,7 +29863,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) { return host.createAccessibilityNodeInfoInternal(); } @@ -30231,7 +30281,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return true; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void hideTooltip() { if (mTooltipInfo == null) { return; diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index abf76ece1f3d..16211fcecdf4 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -680,7 +680,7 @@ public class ViewConfiguration { * to a hover movement gesture. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int getHoverTapSlop() { return HOVER_TAP_SLOP; } diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index 100b4fdbf446..01cb0a67c1a2 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -29,6 +29,7 @@ import android.graphics.Picture; import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.graphics.RenderNode; +import android.os.Build; import android.os.Debug; import android.os.Handler; import android.os.Looper; @@ -476,7 +477,7 @@ public class ViewDebug { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static long getViewRootImplCount() { return Debug.countInstancesOfClass(ViewRootImpl.class); } @@ -1152,7 +1153,7 @@ public class ViewDebug { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void dump(View root, boolean skipChildren, boolean includeProperties, OutputStream clientStream) throws IOException { BufferedWriter out = null; diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index eb6c49549100..37bea5821e42 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -131,7 +131,7 @@ import java.util.function.Predicate; public abstract class ViewGroup extends View implements ViewParent, ViewManager { private static final String TAG = "ViewGroup"; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final boolean DBG = false; /** @@ -3059,7 +3059,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void transformPointToViewLocal(float[] point, View child) { point[0] += mScrollX - child.mLeft; point[1] += mScrollY - child.mTop; @@ -3772,7 +3772,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** @hide */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfoInternal(info); if (getAccessibilityNodeProvider() != null) { @@ -3904,7 +3904,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void dispatchDetachedFromWindow() { // If we still have a touch target, we are still in the process of // dispatching motion events to a child; we need to get rid of that @@ -7769,7 +7769,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @hide */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void resolvePadding() { super.resolvePadding(); int count = getChildCount(); @@ -9240,7 +9240,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** @hide */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void encodeProperties(@NonNull ViewHierarchyEncoder encoder) { super.encodeProperties(encoder); diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java index 274f1eddee95..02f7e95ba742 100644 --- a/core/java/android/view/ViewOverlay.java +++ b/core/java/android/view/ViewOverlay.java @@ -22,6 +22,7 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Build; import java.util.ArrayList; @@ -56,7 +57,7 @@ public class ViewOverlay { * of the overlay * @return */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) ViewGroup getOverlayView() { return mOverlayViewGroup; } @@ -96,7 +97,7 @@ public class ViewOverlay { mOverlayViewGroup.clear(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean isEmpty() { return mOverlayViewGroup.isEmpty(); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 9bc07702feee..14ba699933f0 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -272,7 +272,7 @@ public final class ViewRootImpl implements ViewParent, */ private static final int CONTENT_CAPTURE_ENABLED_FALSE = 2; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static final ThreadLocal<HandlerActionQueue> sRunQueues = new ThreadLocal<HandlerActionQueue>(); static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList<>(); @@ -417,11 +417,11 @@ public final class ViewRootImpl implements ViewParent, final Region mTransparentRegion; final Region mPreviousTransparentRegion; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int mWidth; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int mHeight; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Rect mDirty; public boolean mIsAnimating; @@ -801,7 +801,7 @@ public final class ViewRootImpl implements ViewParent, } /** Add static config callback to be notified about global config changes. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void addConfigCallback(ConfigChangedCallback callback) { synchronized (sConfigCallbacks) { sConfigCallbacks.add(callback); @@ -1175,7 +1175,7 @@ public final class ViewRootImpl implements ViewParent, } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getWindowFlags() { return mWindowAttributes.flags; } @@ -1758,7 +1758,6 @@ public final class ViewRootImpl implements ViewParent, destroySurface(); } } - scheduleConsumeBatchedInputImmediately(); } @@ -1957,7 +1956,7 @@ public final class ViewRootImpl implements ViewParent, } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void scheduleTraversals() { if (!mTraversalScheduled) { mTraversalScheduled = true; @@ -5206,7 +5205,7 @@ public final class ViewRootImpl implements ViewParent, * @param inTouchMode Whether we want to be in touch mode. * @return True if the touch mode changed and focus changed was changed as a result */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean ensureTouchMode(boolean inTouchMode) { if (DBG) Log.d("touchmode", "ensureTouchMode(" + inTouchMode + "), current " + "touch mode is " + mAttachInfo.mInTouchMode); @@ -7239,7 +7238,7 @@ public final class ViewRootImpl implements ViewParent, } /* drag/drop */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void setLocalDragState(Object obj) { mLocalDragState = obj; } @@ -7865,7 +7864,7 @@ public final class ViewRootImpl implements ViewParent, } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void dispatchResized(ClientWindowFrames frames, boolean reportDraw, MergedConfiguration mergedConfiguration, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId) { @@ -8056,7 +8055,7 @@ public final class ViewRootImpl implements ViewParent, } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void enqueueInputEvent(InputEvent event) { enqueueInputEvent(event, null, 0, false); } @@ -8314,11 +8313,8 @@ public final class ViewRootImpl implements ViewParent, @Override public void onBatchedInputEventPending(int source) { - // mStopped: There will be no more choreographer callbacks if we are stopped, - // so we must consume all input immediately to prevent ANR final boolean unbuffered = mUnbufferedInputDispatch - || (source & mUnbufferedInputSource) != SOURCE_CLASS_NONE - || mStopped; + || (source & mUnbufferedInputSource) != SOURCE_CLASS_NONE; if (unbuffered) { if (mConsumeBatchedInputScheduled) { unscheduleConsumeBatchedInput(); @@ -8475,7 +8471,7 @@ public final class ViewRootImpl implements ViewParent, mInvalidateOnAnimationRunnable.addViewRect(info); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void cancelInvalidate(View view) { mHandler.removeMessages(MSG_INVALIDATE, view); // fixme: might leak the AttachInfo.InvalidateInfo objects instead of returning @@ -8484,12 +8480,12 @@ public final class ViewRootImpl implements ViewParent, mInvalidateOnAnimationRunnable.removeView(view); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void dispatchInputEvent(InputEvent event) { dispatchInputEvent(event, null); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void dispatchInputEvent(InputEvent event, InputEventReceiver receiver) { SomeArgs args = SomeArgs.obtain(); args.arg1 = event; diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java index d9b55e4e729d..5a99ab2f5bdb 100644 --- a/core/java/android/view/ViewTreeObserver.java +++ b/core/java/android/view/ViewTreeObserver.java @@ -51,7 +51,7 @@ public final class ViewTreeObserver { // Non-recursive listeners use CopyOnWriteArray // Any listener invoked from ViewRootImpl.performTraversals() should not be recursive - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private CopyOnWriteArray<OnGlobalLayoutListener> mOnGlobalLayoutListeners; @UnsupportedAppUsage private CopyOnWriteArray<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners; @@ -242,7 +242,7 @@ public final class ViewTreeObserver { * Only used when {@link #setTouchableInsets(int)} is called with * the option {@link #TOUCHABLE_INSETS_REGION}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final Region touchableRegion = new Region(); /** @@ -267,7 +267,7 @@ public final class ViewTreeObserver { * Option for {@link #setTouchableInsets(int)}: the area inside of * the provided touchable region in {@link #touchableRegion} can be touched. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int TOUCHABLE_INSETS_REGION = 3; /** diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 5331a1b8d538..8dd4b667d357 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -162,7 +162,7 @@ public abstract class Window { * Max value used as a feature ID * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int FEATURE_MAX = FEATURE_ACTIVITY_TRANSITIONS; /** @@ -791,7 +791,7 @@ public abstract class Window { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final boolean isDestroyed() { return mDestroyed; } @@ -1137,7 +1137,7 @@ public abstract class Window { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addPrivateFlags(int flags) { setPrivateFlags(flags, flags); } diff --git a/core/java/android/view/WindowAnimationFrameStats.java b/core/java/android/view/WindowAnimationFrameStats.java index dfc4f0cd4dc6..251ae9bd58f2 100644 --- a/core/java/android/view/WindowAnimationFrameStats.java +++ b/core/java/android/view/WindowAnimationFrameStats.java @@ -17,6 +17,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -48,7 +49,7 @@ public final class WindowAnimationFrameStats extends FrameStats implements Parce * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void init(long refreshPeriodNano, long[] framesPresentedTimeNano) { mRefreshPeriodNano = refreshPeriodNano; mFramesPresentedTimeNano = framesPresentedTimeNano; diff --git a/core/java/android/view/WindowContentFrameStats.java b/core/java/android/view/WindowContentFrameStats.java index 217197c96793..c788346efdd8 100644 --- a/core/java/android/view/WindowContentFrameStats.java +++ b/core/java/android/view/WindowContentFrameStats.java @@ -17,6 +17,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -61,7 +62,7 @@ public final class WindowContentFrameStats extends FrameStats implements Parcela * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void init(long refreshPeriodNano, long[] framesPostedTimeNano, long[] framesPresentedTimeNano, long[] framesReadyTimeNano) { mRefreshPeriodNano = refreshPeriodNano; diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 2cab32b48793..f85489871730 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -76,6 +76,7 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; +import android.os.Build; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -1078,7 +1079,7 @@ public interface WindowManager extends ViewManager { * In multiuser systems shows only on the owning user's window. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15; /** @@ -1147,7 +1148,7 @@ public interface WindowManager extends ViewManager { * In multiuser systems shows on all users' windows. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int TYPE_DISPLAY_OVERLAY = FIRST_SYSTEM_WINDOW+26; /** @@ -2154,7 +2155,7 @@ public interface WindowManager extends ViewManager { * {@link DragEvent#ACTION_DROP}) will be relinquished to the window. * @hide */ - @RequiresPermission(permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(permission.MANAGE_ACTIVITY_TASKS) public static final int PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP = 0x80000000; /** @@ -2724,7 +2725,7 @@ public interface WindowManager extends ViewManager { * The ui visibility as requested by the views in this hierarchy. * the combined value should be systemUiVisibility | subtreeSystemUiVisibility. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int subtreeSystemUiVisibility; /** @@ -2900,7 +2901,7 @@ public interface WindowManager extends ViewManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004; /** @@ -4069,11 +4070,12 @@ public interface WindowManager extends ViewManager { /** * Holds the WM lock for the specified amount of milliseconds. * Intended for use by the tests that need to imitate lock contention. + * The token should be obtained by + * {@link android.content.pm.PackageManager#getHoldLockToken()}. * @hide */ @TestApi - @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) - default void holdLock(int durationMs) { + default void holdLock(IBinder token, int durationMs) { throw new UnsupportedOperationException(); } } diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index f01cbcc1430e..dd0ab6503a8a 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -259,7 +259,7 @@ public final class WindowManagerGlobal { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ArrayList<ViewRootImpl> getRootViews(IBinder token) { ArrayList<ViewRootImpl> views = new ArrayList<>(); synchronized (mLock) { @@ -438,7 +438,7 @@ public final class WindowManagerGlobal { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void removeView(View view, boolean immediate) { if (view == null) { throw new IllegalArgumentException("view must not be null"); diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index 7dfae002b554..4292a800afe1 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -280,9 +280,9 @@ public final class WindowManagerImpl implements WindowManager { } @Override - public void holdLock(int durationMs) { + public void holdLock(IBinder token, int durationMs) { try { - WindowManagerGlobal.getWindowManagerService().holdLock(durationMs); + WindowManagerGlobal.getWindowManagerService().holdLock(token, durationMs); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index d803f8bfa6cc..f63749be6df2 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -126,7 +126,7 @@ public final class AccessibilityInteractionClient /** * @return The client for the current thread. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static AccessibilityInteractionClient getInstance() { final long threadId = Thread.currentThread().getId(); return getInstanceForThread(threadId); @@ -205,7 +205,7 @@ public final class AccessibilityInteractionClient * * @param message The message. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSameThreadMessage(Message message) { synchronized (mInstanceLock) { mSameThreadMessage = message; @@ -729,7 +729,7 @@ public final class AccessibilityInteractionClient return false; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void clearCache() { sAccessibilityCache.clear(); } diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index a9e8d5498a57..a8534faf43e5 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -111,7 +111,7 @@ public final class AccessibilityManager { public static final int DALTONIZER_DISABLED = -1; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int DALTONIZER_SIMULATE_MONOCHROMACY = 0; /** @hide */ diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 303ba9e2a7d8..97ce92cd90aa 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -726,7 +726,7 @@ public class AccessibilityNodeInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int getAccessibilityViewId(long accessibilityNodeId) { return (int) accessibilityNodeId; } @@ -740,7 +740,7 @@ public class AccessibilityNodeInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int getVirtualDescendantId(long accessibilityNodeId) { return (int) ((accessibilityNodeId & VIRTUAL_DESCENDANT_ID_MASK) >> VIRTUAL_DESCENDANT_ID_SHIFT); @@ -768,7 +768,7 @@ public class AccessibilityNodeInfo implements Parcelable { private static final AccessibilityNodeInfo DEFAULT = new AccessibilityNodeInfo(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mSealed; // Data. @@ -988,7 +988,7 @@ public class AccessibilityNodeInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean refresh(Bundle arguments, boolean bypassCache) { enforceSealed(); if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) { diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl index f96f0acd6082..049bb31adbb1 100644 --- a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl +++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl @@ -33,7 +33,7 @@ oneway interface IAccessibilityInteractionConnectionCallback { * @param infos The result {@link AccessibilityNodeInfo}. * @param interactionId The interaction id to match the result with the request. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setFindAccessibilityNodeInfoResult(in AccessibilityNodeInfo info, int interactionId); /** @@ -42,7 +42,7 @@ oneway interface IAccessibilityInteractionConnectionCallback { * @param infos The result {@link AccessibilityNodeInfo}s. * @param interactionId The interaction id to match the result with the request. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setFindAccessibilityNodeInfosResult(in List<AccessibilityNodeInfo> infos, int interactionId); @@ -52,6 +52,6 @@ oneway interface IAccessibilityInteractionConnectionCallback { * @param Whether the action was performed. * @param interactionId The interaction id to match the result with the request. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setPerformAccessibilityActionResult(boolean succeeded, int interactionId); } diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl index 97036f3f3a1b..5d3c72015ee3 100644 --- a/core/java/android/view/accessibility/IAccessibilityManager.aidl +++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl @@ -44,7 +44,7 @@ interface IAccessibilityManager { List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType, int userId); int addAccessibilityInteractionConnection(IWindow windowToken, IBinder leashToken, diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index fb66b5298839..81db62857c17 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -19,6 +19,7 @@ package android.view.autofill; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE; import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED; +import static android.view.OnReceiveContentCallback.Payload.SOURCE_AUTOFILL; import static android.view.autofill.Helper.sDebug; import static android.view.autofill.Helper.sVerbose; import static android.view.autofill.Helper.toList; @@ -32,6 +33,7 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.content.AutofillOptions; +import android.content.ClipData; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -60,6 +62,7 @@ import android.util.Slog; import android.util.SparseArray; import android.view.Choreographer; import android.view.KeyEvent; +import android.view.OnReceiveContentCallback; import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -2350,6 +2353,49 @@ public final class AutofillManager { } } + private void autofillContent(int sessionId, AutofillId id, ClipData clip) { + synchronized (mLock) { + if (sessionId != mSessionId) { + return; + } + final AutofillClient client = getClient(); + if (client == null) { + return; + } + final View view = client.autofillClientFindViewByAutofillIdTraversal(id); + if (view == null) { + // Most likely view has been removed after the initial request was sent to the + // the service; this is fine, but we need to update the view status in the + // server side so it can be triggered again. + Log.d(TAG, "autofillContent(): no view with id " + id); + reportAutofillContentFailure(id); + return; + } + OnReceiveContentCallback.Payload payload = + new OnReceiveContentCallback.Payload.Builder(clip, SOURCE_AUTOFILL) + .build(); + boolean handled = view.onReceiveContent(payload); + if (!handled) { + Log.w(TAG, "autofillContent(): receiver returned false: id=" + id + + ", view=" + view + ", clip=" + clip); + reportAutofillContentFailure(id); + return; + } + mMetricsLogger.write(newLog(MetricsEvent.AUTOFILL_DATASET_APPLIED) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_VALUES, 1) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_VIEWS_FILLED, 1)); + } + } + + private void reportAutofillContentFailure(AutofillId id) { + try { + mService.setAutofillFailure(mSessionId, Collections.singletonList(id), + mContext.getUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private LogMaker newLog(int category) { final LogMaker log = new LogMaker(category) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SESSION_ID, mSessionId); @@ -3391,6 +3437,14 @@ public final class AutofillManager { } @Override + public void autofillContent(int sessionId, AutofillId id, ClipData content) { + final AutofillManager afm = mAfm.get(); + if (afm != null) { + afm.post(() -> afm.autofillContent(sessionId, id, content)); + } + } + + @Override public void authenticate(int sessionId, int authenticationId, IntentSender intent, Intent fillInIntent, boolean authenticateInline) { final AutofillManager afm = mAfm.get(); diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl index f8ccea5d8356..1f833f66c257 100644 --- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl +++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl @@ -18,6 +18,7 @@ package android.view.autofill; import java.util.List; +import android.content.ClipData; import android.content.ComponentName; import android.content.Intent; import android.content.IntentSender; @@ -48,6 +49,11 @@ oneway interface IAutoFillManagerClient { boolean hideHighlight); /** + * Autofills the activity with rich content data (e.g. an image) from a dataset. + */ + void autofillContent(int sessionId, in AutofillId id, in ClipData content); + + /** * Authenticates a fill response or a data set. */ void authenticate(int sessionId, int authenticationId, in IntentSender intent, diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index e0711132f459..093dfb4e196e 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -22,6 +22,7 @@ import android.annotation.CallSuper; import android.annotation.IntRange; import android.annotation.Nullable; import android.content.ClipData; +import android.content.ClipDescription; import android.content.Context; import android.content.res.TypedArray; import android.os.Bundle; @@ -918,23 +919,18 @@ public class BaseInputConnection implements InputConnection { } /** - * Default implementation which invokes the target view's {@link OnReceiveContentCallback} if - * it is {@link View#setOnReceiveContentCallback set} and supports the MIME type of the given - * content; otherwise, simply returns false. + * Default implementation which invokes {@link View#onReceiveContent} on the target view if the + * MIME type of the content matches one of the MIME types returned by + * {@link View#getOnReceiveContentMimeTypes()}. If the MIME type of the content is not matched, + * returns false without any side effects. */ public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) { - @SuppressWarnings("unchecked") final OnReceiveContentCallback<View> receiver = - (OnReceiveContentCallback<View>) mTargetView.getOnReceiveContentCallback(); - if (receiver == null) { + ClipDescription description = inputContentInfo.getDescription(); + final String[] viewMimeTypes = mTargetView.getOnReceiveContentMimeTypes(); + if (viewMimeTypes == null || !description.hasMimeType(viewMimeTypes)) { if (DEBUG) { - Log.d(TAG, "Can't insert content from IME; no callback"); - } - return false; - } - if (!receiver.supports(mTargetView, inputContentInfo.getDescription())) { - if (DEBUG) { - Log.d(TAG, "Can't insert content from IME; callback doesn't support MIME type: " - + inputContentInfo.getDescription()); + Log.d(TAG, "Can't insert content from IME; unsupported MIME type: content=" + + description + ", viewMimeTypes=" + viewMimeTypes); } return false; } @@ -946,13 +942,13 @@ public class BaseInputConnection implements InputConnection { return false; } } - final ClipData clip = new ClipData(inputContentInfo.getDescription(), + final ClipData clip = new ClipData(description, new ClipData.Item(inputContentInfo.getContentUri())); final OnReceiveContentCallback.Payload payload = new OnReceiveContentCallback.Payload.Builder(clip, SOURCE_INPUT_METHOD) .setLinkUri(inputContentInfo.getLinkUri()) .setExtras(opts) .build(); - return receiver.onReceiveContent(mTargetView, payload); + return mTargetView.onReceiveContent(payload); } } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 5785999e2672..1931174d4bb8 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -2334,7 +2334,7 @@ public final class InputMethodManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isCursorAnchorInfoEnabled() { synchronized (mH) { final boolean isImmediate = (mRequestUpdateCursorAnchorInfoMonitorMode & @@ -2350,7 +2350,7 @@ public final class InputMethodManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setUpdateCursorAnchorInfoMode(int flags) { synchronized (mH) { mRequestUpdateCursorAnchorInfoMonitorMode = flags; diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java index ab6dcb1b27a7..7db35d4bf8b5 100644 --- a/core/java/android/view/textclassifier/TextClassification.java +++ b/core/java/android/view/textclassifier/TextClassification.java @@ -318,7 +318,8 @@ public final class TextClassification implements Parcelable { public static PendingIntent createPendingIntent( @NonNull final Context context, @NonNull final Intent intent, int requestCode) { return PendingIntent.getActivity( - context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + context, requestCode, intent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); } /** diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java index fa4f7d6d32da..b606340b77a7 100644 --- a/core/java/android/view/textclassifier/TextClassificationManager.java +++ b/core/java/android/view/textclassifier/TextClassificationManager.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.annotation.SystemService; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.ServiceManager; import android.view.textclassifier.TextClassifier.TextClassifierType; @@ -104,7 +105,7 @@ public final class TextClassificationManager { * @see TextClassifier#DEFAULT_SYSTEM * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public TextClassifier getTextClassifier(@TextClassifierType int type) { switch (type) { case TextClassifier.LOCAL: diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java index afddaa2ff58a..35d84458bd35 100644 --- a/core/java/android/view/textservice/SpellCheckerSession.java +++ b/core/java/android/view/textservice/SpellCheckerSession.java @@ -18,6 +18,7 @@ package android.view.textservice; import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -97,7 +98,7 @@ public class SpellCheckerSession { private final InternalListener mInternalListener; private final TextServicesManager mTextServicesManager; private final SpellCheckerInfo mSpellCheckerInfo; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final SpellCheckerSessionListener mSpellCheckerSessionListener; private final SpellCheckerSessionListenerImpl mSpellCheckerSessionListenerImpl; diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java index cd70a313db67..d34c8d58e789 100644 --- a/core/java/android/view/textservice/TextServicesManager.java +++ b/core/java/android/view/textservice/TextServicesManager.java @@ -22,6 +22,7 @@ import android.annotation.TestApi; import android.annotation.UserIdInt; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; @@ -217,7 +218,7 @@ public final class TextServicesManager { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public SpellCheckerInfo[] getEnabledSpellCheckers() { try { final SpellCheckerInfo[] retval = mService.getEnabledSpellCheckers(mUserId); diff --git a/core/java/android/webkit/IWebViewUpdateService.aidl b/core/java/android/webkit/IWebViewUpdateService.aidl index 1da0500727ad..e17773159ec5 100644 --- a/core/java/android/webkit/IWebViewUpdateService.aidl +++ b/core/java/android/webkit/IWebViewUpdateService.aidl @@ -51,7 +51,7 @@ interface IWebViewUpdateService { * DevelopmentSettings uses this to get the current available WebView * providers (to display as choices to the user). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) WebViewProviderInfo[] getValidWebViewPackages(); /** @@ -62,7 +62,7 @@ interface IWebViewUpdateService { /** * Used by DevelopmentSetting to get the name of the WebView provider currently in use. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String getCurrentWebViewPackageName(); /** diff --git a/core/java/android/webkit/PluginData.java b/core/java/android/webkit/PluginData.java index c9a196017a75..5d481b12a27c 100644 --- a/core/java/android/webkit/PluginData.java +++ b/core/java/android/webkit/PluginData.java @@ -17,6 +17,7 @@ package android.webkit; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.io.InputStream; import java.util.Map; @@ -93,7 +94,7 @@ public final class PluginData { * deprecated, so is this class. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public InputStream getInputStream() { return mStream; } @@ -108,7 +109,7 @@ public final class PluginData { * deprecated, so is this class. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getContentLength() { return mContentLength; } @@ -126,7 +127,7 @@ public final class PluginData { * deprecated, so is this class. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Map<String, String[]> getHeaders() { return mHeaders; } @@ -141,7 +142,7 @@ public final class PluginData { * deprecated, so is this class. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getStatusCode() { return mStatusCode; } diff --git a/core/java/android/webkit/UrlInterceptRegistry.java b/core/java/android/webkit/UrlInterceptRegistry.java index c9dee00942c3..4fa6fdeecbee 100644 --- a/core/java/android/webkit/UrlInterceptRegistry.java +++ b/core/java/android/webkit/UrlInterceptRegistry.java @@ -18,6 +18,7 @@ package android.webkit; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.webkit.CacheManager.CacheResult; import java.util.Iterator; @@ -154,7 +155,7 @@ public final class UrlInterceptRegistry { */ @Deprecated @Nullable - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static synchronized PluginData getPluginData( String url, Map<String, String> headers) { if (urlInterceptDisabled()) { diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java index 219523b15ab0..e4af9095265c 100644 --- a/core/java/android/webkit/WebResourceResponse.java +++ b/core/java/android/webkit/WebResourceResponse.java @@ -19,6 +19,7 @@ package android.webkit; import android.annotation.NonNull; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.io.InputStream; import java.io.StringBufferInputStream; @@ -34,7 +35,7 @@ public class WebResourceResponse { private boolean mImmutable; private String mMimeType; private String mEncoding; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mStatusCode; private String mReasonPhrase; private Map<String, String> mResponseHeaders; diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 8eb1371505bf..487d13e40bf3 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -112,7 +112,7 @@ public class WebView extends AbsoluteLayout // Throwing an exception for incorrect thread usage if the // build target is JB MR2 or newer. Defaults to false, and is // set in the WebView constructor. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static volatile boolean sEnforceThreadChecking = false; /** @@ -407,7 +407,7 @@ public class WebView extends AbsoluteLayout * @hide */ @SuppressWarnings("deprecation") // for super() call into deprecated base class constructor. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected WebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes, @Nullable Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) { @@ -2587,7 +2587,7 @@ public class WebView extends AbsoluteLayout return WebViewFactory.getProvider(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final Looper mWebViewThread = Looper.myLooper(); @UnsupportedAppUsage diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 5fc93443f4b8..dde9c3089370 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -26,6 +26,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; +import android.os.Build; import android.os.RemoteException; import android.os.ServiceManager; import android.os.Trace; @@ -390,7 +391,7 @@ public final class WebViewFactory { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static Class<WebViewFactoryProvider> getProviderClass() { Context webViewContext = null; Application initialApplication = AppGlobals.getInitialApplication(); diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 45b21c569cea..88c0809613ee 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -253,7 +253,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Controls CHOICE_MODE_MULTIPLE_MODAL. null when inactive. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) ActionMode mChoiceActionMode; /** @@ -288,7 +288,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Should be used by subclasses to listen to changes in the dataset */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AdapterDataSetObserver mDataSetObserver; /** @@ -452,7 +452,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Handles scrolling between positions within the list. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AbsPositionScroller mPositionScroller; /** @@ -1454,7 +1454,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @hide */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected boolean isVerticalScrollBarHidden() { return isFastScrollEnabled(); } @@ -2249,7 +2249,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean canScrollUp() { boolean canScrollUp; // 0th element is not visible @@ -2266,7 +2266,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return canScrollUp; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean canScrollDown() { boolean canScrollDown; int count = getChildCount(); @@ -3275,7 +3275,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te CheckForLongPress.INVALID_COORD); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean performLongPress(final View child, final int longPressPosition, final long longPressId, float x, float y) { // CHOICE_MODE_MULTIPLE_MODAL takes over long press. @@ -6694,7 +6694,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * scrap heap. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int scrappedFromPosition; /** diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index 67ed30f2ec73..b9ff26b7d9ff 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -29,6 +29,7 @@ import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.Region.Op; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.util.AttributeSet; import android.view.KeyEvent; @@ -857,7 +858,7 @@ public abstract class AbsSeekBar extends ProgressBar { /** * Draw the thumb. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void drawThumb(Canvas canvas) { if (mThumb != null) { final int saveCount = canvas.save(); diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java index aa3590aaff0a..6d566baa23cd 100644 --- a/core/java/android/widget/ActionMenuPresenter.java +++ b/core/java/android/widget/ActionMenuPresenter.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.SparseArray; @@ -587,7 +588,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter * Dismiss all popup menus - overflow and submenus. * @return true if popups were dismissed, false otherwise. (This can be because none were open.) */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean dismissPopupMenus() { boolean result = hideOverflowMenu(); result |= hideSubMenus(); @@ -610,7 +611,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter /** * @return true if the overflow menu is currently showing */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isOverflowMenuShowing() { return mOverflowPopup != null && mOverflowPopup.isShowing(); } @@ -769,7 +770,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Parcelable onSaveInstanceState() { SavedState state = new SavedState(); state.openSubMenuId = mOpenSubMenuId; @@ -777,7 +778,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onRestoreInstanceState(Parcelable state) { SavedState saved = (SavedState) state; if (saved.openSubMenuId > 0) { diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java index 3a743562110f..f83ff305cfdc 100644 --- a/core/java/android/widget/ActionMenuView.java +++ b/core/java/android/widget/ActionMenuView.java @@ -22,6 +22,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.graphics.drawable.Drawable; +import android.os.Build; import android.util.AttributeSet; import android.view.ContextThemeWrapper; import android.view.Gravity; @@ -719,7 +720,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo * @hide Private LinearLayout (superclass) API. Un-hide if LinearLayout API is made public. */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected boolean hasDividerBeforeChildAt(int childIndex) { if (childIndex == 0) { return false; @@ -790,7 +791,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo /** @hide */ public interface ActionMenuChildView { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean needsDividerBefore(); public boolean needsDividerAfter(); } @@ -798,31 +799,31 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo public static class LayoutParams extends LinearLayout.LayoutParams { /** @hide */ @ViewDebug.ExportedProperty(category = "layout") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isOverflowButton; /** @hide */ @ViewDebug.ExportedProperty(category = "layout") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int cellsUsed; /** @hide */ @ViewDebug.ExportedProperty(category = "layout") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int extraPixels; /** @hide */ @ViewDebug.ExportedProperty(category = "layout") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean expandable; /** @hide */ @ViewDebug.ExportedProperty(category = "layout") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean preventEdgeOffset; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean expanded; public LayoutParams(Context c, AttributeSet attrs) { diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java index 9da337ad97da..299760bfa91f 100644 --- a/core/java/android/widget/ActivityChooserModel.java +++ b/core/java/android/widget/ActivityChooserModel.java @@ -27,6 +27,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.database.DataSetObservable; import android.os.AsyncTask; +import android.os.Build; import android.text.TextUtils; import android.util.Log; import android.util.Xml; @@ -379,7 +380,7 @@ public class ActivityChooserModel extends DataSetObservable { * * @param intent The intent. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setIntent(Intent intent) { synchronized (mInstanceLock) { if (mIntent == intent) { @@ -514,7 +515,7 @@ public class ActivityChooserModel extends DataSetObservable { * * @param listener The listener. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setOnChooseActivityListener(OnChooseActivityListener listener) { synchronized (mInstanceLock) { mActivityChoserModelPolicy = listener; diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 00526d9f8a2c..ea906c68c69b 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -113,7 +113,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe private final PassThroughClickListener mPassThroughClickListener; private CharSequence mHintText; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private TextView mHintView; private int mHintResource; @@ -615,7 +615,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe * * @hide Pending API council approval */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDropDownDismissedOnCompletion(boolean dropDownDismissedOnCompletion) { mDropDownDismissedOnCompletion = dropDownDismissedOnCompletion; } @@ -1225,7 +1225,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe * * @hide internal used only by SearchDialog */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void showDropDownAfterLayout() { mPopup.postShow(); } diff --git a/core/java/android/widget/DatePickerSpinnerDelegate.java b/core/java/android/widget/DatePickerSpinnerDelegate.java index fd89b2e09131..c6d456d8cb01 100644 --- a/core/java/android/widget/DatePickerSpinnerDelegate.java +++ b/core/java/android/widget/DatePickerSpinnerDelegate.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; import android.icu.util.Calendar; +import android.os.Build; import android.os.Parcelable; import android.text.InputType; import android.text.TextUtils; @@ -501,7 +502,7 @@ class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate { || mCurrentDate.get(Calendar.DAY_OF_MONTH) != dayOfMonth); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void setDate(int year, int month, int dayOfMonth) { mCurrentDate.set(year, month, dayOfMonth); resetAutofilledValue(); @@ -512,7 +513,7 @@ class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void updateSpinners() { // set the spinner ranges respecting the min and max dates if (mCurrentDate.equals(mMinDate)) { @@ -565,7 +566,7 @@ class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate { /** * Updates the calendar view with the current date. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void updateCalendarView() { mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false); } @@ -574,7 +575,7 @@ class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate { /** * Notifies the listener, if such, for a change in the selected date. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void notifyDateChanged() { mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); if (mOnDateChangedListener != null) { @@ -630,7 +631,7 @@ class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void updateInputState() { // Make sure that if the user changes the value and the IME is active // for one of the inputs if this widget, the IME is closed. If the user diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java index 20a53c03bed1..955552289c3a 100644 --- a/core/java/android/widget/DateTimeView.java +++ b/core/java/android/widget/DateTimeView.java @@ -30,6 +30,7 @@ import android.content.IntentFilter; import android.content.res.Configuration; import android.content.res.TypedArray; import android.database.ContentObserver; +import android.os.Build; import android.os.Handler; import android.util.AttributeSet; import android.view.accessibility.AccessibilityNodeInfo; @@ -81,7 +82,7 @@ public class DateTimeView extends TextView { this(context, null); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public DateTimeView(Context context, AttributeSet attrs) { super(context, attrs); final TypedArray a = context.obtainStyledAttributes(attrs, diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java index 32f3acd387b0..c10ffbee686a 100644 --- a/core/java/android/widget/EdgeEffect.java +++ b/core/java/android/widget/EdgeEffect.java @@ -87,7 +87,7 @@ public class EdgeEffect { private static final float RADIUS_FACTOR = 0.6f; private float mGlowAlpha; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mGlowScaleY; private float mGlowAlphaStart; diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index f2955ac554fc..4099c8aa6710 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -323,7 +323,7 @@ public class Editor { private boolean mShowErrorAfterAttach; boolean mInBatchEditControllers; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean mShowSoftInputOnFocus = true; private boolean mPreserveSelection; private boolean mRestartActionModeOnNextRefresh; @@ -355,7 +355,7 @@ public class Editor { Callback mCustomInsertionActionModeCallback; // Set when this TextView gained focus with some text selected. Will start selection mode. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean mCreatedWithASelection; // The button state as of the last time #onTouchEvent is called. diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index 0c0b3491a854..7dbe7b234422 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -140,7 +140,7 @@ class FastScroller { @UnsupportedAppUsage private Drawable mThumbDrawable; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Drawable mTrackDrawable; private int mTextAppearance; private int mThumbPosition; diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index a6dce7f05f4a..50773b1c43b9 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -39,6 +39,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Insets; import android.graphics.Paint; +import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.util.LogPrinter; @@ -2815,7 +2816,7 @@ public class GridLayout extends ViewGroup { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static final Alignment UNDEFINED_ALIGNMENT = new Alignment() { @Override int getGravityOffset(View view, int cellDelta) { diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java index 4a5e95e492e5..196d68bcd08a 100644 --- a/core/java/android/widget/GridView.java +++ b/core/java/android/widget/GridView.java @@ -979,7 +979,7 @@ public class GridView extends AbsListView { return sel; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean determineColumns(int availableSpace) { final int requestedHorizontalSpacing = mRequestedHorizontalSpacing; final int stretchMode = mStretchMode; diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index 3bb39c135034..97dbb1542717 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -150,9 +150,9 @@ public class HorizontalScrollView extends FrameLayout { private int mMinimumVelocity; private int mMaximumVelocity; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mOverscrollDistance; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mOverflingDistance; private float mHorizontalScrollFactor; diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index c20773848759..e4de4001c3e2 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -127,7 +127,7 @@ public class ImageView extends View { @UnsupportedAppUsage private Drawable mDrawable = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private BitmapDrawable mRecycleableBitmapDrawable = null; private ColorStateList mDrawableTintList = null; private BlendMode mDrawableBlendMode = null; diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java index a796ba545d8f..fa84407c5c4d 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -212,9 +212,9 @@ public class LinearLayout extends ViewGroup { private static final int VERTICAL_GRAVITY_COUNT = 4; private static final int INDEX_CENTER_VERTICAL = 0; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int INDEX_TOP = 1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int INDEX_BOTTOM = 2; private static final int INDEX_FILL = 3; diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 4311ffbe0e95..6232480f8620 100755 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -332,7 +332,7 @@ public class ListPopupWindow implements ShowableListMenu { * * @hide Only used by AutoCompleteTextView under special conditions. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) { mDropDownAlwaysVisible = dropDownAlwaysVisible; } @@ -342,7 +342,7 @@ public class ListPopupWindow implements ShowableListMenu { * * @hide Only used by AutoCompleteTextView under special conditions. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isDropDownAlwaysVisible() { return mDropDownAlwaysVisible; } @@ -933,7 +933,7 @@ public class ListPopupWindow implements ShowableListMenu { * * @param max Max number of items that can be visible and still allow the list to expand. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void setListItemExpandMax(int max) { mListItemExpandMaximum = max; } @@ -1130,7 +1130,7 @@ public class ListPopupWindow implements ShowableListMenu { * * @return the content's height or -1 if content already exists */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int buildDropDown() { ViewGroup dropDownView; int otherHeights = 0; diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 3c3daa3c7001..cf0e0d1f1842 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -1979,7 +1979,7 @@ public class ListView extends AbsListView { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean trackMotionScroll(int deltaY, int incrementalDeltaY) { final boolean result = super.trackMotionScroll(deltaY, incrementalDeltaY); removeUnusedFixedViews(mHeaderViewInfos); @@ -4028,7 +4028,7 @@ public class ListView extends AbsListView { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int getHeightForPosition(int position) { final int height = super.getHeightForPosition(position); if (shouldAdjustHeightForDivider(position)) { diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 8dfb936ef7ee..7c20472df357 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -250,7 +250,7 @@ public class NumberPicker extends LinearLayout { /** * The min height of this widget. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mMinHeight; /** @@ -261,7 +261,7 @@ public class NumberPicker extends LinearLayout { /** * The max width of this widget. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mMinWidth; /** @@ -277,7 +277,7 @@ public class NumberPicker extends LinearLayout { /** * The height of the text. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mTextSize; /** @@ -298,7 +298,7 @@ public class NumberPicker extends LinearLayout { /** * Upper value of the range of numbers allowed for the NumberPicker */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mMaxValue; /** @@ -309,7 +309,7 @@ public class NumberPicker extends LinearLayout { /** * Listener to be notified upon current value change. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private OnValueChangeListener mOnValueChangeListener; /** @@ -367,7 +367,7 @@ public class NumberPicker extends LinearLayout { /** * The {@link Scroller} responsible for flinging the selector. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final Scroller mFlingScroller; /** @@ -429,7 +429,7 @@ public class NumberPicker extends LinearLayout { /** * @see ViewConfiguration#getScaledMaximumFlingVelocity() */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mMaximumFlingVelocity; /** diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java index 1c33d80fd4ca..27fcde25ad37 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -19,6 +19,7 @@ package android.widget; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.hardware.SensorManager; +import android.os.Build; import android.util.Log; import android.view.ViewConfiguration; import android.view.animation.AnimationUtils; @@ -36,7 +37,7 @@ public class OverScroller { @UnsupportedAppUsage private final SplineOverScroller mScrollerY; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Interpolator mInterpolator; private final boolean mFlywheel; diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java index 0ce964666a2b..2aa587539930 100644 --- a/core/java/android/widget/PopupMenu.java +++ b/core/java/android/widget/PopupMenu.java @@ -20,6 +20,7 @@ import android.annotation.MenuRes; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.view.Gravity; import android.view.Menu; import android.view.MenuInflater; @@ -40,7 +41,7 @@ import com.android.internal.view.menu.ShowableListMenu; * it. */ public class PopupMenu { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final Context mContext; private final MenuBuilder mMenu; private final View mAnchor; diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index cc3d74477342..e7e148abb95a 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -183,7 +183,7 @@ public class PopupWindow { private boolean mClipToScreen; private boolean mAllowScrollingAnchorParent = true; private boolean mLayoutInsetDecor = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mNotTouchModal; private boolean mAttachedInDecor = true; private boolean mAttachedInDecorSet = false; diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 796654a4dc99..67216f5955f7 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -240,7 +240,7 @@ public class ProgressBar extends View { /** Value used to track progress animation, in the range [0...1]. */ private float mVisualProgress; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean mMirrorForRtl = false; private boolean mAggregatedIsVisible; @@ -1673,7 +1673,7 @@ public class ProgressBar extends View { // Stub method. } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private synchronized void refreshProgress(int id, int progress, boolean fromUser, boolean animate) { if (mUiThreadId == Thread.currentThread().getId()) { diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index dcfb3872bda0..4ba1ca8989b7 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -261,7 +261,7 @@ public class RemoteViews implements Parcelable, Filter { * RemoteViews. */ private RemoteViews mLandscape = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private RemoteViews mPortrait = null; @ApplyFlags @@ -439,7 +439,7 @@ public class RemoteViews implements Parcelable, Filter { // Do nothing } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mergeBehavior() { return MERGE_REPLACE; } @@ -508,7 +508,7 @@ public class RemoteViews implements Parcelable, Filter { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void mergeRemoteViews(RemoteViews newRv) { if (newRv == null) return; // We first copy the new RemoteViews, as the process of merging modifies the way the actions @@ -700,7 +700,7 @@ public class RemoteViews implements Parcelable, Filter { return SET_PENDING_INTENT_TEMPLATE_TAG; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) PendingIntent pendingIntentTemplate; } @@ -1148,7 +1148,7 @@ public class RemoteViews implements Parcelable, Filter { private static class BitmapCache { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) ArrayList<Bitmap> mBitmaps; int mBitmapMemory = -1; @@ -1564,7 +1564,7 @@ public class RemoteViews implements Parcelable, Filter { * ViewGroup methods that are related to adding Views. */ private class ViewGroupActionAdd extends Action { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private RemoteViews mNestedViews; private int mIndex; @@ -2479,7 +2479,7 @@ public class RemoteViews implements Parcelable, Filter { * Returns an estimate of the bitmap heap memory usage for this RemoteViews. */ /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int estimateMemoryUsage() { return mBitmapCache.getBitmapMemory(); } @@ -3004,7 +3004,7 @@ public class RemoteViews implements Parcelable, Filter { * @hide * @deprecated this appears to have no users outside of UnsupportedAppUsage? */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Deprecated public void setRemoteAdapter(int viewId, ArrayList<RemoteViews> list, int viewTypeCount) { addAction(new SetRemoteViewsAdapterList(viewId, list, viewTypeCount)); diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java index b8849367b7b6..c98ed6a2f5d0 100644 --- a/core/java/android/widget/RemoteViewsAdapter.java +++ b/core/java/android/widget/RemoteViewsAdapter.java @@ -32,6 +32,7 @@ import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.res.Configuration; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -107,7 +108,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback private final Executor mAsyncViewLoadExecutor; private OnClickHandler mRemoteViewsOnClickHandler; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final FixedSizeRemoteViewsCache mCache; private int mVisibleWindowLowerBound; private int mVisibleWindowUpperBound; @@ -116,7 +117,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // loaded. private RemoteViewsFrameLayoutRefSet mRequestedViews; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final HandlerThread mWorkerThread; // items may be interrupted within the normally processed queues private final Handler mMainHandler; @@ -896,17 +897,17 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isDataReady() { return mDataReady; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRemoteViewsOnClickHandler(OnClickHandler handler) { mRemoteViewsOnClickHandler = handler; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void saveRemoteViewsCache() { final RemoteViewsCacheKey key = new RemoteViewsCacheKey( new Intent.FilterComparison(mIntent), mAppWidgetId); @@ -1051,7 +1052,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Intent getRemoteViewsServiceIntent() { return mIntent; } @@ -1098,7 +1099,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback * views are currently being displayed. This allows for certain optimizations and preloading * which wouldn't otherwise be possible. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setVisibleRangeHint(int lowerBound, int upperBound) { mVisibleWindowLowerBound = lowerBound; mVisibleWindowUpperBound = upperBound; diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index b44b8c222fac..f3de9828c4aa 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -188,7 +188,7 @@ public class ScrollView extends FrameLayout { * These are no-ops on user builds. */ private StrictMode.Span mScrollStrictSpan = null; // aka "drag" - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private StrictMode.Span mFlingStrictSpan = null; /** diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java index b8a324931f86..2108f8ea350e 100755 --- a/core/java/android/widget/SearchView.java +++ b/core/java/android/widget/SearchView.java @@ -1938,7 +1938,7 @@ public class SearchView extends LinearLayout implements CollapsibleActionView { mThreshold = getThreshold(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public SearchAutoComplete(Context context, AttributeSet attrs) { super(context, attrs); mThreshold = getThreshold(); diff --git a/core/java/android/widget/SeekBar.java b/core/java/android/widget/SeekBar.java index 5676881cee76..201cab1c81e3 100644 --- a/core/java/android/widget/SeekBar.java +++ b/core/java/android/widget/SeekBar.java @@ -18,6 +18,7 @@ package android.widget; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.util.AttributeSet; import android.view.accessibility.AccessibilityNodeInfo; @@ -90,7 +91,7 @@ public class SeekBar extends AbsSeekBar { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void onProgressRefresh(float scale, boolean fromUser, int progress) { super.onProgressRefresh(scale, fromUser, progress); diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index 46fc09f4c3b3..ba6fa197f164 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -1082,7 +1082,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { /** * @return true if the popup is showing, false otherwise. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isShowing(); /** @@ -1113,7 +1113,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isShowing() { return mPopup != null ? mPopup.isShowing() : false; } diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index 5bca56f14add..3295fd2ea1c3 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -35,6 +35,7 @@ import android.graphics.Rect; import android.graphics.Region.Op; import android.graphics.Typeface; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Build.VERSION_CODES; import android.text.Layout; import android.text.StaticLayout; @@ -110,7 +111,7 @@ public class Switch extends CompoundButton { private boolean mHasTrackTintMode = false; private int mThumbTextPadding; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mSwitchMinWidth; private int mSwitchPadding; private boolean mSplitTrack; diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java index 95c0e8658c57..b1485ef27de5 100644 --- a/core/java/android/widget/TextClock.java +++ b/core/java/android/widget/TextClock.java @@ -32,6 +32,7 @@ import android.content.res.TypedArray; import android.database.ContentObserver; import android.icu.text.DateTimePatternGenerator; import android.net.Uri; +import android.os.Build; import android.os.Handler; import android.os.SystemClock; import android.os.UserHandle; @@ -494,7 +495,7 @@ public class TextClock extends TextView { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CharSequence getFormat() { return mFormat; } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 3fc0f4efd608..3ac78bafdedc 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -4364,7 +4364,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener shouldRequestLayout); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void setRawTextSize(float size, boolean shouldRequestLayout) { if (size != mTextPaint.getTextSize()) { mTextPaint.setTextSize(size); @@ -7876,7 +7876,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return drawableState; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Path getUpdatedHighlightPath() { Path highlight = null; Paint highlightPaint = mHighlightPaint; @@ -8747,12 +8747,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener outAttrs.initialSelEnd = getSelectionEnd(); outAttrs.initialCapsMode = ic.getCursorCapsMode(getInputType()); outAttrs.setInitialSurroundingText(mText); - // If a custom `OnReceiveContentCallback` is set, pass its supported MIME types. - OnReceiveContentCallback<TextView> receiver = getOnReceiveContentCallback(); - if (receiver != null) { - outAttrs.contentMimeTypes = receiver.getSupportedMimeTypes(this) - .toArray(new String[0]); - } + outAttrs.contentMimeTypes = getOnReceiveContentMimeTypes(); return ic; } } @@ -12359,7 +12354,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * be {@code null} if no text is set */ @Nullable - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private CharSequence getTextForAccessibility() { // If the text is empty, we must be showing the hint text. if (TextUtils.isEmpty(mText)) { @@ -12501,7 +12496,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return false; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) CharSequence getTransformedText(int start, int end) { return removeSuggestionSpans(mTransformed.subSequence(start, end)); } @@ -12989,7 +12984,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return x; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int getLineAtCoordinate(float y) { y -= getTotalPaddingTop(); // Clamp the position to inside of the view. @@ -13178,7 +13173,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * Deletes the range of text [start, end[. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected void deleteText_internal(int start, int end) { ((Editable) mText).delete(start, end); } @@ -13230,7 +13225,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @hide */ @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CharSequence getIterableTextForAccessibility() { return mText; } @@ -13735,20 +13730,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * Returns the callback used for handling insertion of content into this view. See - * {@link #setOnReceiveContentCallback} for more info. - * - * @return The callback for handling insertion of content. Returns null if no callback has been - * {@link #setOnReceiveContentCallback set}. - */ - @SuppressWarnings("unchecked") - @Nullable - @Override - public OnReceiveContentCallback<TextView> getOnReceiveContentCallback() { - return (OnReceiveContentCallback<TextView>) super.getOnReceiveContentCallback(); - } - - /** * Sets the callback to handle insertion of content into this view. * * <p>This callback will be invoked for the following scenarios: @@ -13761,32 +13742,51 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * <li>{@link Intent#ACTION_PROCESS_TEXT} replacement * </ol> * - * <p>The callback will only be invoked if the MIME type of the content is - * {@link OnReceiveContentCallback#getSupportedMimeTypes declared as supported} by the callback. - * If the content type is not supported by the callback, the default platform handling will be - * executed instead. + * <p>This callback is only invoked for content whose MIME type matches a type specified via + * the {code mimeTypes} parameter. If the MIME type is not supported by the callback, the + * default platform handling will be executed instead (no-op for the default {@link View}). + * + * <p><em>Note: MIME type matching in the Android framework is case-sensitive, unlike formal RFC + * MIME types. As a result, you should always write your MIME types with lower case letters, or + * use {@link android.content.Intent#normalizeMimeType} to ensure that it is converted to lower + * case.</em> * + * @param mimeTypes The type of content for which the callback should be invoked. This may use + * wildcards such as "text/*", "image/*", etc. This must not be null or empty if a non-null + * callback is passed in. * @param callback The callback to use. This can be null to reset to the default behavior. */ + @SuppressWarnings("rawtypes") @Override public void setOnReceiveContentCallback( - @Nullable OnReceiveContentCallback<? extends View> callback) { - super.setOnReceiveContentCallback(callback); + @Nullable String[] mimeTypes, + @Nullable OnReceiveContentCallback callback) { + super.setOnReceiveContentCallback(mimeTypes, callback); } /** - * Handles the request to insert content using the configured callback or the default callback. + * Receives the given content. The default implementation invokes the callback set via + * {@link #setOnReceiveContentCallback}. If no callback is set or if the callback does not + * support the given content (based on the MIME type), executes the default platform handling + * (e.g. coerces content to text if the source is + * {@link OnReceiveContentCallback.Payload#SOURCE_CLIPBOARD} and this is an editable + * {@link TextView}). * - * @hide + * @param payload The content to insert and related metadata. + * + * @return Returns true if the content was handled in some way, false otherwise. Actual + * insertion may be processed asynchronously in the background and may or may not succeed even + * if this method returns true. For example, an app may not end up inserting an item if it + * exceeds the app's size limit for that type of content. */ - void onReceiveContent(@NonNull OnReceiveContentCallback.Payload payload) { - OnReceiveContentCallback<TextView> receiver = getOnReceiveContentCallback(); - ClipDescription description = payload.getClip().getDescription(); - if (receiver != null && receiver.supports(this, description)) { - receiver.onReceiveContent(this, payload); + @Override + public boolean onReceiveContent(@NonNull OnReceiveContentCallback.Payload payload) { + if (super.onReceiveContent(payload)) { + return true; } else if (mEditor != null) { - mEditor.getDefaultOnReceiveContentCallback().onReceiveContent(this, payload); + return mEditor.getDefaultOnReceiveContentCallback().onReceiveContent(this, payload); } + return false; } private static void logCursor(String location, @Nullable String msgFormat, Object ... msgArgs) { diff --git a/core/java/android/widget/TextViewOnReceiveContentCallback.java b/core/java/android/widget/TextViewOnReceiveContentCallback.java index d7c95b7eae86..7ed70ec18a7b 100644 --- a/core/java/android/widget/TextViewOnReceiveContentCallback.java +++ b/core/java/android/widget/TextViewOnReceiveContentCallback.java @@ -20,12 +20,12 @@ import static android.content.ContentResolver.SCHEME_CONTENT; import static android.view.OnReceiveContentCallback.Payload.FLAG_CONVERT_TO_PLAIN_TEXT; import static android.view.OnReceiveContentCallback.Payload.SOURCE_AUTOFILL; import static android.view.OnReceiveContentCallback.Payload.SOURCE_DRAG_AND_DROP; +import static android.view.OnReceiveContentCallback.Payload.SOURCE_INPUT_METHOD; import static java.util.Collections.singleton; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SuppressLint; import android.compat.Compatibility; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; @@ -72,16 +72,6 @@ public class TextViewOnReceiveContentCallback implements OnReceiveContentCallbac @Nullable private InputConnectionInfo mInputConnectionInfo; @Nullable private ArraySet<String> mCachedSupportedMimeTypes; - @SuppressLint("CallbackMethodName") - @NonNull - @Override - public Set<String> getSupportedMimeTypes(@NonNull TextView view) { - if (!isUsageOfImeCommitContentEnabled(view)) { - return MIME_TYPES_ALL_TEXT; - } - return getSupportedMimeTypesAugmentedWithImeCommitContentMimeTypes(); - } - @Override public boolean onReceiveContent(@NonNull TextView view, @NonNull Payload payload) { if (Log.isLoggable(LOG_TAG, Log.DEBUG)) { @@ -90,6 +80,11 @@ public class TextViewOnReceiveContentCallback implements OnReceiveContentCallbac ClipData clip = payload.getClip(); @Source int source = payload.getSource(); @Flags int flags = payload.getFlags(); + if (source == SOURCE_INPUT_METHOD) { + // InputConnection.commitContent() should only be used for non-text input which is not + // supported by the default implementation. + return false; + } if (source == SOURCE_AUTOFILL) { return onReceiveForAutofill(view, clip, flags); } @@ -123,7 +118,7 @@ public class TextViewOnReceiveContentCallback implements OnReceiveContentCallbac } } } - return true; + return didFirst; } private static void replaceSelection(@NonNull Editable editable, @@ -160,7 +155,7 @@ public class TextViewOnReceiveContentCallback implements OnReceiveContentCallbac @NonNull ClipData clip, @Flags int flags) { final CharSequence text = coerceToText(clip, textView.getContext(), flags); if (text.length() == 0) { - return true; + return false; } replaceSelection((Editable) textView.getText(), text); return true; @@ -205,7 +200,7 @@ public class TextViewOnReceiveContentCallback implements OnReceiveContentCallbac * non-text content. */ private static boolean isUsageOfImeCommitContentEnabled(@NonNull View view) { - if (view.getOnReceiveContentCallback() != null) { + if (view.getOnReceiveContentMimeTypes() != null) { if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) { Log.v(LOG_TAG, "Fallback to commitContent disabled (custom callback is set)"); } @@ -267,6 +262,17 @@ public class TextViewOnReceiveContentCallback implements OnReceiveContentCallbac mInputConnectionInfo = null; } + // TODO(b/168253885): Use this to populate the assist structure for Autofill + + /** @hide */ + @VisibleForTesting + public Set<String> getMimeTypes(TextView view) { + if (!isUsageOfImeCommitContentEnabled(view)) { + return MIME_TYPES_ALL_TEXT; + } + return getSupportedMimeTypesAugmentedWithImeCommitContentMimeTypes(); + } + private Set<String> getSupportedMimeTypesAugmentedWithImeCommitContentMimeTypes() { InputConnectionInfo icInfo = mInputConnectionInfo; if (icInfo == null) { @@ -291,7 +297,8 @@ public class TextViewOnReceiveContentCallback implements OnReceiveContentCallbac } /** - * We want to avoid creating a new set on every invocation of {@link #getSupportedMimeTypes}. + * We want to avoid creating a new set on every invocation of + * {@link #getSupportedMimeTypesAugmentedWithImeCommitContentMimeTypes()}. * This method will check if the cached set of MIME types matches the data in the given array * from {@link EditorInfo} or if a new set should be created. The custom logic is needed for * comparing the data because the set contains the additional "text/*" MIME type. diff --git a/core/java/android/widget/ViewAnimator.java b/core/java/android/widget/ViewAnimator.java index 90f61ca50d52..3f8325a8f547 100644 --- a/core/java/android/widget/ViewAnimator.java +++ b/core/java/android/widget/ViewAnimator.java @@ -21,6 +21,7 @@ import android.annotation.AnimRes; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; +import android.os.Build; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; @@ -156,7 +157,7 @@ public class ViewAnimator extends FrameLayout { * @param animate Whether or not to use the in and out animations, defaults * to true. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void showOnly(int childIndex, boolean animate) { final int count = getChildCount(); for (int i = 0; i < count; i++) { diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java index 2df9a785450b..5abb6e1637e7 100644 --- a/core/java/android/widget/ViewFlipper.java +++ b/core/java/android/widget/ViewFlipper.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.TypedArray; +import android.os.Build; import android.os.Message; import android.util.AttributeSet; import android.util.Log; @@ -183,7 +184,7 @@ public class ViewFlipper extends ViewAnimator { * addition to queuing future flips. If omitted, defaults to * true. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void updateRunning(boolean flipNow) { boolean running = mVisible && mStarted && mUserPresent; if (running != mRunning) { diff --git a/core/java/android/window/DisplayAreaAppearedInfo.aidl b/core/java/android/window/DisplayAreaAppearedInfo.aidl new file mode 100644 index 000000000000..365f3e56d968 --- /dev/null +++ b/core/java/android/window/DisplayAreaAppearedInfo.aidl @@ -0,0 +1,24 @@ +/* + * 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.window; + +/** + * Data object for the DisplayArea info provided when a DisplayArea is presented to an organizer. + * + * @hide + */ +parcelable DisplayAreaAppearedInfo; diff --git a/core/java/android/window/DisplayAreaAppearedInfo.java b/core/java/android/window/DisplayAreaAppearedInfo.java new file mode 100644 index 000000000000..d33d77d54031 --- /dev/null +++ b/core/java/android/window/DisplayAreaAppearedInfo.java @@ -0,0 +1,88 @@ +/* + * 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.window; + +import android.annotation.NonNull; +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.SurfaceControl; + +/** + * Data object for the DisplayArea info provided when a DisplayArea is presented to an organizer. + * + * @hide + */ +@TestApi +public final class DisplayAreaAppearedInfo implements Parcelable { + + @NonNull + private final DisplayAreaInfo mDisplayAreaInfo; + + @NonNull + private final SurfaceControl mLeash; + + @NonNull + public static final Creator<DisplayAreaAppearedInfo> CREATOR = + new Creator<DisplayAreaAppearedInfo>() { + @Override + public DisplayAreaAppearedInfo createFromParcel(Parcel source) { + final DisplayAreaInfo displayAreaInfo = source.readTypedObject(DisplayAreaInfo.CREATOR); + final SurfaceControl leash = source.readTypedObject(SurfaceControl.CREATOR); + return new DisplayAreaAppearedInfo(displayAreaInfo, leash); + } + + @Override + public DisplayAreaAppearedInfo[] newArray(int size) { + return new DisplayAreaAppearedInfo[size]; + } + + }; + + public DisplayAreaAppearedInfo(@NonNull DisplayAreaInfo displayAreaInfo, + @NonNull SurfaceControl leash) { + mDisplayAreaInfo = displayAreaInfo; + mLeash = leash; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeTypedObject(mDisplayAreaInfo, flags); + dest.writeTypedObject(mLeash, flags); + } + + @Override + public int describeContents() { + return 0; + } + + /** + * @return the DisplayArea info. + */ + @NonNull + public DisplayAreaInfo getDisplayAreaInfo() { + return mDisplayAreaInfo; + } + + /** + * @return the leash for the DisplayArea. + */ + @NonNull + public SurfaceControl getLeash() { + return mLeash; + } +} diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java index 78fa30358d74..6ec093e045fa 100644 --- a/core/java/android/window/DisplayAreaOrganizer.java +++ b/core/java/android/window/DisplayAreaOrganizer.java @@ -16,12 +16,15 @@ package android.window; +import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.TestApi; import android.os.RemoteException; import android.view.SurfaceControl; +import java.util.List; + /** * Interface for WindowManager to delegate control of display areas. * @hide @@ -84,10 +87,17 @@ public class DisplayAreaOrganizer extends WindowOrganizer { */ public static final int FEATURE_VENDOR_FIRST = FEATURE_SYSTEM_LAST + 1; - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) - public void registerOrganizer(int displayAreaFeature) { + /** + * Registers a DisplayAreaOrganizer to manage display areas for a given feature. + * + * @return a list of display areas that should be managed by the organizer. + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) + @CallSuper + @NonNull + public List<DisplayAreaAppearedInfo> registerOrganizer(int displayAreaFeature) { try { - getController().registerOrganizer(mInterface, displayAreaFeature); + return getController().registerOrganizer(mInterface, displayAreaFeature).getList(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -96,7 +106,8 @@ public class DisplayAreaOrganizer extends WindowOrganizer { /** * @hide */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) + @CallSuper public void unregisterOrganizer() { try { getController().unregisterOrganizer(mInterface); @@ -105,6 +116,11 @@ public class DisplayAreaOrganizer extends WindowOrganizer { } } + /** + * Called when a DisplayArea of the registered window type can be controlled by this organizer. + * It will not be called for the DisplayAreas that exist when {@link #registerOrganizer(int)} is + * called. + */ public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo, @NonNull SurfaceControl leash) {} diff --git a/core/java/android/window/IDisplayAreaOrganizerController.aidl b/core/java/android/window/IDisplayAreaOrganizerController.aidl index 41b9d027344e..8943847073c7 100644 --- a/core/java/android/window/IDisplayAreaOrganizerController.aidl +++ b/core/java/android/window/IDisplayAreaOrganizerController.aidl @@ -16,13 +16,20 @@ package android.window; +import android.content.pm.ParceledListSlice; +import android.window.DisplayAreaAppearedInfo; import android.window.IDisplayAreaOrganizer; /** @hide */ interface IDisplayAreaOrganizerController { - /** Register a DisplayAreaOrganizer to manage display areas for a given feature. */ - void registerOrganizer(in IDisplayAreaOrganizer organizer, int displayAreaFeature); + /** + * Registers a DisplayAreaOrganizer to manage display areas for a given feature. + * + * @return a list of display areas that should be managed by the organizer. + */ + ParceledListSlice<DisplayAreaAppearedInfo> registerOrganizer(in IDisplayAreaOrganizer organizer, + int displayAreaFeature); /** * Unregisters a previously registered display area organizer. diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl index 3a84c1f98ce6..4a43a438b69d 100644 --- a/core/java/android/window/ITaskOrganizerController.aidl +++ b/core/java/android/window/ITaskOrganizerController.aidl @@ -40,7 +40,7 @@ interface ITaskOrganizerController { void unregisterTaskOrganizer(ITaskOrganizer organizer); /** Creates a persistent root task in WM for a particular windowing-mode. */ - ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode); + void createRootTask(int displayId, int windowingMode, IBinder launchCookie); /** Deletes a persistent root task in WM */ boolean deleteRootTask(in WindowContainerToken task); diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index 6c739bed35a4..4e209206f233 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -23,6 +23,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.TestApi; import android.app.ActivityManager; +import android.os.IBinder; import android.os.RemoteException; import android.view.SurfaceControl; @@ -61,7 +62,7 @@ public class TaskOrganizer extends WindowOrganizer { * @return a list of the tasks that should be managed by the organizer, not including tasks * created via {@link #createRootTask}. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) @CallSuper @NonNull public List<TaskAppearedInfo> registerOrganizer() { @@ -73,7 +74,7 @@ public class TaskOrganizer extends WindowOrganizer { } /** Unregisters a previously registered task organizer. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) @CallSuper public void unregisterOrganizer() { try { @@ -101,19 +102,25 @@ public class TaskOrganizer extends WindowOrganizer { @BinderThread public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} - /** Creates a persistent root task in WM for a particular windowing-mode. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + /** + * Creates a persistent root task in WM for a particular windowing-mode. + * @param displayId The display to create the root task on. + * @param windowingMode Windowing mode to put the root task in. + * @param launchCookie Launch cookie to associate with the task so that is can be identified + * when the {@link ITaskOrganizer#onTaskAppeared} callback is called. + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) @Nullable - public ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode) { + public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) { try { - return mTaskOrganizerController.createRootTask(displayId, windowingMode); + mTaskOrganizerController.createRootTask(displayId, windowingMode, launchCookie); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** Deletes a persistent root task in WM */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean deleteRootTask(@NonNull WindowContainerToken task) { try { return mTaskOrganizerController.deleteRootTask(task); @@ -123,7 +130,7 @@ public class TaskOrganizer extends WindowOrganizer { } /** Gets direct child tasks (ordered from top-to-bottom) */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) @Nullable public List<ActivityManager.RunningTaskInfo> getChildTasks( @NonNull WindowContainerToken parent, @NonNull int[] activityTypes) { @@ -135,7 +142,7 @@ public class TaskOrganizer extends WindowOrganizer { } /** Gets all root tasks on a display (ordered from top-to-bottom) */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) @Nullable public List<ActivityManager.RunningTaskInfo> getRootTasks( int displayId, @NonNull int[] activityTypes) { @@ -147,7 +154,7 @@ public class TaskOrganizer extends WindowOrganizer { } /** Get the root task which contains the current ime target */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) @Nullable public WindowContainerToken getImeTarget(int display) { try { @@ -161,7 +168,7 @@ public class TaskOrganizer extends WindowOrganizer { * Set's the root task to launch new tasks into on a display. {@code null} means no launch * root and thus new tasks just end up directly on the display. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void setLaunchRoot(int displayId, @NonNull WindowContainerToken root) { try { mTaskOrganizerController.setLaunchRoot(displayId, root); @@ -174,7 +181,7 @@ public class TaskOrganizer extends WindowOrganizer { * Requests that the given task organizer is notified when back is pressed on the root activity * of one of its controlled tasks. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void setInterceptBackPressedOnTaskRoot(@NonNull WindowContainerToken task, boolean interceptBackPressed) { try { diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java index 5ac19fa685d7..bb03e2829715 100644 --- a/core/java/android/window/WindowOrganizer.java +++ b/core/java/android/window/WindowOrganizer.java @@ -39,7 +39,7 @@ public class WindowOrganizer { * Apply multiple WindowContainer operations at once. * @param t The transaction to apply. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void applyTransaction(@NonNull WindowContainerTransaction t) { try { getWindowOrganizerController().applyTransaction(t); @@ -57,7 +57,7 @@ public class WindowOrganizer { * @return An ID for the sync operation which will later be passed to transactionReady callback. * This lets the caller differentiate overlapping sync operations. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public int applySyncTransaction(@NonNull WindowContainerTransaction t, @NonNull WindowContainerTransactionCallback callback) { try { @@ -76,7 +76,7 @@ public class WindowOrganizer { * was provided. * @hide */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) @NonNull public IBinder startTransition(int type, @Nullable IBinder transitionToken, @Nullable WindowContainerTransaction t) { @@ -97,7 +97,7 @@ public class WindowOrganizer { * @hide */ @SuppressLint("ExecutorRegistration") - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public int finishTransition(@NonNull IBinder transitionToken, @Nullable WindowContainerTransaction t, @Nullable WindowContainerTransactionCallback callback) { @@ -135,7 +135,7 @@ public class WindowOrganizer { * Register an ITransitionPlayer to handle transition animations. * @hide */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void registerTransitionPlayer(@Nullable ITransitionPlayer player) { try { getWindowOrganizerController().registerTransitionPlayer(player); @@ -144,7 +144,7 @@ public class WindowOrganizer { } } - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) IWindowOrganizerController getWindowOrganizerController() { return IWindowOrganizerControllerSingleton.get(); } diff --git a/core/java/com/android/ims/internal/uce/common/CapInfo.java b/core/java/com/android/ims/internal/uce/common/CapInfo.java index a7a90f6912c2..bca647a911d6 100644 --- a/core/java/com/android/ims/internal/uce/common/CapInfo.java +++ b/core/java/com/android/ims/internal/uce/common/CapInfo.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.common; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -91,7 +92,7 @@ public class CapInfo implements Parcelable { /** * Constructor for the CapInfo class. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CapInfo() { }; @@ -99,7 +100,7 @@ public class CapInfo implements Parcelable { /** * Checks whether IM is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isImSupported() { return mImSupported; } @@ -107,7 +108,7 @@ public class CapInfo implements Parcelable { /** * Sets IM as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setImSupported(boolean imSupported) { this.mImSupported = imSupported; } @@ -115,7 +116,7 @@ public class CapInfo implements Parcelable { /** * Checks whether FT Thumbnail is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isFtThumbSupported() { return mFtThumbSupported; } @@ -123,7 +124,7 @@ public class CapInfo implements Parcelable { /** * Sets FT thumbnail as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setFtThumbSupported(boolean ftThumbSupported) { this.mFtThumbSupported = ftThumbSupported; } @@ -133,7 +134,7 @@ public class CapInfo implements Parcelable { /** * Checks whether FT Store and Forward is supported */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isFtSnFSupported() { return mFtSnFSupported; } @@ -141,7 +142,7 @@ public class CapInfo implements Parcelable { /** * Sets FT Store and Forward as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setFtSnFSupported(boolean ftSnFSupported) { this.mFtSnFSupported = ftSnFSupported; } @@ -149,7 +150,7 @@ public class CapInfo implements Parcelable { /** * Checks whether File transfer HTTP is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isFtHttpSupported() { return mFtHttpSupported; } @@ -157,7 +158,7 @@ public class CapInfo implements Parcelable { /** * Sets File transfer HTTP as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setFtHttpSupported(boolean ftHttpSupported) { this.mFtHttpSupported = ftHttpSupported; } @@ -165,7 +166,7 @@ public class CapInfo implements Parcelable { /** * Checks whether FT is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isFtSupported() { return mFtSupported; } @@ -173,7 +174,7 @@ public class CapInfo implements Parcelable { /** * Sets FT as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setFtSupported(boolean ftSupported) { this.mFtSupported = ftSupported; } @@ -181,7 +182,7 @@ public class CapInfo implements Parcelable { /** * Checks whether IS is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isIsSupported() { return mIsSupported; } @@ -189,7 +190,7 @@ public class CapInfo implements Parcelable { /** * Sets IS as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setIsSupported(boolean isSupported) { this.mIsSupported = isSupported; } @@ -197,7 +198,7 @@ public class CapInfo implements Parcelable { /** * Checks whether video sharing is supported during a CS call. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isVsDuringCSSupported() { return mVsDuringCSSupported; } @@ -206,7 +207,7 @@ public class CapInfo implements Parcelable { * Sets video sharing as supported or not supported during a CS * call. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setVsDuringCSSupported(boolean vsDuringCSSupported) { this.mVsDuringCSSupported = vsDuringCSSupported; } @@ -215,7 +216,7 @@ public class CapInfo implements Parcelable { * Checks whether video sharing outside a voice call is * supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isVsSupported() { return mVsSupported; } @@ -223,7 +224,7 @@ public class CapInfo implements Parcelable { /** * Sets video sharing as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setVsSupported(boolean vsSupported) { this.mVsSupported = vsSupported; } @@ -231,7 +232,7 @@ public class CapInfo implements Parcelable { /** * Checks whether social presence is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isSpSupported() { return mSpSupported; } @@ -239,7 +240,7 @@ public class CapInfo implements Parcelable { /** * Sets social presence as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSpSupported(boolean spSupported) { this.mSpSupported = spSupported; } @@ -248,7 +249,7 @@ public class CapInfo implements Parcelable { * Checks whether capability discovery via presence is * supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isCdViaPresenceSupported() { return mCdViaPresenceSupported; } @@ -257,7 +258,7 @@ public class CapInfo implements Parcelable { * Sets capability discovery via presence as supported or not * supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCdViaPresenceSupported(boolean cdViaPresenceSupported) { this.mCdViaPresenceSupported = cdViaPresenceSupported; } @@ -265,7 +266,7 @@ public class CapInfo implements Parcelable { /** * Checks whether IP voice call is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isIpVoiceSupported() { return mIpVoiceSupported; } @@ -273,7 +274,7 @@ public class CapInfo implements Parcelable { /** * Sets IP voice call as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setIpVoiceSupported(boolean ipVoiceSupported) { this.mIpVoiceSupported = ipVoiceSupported; } @@ -281,7 +282,7 @@ public class CapInfo implements Parcelable { /** * Checks whether IP video call is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isIpVideoSupported() { return mIpVideoSupported; } @@ -289,7 +290,7 @@ public class CapInfo implements Parcelable { /** * Sets IP video call as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setIpVideoSupported(boolean ipVideoSupported) { this.mIpVideoSupported = ipVideoSupported; } @@ -298,7 +299,7 @@ public class CapInfo implements Parcelable { * Checks whether Geo location Pull using File Transfer is * supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isGeoPullFtSupported() { return mGeoPullFtSupported; } @@ -307,7 +308,7 @@ public class CapInfo implements Parcelable { * Sets Geo location Pull using File Transfer as supported or * not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setGeoPullFtSupported(boolean geoPullFtSupported) { this.mGeoPullFtSupported = geoPullFtSupported; } @@ -315,7 +316,7 @@ public class CapInfo implements Parcelable { /** * Checks whether Geo Pull is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isGeoPullSupported() { return mGeoPullSupported; } @@ -323,7 +324,7 @@ public class CapInfo implements Parcelable { /** * Sets Geo Pull as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setGeoPullSupported(boolean geoPullSupported) { this.mGeoPullSupported = geoPullSupported; } @@ -331,7 +332,7 @@ public class CapInfo implements Parcelable { /** * Checks whether Geo Push is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isGeoPushSupported() { return mGeoPushSupported; } @@ -339,7 +340,7 @@ public class CapInfo implements Parcelable { /** * Sets Geo Push as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setGeoPushSupported(boolean geoPushSupported) { this.mGeoPushSupported = geoPushSupported; } @@ -347,7 +348,7 @@ public class CapInfo implements Parcelable { /** * Checks whether short messaging is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isSmSupported() { return mSmSupported; } @@ -355,7 +356,7 @@ public class CapInfo implements Parcelable { /** * Sets short messaging as supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSmSupported(boolean smSupported) { this.mSmSupported = smSupported; } @@ -363,22 +364,22 @@ public class CapInfo implements Parcelable { /** * Checks whether store/forward and group chat are supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isFullSnFGroupChatSupported() { return mFullSnFGroupChatSupported; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isRcsIpVoiceCallSupported() { return mRcsIpVoiceCallSupported; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isRcsIpVideoCallSupported() { return mRcsIpVideoCallSupported; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isRcsIpVideoOnlyCallSupported() { return mRcsIpVideoOnlyCallSupported; } @@ -386,20 +387,20 @@ public class CapInfo implements Parcelable { /** * Sets store/forward and group chat supported or not supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setFullSnFGroupChatSupported(boolean fullSnFGroupChatSupported) { this.mFullSnFGroupChatSupported = fullSnFGroupChatSupported; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRcsIpVoiceCallSupported(boolean rcsIpVoiceCallSupported) { this.mRcsIpVoiceCallSupported = rcsIpVoiceCallSupported; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRcsIpVideoCallSupported(boolean rcsIpVideoCallSupported) { this.mRcsIpVideoCallSupported = rcsIpVideoCallSupported; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRcsIpVideoOnlyCallSupported(boolean rcsIpVideoOnlyCallSupported) { this.mRcsIpVideoOnlyCallSupported = rcsIpVideoOnlyCallSupported; } @@ -536,20 +537,20 @@ public class CapInfo implements Parcelable { } /** Sets the list of supported extensions. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setExts(String[] exts) { this.mExts = exts; } /** Gets the time stamp for when to query again. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getCapTimestamp() { return mCapTimestamp; } /** Sets the time stamp for when to query again. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCapTimestamp(long capTimestamp) { this.mCapTimestamp = capTimestamp; } diff --git a/core/java/com/android/ims/internal/uce/common/StatusCode.java b/core/java/com/android/ims/internal/uce/common/StatusCode.java index 7f69493aa284..847792f4b50c 100644 --- a/core/java/com/android/ims/internal/uce/common/StatusCode.java +++ b/core/java/com/android/ims/internal/uce/common/StatusCode.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.common; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -75,14 +76,14 @@ public class StatusCode implements Parcelable { * Constructor for the StatusCode class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public StatusCode() {} /** * Gets the status code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getStatusCode() { return mStatusCode; } @@ -91,7 +92,7 @@ public class StatusCode implements Parcelable { * Sets the status code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setStatusCode(int nStatusCode) { this.mStatusCode = nStatusCode; } diff --git a/core/java/com/android/ims/internal/uce/common/UceLong.java b/core/java/com/android/ims/internal/uce/common/UceLong.java index bf514471b506..d878c10c76b4 100644 --- a/core/java/com/android/ims/internal/uce/common/UceLong.java +++ b/core/java/com/android/ims/internal/uce/common/UceLong.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.common; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -32,7 +33,7 @@ public class UceLong implements Parcelable { * Constructor for the UceLong class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public UceLong() { }; @@ -40,7 +41,7 @@ public class UceLong implements Parcelable { * Gets the long value. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getUceLong() { return mUceLong; } @@ -49,7 +50,7 @@ public class UceLong implements Parcelable { * Sets the long value. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setUceLong(long uceLong) { this.mUceLong = uceLong; } @@ -57,7 +58,7 @@ public class UceLong implements Parcelable { /** Get the client ID as integer value. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getClientId() { return mClientId; } @@ -66,7 +67,7 @@ public class UceLong implements Parcelable { * Set the client ID as integer value. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setClientId(int nClientId) { this.mClientId = nClientId; } diff --git a/core/java/com/android/ims/internal/uce/options/IOptionsListener.aidl b/core/java/com/android/ims/internal/uce/options/IOptionsListener.aidl index c69d5a94f760..62897c7fb1ae 100644 --- a/core/java/com/android/ims/internal/uce/options/IOptionsListener.aidl +++ b/core/java/com/android/ims/internal/uce/options/IOptionsListener.aidl @@ -29,7 +29,7 @@ interface IOptionsListener * @param version, version information of the service. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void getVersionCb(in String version ); /** @@ -38,7 +38,7 @@ interface IOptionsListener * @param statusCode, UCE_SUCCESS as service availability. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void serviceAvailable(in StatusCode statusCode); /** @@ -47,7 +47,7 @@ interface IOptionsListener * @param statusCode, UCE_SUCCESS as service unavailability. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void serviceUnavailable(in StatusCode statusCode); /** @@ -58,7 +58,7 @@ interface IOptionsListener * @param capInfo, capabilities of the remote entity received. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void sipResponseReceived( String uri, in OptionsSipResponse sipResponse, in OptionsCapInfo capInfo); @@ -67,7 +67,7 @@ interface IOptionsListener * @param cmdStatus, command status of the request placed. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void cmdStatus(in OptionsCmdStatus cmdStatus); /** @@ -78,7 +78,7 @@ interface IOptionsListener * @param tID, transation of the request received from network. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void incomingOptions( String uri, in OptionsCapInfo capInfo, in int tID); } diff --git a/core/java/com/android/ims/internal/uce/options/IOptionsService.aidl b/core/java/com/android/ims/internal/uce/options/IOptionsService.aidl index 2e49082988c3..a7487b804567 100644 --- a/core/java/com/android/ims/internal/uce/options/IOptionsService.aidl +++ b/core/java/com/android/ims/internal/uce/options/IOptionsService.aidl @@ -33,7 +33,7 @@ interface IOptionsService * @return StatusCode, status of the request placed. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode getVersion(int optionsServiceHandle); /** @@ -45,7 +45,7 @@ interface IOptionsService * The service will fill UceLong.mUceLong with optionsServiceListenerHdl * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode addListener(int optionsServiceHandle, IOptionsListener optionsListener, inout UceLong optionsServiceListenerHdl); @@ -56,7 +56,7 @@ interface IOptionsService * @param optionsServiceListenerHdl provided in createOptionsService() or Addlistener(). * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode removeListener(int optionsServiceHandle, in UceLong optionsServiceListenerHdl); /** @@ -69,7 +69,7 @@ interface IOptionsService * with original request. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode setMyInfo(int optionsServiceHandle , in CapInfo capInfo, int reqUserData); @@ -82,7 +82,7 @@ interface IOptionsService * with original request. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode getMyInfo(int optionsServiceHandle , int reqUserdata); /** @@ -95,7 +95,7 @@ interface IOptionsService * with original request. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode getContactCap(int optionsServiceHandle , String remoteURI, int reqUserData); @@ -109,7 +109,7 @@ interface IOptionsService * with original request. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode getContactListCap(int optionsServiceHandle, in String[] remoteURIList, int reqUserData); @@ -126,7 +126,7 @@ interface IOptionsService * @param bContactInBL, true if the contact is blacklisted, else false. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode responseIncomingOptions(int optionsServiceHandle, int tId, int sipResponseCode, String reasonPhrase, in OptionsCapInfo capInfo, in boolean bContactInBL); diff --git a/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java b/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java index 1da5a2439f02..6f83bf3224a8 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java @@ -16,6 +16,7 @@ package com.android.ims.internal.uce.options; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -31,12 +32,12 @@ public class OptionsCapInfo implements Parcelable { return new OptionsCapInfo(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getSdp() { return mSdp; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSdp(String sdp) { this.mSdp = sdp; } @@ -44,19 +45,19 @@ public class OptionsCapInfo implements Parcelable { /** * Constructor for the OptionsCapInfo class. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public OptionsCapInfo() { mCapInfo = new CapInfo(); }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CapInfo getCapInfo() { return mCapInfo; } /** * Sets the CapInfo */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCapInfo(CapInfo capInfo) { this.mCapInfo = capInfo; } diff --git a/core/java/com/android/ims/internal/uce/options/OptionsCmdId.java b/core/java/com/android/ims/internal/uce/options/OptionsCmdId.java index 401ca2fa24ea..82eb1b54a775 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsCmdId.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsCmdId.java @@ -18,6 +18,7 @@ package com.android.ims.internal.uce.options; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -56,7 +57,7 @@ public class OptionsCmdId implements Parcelable { * Sets the command ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCmdId(int nCmdId) { this.mCmdId = nCmdId; } @@ -65,7 +66,7 @@ public class OptionsCmdId implements Parcelable { * Constructor for the OptionsCDCmdId class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public OptionsCmdId(){}; /** @hide */ diff --git a/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java b/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java index 70a7a84d3820..461f8bfb48c8 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.options; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -42,7 +43,7 @@ public class OptionsCmdStatus implements Parcelable { * Sets the command ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCmdId(OptionsCmdId cmdId) { this.mCmdId = cmdId; } @@ -58,7 +59,7 @@ public class OptionsCmdStatus implements Parcelable { /** Sets the user data. @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setUserData(int userData) { this.mUserData = userData; } @@ -75,7 +76,7 @@ public class OptionsCmdStatus implements Parcelable { * Sets the status code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setStatus(StatusCode status) { this.mStatus = status; } @@ -84,7 +85,7 @@ public class OptionsCmdStatus implements Parcelable { * Constructor for the OptionsCmdStatus class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public OptionsCmdStatus() { mStatus = new StatusCode(); mCapInfo = new CapInfo(); @@ -101,7 +102,7 @@ public class OptionsCmdStatus implements Parcelable { * Sets the CapInfo * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCapInfo(CapInfo capInfo) { this.mCapInfo = capInfo; } diff --git a/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java b/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java index 5afddf0c42c0..acea0f03742f 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.options; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -42,7 +43,7 @@ public class OptionsSipResponse implements Parcelable { * Sets the Options command ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCmdId(OptionsCmdId cmdId) { this.mCmdId = cmdId; } @@ -59,7 +60,7 @@ public class OptionsSipResponse implements Parcelable { * Sets the request ID * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRequestId(int requestId) { this.mRequestId = requestId; } @@ -76,7 +77,7 @@ public class OptionsSipResponse implements Parcelable { * Sets the SIP response code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSipResponseCode(int sipResponseCode) { this.mSipResponseCode = sipResponseCode; } @@ -93,7 +94,7 @@ public class OptionsSipResponse implements Parcelable { * Sets the SIP response code reason phrase. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setReasonPhrase(String reasonPhrase) { this.mReasonPhrase = reasonPhrase; } @@ -110,7 +111,7 @@ public class OptionsSipResponse implements Parcelable { * Sets the SIP retryAfter sec value * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRetryAfter(int retryAfter) { this.mRetryAfter = retryAfter; } @@ -119,7 +120,7 @@ public class OptionsSipResponse implements Parcelable { * Constructor for the OptionsSipResponse class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public OptionsSipResponse() { mCmdId = new OptionsCmdId(); }; diff --git a/core/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl b/core/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl index 65e7fc9756bb..572a5f32ee93 100644 --- a/core/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl +++ b/core/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl @@ -36,7 +36,7 @@ interface IPresenceListener * Gets the version of the presence listener implementation. * @param version, version information. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void getVersionCb(in String version ); /** @@ -44,7 +44,7 @@ interface IPresenceListener * availability. * @param statusCode, UCE_SUCCESS as service availability. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void serviceAvailable(in StatusCode statusCode); /** @@ -52,7 +52,7 @@ interface IPresenceListener * unavailability. * @param statusCode, UCE_SUCCESS as service unAvailability. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void serviceUnAvailable(in StatusCode statusCode); /** @@ -60,14 +60,14 @@ interface IPresenceListener * publish request. * @param publishTrigger, Publish trigger for the network being supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void publishTriggering(in PresPublishTriggerType publishTrigger); /** * Callback function to be invoked to inform the client of the status of an asynchronous call. * @param cmdStatus, command status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void cmdStatus( in PresCmdStatus cmdStatus); /** @@ -75,7 +75,7 @@ interface IPresenceListener * such as PUBLISH or SUBSCRIBE, has been received. * @param sipResponse, network response received for the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void sipResponseReceived(in PresSipResponse sipResponse); /** @@ -84,7 +84,7 @@ interface IPresenceListener * @param presentityURI, URI of the remote entity the request was placed. * @param tupleInfo, array of capability information remote entity supports. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void capInfoReceived(in String presentityURI, in PresTupleInfo [] tupleInfo); @@ -94,7 +94,7 @@ interface IPresenceListener * @param rlmiInfo, resource infomation received from network. * @param resInfo, array of capabilities received from network for the list of remore URI. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void listCapInfoReceived(in PresRlmiInfo rlmiInfo, in PresResInfo [] resInfo); @@ -102,7 +102,7 @@ interface IPresenceListener * Callback function to be invoked to inform the client when Unpublish message * is sent to network. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void unpublishMessageSent(); }
\ No newline at end of file diff --git a/core/java/com/android/ims/internal/uce/presence/IPresenceService.aidl b/core/java/com/android/ims/internal/uce/presence/IPresenceService.aidl index 26a3e83efcfa..de28dfa9f2d7 100644 --- a/core/java/com/android/ims/internal/uce/presence/IPresenceService.aidl +++ b/core/java/com/android/ims/internal/uce/presence/IPresenceService.aidl @@ -33,7 +33,7 @@ interface IPresenceService * @param presenceServiceHdl returned in createPresenceService(). * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode getVersion(int presenceServiceHdl); /** @@ -46,7 +46,7 @@ interface IPresenceService * * @return StatusCode, status of the request placed */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode addListener(int presenceServiceHdl, IPresenceListener presenceServiceListener, inout UceLong presenceServiceListenerHdl); @@ -56,7 +56,7 @@ interface IPresenceService * @param presenceServiceListenerHdl provided in createPresenceService() or Addlistener(). * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode removeListener(int presenceServiceHdl, in UceLong presenceServiceListenerHdl); /** @@ -72,7 +72,7 @@ interface IPresenceService * with original request. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode reenableService(int presenceServiceHdl, int userData); /** @@ -85,7 +85,7 @@ interface IPresenceService * with original request. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode publishMyCap(int presenceServiceHdl, in PresCapInfo myCapInfo , int userData); /** @@ -99,7 +99,7 @@ interface IPresenceService * with original request. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode getContactCap(int presenceServiceHdl , String remoteUri, int userData); /** @@ -113,7 +113,7 @@ interface IPresenceService * with original request. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode getContactListCap(int presenceServiceHdl, in String[] remoteUriList, int userData); /** @@ -129,7 +129,7 @@ interface IPresenceService * with original request. * @return StatusCode, status of the request placed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) StatusCode setNewFeatureTag(int presenceServiceHdl, String featureTag, in PresServiceInfo serviceInfo, int userData); diff --git a/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java b/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java index 1a3a028713f6..ec8b6bfa4ef3 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -27,14 +28,14 @@ import com.android.ims.internal.uce.common.CapInfo; public class PresCapInfo implements Parcelable { private CapInfo mCapInfo; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String mContactUri = ""; /** * Gets the UCE capability information. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CapInfo getCapInfo() { return mCapInfo; } @@ -51,7 +52,7 @@ public class PresCapInfo implements Parcelable { * Gets the contact URI. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getContactUri() { return mContactUri; } diff --git a/core/java/com/android/ims/internal/uce/presence/PresCmdId.java b/core/java/com/android/ims/internal/uce/presence/PresCmdId.java index fba0c77e8dbf..9692b428c792 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCmdId.java +++ b/core/java/com/android/ims/internal/uce/presence/PresCmdId.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -58,7 +59,7 @@ public class PresCmdId implements Parcelable { * Sets the command ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCmdId(int nCmdId) { this.mCmdId = nCmdId; } @@ -68,7 +69,7 @@ public class PresCmdId implements Parcelable { * Constructor for the PresCmdId class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresCmdId(){}; diff --git a/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java b/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java index fbc64b83a360..7e22106f3be3 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java +++ b/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -43,7 +44,7 @@ public class PresCmdStatus implements Parcelable{ * Sets the command ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCmdId(PresCmdId cmdId) { this.mCmdId = cmdId; } @@ -60,7 +61,7 @@ public class PresCmdStatus implements Parcelable{ * Sets the user data. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setUserData(int userData) { this.mUserData = userData; } @@ -76,7 +77,7 @@ public class PresCmdStatus implements Parcelable{ * Sets the status code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setStatus(StatusCode status) { this.mStatus = status; } @@ -93,7 +94,7 @@ public class PresCmdStatus implements Parcelable{ * Sets the request ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRequestId(int requestId) { this.mRequestId = requestId; } @@ -102,7 +103,7 @@ public class PresCmdStatus implements Parcelable{ * Constructor for the PresCmdStatus class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresCmdStatus() { mStatus = new StatusCode(); }; diff --git a/core/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java b/core/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java index fdff86f9669f..04bbf6cd8e30 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java +++ b/core/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -70,7 +71,7 @@ public class PresPublishTriggerType implements Parcelable { * Sets the publish trigger type. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setPublishTrigeerType(int nPublishTriggerType) { this.mPublishTriggerType = nPublishTriggerType; } @@ -80,7 +81,7 @@ public class PresPublishTriggerType implements Parcelable { * Constructor for the PresPublishTriggerType class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresPublishTriggerType(){}; /** @hide */ diff --git a/core/java/com/android/ims/internal/uce/presence/PresResInfo.java b/core/java/com/android/ims/internal/uce/presence/PresResInfo.java index af9b0568d29b..2f797b41b14f 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresResInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresResInfo.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -39,7 +40,7 @@ public class PresResInfo implements Parcelable { * Sets the Presence service resource instance information. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setInstanceInfo(PresResInstanceInfo instanceInfo) { this.mInstanceInfo = instanceInfo; } @@ -56,7 +57,7 @@ public class PresResInfo implements Parcelable { * Sets the resource URI. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setResUri(String resUri) { this.mResUri = resUri; } @@ -73,7 +74,7 @@ public class PresResInfo implements Parcelable { * Sets the display name. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDisplayName(String displayName) { this.mDisplayName = displayName; } @@ -83,7 +84,7 @@ public class PresResInfo implements Parcelable { * Constructor for the PresResInstanceInfo class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresResInfo() { mInstanceInfo = new PresResInstanceInfo(); }; diff --git a/core/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java b/core/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java index 9f3725133452..733c0afff367 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -61,7 +62,7 @@ public class PresResInstanceInfo implements Parcelable{ * Sets the resource instance state. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setResInstanceState(int nResInstanceState) { this.mResInstanceState = nResInstanceState; } @@ -78,7 +79,7 @@ public class PresResInstanceInfo implements Parcelable{ * Sets the resource ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setResId(String resourceId) { this.mId = resourceId; } @@ -97,7 +98,7 @@ public class PresResInstanceInfo implements Parcelable{ * code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setReason(String reason) { this.mReason = reason; } @@ -114,7 +115,7 @@ public class PresResInstanceInfo implements Parcelable{ * Sets the entity URI. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setPresentityUri(String presentityUri) { this.mPresentityUri = presentityUri; } @@ -131,7 +132,7 @@ public class PresResInstanceInfo implements Parcelable{ * Sets the tuple information. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setTupleInfo(PresTupleInfo[] tupleInfo) { this.mTupleInfoArray = new PresTupleInfo[tupleInfo.length]; this.mTupleInfoArray = tupleInfo; @@ -142,7 +143,7 @@ public class PresResInstanceInfo implements Parcelable{ * Constructor for the PresResInstanceInfo class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresResInstanceInfo(){ }; diff --git a/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java b/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java index 65b9fdbbeb18..e33aa1303886 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -61,7 +62,7 @@ public class PresRlmiInfo implements Parcelable { * Sets the URI. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setUri(String uri) { this.mUri = uri; } @@ -78,7 +79,7 @@ public class PresRlmiInfo implements Parcelable { * Sets the version. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setVersion(int version) { this.mVersion = version; } @@ -95,7 +96,7 @@ public class PresRlmiInfo implements Parcelable { * Sets the RLMI state. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setFullState(boolean fullState) { this.mFullState = fullState; } @@ -112,7 +113,7 @@ public class PresRlmiInfo implements Parcelable { * Sets the RLMI list name. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setListName(String listName) { this.mListName = listName; } @@ -129,7 +130,7 @@ public class PresRlmiInfo implements Parcelable { * Sets the subscription request ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRequestId(int requestId) { this.mRequestId = requestId; } @@ -146,7 +147,7 @@ public class PresRlmiInfo implements Parcelable { * Sets the presence subscription state. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setPresSubscriptionState(PresSubscriptionState presSubscriptionState) { this.mPresSubscriptionState = presSubscriptionState; } @@ -163,7 +164,7 @@ public class PresRlmiInfo implements Parcelable { * Sets the presence subscription expiration time. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSubscriptionExpireTime(int subscriptionExpireTime) { this.mSubscriptionExpireTime = subscriptionExpireTime; } @@ -180,7 +181,7 @@ public class PresRlmiInfo implements Parcelable { * Sets the presence subscription terminated reason. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSubscriptionTerminatedReason(String subscriptionTerminatedReason) { this.mSubscriptionTerminatedReason = subscriptionTerminatedReason; } @@ -189,7 +190,7 @@ public class PresRlmiInfo implements Parcelable { * Constructor for the PresTupleInfo class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresRlmiInfo(){}; /** @hide */ diff --git a/core/java/com/android/ims/internal/uce/presence/PresServiceInfo.java b/core/java/com/android/ims/internal/uce/presence/PresServiceInfo.java index 5eafa0fde8cc..aed673e63d94 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresServiceInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresServiceInfo.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -46,7 +47,7 @@ public class PresServiceInfo implements Parcelable { * Gets the media type. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getMediaType() { return mMediaCap; } @@ -63,7 +64,7 @@ public class PresServiceInfo implements Parcelable { * Gets the service ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getServiceId() { return mServiceID; } @@ -79,7 +80,7 @@ public class PresServiceInfo implements Parcelable { * Gets the service description. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getServiceDesc() { return mServiceDesc; } @@ -96,7 +97,7 @@ public class PresServiceInfo implements Parcelable { * Gets the service version. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getServiceVer() { return mServiceVer; } diff --git a/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java b/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java index 45b02f31eddc..9549152ce175 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java +++ b/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -33,7 +34,7 @@ public class PresSipResponse implements Parcelable { * Gets the Presence command ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresCmdId getCmdId() { return mCmdId; } @@ -42,7 +43,7 @@ public class PresSipResponse implements Parcelable { * Sets the Presence command ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCmdId(PresCmdId cmdId) { this.mCmdId = cmdId; } @@ -51,7 +52,7 @@ public class PresSipResponse implements Parcelable { * Gets the request ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getRequestId() { return mRequestId; } @@ -60,7 +61,7 @@ public class PresSipResponse implements Parcelable { * Sets the request ID. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRequestId(int requestId) { this.mRequestId = requestId; } @@ -69,7 +70,7 @@ public class PresSipResponse implements Parcelable { * Gets the SIP response code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getSipResponseCode() { return mSipResponseCode; } @@ -78,7 +79,7 @@ public class PresSipResponse implements Parcelable { * Sets the SIP response code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSipResponseCode(int sipResponseCode) { this.mSipResponseCode = sipResponseCode; } @@ -89,7 +90,7 @@ public class PresSipResponse implements Parcelable { * code. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getReasonPhrase() { return mReasonPhrase; } @@ -98,7 +99,7 @@ public class PresSipResponse implements Parcelable { * Sets the SIP response code reason phrase. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setReasonPhrase(String reasonPhrase) { this.mReasonPhrase = reasonPhrase; } @@ -107,7 +108,7 @@ public class PresSipResponse implements Parcelable { * Gets the SIP retryAfter sec value. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getRetryAfter() { return mRetryAfter; } @@ -116,7 +117,7 @@ public class PresSipResponse implements Parcelable { * Sets the SIP retryAfter sec value * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setRetryAfter(int retryAfter) { this.mRetryAfter = retryAfter; } @@ -125,7 +126,7 @@ public class PresSipResponse implements Parcelable { * Constructor for the PresSipResponse class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresSipResponse(){}; /** @hide */ diff --git a/core/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java b/core/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java index ab1e17c48e75..85ec3967f8f3 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java +++ b/core/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -78,7 +79,7 @@ public class PresSubscriptionState implements Parcelable { * Constructor for the PresSubscriptionState class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresSubscriptionState() { }; /** @@ -94,7 +95,7 @@ public class PresSubscriptionState implements Parcelable { * Sets the Presence subscription state. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setPresSubscriptionState(int nPresSubscriptionState) { this.mPresSubscriptionState = nPresSubscriptionState; } diff --git a/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java b/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java index 3608eb6a5e8a..34a7b1e3de65 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresTupleInfo.java @@ -17,6 +17,7 @@ package com.android.ims.internal.uce.presence; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -40,7 +41,7 @@ public class PresTupleInfo implements Parcelable { * Sets the feature tag. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setFeatureTag(String featureTag) { this.mFeatureTag = featureTag; } @@ -56,7 +57,7 @@ public class PresTupleInfo implements Parcelable { * Sets the contact URI. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setContactUri(String contactUri) { this.mContactUri = contactUri; } @@ -73,7 +74,7 @@ public class PresTupleInfo implements Parcelable { * Sets the timestamp. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setTimestamp(String timestamp) { this.mTimestamp = timestamp; } @@ -82,7 +83,7 @@ public class PresTupleInfo implements Parcelable { * Constructor for the PresTupleInfo class. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PresTupleInfo(){}; /** @hide */ diff --git a/core/java/com/android/ims/internal/uce/uceservice/IUceListener.aidl b/core/java/com/android/ims/internal/uce/uceservice/IUceListener.aidl index 41abf7d1a1f0..2341faed3e15 100644 --- a/core/java/com/android/ims/internal/uce/uceservice/IUceListener.aidl +++ b/core/java/com/android/ims/internal/uce/uceservice/IUceListener.aidl @@ -25,6 +25,6 @@ interface IUceListener * @param serviceStatusValue defined in ImsUceManager * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setStatus(int serviceStatusValue); } diff --git a/core/java/com/android/ims/internal/uce/uceservice/IUceService.aidl b/core/java/com/android/ims/internal/uce/uceservice/IUceService.aidl index ec45371689cf..156e9229e256 100644 --- a/core/java/com/android/ims/internal/uce/uceservice/IUceService.aidl +++ b/core/java/com/android/ims/internal/uce/uceservice/IUceService.aidl @@ -38,7 +38,7 @@ interface IUceService * Service status is returned in setStatus callback in IUceListener. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean startService(IUceListener uceListener); /** @@ -46,7 +46,7 @@ interface IUceService * @return boolean true if the service stop request is processed successfully, FALSE otherwise. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean stopService(); @@ -56,7 +56,7 @@ interface IUceService * @return boolean true if service started else false. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isServiceStarted(); /** @@ -74,7 +74,7 @@ interface IUceService * * @deprecated This is replaced with new API createOptionsServiceForSubscription() */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int createOptionsService(IOptionsListener optionsListener, inout UceLong optionsServiceListenerHdl); /** @@ -101,7 +101,7 @@ interface IUceService * in IOptionsListener * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void destroyOptionsService(int optionsServiceHandle); /** @@ -119,7 +119,7 @@ interface IUceService * * @deprecated This is replaced with new API createPresenceServiceForSubscription() */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int createPresenceService(IPresenceListener presenceServiceListener, inout UceLong presenceServiceListenerHdl); /** @@ -147,7 +147,7 @@ interface IUceService * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void destroyPresenceService(int presenceServiceHdl); @@ -159,7 +159,7 @@ interface IUceService * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean getServiceStatus(); /** @@ -171,7 +171,7 @@ interface IUceService * * @deprecated use API getPresenceServiceForSubscription() */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) IPresenceService getPresenceService(); /** @@ -194,7 +194,7 @@ interface IUceService * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) IOptionsService getOptionsService(); /** diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java index be43e82c3f88..f690bd3477f0 100644 --- a/core/java/com/android/internal/app/AlertController.java +++ b/core/java/com/android/internal/app/AlertController.java @@ -26,6 +26,7 @@ import android.content.DialogInterface; import android.content.res.TypedArray; import android.database.Cursor; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Handler; import android.os.Message; import android.text.Layout; @@ -979,7 +980,7 @@ public class AlertController { boolean mRecycleOnMeasure = true; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public RecycleListView(Context context) { this(context, null); } diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index 04146bcad083..3a9f3b9c1128 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -89,7 +89,7 @@ interface IAppOpsService { void setUidMode(int code, int uid, int mode); @UnsupportedAppUsage void setMode(int code, int uid, String packageName, int mode); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void resetAllModes(int reqUserId, String reqPackageName); void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages); diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index 6a0b443b7df8..e6a166140d89 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -55,7 +55,7 @@ interface IBatteryStats { ParcelFileDescriptor getStatisticsStream(); // Return true if we see the battery as currently charging. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isCharging(); // Return the computed amount of time remaining on battery, in milliseconds. @@ -64,7 +64,7 @@ interface IBatteryStats { // Return the computed amount of time remaining to fully charge, in milliseconds. // Returns -1 if nothing could be computed. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) long computeChargeTimeRemaining(); void noteEvent(int code, String name, int uid); @@ -134,7 +134,7 @@ interface IBatteryStats { void noteDeviceIdleMode(int mode, String activeReason, int activeUid); void setBatteryState(int status, int health, int plugType, int level, int temp, int volt, int chargeUAh, int chargeFullUAh, long chargeTimeToFullSeconds); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) long getAwakeTimeBattery(); long getAwakeTimePlugged(); diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl index 49b4cd1e6a73..81c61aa0f250 100644 --- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl +++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl @@ -61,7 +61,7 @@ interface IVoiceInteractionManagerService { * @param bcp47Locale The BCP47 language tag for the keyphrase's locale. * @RequiresPermission Manifest.permission.MANAGE_VOICE_KEYPHRASES */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) SoundTrigger.KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId, in String bcp47Locale); /** * Add/Update the given keyphrase sound model for the current user. diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 61a52bcc03f9..3e1fa1d5fe59 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -38,6 +38,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.metrics.LogMaker; +import android.os.Build; import android.os.Bundle; import android.os.RemoteException; import android.os.UserHandle; @@ -64,7 +65,7 @@ import java.util.concurrent.Executors; * be passed in and out of a managed profile. */ public class IntentForwarderActivity extends Activity { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String TAG = "IntentForwarderActivity"; public static String FORWARD_INTENT_TO_PARENT diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java index 105e05a4a6c3..3c53d07b6180 100644 --- a/core/java/com/android/internal/app/LocalePicker.java +++ b/core/java/com/android/internal/app/LocalePicker.java @@ -27,6 +27,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; +import android.os.Build; import android.os.Bundle; import android.os.LocaleList; import android.os.RemoteException; @@ -78,7 +79,7 @@ public class LocalePicker extends ListFragment { return label; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Locale getLocale() { return locale; } diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java index 52dc7e646d29..762297d15e6d 100644 --- a/core/java/com/android/internal/app/SuspendedAppActivity.java +++ b/core/java/com/android/internal/app/SuspendedAppActivity.java @@ -193,7 +193,7 @@ public class SuspendedAppActivity extends AlertActivity try { mSuspendingAppResources = createContextAsUser( UserHandle.of(mUserId), /* flags */ 0).getPackageManager() - .getResourcesForApplication(mSuspendedPackage); + .getResourcesForApplication(mSuspendingPackage); } catch (PackageManager.NameNotFoundException ne) { Slog.e(TAG, "Could not find resources for " + mSuspendingPackage, ne); } diff --git a/core/java/com/android/internal/app/TEST_MAPPING b/core/java/com/android/internal/app/TEST_MAPPING index 373a5d9413a5..8bd791297e9d 100644 --- a/core/java/com/android/internal/app/TEST_MAPPING +++ b/core/java/com/android/internal/app/TEST_MAPPING @@ -1,4 +1,10 @@ { + "presubmit": [ + { + "name": "CtsSuspendAppsTestCases", + "file_patterns": ["(/|^)SuspendedAppActivity\\.java"] + } + ], "postsubmit": [ { "name": "FrameworksCoreTests", @@ -17,4 +23,4 @@ ] } ] -}
\ No newline at end of file +} diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java index 0cd12022e17d..8cab91aab512 100644 --- a/core/java/com/android/internal/app/WindowDecorActionBar.java +++ b/core/java/com/android/internal/app/WindowDecorActionBar.java @@ -32,6 +32,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; +import android.os.Build; import android.util.TypedValue; import android.view.ActionMode; import android.view.ContextThemeWrapper; @@ -80,11 +81,11 @@ public class WindowDecorActionBar extends ActionBar implements private ActionBarOverlayLayout mOverlayLayout; private ActionBarContainer mContainerView; private DecorToolbar mDecorToolbar; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private ActionBarContextView mContextView; private ActionBarContainer mSplitView; private View mContentView; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private ScrollingTabContainerView mTabScrollView; private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>(); @@ -1149,7 +1150,7 @@ public class WindowDecorActionBar extends ActionBar implements * @hide */ public class TabImpl extends ActionBar.Tab { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private ActionBar.TabListener mCallback; private Object mTag; private Drawable mIcon; diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl index 1186dfe92906..2d68cb472fa3 100644 --- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl +++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl @@ -42,7 +42,7 @@ interface IAppWidgetService { void deleteAppWidgetId(String callingPackage, int appWidgetId); void deleteHost(String packageName, int hostId); void deleteAllHosts(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) RemoteViews getAppWidgetViews(String callingPackage, int appWidgetId); int[] getAppWidgetIdsForHost(String callingPackage, int hostId); IntentSender createAppWidgetConfigIntentSender(String callingPackage, int appWidgetId, @@ -64,10 +64,10 @@ interface IAppWidgetService { AppWidgetProviderInfo getAppWidgetInfo(String callingPackage, int appWidgetId); boolean hasBindAppWidgetPermission(in String packageName, int userId); void setBindAppWidgetPermission(in String packageName, int userId, in boolean permission); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean bindAppWidgetId(in String callingPackage, int appWidgetId, int providerProfileId, in ComponentName providerComponent, in Bundle options); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean bindRemoteViewsService(String callingPackage, int appWidgetId, in Intent intent, IApplicationThread caller, IBinder token, IServiceConnection connection, int flags); diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index 140c410e8de6..7b6df6c7118a 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -63,7 +63,7 @@ public class MetricsLogger { public static final int LOGTAG = EventLogTags.SYSUI_MULTI_ACTION; /** Write an event log record, consisting of content.serialize(). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void write(LogMaker content) { if (content.getType() == MetricsEvent.TYPE_UNKNOWN) { content.setType(MetricsEvent.TYPE_ACTION); diff --git a/core/java/com/android/internal/net/LegacyVpnInfo.java b/core/java/com/android/internal/net/LegacyVpnInfo.java index 4eb7dede7769..43984b59378c 100644 --- a/core/java/com/android/internal/net/LegacyVpnInfo.java +++ b/core/java/com/android/internal/net/LegacyVpnInfo.java @@ -83,8 +83,8 @@ public class LegacyVpnInfo implements Parcelable { * Return best matching {@link LegacyVpnInfo} state based on given * {@link NetworkInfo}. */ - public static int stateFromNetworkInfo(NetworkInfo info) { - switch (info.getDetailedState()) { + public static int stateFromNetworkInfo(NetworkInfo.DetailedState state) { + switch (state) { case CONNECTING: return STATE_CONNECTING; case CONNECTED: @@ -94,8 +94,7 @@ public class LegacyVpnInfo implements Parcelable { case FAILED: return STATE_FAILED; default: - Log.w(TAG, "Unhandled state " + info.getDetailedState() - + " ; treating as disconnected"); + Log.w(TAG, "Unhandled state " + state + " ; treating as disconnected"); return STATE_DISCONNECTED; } } diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index b4727499d8ef..a17f5f5f8910 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -236,7 +236,7 @@ public final class VpnProfile implements Cloneable, Parcelable { * * <p>See {@link #encode()} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static VpnProfile decode(String key, byte[] value) { try { if (key == null) { diff --git a/core/java/com/android/internal/os/BaseCommand.java b/core/java/com/android/internal/os/BaseCommand.java index 32442f0472bb..c110b263e781 100644 --- a/core/java/com/android/internal/os/BaseCommand.java +++ b/core/java/com/android/internal/os/BaseCommand.java @@ -19,12 +19,13 @@ package com.android.internal.os; import android.compat.annotation.UnsupportedAppUsage; import android.os.BasicShellCommandHandler; +import android.os.Build; import java.io.PrintStream; public abstract class BaseCommand { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final protected BasicShellCommandHandler mArgs = new BasicShellCommandHandler() { @Override public int onCommand(String cmd) { return 0; @@ -40,7 +41,7 @@ public abstract class BaseCommand { private String[] mRawArgs; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public BaseCommand() { } diff --git a/core/java/com/android/internal/os/BatterySipper.java b/core/java/com/android/internal/os/BatterySipper.java index 2620ba0749a9..5337ac3cc27e 100644 --- a/core/java/com/android/internal/os/BatterySipper.java +++ b/core/java/com/android/internal/os/BatterySipper.java @@ -17,6 +17,7 @@ package com.android.internal.os; import android.compat.annotation.UnsupportedAppUsage; import android.os.BatteryStats.Uid; +import android.os.Build; import java.util.List; @@ -120,7 +121,7 @@ public class BatterySipper implements Comparable<BatterySipper> { public double audioPowerMah; public double bluetoothPowerMah; public double cameraPowerMah; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public double cpuPowerMah; public double flashlightPowerMah; public double gpsPowerMah; diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index 3dfa3c3f6906..92dd4dda39df 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -26,6 +26,7 @@ import android.hardware.SensorManager; import android.net.ConnectivityManager; import android.os.BatteryStats; import android.os.BatteryStats.Uid; +import android.os.Build; import android.os.Bundle; import android.os.MemoryFile; import android.os.Parcel; @@ -272,7 +273,7 @@ public class BatteryStatsHelper { return mStats; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Intent getBatteryBroadcast() { if (mBatteryBroadcast == null && mCollectBatteryBroadcast) { load(); @@ -361,7 +362,7 @@ public class BatteryStatsHelper { /** * Refreshes the power usage list. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void refreshStats(int statsType, SparseArray<UserHandle> asUsers) { refreshStats(statsType, asUsers, SystemClock.elapsedRealtime() * 1000, SystemClock.uptimeMillis() * 1000); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index b986463a62f7..e7e75a84643b 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -13558,7 +13558,7 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getDischargeStartLevel() { synchronized(this) { return getDischargeStartLevelLocked(); @@ -13570,7 +13570,7 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getDischargeCurrentLevel() { synchronized(this) { return getDischargeCurrentLevelLocked(); diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java index f83c5bdc4e28..d347f2e21dd2 100644 --- a/core/java/com/android/internal/os/ClassLoaderFactory.java +++ b/core/java/com/android/internal/os/ClassLoaderFactory.java @@ -17,6 +17,7 @@ package com.android.internal.os; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Trace; import dalvik.system.DelegateLastClassLoader; @@ -139,7 +140,7 @@ public class ClassLoaderFactory { return classLoader; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native String createClassloaderNamespace(ClassLoader classLoader, int targetSdkVersion, String librarySearchPath, diff --git a/core/java/com/android/internal/os/FuseAppLoop.java b/core/java/com/android/internal/os/FuseAppLoop.java index 2393036b5a38..1c6c6a73b44d 100644 --- a/core/java/com/android/internal/os/FuseAppLoop.java +++ b/core/java/com/android/internal/os/FuseAppLoop.java @@ -19,6 +19,7 @@ package com.android.internal.os; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Handler; import android.os.Message; import android.os.ParcelFileDescriptor; @@ -230,7 +231,7 @@ public class FuseAppLoop implements Handler.Callback { // Called by JNI. @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void onCommand(int command, long unique, long inode, long offset, int size, byte[] data) { synchronized (mLock) { @@ -259,7 +260,7 @@ public class FuseAppLoop implements Handler.Callback { // Called by JNI. @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private byte[] onOpen(long unique, long inode) { synchronized (mLock) { try { diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java index 8e0546e6a86c..6d5cb67352b3 100644 --- a/core/java/com/android/internal/os/ProcessCpuTracker.java +++ b/core/java/com/android/internal/os/ProcessCpuTracker.java @@ -24,6 +24,7 @@ import static android.os.Process.PROC_PARENS; import static android.os.Process.PROC_SPACE_TERM; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.CpuUsageProto; import android.os.Process; import android.os.StrictMode; @@ -200,7 +201,7 @@ public class ProcessCpuTracker { public boolean interesting; public String baseName; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String name; public int nameWidth; @@ -216,7 +217,7 @@ public class ProcessCpuTracker { /** * Time in milliseconds. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long rel_uptime; /** @@ -232,13 +233,13 @@ public class ProcessCpuTracker { /** * Time in milliseconds. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int rel_utime; /** * Time in milliseconds. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int rel_stime; public long base_minfaults; @@ -732,13 +733,13 @@ public class ProcessCpuTracker { return statses; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final public int countWorkingStats() { buildWorkingProcs(); return mWorkingProcs.size(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final public Stats getWorkingStats(int index) { return mWorkingProcs.get(index); } diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java index 003f61079dcf..5ec882cee3c8 100644 --- a/core/java/com/android/internal/os/SomeArgs.java +++ b/core/java/com/android/internal/os/SomeArgs.java @@ -17,6 +17,7 @@ package com.android.internal.os; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * Helper class for passing more arguments though a message @@ -42,11 +43,11 @@ public final class SomeArgs { static final int WAIT_FINISHED = 2; int mWaitState = WAIT_NONE; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Object arg1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Object arg2; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Object arg3; public Object arg4; public Object arg5; @@ -55,9 +56,9 @@ public final class SomeArgs { public Object arg8; public Object arg9; public int argi1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int argi2; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int argi3; public int argi4; public int argi5; @@ -67,7 +68,7 @@ public final class SomeArgs { /* do nothing - reduce visibility */ } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static SomeArgs obtain() { synchronized (sPoolLock) { if (sPoolSize > 0) { @@ -93,7 +94,7 @@ public final class SomeArgs { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void recycle() { if (mInPool) { throw new IllegalStateException("Already recycled."); diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index e848da9b8ee3..f89e52d4f91d 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -2540,6 +2540,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } } + params.backgroundBlurRadius = a.getDimensionPixelSize( + R.styleable.Window_windowBackgroundBlurRadius, 0); + if (params.windowAnimations == 0) { params.windowAnimations = a.getResourceId( R.styleable.Window_windowAnimationStyle, 0); diff --git a/core/java/com/android/internal/protolog/common/ProtoLog.java b/core/java/com/android/internal/protolog/common/ProtoLog.java index ab58d351d3b9..01cc1ed37ad4 100644 --- a/core/java/com/android/internal/protolog/common/ProtoLog.java +++ b/core/java/com/android/internal/protolog/common/ProtoLog.java @@ -35,6 +35,10 @@ package com.android.internal.protolog.common; * during build. */ public class ProtoLog { + + // Needs to be set directly otherwise the protologtool tries to transform the method call + public static boolean REQUIRE_PROTOLOGTOOL = true; + /** * DEBUG level log. * @@ -44,8 +48,10 @@ public class ProtoLog { */ public static void d(IProtoLogGroup group, String messageString, Object... args) { // Stub, replaced by the ProtoLogTool. - throw new UnsupportedOperationException( - "ProtoLog calls MUST be processed with ProtoLogTool"); + if (REQUIRE_PROTOLOGTOOL) { + throw new UnsupportedOperationException( + "ProtoLog calls MUST be processed with ProtoLogTool"); + } } /** @@ -57,8 +63,10 @@ public class ProtoLog { */ public static void v(IProtoLogGroup group, String messageString, Object... args) { // Stub, replaced by the ProtoLogTool. - throw new UnsupportedOperationException( - "ProtoLog calls MUST be processed with ProtoLogTool"); + if (REQUIRE_PROTOLOGTOOL) { + throw new UnsupportedOperationException( + "ProtoLog calls MUST be processed with ProtoLogTool"); + } } /** @@ -70,8 +78,10 @@ public class ProtoLog { */ public static void i(IProtoLogGroup group, String messageString, Object... args) { // Stub, replaced by the ProtoLogTool. - throw new UnsupportedOperationException( - "ProtoLog calls MUST be processed with ProtoLogTool"); + if (REQUIRE_PROTOLOGTOOL) { + throw new UnsupportedOperationException( + "ProtoLog calls MUST be processed with ProtoLogTool"); + } } /** @@ -83,8 +93,10 @@ public class ProtoLog { */ public static void w(IProtoLogGroup group, String messageString, Object... args) { // Stub, replaced by the ProtoLogTool. - throw new UnsupportedOperationException( - "ProtoLog calls MUST be processed with ProtoLogTool"); + if (REQUIRE_PROTOLOGTOOL) { + throw new UnsupportedOperationException( + "ProtoLog calls MUST be processed with ProtoLogTool"); + } } /** @@ -96,8 +108,10 @@ public class ProtoLog { */ public static void e(IProtoLogGroup group, String messageString, Object... args) { // Stub, replaced by the ProtoLogTool. - throw new UnsupportedOperationException( - "ProtoLog calls MUST be processed with ProtoLogTool"); + if (REQUIRE_PROTOLOGTOOL) { + throw new UnsupportedOperationException( + "ProtoLog calls MUST be processed with ProtoLogTool"); + } } /** @@ -109,7 +123,9 @@ public class ProtoLog { */ public static void wtf(IProtoLogGroup group, String messageString, Object... args) { // Stub, replaced by the ProtoLogTool. - throw new UnsupportedOperationException( - "ProtoLog calls MUST be processed with ProtoLogTool"); + if (REQUIRE_PROTOLOGTOOL) { + throw new UnsupportedOperationException( + "ProtoLog calls MUST be processed with ProtoLogTool"); + } } } diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 77c7ce8cf5c4..b9c2fd532d0f 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -145,8 +145,8 @@ oneway interface IStatusBar // Used to show the authentication dialog (Biometrics, Device Credential) void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver, - int biometricModality, boolean requireConfirmation, int userId, String opPackageName, - long operationId); + in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, + String opPackageName, long operationId); // Used to notify the authentication dialog that a biometric has been authenticated void onBiometricAuthenticated(); // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index bcbbf6e98dae..bb0fd7fb8c23 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -106,8 +106,9 @@ interface IStatusBarService // Used to show the authentication dialog (Biometrics, Device Credential) void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver, - int biometricModality, boolean requireConfirmation, int userId, String opPackageName, - long operationId); + in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, + int userId, String opPackageName,long operationId); + // Used to notify the authentication dialog that a biometric has been authenticated void onBiometricAuthenticated(); // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 313bd42fe8c1..a28a66376497 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -51,7 +51,7 @@ interface ITelephonyRegistry { boolean notifyNow); void listenForSubscriber(in int subId, String pkg, String featureId, IPhoneStateListener callback, long events, boolean notifyNow); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void notifyCallStateForAllSubs(int state, String incomingNumber); void notifyCallState(in int phoneId, in int subId, int state, String incomingNumber); void notifyServiceStateForPhoneId(in int phoneId, in int subId, in ServiceState state); diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index c6dea18d77d1..5571a58a8999 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -19,6 +19,7 @@ package com.android.internal.util; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.util.ArraySet; import dalvik.system.VMRuntime; @@ -56,7 +57,7 @@ public class ArrayUtils { return (char[])VMRuntime.getRuntime().newUnpaddedArray(char.class, minLen); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int[] newUnpaddedIntArray(int minLen) { return (int[])VMRuntime.getRuntime().newUnpaddedArray(int.class, minLen); } @@ -77,7 +78,7 @@ public class ArrayUtils { return (Object[])VMRuntime.getRuntime().newUnpaddedArray(Object.class, minLen); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @SuppressWarnings("unchecked") public static <T> T[] newUnpaddedArray(Class<T> clazz, int minLen) { return (T[])VMRuntime.getRuntime().newUnpaddedArray(clazz, minLen); @@ -386,7 +387,7 @@ public class ArrayUtils { * Adds value to given array if not already present, providing set-like * behavior. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @SuppressWarnings("unchecked") public static @NonNull <T> T[] appendElement(Class<T> kind, @Nullable T[] array, T element) { return appendElement(kind, array, element, false); @@ -416,7 +417,7 @@ public class ArrayUtils { /** * Removes value from given array if present, providing set-like behavior. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @SuppressWarnings("unchecked") public static @Nullable <T> T[] removeElement(Class<T> kind, @Nullable T[] array, T element) { if (array != null) { diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java index 7e3c171abfa6..0e8c92991b66 100644 --- a/core/java/com/android/internal/util/AsyncChannel.java +++ b/core/java/com/android/internal/util/AsyncChannel.java @@ -401,7 +401,7 @@ public class AsyncChannel { * @param srcHandler * @param dstMessenger */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) { if (DBG) log("connected srcHandler to the dstMessenger E"); @@ -514,7 +514,7 @@ public class AsyncChannel { * @param what * @param arg1 */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void sendMessage(int what, int arg1) { Message msg = Message.obtain(); msg.what = what; @@ -606,7 +606,7 @@ public class AsyncChannel { * @param what * @param arg1 */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void replyToMessage(Message srcMsg, int what, int arg1) { Message msg = Message.obtain(); msg.what = what; @@ -639,7 +639,7 @@ public class AsyncChannel { * @param arg2 * @param obj */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void replyToMessage(Message srcMsg, int what, int arg1, int arg2, Object obj) { Message msg = Message.obtain(); msg.what = what; @@ -656,7 +656,7 @@ public class AsyncChannel { * @param what * @param obj */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void replyToMessage(Message srcMsg, int what, Object obj) { Message msg = Message.obtain(); msg.what = what; @@ -670,7 +670,7 @@ public class AsyncChannel { * @param msg to send * @return reply message or null if an error. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Message sendMessageSynchronously(Message msg) { Message resultMsg = SyncMessenger.sendMessageSynchronously(mDstMessenger, msg); return resultMsg; @@ -712,7 +712,7 @@ public class AsyncChannel { * @param arg2 * @return reply message or null if an error. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Message sendMessageSynchronously(int what, int arg1, int arg2) { Message msg = Message.obtain(); msg.what = what; diff --git a/core/java/com/android/internal/util/GrowingArrayUtils.java b/core/java/com/android/internal/util/GrowingArrayUtils.java index 597fe6b53d11..8c12e36a27d1 100644 --- a/core/java/com/android/internal/util/GrowingArrayUtils.java +++ b/core/java/com/android/internal/util/GrowingArrayUtils.java @@ -17,6 +17,7 @@ package com.android.internal.util; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * A helper class that aims to provide comparable growth performance to ArrayList, but on primitive @@ -39,7 +40,7 @@ public final class GrowingArrayUtils { * @return the array to which the element was appended. This may be different than the given * array. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static <T> T[] append(T[] array, int currentSize, T element) { assert currentSize <= array.length; @@ -57,7 +58,7 @@ public final class GrowingArrayUtils { /** * Primitive int version of {@link #append(Object[], int, Object)}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int[] append(int[] array, int currentSize, int element) { assert currentSize <= array.length; diff --git a/core/java/com/android/internal/util/HexDump.java b/core/java/com/android/internal/util/HexDump.java index ad88dd6deec6..6468cafe85d4 100644 --- a/core/java/com/android/internal/util/HexDump.java +++ b/core/java/com/android/internal/util/HexDump.java @@ -107,7 +107,7 @@ public class HexDump return toHexString(array, 0, array.length, true); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) public static String toHexString(byte[] array, boolean upperCase) { return toHexString(array, 0, array.length, upperCase); diff --git a/core/java/com/android/internal/util/IndentingPrintWriter.java b/core/java/com/android/internal/util/IndentingPrintWriter.java index 2435afb61083..520f5184260a 100644 --- a/core/java/com/android/internal/util/IndentingPrintWriter.java +++ b/core/java/com/android/internal/util/IndentingPrintWriter.java @@ -17,6 +17,7 @@ package com.android.internal.util; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.io.Writer; @@ -26,7 +27,7 @@ import java.io.Writer; @Deprecated public class IndentingPrintWriter extends android.util.IndentingPrintWriter { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public IndentingPrintWriter(Writer writer, String singleIndent) { super(writer, singleIndent, -1); } @@ -49,13 +50,13 @@ public class IndentingPrintWriter extends android.util.IndentingPrintWriter { return this; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public IndentingPrintWriter increaseIndent() { super.increaseIndent(); return this; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public IndentingPrintWriter decreaseIndent() { super.decreaseIndent(); return this; diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java index 5de77d9b0545..0c5c8537e85a 100644 --- a/core/java/com/android/internal/util/MemInfoReader.java +++ b/core/java/com/android/internal/util/MemInfoReader.java @@ -17,6 +17,7 @@ package com.android.internal.util; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Debug; import android.os.StrictMode; @@ -51,7 +52,7 @@ public final class MemInfoReader { /** * Amount of RAM that is not being used for anything. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getFreeSize() { return mInfos[Debug.MEMINFO_FREE] * 1024; } @@ -60,7 +61,7 @@ public final class MemInfoReader { * Amount of RAM that the kernel is being used for caches, not counting caches * that are mapped in to processes. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getCachedSize() { return getCachedSizeKb() * 1024; } diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java index 4d441cd98a96..88e4e355000a 100644 --- a/core/java/com/android/internal/util/Preconditions.java +++ b/core/java/com/android/internal/util/Preconditions.java @@ -19,6 +19,7 @@ package com.android.internal.util; import android.annotation.IntRange; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.text.TextUtils; import java.util.Arrays; @@ -52,7 +53,7 @@ public class Preconditions { * be converted to a string using {@link String#valueOf(Object)} * @throws IllegalArgumentException if {@code expression} is false */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void checkArgument(boolean expression, final Object errorMessage) { if (!expression) { throw new IllegalArgumentException(String.valueOf(errorMessage)); @@ -208,7 +209,7 @@ public class Preconditions { * be converted to a string using {@link String#valueOf(Object)} * @throws IllegalStateException if {@code expression} is false */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void checkState(final boolean expression, String errorMessage) { if (!expression) { throw new IllegalStateException(errorMessage); @@ -518,7 +519,7 @@ public class Preconditions { * * @throws IllegalArgumentException if {@code value} was not within the range */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int checkArgumentInRange(int value, int lower, int upper, String valueName) { if (value < lower) { diff --git a/core/java/com/android/internal/util/State.java b/core/java/com/android/internal/util/State.java index 636378e32091..4613dad8cc67 100644 --- a/core/java/com/android/internal/util/State.java +++ b/core/java/com/android/internal/util/State.java @@ -17,6 +17,7 @@ package com.android.internal.util; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Message; /** @@ -44,7 +45,7 @@ public class State implements IState { /* (non-Javadoc) * @see com.android.internal.util.IState#exit() */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Override public void exit() { } diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java index 7a79cc9ef868..4cff785cd671 100644 --- a/core/java/com/android/internal/util/StateMachine.java +++ b/core/java/com/android/internal/util/StateMachine.java @@ -17,6 +17,7 @@ package com.android.internal.util; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -1324,7 +1325,7 @@ public class StateMachine { * * @param name of the state machine */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected StateMachine(String name, Handler handler) { initStateMachine(name, handler.getLooper()); } @@ -1357,7 +1358,7 @@ public class StateMachine { * Add a new state to the state machine, parent will be null * @param state to add */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final void addState(State state) { mSmHandler.addState(state, null); } @@ -1376,7 +1377,7 @@ public class StateMachine { * * @param initialState is the state which will receive the first message. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final void setInitialState(State initialState) { mSmHandler.setInitialState(initialState); } @@ -1415,7 +1416,7 @@ public class StateMachine { * * @param destState will be the state that receives the next message. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final void transitionTo(IState destState) { mSmHandler.transitionTo(destState); } @@ -1700,7 +1701,7 @@ public class StateMachine { * @param obj is assigned to Message.obj * @return A Message object from the global pool */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final Message obtainMessage(int what, int arg1, int arg2, Object obj) { return Message.obtain(mSmHandler, what, arg1, arg2, obj); } @@ -1738,7 +1739,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void sendMessage(int what, int arg1) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -1765,7 +1766,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void sendMessage(int what, int arg1, int arg2, Object obj) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -2066,7 +2067,7 @@ public class StateMachine { /** * Start the state machine. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void start() { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -2083,7 +2084,7 @@ public class StateMachine { * @param pw * @param args */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println(getName() + ":"); pw.println(" total records=" + getLogRecCount()); diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java index cd5502c9f270..33ebe43cb23a 100644 --- a/core/java/com/android/internal/view/IInputConnectionWrapper.java +++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java @@ -82,7 +82,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub { private Looper mMainLooper; private Handler mH; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Object mLock = new Object(); @GuardedBy("mLock") private boolean mFinished = false; diff --git a/core/java/com/android/internal/view/menu/ActionMenu.java b/core/java/com/android/internal/view/menu/ActionMenu.java index 648262965ab1..c699ca193f2b 100644 --- a/core/java/com/android/internal/view/menu/ActionMenu.java +++ b/core/java/com/android/internal/view/menu/ActionMenu.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.Build; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; @@ -40,7 +41,7 @@ public class ActionMenu implements Menu { private ArrayList<ActionMenuItem> mItems; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ActionMenu(Context context) { mContext = context; mItems = new ArrayList<ActionMenuItem>(); diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java index bd8bcb9cf81e..acb233e39cc8 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItem.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java @@ -23,6 +23,7 @@ import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; +import android.os.Build; import android.view.ActionProvider; import android.view.ContextMenu.ContextMenuInfo; import android.view.KeyEvent; @@ -70,7 +71,7 @@ public class ActionMenuItem implements MenuItem { private static final int HIDDEN = 0x00000008; private static final int ENABLED = 0x00000010; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ActionMenuItem(Context context, int group, int id, int categoryOrder, int ordering, CharSequence title) { mContext = context; diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java index 7622b939b6eb..61536e8960e2 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java @@ -22,6 +22,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Parcelable; import android.text.TextUtils; import android.util.AttributeSet; @@ -225,7 +226,7 @@ public class ActionMenuItemView extends TextView updateTextButtonVisibility(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean hasText() { return !TextUtils.isEmpty(getText()); } diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java index b31ae38b4566..0b490b20df0e 100644 --- a/core/java/com/android/internal/view/menu/MenuBuilder.java +++ b/core/java/com/android/internal/view/menu/MenuBuilder.java @@ -27,6 +27,7 @@ import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.os.Parcelable; import android.util.SparseArray; @@ -210,7 +211,7 @@ public class MenuBuilder implements Menu { setShortcutsVisibleInner(true); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public MenuBuilder setDefaultShowAsAction(int defaultShowAsAction) { mDefaultShowAsAction = defaultShowAsAction; return this; @@ -223,7 +224,7 @@ public class MenuBuilder implements Menu { * * @param presenter The presenter to add */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addMenuPresenter(MenuPresenter presenter) { addMenuPresenter(presenter, mContext); } @@ -250,7 +251,7 @@ public class MenuBuilder implements Menu { * * @param presenter The presenter to remove */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void removeMenuPresenter(MenuPresenter presenter) { for (WeakReference<MenuPresenter> ref : mPresenters) { final MenuPresenter item = ref.get(); @@ -1015,7 +1016,7 @@ public class MenuBuilder implements Menu { * {@link #startDispatchingItemsChanged()} is called. Useful when * many menu operations are going to be performed as a batch. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void stopDispatchingItemsChanged() { if (!mPreventDispatchingItemsChanged) { mPreventDispatchingItemsChanged = true; @@ -1023,7 +1024,7 @@ public class MenuBuilder implements Menu { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void startDispatchingItemsChanged() { mPreventDispatchingItemsChanged = false; @@ -1145,7 +1146,7 @@ public class MenuBuilder implements Menu { return mActionItems; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ArrayList<MenuItemImpl> getNonActionItems() { flagActionItems(); return mNonActionItems; diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java index 218f5185ec47..2452398a5348 100644 --- a/core/java/com/android/internal/view/menu/MenuItemImpl.java +++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java @@ -25,6 +25,7 @@ import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; +import android.os.Build; import android.util.Log; import android.view.ActionProvider; import android.view.ContextMenu.ContextMenuInfo; @@ -662,17 +663,17 @@ public final class MenuItemImpl implements MenuItem { return mMenu.getOptionalIconsVisible(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isActionButton() { return (mFlags & IS_ACTION) == IS_ACTION; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean requestsActionButton() { return (mShowAsAction & SHOW_AS_ACTION_IF_ROOM) == SHOW_AS_ACTION_IF_ROOM; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean requiresActionButton() { return (mShowAsAction & SHOW_AS_ACTION_ALWAYS) == SHOW_AS_ACTION_ALWAYS; } diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java index 980943ebea5a..c266d0218b31 100644 --- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java +++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java @@ -23,6 +23,7 @@ import android.annotation.StyleRes; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; +import android.os.Build; import android.view.Gravity; import android.view.View; import android.view.WindowManager; @@ -47,14 +48,14 @@ public class MenuPopupHelper implements MenuHelper { // Mutable cached popup menu properties. private View mAnchorView; private int mDropDownGravity = Gravity.START; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mForceShowIcon; private Callback mPresenterCallback; private MenuPopup mPopup; private OnDismissListener mOnDismissListener; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public MenuPopupHelper(@NonNull Context context, @NonNull MenuBuilder menu) { this(context, menu, null, false, com.android.internal.R.attr.popupMenuStyle, 0); } @@ -93,7 +94,7 @@ public class MenuPopupHelper implements MenuHelper { * * @param anchor the view to which the popup window should be anchored */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setAnchorView(@NonNull View anchor) { mAnchorView = anchor; } @@ -125,7 +126,7 @@ public class MenuPopupHelper implements MenuHelper { * * @param gravity alignment of the popup relative to the anchor */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setGravity(int gravity) { mDropDownGravity = gravity; } @@ -151,7 +152,7 @@ public class MenuPopupHelper implements MenuHelper { } @NonNull - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public MenuPopup getPopup() { if (mPopup == null) { mPopup = createPopup(); @@ -165,7 +166,7 @@ public class MenuPopupHelper implements MenuHelper { * @return {@code true} if the popup was shown or was already showing prior to calling this * method, {@code false} otherwise */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean tryShow() { if (isShowing()) { return true; diff --git a/core/java/com/android/internal/view/menu/MenuPresenter.java b/core/java/com/android/internal/view/menu/MenuPresenter.java index 35b8fefe75ab..37155b9ff7fe 100644 --- a/core/java/com/android/internal/view/menu/MenuPresenter.java +++ b/core/java/com/android/internal/view/menu/MenuPresenter.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.Parcelable; import android.view.ViewGroup; @@ -48,7 +49,7 @@ public interface MenuPresenter { * @return true if the Callback will handle presenting the submenu, false if * the presenter should attempt to do so. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean onOpenSubMenu(MenuBuilder subMenu); } diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java index 0f0c1a3de3a2..914de6102fef 100644 --- a/core/java/com/android/internal/widget/AbsActionBarView.java +++ b/core/java/com/android/internal/widget/AbsActionBarView.java @@ -23,6 +23,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; +import android.os.Build; import android.util.AttributeSet; import android.util.TypedValue; import android.view.ContextThemeWrapper; @@ -294,7 +295,7 @@ public abstract class AbsActionBarView extends ViewGroup { return isOverflowReserved() && getVisibility() == VISIBLE; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void dismissPopupMenus() { if (mActionMenuPresenter != null) { mActionMenuPresenter.dismissPopupMenus(); diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java index 051526ef2da7..80fc218839d5 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -19,6 +19,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; +import android.os.Build; import android.text.TextUtils; import android.util.AttributeSet; import android.view.ActionMode; @@ -58,7 +59,7 @@ public class ActionBarContextView extends AbsActionBarView { this(context, null); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ActionBarContextView(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.actionModeStyle); } diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java index aca0b713686f..adbf645de74e 100644 --- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java +++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java @@ -170,7 +170,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar init(context); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ActionBarOverlayLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context); diff --git a/core/java/com/android/internal/widget/CachingIconView.java b/core/java/com/android/internal/widget/CachingIconView.java index 0bf323f8f493..4a70f7416075 100644 --- a/core/java/com/android/internal/widget/CachingIconView.java +++ b/core/java/com/android/internal/widget/CachingIconView.java @@ -28,6 +28,7 @@ import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.net.Uri; +import android.os.Build; import android.text.TextUtils; import android.util.AttributeSet; import android.view.RemotableViewMethod; @@ -54,7 +55,7 @@ public class CachingIconView extends ImageView { private int mBackgroundColor; private boolean mWillBeForceHidden; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CachingIconView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } diff --git a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl index d6efca5d36eb..c06dab9f75d6 100644 --- a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl +++ b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl @@ -21,23 +21,23 @@ import android.widget.RemoteViews; /** {@hide} */ interface IRemoteViewsFactory { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onDataSetChanged(); oneway void onDataSetChangedAsync(); oneway void onDestroy(in Intent intent); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int getCount(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) RemoteViews getViewAt(int position); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) RemoteViews getLoadingView(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int getViewTypeCount(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) long getItemId(int position); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean hasStableIds(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isCreated(); } diff --git a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java index 9ef9f697c46c..f230ddb8b5ea 100644 --- a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java +++ b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java @@ -19,6 +19,7 @@ package com.android.internal.widget; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; +import android.os.Build; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -46,7 +47,7 @@ public class LinearLayoutWithDefaultTouchRecepient extends LinearLayout { super(context, attrs); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDefaultTouchRecepient(View defaultTouchRecepient) { mDefaultTouchRecepient = defaultTouchRecepient; } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index c0c7f100ef21..b562ef838633 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -35,6 +35,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.pm.UserInfo; import android.os.AsyncTask; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -729,13 +730,13 @@ public class LockPatternUtils { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setOwnerInfo(String info, int userId) { setString(LOCK_SCREEN_OWNER_INFO, info, userId); updateCryptoUserInfo(userId); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setOwnerInfoEnabled(boolean enabled, int userId) { setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId); updateCryptoUserInfo(userId); @@ -1113,7 +1114,7 @@ public class LockPatternUtils { return type != CREDENTIAL_TYPE_NONE; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isLockPasswordEnabled(int userId) { int type = getCredentialTypeForUser(userId); return type == CREDENTIAL_TYPE_PASSWORD || type == CREDENTIAL_TYPE_PIN; diff --git a/core/java/com/android/internal/widget/NumericTextView.java b/core/java/com/android/internal/widget/NumericTextView.java index c8f901133be6..e6cb24de9f94 100644 --- a/core/java/com/android/internal/widget/NumericTextView.java +++ b/core/java/com/android/internal/widget/NumericTextView.java @@ -19,6 +19,7 @@ package com.android.internal.widget; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; +import android.os.Build; import android.util.AttributeSet; import android.util.StateSet; import android.view.KeyEvent; @@ -54,7 +55,7 @@ public class NumericTextView extends TextView { private OnValueChangedListener mListener; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NumericTextView(Context context, AttributeSet attrs) { super(context, attrs); diff --git a/core/java/com/android/internal/widget/PreferenceImageView.java b/core/java/com/android/internal/widget/PreferenceImageView.java index 43b6b5a169c5..0ca98cfbdfb8 100644 --- a/core/java/com/android/internal/widget/PreferenceImageView.java +++ b/core/java/com/android/internal/widget/PreferenceImageView.java @@ -18,6 +18,7 @@ package com.android.internal.widget; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.util.AttributeSet; import android.widget.ImageView; @@ -30,7 +31,7 @@ public class PreferenceImageView extends ImageView { this(context, null); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PreferenceImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java index d7a01c4762f1..fd9e43081d10 100644 --- a/core/java/com/android/internal/widget/RecyclerView.java +++ b/core/java/com/android/internal/widget/RecyclerView.java @@ -4968,7 +4968,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro * constructed by {@link GapWorker} prefetch from being bound to a lower priority prefetch. */ static class ScrapData { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) ArrayList<ViewHolder> mScrapHeap = new ArrayList<>(); int mMaxScrap = DEFAULT_MAX_SCRAP; long mCreateRunningAverageNs = 0; diff --git a/core/java/com/android/internal/widget/ScrollBarUtils.java b/core/java/com/android/internal/widget/ScrollBarUtils.java index 3e9d697a0ace..0108bd4a27cf 100644 --- a/core/java/com/android/internal/widget/ScrollBarUtils.java +++ b/core/java/com/android/internal/widget/ScrollBarUtils.java @@ -17,10 +17,11 @@ package com.android.internal.widget; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; public class ScrollBarUtils { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int getThumbLength(int size, int thickness, int extent, int range) { // Avoid the tiny thumb. final int minLength = thickness * 2; diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java index aa0b0bbd4c19..d3029676cbb2 100644 --- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java +++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java @@ -23,6 +23,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.graphics.drawable.Drawable; +import android.os.Build; import android.text.TextUtils; import android.text.TextUtils.TruncateAt; import android.view.Gravity; @@ -224,7 +225,7 @@ public class ScrollingTabContainerView extends HorizontalScrollView mStackedTabMaxWidth = abp.getStackedTabMaxWidth(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void animateToVisibility(int visibility) { if (mVisibilityAnim != null) { mVisibilityAnim.cancel(); @@ -249,7 +250,7 @@ public class ScrollingTabContainerView extends HorizontalScrollView } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void animateToTab(final int position) { final View tabView = mTabLayout.getChildAt(position); if (mTabSelector != null) { @@ -331,7 +332,7 @@ public class ScrollingTabContainerView extends HorizontalScrollView } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void updateTab(int position) { ((TabView) mTabLayout.getChildAt(position)).update(); if (mTabSpinner != null) { diff --git a/core/java/com/android/server/net/NetlinkTracker.java b/core/java/com/android/server/net/NetlinkTracker.java index b57397f46a7e..197984fc7dcd 100644 --- a/core/java/com/android/server/net/NetlinkTracker.java +++ b/core/java/com/android/server/net/NetlinkTracker.java @@ -20,6 +20,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.RouteInfo; +import android.os.Build; import android.util.Log; import java.net.InetAddress; @@ -80,7 +81,7 @@ public class NetlinkTracker extends BaseNetworkObserver { private static final boolean DBG = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetlinkTracker(String iface, Callback callback) { TAG = "NetlinkTracker/" + iface; mInterfaceName = iface; @@ -189,12 +190,12 @@ public class NetlinkTracker extends BaseNetworkObserver { /** * Returns a copy of this object's LinkProperties. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public synchronized LinkProperties getLinkProperties() { return new LinkProperties(mLinkProperties); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public synchronized void clearLinkProperties() { // Clear the repository before clearing mLinkProperties. That way, if a clear() happens // while interfaceDnsServerInfo() is being called, we'll end up with no DNS servers in diff --git a/core/java/com/google/android/collect/Sets.java b/core/java/com/google/android/collect/Sets.java index c67a88a19080..e2429157d529 100644 --- a/core/java/com/google/android/collect/Sets.java +++ b/core/java/com/google/android/collect/Sets.java @@ -17,6 +17,7 @@ package com.google.android.collect; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.util.ArraySet; import java.util.Collections; @@ -107,7 +108,7 @@ public class Sets { /** * Creates a {@code ArraySet} instance containing the given elements. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static <E> ArraySet<E> newArraySet(E... elements) { int capacity = elements.length * 4 / 3 + 1; ArraySet<E> set = new ArraySet<E>(capacity); diff --git a/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java b/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java index e1fe1bdbdd5f..25091263b2b0 100644 --- a/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java +++ b/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java @@ -182,7 +182,7 @@ public class SSLSocketFactory implements LayeredSocketFactory { private final SSLContext sslcontext; @UnsupportedAppUsage private final javax.net.ssl.SSLSocketFactory socketfactory; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final HostNameResolver nameResolver; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private X509HostnameVerifier hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; @@ -262,7 +262,7 @@ public class SSLSocketFactory implements LayeredSocketFactory { this.nameResolver = null; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static KeyManager[] createKeyManagers(final KeyStore keystore, final String password) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { if (keystore == null) { @@ -274,7 +274,7 @@ public class SSLSocketFactory implements LayeredSocketFactory { return kmfactory.getKeyManagers(); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static TrustManager[] createTrustManagers(final KeyStore keystore) throws KeyStoreException, NoSuchAlgorithmException { if (keystore == null) { diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 4f97975838d5..661bbed8abcb 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -1,4 +1,3 @@ - cc_library_shared { name: "libandroid_runtime", host_supported: true, @@ -286,8 +285,9 @@ cc_library_shared { ], include_dirs: [ "external/vulkan-headers/include", + "frameworks/native/libs/math/include", "frameworks/native/libs/nativebase/include", - "frameworks/native/libs/nativewindow/include" + "frameworks/native/libs/nativewindow/include", ], shared_libs: [ "libicui18n", @@ -303,10 +303,36 @@ cc_library_shared { linux_glibc: { srcs: [ "android_content_res_ApkAssets.cpp", + "android_hardware_input_InputApplicationHandle.cpp", "android_os_MessageQueue.cpp", + "android_os_Parcel.cpp", + + "android_view_KeyCharacterMap.cpp", + "android_view_KeyEvent.cpp", + "android_view_InputChannel.cpp", + "android_view_InputDevice.cpp", + "android_view_InputEventReceiver.cpp", + "android_view_InputEventSender.cpp", + "android_view_MotionEvent.cpp", + "android_view_VelocityTracker.cpp", + "android_view_VerifiedKeyEvent.cpp", + "android_view_VerifiedMotionEvent.cpp", + "android_util_AssetManager.cpp", + "android_util_Binder.cpp", + "android_util_FileObserver.cpp", ], + static_libs: [ + "libinput", + "libbinderthreadstateutils", + ], + shared_libs: [ + // libbinder needs to be shared since it has global state + // (e.g. gDefaultServiceManager) + "libbinder", + "libhidlbase", // libhwbinder is in here + ], }, windows: { enabled: true, diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 32b8fa61c8a0..a3cb4c076593 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -40,6 +40,7 @@ #include <binder/Stability.h> #include <binderthreadstate/CallerUtils.h> #include <cutils/atomic.h> +#include <cutils/threads.h> #include <log/log.h> #include <utils/KeyedVector.h> #include <utils/List.h> diff --git a/core/jni/android_view_InputEventReceiver.md b/core/jni/android_view_InputEventReceiver.md new file mode 100644 index 000000000000..7df346139a4d --- /dev/null +++ b/core/jni/android_view_InputEventReceiver.md @@ -0,0 +1,49 @@ +# Batched consumption # + +Most apps draw once per vsync. Therefore, apps can only respond to 1 input event per frame. If multiple input events come in during the period of 1 vsync, it would be wasteful to deliver them all at once to the app. For this reason, input events are batched to only deliver 1 event per frame to the app. + +The batching process works in the following manner: + +1. `InputDispatcher` sends an event to the app +2. The app's `Looper` is notified about the available event. +3. The `handleEvent` callback is executed. Events are read from fd. +4. If a batched input event is available, `InputConsumer::hasPendingBatch` returns true. No event is sent to the app at this point. +5. The app is notified that a batched event is available for consumption, and schedules a runnable via the `Choreographer` to consume it a short time before the next frame +6. When the scheduled runnable is executed, it doesn't just consume the batched input. It proactively tries to consume everything that has come in to the socket. +7. The batched event is sent to the app, along with any of the other events that have come in. + +Let's discuss the specifics of some of these steps. + +## 1. Consuming events in `handleEvent` callback ## + +The app is notified about the available event via the `Looper` callback `handleEvent`. When the app's input socket becomes readable (e.g., it has unread events), the looper will execute `handleEvent`. At this point, the app is expected to read in the events that have come in to the socket. The function `handleEvent` will continue to trigger as long as there are unread events in the socket. Thus, the app could choose to read events 1 at a time, or all at once. If there are no more events in the app's socket, handleEvent will no longer execute. + +Even though it is perfectly valid for the app to read events 1 at a time, it is more efficient to read them all at once. Therefore, whenever the events are available, the app will try to completely drain the socket. + +To consume the events inside `handleEvent`, the app calls `InputConsumer::consume(.., consumeBatches=false, frameTime=-1, ..)`. That is, when `handleEvent` runs, there is no information about the upcoming frameTime, and we dont want to consume the batches because there may be other events that come in before the 'consume batched input' runnable runs. + +If a batched event comes in at this point (typically, any MOVE event that has source = TOUCHSCREEN), the `consume` function above would actually return a `NULL` event with status `WOULD_BLOCK`. When this happens, the caller (`NativeInputEventReceiver`) is responsible for checking whether `InputConsumer::hasPendingBatch` is set to true. If so, the caller is responsible for scheduling a runnable to consume these batched events. + +## 2. Consuming batched events ## + +In the previous section, we learned that the app can read events inside the `handleEvent` callback. The other time when the app reads events is when the 'consume batched input' runnable is executed. This runnable is scheduled via the Choreographer by requesting a `CALLBACK_INPUT` event. + +Before the batched events are consumed, the socket is drained once again. This is an optimization. + +To consume the events inside 'consume batched input' runnable, the app calls `InputConsumer::consume(.., consumeBatches=true, frameTime=<valid frame time>, ..)`. At this point, the `consume` function will return all batched events up to the `frameTime` point. There may be batched events remaining. + +## 3. Key points ## + +Some of the behaviours above should be highlighted, because they may be unexpected. + +1. Even if events have been read by `InputConsumer`, `consume` will return `NULL` event with status `WOULD_BLOCK` if those events caused a new batch to be started. + +2. Events are read from the fd outside of the regular `handleEvent` case, during batched consumption. + +3. The function `handleEvent` will always execute as long as there are unread events in the fd + +4. The `consume` function is called in 1 of 2 possible ways: + - `consumeBatches=false, frameTime=-1` + - `consumeBatches=true, frameTime=<valid time>` + + I.e., it is never called with `consumeBatches=true, frameTime=-1`. diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 62f844eb59a8..94151b522c9c 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -110,6 +110,7 @@ static struct { jfieldID sourceCrop; jfieldID frameScale; jfieldID captureSecureLayers; + jfieldID allowProtected; } gCaptureArgsClassInfo; static struct { @@ -196,6 +197,7 @@ static struct { jclass clazz; jmethodID ctor; jfieldID defaultConfig; + jfieldID allowGroupSwitching; jfieldID primaryRefreshRateMin; jfieldID primaryRefreshRateMax; jfieldID appRequestRefreshRateMin; @@ -367,6 +369,8 @@ static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScale); captureArgs.captureSecureLayers = env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers); + captureArgs.allowProtected = + env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.allowProtected); } static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env, @@ -1003,6 +1007,9 @@ static jboolean nativeSetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, jo jint defaultConfig = env->GetIntField(desiredDisplayConfigSpecs, gDesiredDisplayConfigSpecsClassInfo.defaultConfig); + jboolean allowGroupSwitching = + env->GetBooleanField(desiredDisplayConfigSpecs, + gDesiredDisplayConfigSpecsClassInfo.allowGroupSwitching); jfloat primaryRefreshRateMin = env->GetFloatField(desiredDisplayConfigSpecs, gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMin); @@ -1017,6 +1024,7 @@ static jboolean nativeSetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, jo gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMax); size_t result = SurfaceComposerClient::setDesiredDisplayConfigSpecs(token, defaultConfig, + allowGroupSwitching, primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin, @@ -1029,11 +1037,13 @@ static jobject nativeGetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, job if (token == nullptr) return nullptr; int32_t defaultConfig; + bool allowGroupSwitching; float primaryRefreshRateMin; float primaryRefreshRateMax; float appRequestRefreshRateMin; float appRequestRefreshRateMax; if (SurfaceComposerClient::getDesiredDisplayConfigSpecs(token, &defaultConfig, + &allowGroupSwitching, &primaryRefreshRateMin, &primaryRefreshRateMax, &appRequestRefreshRateMin, @@ -1044,8 +1054,8 @@ static jobject nativeGetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, job return env->NewObject(gDesiredDisplayConfigSpecsClassInfo.clazz, gDesiredDisplayConfigSpecsClassInfo.ctor, defaultConfig, - primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin, - appRequestRefreshRateMax); + allowGroupSwitching, primaryRefreshRateMin, primaryRefreshRateMax, + appRequestRefreshRateMin, appRequestRefreshRateMax); } static jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) { @@ -1862,9 +1872,11 @@ int register_android_view_SurfaceControl(JNIEnv* env) gDesiredDisplayConfigSpecsClassInfo.clazz = MakeGlobalRefOrDie(env, desiredDisplayConfigSpecsClazz); gDesiredDisplayConfigSpecsClassInfo.ctor = - GetMethodIDOrDie(env, gDesiredDisplayConfigSpecsClassInfo.clazz, "<init>", "(IFFFF)V"); + GetMethodIDOrDie(env, gDesiredDisplayConfigSpecsClassInfo.clazz, "<init>", "(IZFFFF)V"); gDesiredDisplayConfigSpecsClassInfo.defaultConfig = GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "defaultConfig", "I"); + gDesiredDisplayConfigSpecsClassInfo.allowGroupSwitching = + GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "allowGroupSwitching", "Z"); gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMin = GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "primaryRefreshRateMin", "F"); gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMax = @@ -1881,6 +1893,8 @@ int register_android_view_SurfaceControl(JNIEnv* env) gCaptureArgsClassInfo.frameScale = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScale", "F"); gCaptureArgsClassInfo.captureSecureLayers = GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z"); + gCaptureArgsClassInfo.allowProtected = + GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z"); jclass displayCaptureArgsClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayCaptureArgs"); diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto index 37a9f50dec89..2d2c8accc039 100644 --- a/core/proto/android/app/enums.proto +++ b/core/proto/android/app/enums.proto @@ -210,4 +210,5 @@ enum AppOpEnum { APP_OP_PHONE_CALL_MICROPHONE = 100; APP_OP_PHONE_CALL_CAMERA = 101; APP_OP_RECORD_AUDIO_HOTWORD = 102; + APP_OP_MANAGE_ONGOING_CALLS = 103; } diff --git a/core/proto/android/providers/settings/config.proto b/core/proto/android/providers/settings/config.proto index f343c3a30927..c5ea2ab0b868 100644 --- a/core/proto/android/providers/settings/config.proto +++ b/core/proto/android/providers/settings/config.proto @@ -31,6 +31,7 @@ message ConfigSettingsProto { repeated SettingProto activity_manager_settings = 4; repeated SettingProto alarm_manager_settings = 26; repeated SettingProto app_compat_settings = 5; + repeated SettingProto app_standby_settings = 27; repeated SettingProto autofill_settings = 6; repeated SettingProto blobstore_settings = 23; repeated SettingProto connectivity_settings = 7; @@ -52,7 +53,7 @@ message ConfigSettingsProto { repeated SettingProto telephony_settings = 21; repeated SettingProto textclassifier_settings = 22; - // Next tag: 27 + // Next tag: 28 message NamespaceProto { optional string namespace = 1; diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index 16a691c9c4ec..1ea1bafd4d2f 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -78,7 +78,7 @@ message GlobalSettingsProto { option (android.msg_privacy).dest = DEST_EXPLICIT; // These are key=value lists, separated by commas. - optional SettingProto idle_constants = 1; + reserved 1; // idle_constants optional SettingProto standby_enabled = 2 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto auto_restriction_enabled = 3 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto forced_app_standby_enabled = 4 [ (android.privacy).dest = DEST_AUTOMATIC ]; @@ -510,7 +510,7 @@ message GlobalSettingsProto { optional IntentFirewall intent_firewall = 65; reserved 66; // job_scheduler_constants - optional SettingProto job_scheduler_quota_controller_constants = 149 [ (android.privacy).dest = DEST_AUTOMATIC ]; + reserved 149; // job_scheduler_quota_controller_constants reserved 150; // job_scheduler_time_controller_constants optional SettingProto keep_profile_in_background = 67 [ (android.privacy).dest = DEST_AUTOMATIC ]; diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index 83c53915694a..d934b82e36c3 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -219,8 +219,10 @@ message SecureSettingsProto { optional SettingProto emergency_assistance_application = 22 [ (android.privacy).dest = DEST_AUTOMATIC ]; message EmergencyResponse { - optional SettingProto panic_gesture_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ]; - optional SettingProto panic_sound_enabled = 2 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto emergency_gesture_enabled = 3 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto emergency_gesture_sound_enabled = 4 [ (android.privacy).dest = DEST_AUTOMATIC ]; + + reserved 1,2; } optional EmergencyResponse emergency_response = 83; diff --git a/core/proto/android/server/fingerprint.proto b/core/proto/android/server/fingerprint.proto index a264f18f921c..a49a1adcc619 100644 --- a/core/proto/android/server/fingerprint.proto +++ b/core/proto/android/server/fingerprint.proto @@ -66,3 +66,36 @@ message PerformanceStatsProto { // Total number of permanent lockouts. optional int32 permanent_lockout = 5; } + +// Internal FingerprintService states. The above messages (FingerprintServiceDumpProto, etc) +// are used for legacy metrics and should not be modified. +message FingerprintServiceStateProto { + option (.android.msg_privacy).dest = DEST_AUTOMATIC; + + repeated SensorStateProto sensor_states = 1; +} + +// State of a single sensor. +message SensorStateProto { + option (.android.msg_privacy).dest = DEST_AUTOMATIC; + + // Unique sensorId + optional int32 sensor_id = 1; + + // State of the sensor's scheduler. True if currently handling an operation, false if idle. + optional bool is_busy = 2; + + // User states for this sensor. + repeated UserStateProto user_states = 3; +} + +// State of a specific user for a specific sensor. +message UserStateProto { + option (.android.msg_privacy).dest = DEST_AUTOMATIC; + + // Android user ID + optional int32 user_id = 1; + + // Number of fingerprints enrolled + optional int32 num_enrolled = 2; +}
\ No newline at end of file diff --git a/core/proto/android/stats/tls/enums.proto b/core/proto/android/stats/tls/enums.proto new file mode 100644 index 000000000000..0ae87ee1d89b --- /dev/null +++ b/core/proto/android/stats/tls/enums.proto @@ -0,0 +1,70 @@ +/* + * 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. + */ +syntax = "proto2"; +package android.stats.tls; + +// Keep in sync with +// external/conscrypt/{android,platform}/src/main/java/org/conscrypt/Platform.java +enum Protocol { + UNKNOWN_PROTO = 0; + SSLv3 = 1; + TLSv1 = 2; + TLSv1_1 = 3; + TLSv1_2 = 4; + TLSv1_3 = 5; +} + +// Cipher suites' ids are based on IANA's database: +// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4 +// +// If you add new cipher suite, make sure id is the same as in IANA's database (see link above) +// +// Keep in sync with +// external/conscrypt/{android,platform}/src/main/java/org/conscrypt/Platform.java +enum CipherSuite { + UNKNOWN_CIPHER_SUITE = 0x0000; + + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A; + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014; + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009; + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013; + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F; + TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A; + + // TLSv1.2 cipher suites + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; + TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D; + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F; + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030; + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B; + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C; + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9; + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8; + + // Pre-Shared Key (PSK) cipher suites + TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C; + TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D; + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035; + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036; + TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC; + + // TLS 1.3 cipher suites + TLS_AES_128_GCM_SHA256 = 0x1301; + TLS_AES_256_GCM_SHA384 = 0x1302; + TLS_CHACHA20_POLY1305_SHA256 = 0x1303; +} + diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 01954510ee08..3248cfedb523 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -349,6 +349,7 @@ <protected-broadcast android:name="com.android.server.WifiManager.action.START_PNO" /> <protected-broadcast android:name="com.android.server.WifiManager.action.DELAYED_DRIVER_STOP" /> <protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" /> + <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_DISPATCH" /> <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" /> <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" /> <protected-broadcast android:name="com.android.internal.action.EUICC_FACTORY_RESET" /> @@ -668,6 +669,10 @@ <!-- For tether entitlement recheck--> <protected-broadcast android:name="com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM" /> + + <!-- Made protected in S (was added in R) --> + <protected-broadcast android:name="com.android.internal.intent.action.BUGREPORT_REQUESTED" /> + <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> <!-- ====================================================================== --> @@ -2229,6 +2234,11 @@ <permission android:name="android.permission.BIND_INCALL_SERVICE" android:protectionLevel="signature|privileged" /> + <!-- Allows to query ongoing call details and manage ongoing calls + <p>Protection level: signature|appop --> + <permission android:name="android.permission.MANAGE_ONGOING_CALLS" + android:protectionLevel="signature|appop" /> + <!-- Allows the app to request network scans from telephony. <p>Not for use by third-party applications. @SystemApi @hide--> @@ -2525,10 +2535,15 @@ <permission android:name="android.permission.REMOVE_TASKS" android:protectionLevel="signature|documenter" /> - <!-- @SystemApi @TestApi @hide Allows an application to create/manage/remove stacks --> + <!-- @deprecated Use MANAGE_ACTIVITY_TASKS instead. + @SystemApi @TestApi @hide Allows an application to create/manage/remove stacks --> <permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" android:protectionLevel="signature" /> + <!-- @SystemApi @TestApi @hide Allows an application to create/manage/remove tasks --> + <permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" + android:protectionLevel="signature" /> + <!-- @SystemApi @TestApi @hide Allows an application to embed other activities --> <permission android:name="android.permission.ACTIVITY_EMBEDDING" android:protectionLevel="signature|privileged" /> @@ -5150,6 +5165,12 @@ <permission android:name="android.permission.INPUT_CONSUMER" android:protectionLevel="signature" /> + <!-- @hide Allows an application to control the system's device state managed by the + {@link android.service.devicestate.DeviceStateManagerService}. For example, on foldable + devices this would grant access to toggle between the folded and unfolded states. --> + <permission android:name="android.permission.CONTROL_DEVICE_STATE" + android:protectionLevel="signature" /> + <!-- Attribution for Geofencing service. --> <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/> <!-- Attribution for Country Detector. --> diff --git a/core/res/res/layout/notification_material_action_list.xml b/core/res/res/layout/notification_material_action_list.xml index df271f0f2942..ffb9603529c2 100644 --- a/core/res/res/layout/notification_material_action_list.xml +++ b/core/res/res/layout/notification_material_action_list.xml @@ -28,6 +28,7 @@ android:gravity="end" android:orientation="horizontal" android:paddingEnd="@dimen/bubble_gone_padding_end" + android:background="@color/notification_action_list_background_color" > <com.android.internal.widget.NotificationActionListLayout @@ -38,7 +39,6 @@ android:orientation="horizontal" android:gravity="center_vertical" android:visibility="gone" - android:background="@color/notification_action_list_background_color" > <!-- actions will be added here --> </com.android.internal.widget.NotificationActionListLayout> diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml index 221bcf6a800c..34c7fa734f21 100644 --- a/core/res/res/layout/notification_template_material_base.xml +++ b/core/res/res/layout/notification_template_material_base.xml @@ -39,10 +39,6 @@ android:layout_height="@dimen/notification_progress_bar_height" android:layout_marginTop="@dimen/notification_progress_margin_top" layout="@layout/notification_template_progress" /> - <include layout="@layout/notification_template_smart_reply_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/notification_content_margin" /> </LinearLayout> <include layout="@layout/notification_template_right_icon" /> </FrameLayout> diff --git a/core/res/res/layout/notification_template_top_line.xml b/core/res/res/layout/notification_template_top_line.xml index 27fab859a045..0786e138559f 100644 --- a/core/res/res/layout/notification_template_top_line.xml +++ b/core/res/res/layout/notification_template_top_line.xml @@ -102,9 +102,8 @@ android:id="@+id/alerted_icon" android:layout_width="@dimen/notification_alerted_size" android:layout_height="@dimen/notification_alerted_size" - android:layout_gravity="center" android:layout_marginStart="4dp" - android:paddingTop="1dp" + android:baseline="10dp" android:scaleType="fitCenter" android:visibility="gone" android:contentDescription="@string/notification_alerted_content_description" @@ -116,8 +115,7 @@ android:layout_height="@dimen/notification_feedback_size" android:layout_marginStart="6dp" android:layout_marginEnd="6dp" - android:paddingTop="2dp" - android:layout_gravity="center" + android:baseline="10dp" android:scaleType="fitCenter" android:src="@drawable/ic_feedback_indicator" android:background="?android:selectableItemBackgroundBorderless" @@ -128,9 +126,8 @@ android:id="@+id/profile_badge" android:layout_width="@dimen/notification_badge_size" android:layout_height="@dimen/notification_badge_size" - android:layout_gravity="center" android:layout_marginStart="4dp" - android:paddingTop="1dp" + android:baseline="10dp" android:scaleType="fitCenter" android:visibility="gone" android:contentDescription="@string/notification_work_profile_content_description" diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 747ecb353e6d..31993fb5860d 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"AF"</string> <string name="checked" msgid="9179896827054513119">"gemerk"</string> <string name="not_checked" msgid="7972320087569023342">"nie gemerk nie"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"gekies"</string> + <string name="not_selected" msgid="410652016565864475">"nie gekies nie"</string> <string name="whichApplication" msgid="5432266899591255759">"Voltooi handeling met"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Voltooi handeling met gebruik van %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Voltooi handeling"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 4142a5c6f71e..dee3521a1b2e 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ውጪ"</string> <string name="checked" msgid="9179896827054513119">"ምልክት ተደርጎበታል"</string> <string name="not_checked" msgid="7972320087569023342">"ምልክት አልተደረገበትም"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"ተመርጧል"</string> + <string name="not_selected" msgid="410652016565864475">"አልተመረጠም"</string> <string name="whichApplication" msgid="5432266899591255759">"... በመጠቀም ድርጊቱን አጠናቅ"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$sን ተጠቅመው እርምጃ ያጠናቅቁ"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"እርምጃውን አጠናቅቅ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 8ec3140d7e75..905d2ddad1db 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1209,10 +1209,8 @@ <string name="capital_off" msgid="7443704171014626777">"إيقاف"</string> <string name="checked" msgid="9179896827054513119">"تم وضع علامة"</string> <string name="not_checked" msgid="7972320087569023342">"لم يتم وضع علامة"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"محدّد"</string> + <string name="not_selected" msgid="410652016565864475">"غير محدّد"</string> <string name="whichApplication" msgid="5432266899591255759">"إكمال الإجراء باستخدام"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"إكمال الإجراء باستخدام %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"إكمال الإجراء"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index d142b6bb2e2d..e58274cedf89 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"অফ কৰক"</string> <string name="checked" msgid="9179896827054513119">"টিক চিহ্ন দিয়া হৈছে"</string> <string name="not_checked" msgid="7972320087569023342">"টিক চিহ্ন দিয়া হোৱা নাই"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"বাছনি কৰা"</string> + <string name="not_selected" msgid="410652016565864475">"বাছনি কৰা হোৱা নাই"</string> <string name="whichApplication" msgid="5432266899591255759">"এয়া ব্যৱহাৰ কৰি কার্য সম্পূর্ণ কৰক"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ব্যৱহাৰ কৰি কাৰ্যটো সম্পূৰ্ণ কৰক"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"কাৰ্য সম্পূৰ্ণ কৰক"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 0db22cc6b46a..499cd202b8ea 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"QAPALI"</string> <string name="checked" msgid="9179896827054513119">"yoxlanılıb"</string> <string name="not_checked" msgid="7972320087569023342">"yoxlanılmayıb"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"seçilib"</string> + <string name="not_selected" msgid="410652016565864475">"seçilməyib"</string> <string name="whichApplication" msgid="5432266899591255759">"Əməliyyatı tamamlayın:"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s istifadə edərək əməliyyatı tamamlayın"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Əməliyyatı tamamlayın"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index a21090218a5e..5e264537c2b0 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -1149,10 +1149,8 @@ <string name="capital_off" msgid="7443704171014626777">"NE"</string> <string name="checked" msgid="9179896827054513119">"označeno je"</string> <string name="not_checked" msgid="7972320087569023342">"nije označeno"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"izabrano"</string> + <string name="not_selected" msgid="410652016565864475">"nije izabrano"</string> <string name="whichApplication" msgid="5432266899591255759">"Dovrši radnju preko"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Završite radnju pomoću aplikacije %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Završi radnju"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 38da725b342a..d6a725706433 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -1169,10 +1169,8 @@ <string name="capital_off" msgid="7443704171014626777">"Выключана"</string> <string name="checked" msgid="9179896827054513119">"пазначана"</string> <string name="not_checked" msgid="7972320087569023342">"не пазначана"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"выбраны"</string> + <string name="not_selected" msgid="410652016565864475">"не выбраны"</string> <string name="whichApplication" msgid="5432266899591255759">"Завяршыць дзеянне з дапамогай"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Завяршыць дзеянне з дапамогай %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Завяршыць дзеянне"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 3fca6eb686f6..376ef26412ff 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ИЗКЛ"</string> <string name="checked" msgid="9179896827054513119">"с отметка"</string> <string name="not_checked" msgid="7972320087569023342">"без отметка"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"избрано"</string> + <string name="not_selected" msgid="410652016565864475">"не е избрано"</string> <string name="whichApplication" msgid="5432266899591255759">"Изпълняване на действието чрез"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Завършване на действието посредством %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Изпълняване на действието"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index eb626f229bdd..f180df6dbe71 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -1149,10 +1149,8 @@ <string name="capital_off" msgid="7443704171014626777">"Isključeno"</string> <string name="checked" msgid="9179896827054513119">"označeno"</string> <string name="not_checked" msgid="7972320087569023342">"nije označeno"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"odabrano"</string> + <string name="not_selected" msgid="410652016565864475">"nije odabrano"</string> <string name="whichApplication" msgid="5432266899591255759">"Završite radnju pomoću aplikacije"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Završite radnju pomoću aplikacije %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Izvršiti akciju"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index dd6e5a36f33f..8c9c674372f8 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -327,7 +327,7 @@ <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Controla el nivell i la posició del zoom de la pantalla."</string> <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Fer gestos"</string> <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Permet tocar, lliscar, pinçar i fer altres gestos."</string> - <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos d\'empremtes dactilars"</string> + <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos d\'empremtes digitals"</string> <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Captura gestos realitzats en el sensor d\'empremtes dactilars del dispositiu."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fes una captura de pantalla"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pots fer una captura de la pantalla."</string> @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"NO"</string> <string name="checked" msgid="9179896827054513119">"seleccionat"</string> <string name="not_checked" msgid="7972320087569023342">"no seleccionat"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"seleccionat"</string> + <string name="not_selected" msgid="410652016565864475">"no seleccionat"</string> <string name="whichApplication" msgid="5432266899591255759">"Completa l\'acció mitjançant"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Completa l\'acció amb %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Completa l\'acció"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index d9f09a2557fb..e9f1fad5e95d 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1169,10 +1169,8 @@ <string name="capital_off" msgid="7443704171014626777">"O"</string> <string name="checked" msgid="9179896827054513119">"vybráno"</string> <string name="not_checked" msgid="7972320087569023342">"nevybráno"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"vybráno"</string> + <string name="not_selected" msgid="410652016565864475">"nevybráno"</string> <string name="whichApplication" msgid="5432266899591255759">"Dokončit akci pomocí aplikace"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Dokončit akci pomocí aplikace %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Dokončit akci"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index d37cee45b5ae..75bdda0b590c 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"FRA"</string> <string name="checked" msgid="9179896827054513119">"slået til"</string> <string name="not_checked" msgid="7972320087569023342">"slået fra"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"valgt"</string> + <string name="not_selected" msgid="410652016565864475">"ikke valgt"</string> <string name="whichApplication" msgid="5432266899591255759">"Brug"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Gennemfør handling ved hjælp af %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Afslut handling"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 4ab45b439d0b..6d82b62daf2e 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -327,7 +327,7 @@ <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Legt die Zoom-Stufe und -Position auf dem Display fest."</string> <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Touch-Gesten möglich"</string> <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Tippen, Wischen, Zusammenziehen und andere Touch-Gesten möglich."</string> - <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingerabdrucksensor-Gesten"</string> + <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gesten auf dem Fingerabdrucksensor"</string> <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Erfasst Touch-Gesten auf dem Fingerabdrucksensor des Geräts."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Screenshot erstellen"</string> <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Es kann ein Screenshot des Displays erstellt werden."</string> @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"AUS"</string> <string name="checked" msgid="9179896827054513119">"aktiviert"</string> <string name="not_checked" msgid="7972320087569023342">"deaktiviert"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"ausgewählt"</string> + <string name="not_selected" msgid="410652016565864475">"nicht ausgewählt"</string> <string name="whichApplication" msgid="5432266899591255759">"Aktion durchführen mit"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Aktion mit %1$s abschließen"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Abschließen"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 933ddf7588e0..42513aa77300 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"Ανενεργό"</string> <string name="checked" msgid="9179896827054513119">"επιλεγμένο"</string> <string name="not_checked" msgid="7972320087569023342">"μη επιλεγμένο"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"επιλεγμένο"</string> + <string name="not_selected" msgid="410652016565864475">"μη επιλεγμένο"</string> <string name="whichApplication" msgid="5432266899591255759">"Ολοκλήρωση ενέργειας με τη χρήση"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Ολοκληρωμένη ενέργεια με χρήση %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Ολοκλήρωση ενέργειας"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index d88f58021a70..1e07593956b3 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"No"</string> <string name="checked" msgid="9179896827054513119">"activado"</string> <string name="not_checked" msgid="7972320087569023342">"desactivado"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"seleccionado"</string> + <string name="not_selected" msgid="410652016565864475">"no seleccionado"</string> <string name="whichApplication" msgid="5432266899591255759">"Completar la acción mediante"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Completar acción con %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Completar acción"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index a498c6afe39f..d0fceb094355 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1778,7 +1778,7 @@ <item quantity="other">Vuelve a intentarlo en <xliff:g id="COUNT">%d</xliff:g> segundos</item> <item quantity="one">Vuelve a intentarlo en 1 segundo</item> </plurals> - <string name="restr_pin_try_later" msgid="5897719962541636727">"Volver a intentar más tarde"</string> + <string name="restr_pin_try_later" msgid="5897719962541636727">"Reintentar más tarde"</string> <string name="immersive_cling_title" msgid="2307034298721541791">"Modo de pantalla completa"</string> <string name="immersive_cling_description" msgid="7092737175345204832">"Para salir, desliza el dedo de arriba abajo."</string> <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 05cd7eb32c0b..69d1526845b8 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"VÄLJAS"</string> <string name="checked" msgid="9179896827054513119">"märgitud"</string> <string name="not_checked" msgid="7972320087569023342">"märkimata"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"valitud"</string> + <string name="not_selected" msgid="410652016565864475">"pole valitud"</string> <string name="whichApplication" msgid="5432266899591255759">"Lõpetage toiming rakendusega"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Toimingu lõpetamine, kasutades rakendust %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Vii toiming lõpule"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 5f63703d0e2a..a00282ff4292 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"DESAKTIBATUTA"</string> <string name="checked" msgid="9179896827054513119">"markatuta"</string> <string name="not_checked" msgid="7972320087569023342">"markatu gabe"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"hautatuta"</string> + <string name="not_selected" msgid="410652016565864475">"hautatu gabe"</string> <string name="whichApplication" msgid="5432266899591255759">"Gauzatu ekintza hau erabilita:"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Osatu ekintza %1$s erabiliz"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Osatu ekintza"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 00956a4129e8..6783b7700a67 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"خاموش"</string> <string name="checked" msgid="9179896827054513119">"علامتزدهشده"</string> <string name="not_checked" msgid="7972320087569023342">"بدون علامت"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"انتخاب شده"</string> + <string name="not_selected" msgid="410652016565864475">"انتخاب نشده"</string> <string name="whichApplication" msgid="5432266899591255759">"تکمیل کنش بااستفاده از"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"تکمیل کنش بااستفاده از %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"تکمیل عملکرد"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 4e488017b71c..27abeea5dd86 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"POIS"</string> <string name="checked" msgid="9179896827054513119">"valittu"</string> <string name="not_checked" msgid="7972320087569023342">"ei valittu"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"valittu"</string> + <string name="not_selected" msgid="410652016565864475">"ei valittu"</string> <string name="whichApplication" msgid="5432266899591255759">"Tee toiminto käyttäen sovellusta"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Suorita sovelluksella %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Suorita toiminto"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 283588eaaf58..542aaf0b456b 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"NON"</string> <string name="checked" msgid="9179896827054513119">"coché"</string> <string name="not_checked" msgid="7972320087569023342">"non coché"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"sélectionné"</string> + <string name="not_selected" msgid="410652016565864475">"non sélectionné"</string> <string name="whichApplication" msgid="5432266899591255759">"Continuer avec"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Continuer avec %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Terminer l\'action"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 83ba1e97b773..4c2984973594 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"NON"</string> <string name="checked" msgid="9179896827054513119">"activé"</string> <string name="not_checked" msgid="7972320087569023342">"désactivé"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"sélectionné"</string> + <string name="not_selected" msgid="410652016565864475">"non sélectionné"</string> <string name="whichApplication" msgid="5432266899591255759">"Continuer avec"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Terminer l\'action avec %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Terminer l\'action"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index dbe9593a6526..893433b7b8a2 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"NON"</string> <string name="checked" msgid="9179896827054513119">"seleccionado"</string> <string name="not_checked" msgid="7972320087569023342">"non seleccionado"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"elemento seleccionado"</string> + <string name="not_selected" msgid="410652016565864475">"elemento non seleccionado"</string> <string name="whichApplication" msgid="5432266899591255759">"Completar a acción usando"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Completar a acción usando %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Completar acción"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index eac5f2d42214..f1e57801d3ec 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"बंद"</string> <string name="checked" msgid="9179896827054513119">"चालू है"</string> <string name="not_checked" msgid="7972320087569023342">"बंद है"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"चुना गया"</string> + <string name="not_selected" msgid="410652016565864475">"नहीं चुना गया"</string> <string name="whichApplication" msgid="5432266899591255759">"इसका इस्तेमाल करके कार्रवाई को पूरा करें"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s का उपयोग करके कार्रवाई पूरी करें"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"कार्रवाई पूरी करें"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 1c80380734ae..4ff37c575a0f 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1149,10 +1149,8 @@ <string name="capital_off" msgid="7443704171014626777">"Isklj."</string> <string name="checked" msgid="9179896827054513119">"potvrđeno"</string> <string name="not_checked" msgid="7972320087569023342">"nije potvrđeno"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"odabrano"</string> + <string name="not_selected" msgid="410652016565864475">"nije odabrano"</string> <string name="whichApplication" msgid="5432266899591255759">"Radnju dovrši pomoću stavke"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Dovršavanje radnje pomoću aplikacije %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Dovrši radnju"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 68ba61e1f848..d01373f749f3 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"Ki"</string> <string name="checked" msgid="9179896827054513119">"kiválasztva"</string> <string name="not_checked" msgid="7972320087569023342">"nincs kiválasztva"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"kiválasztva"</string> + <string name="not_selected" msgid="410652016565864475">"nincs kiválasztva"</string> <string name="whichApplication" msgid="5432266899591255759">"Művelet végrehajtása a következővel:"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Művelet elvégzése a(z) %1$s segítségével"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Művelet végrehajtása"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 6c5223285f52..b1fe76e760e2 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"O"</string> <string name="checked" msgid="9179896827054513119">"նշված է"</string> <string name="not_checked" msgid="7972320087569023342">"նշված չէ"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"ընտրված է"</string> + <string name="not_selected" msgid="410652016565864475">"ընտրված չէ"</string> <string name="whichApplication" msgid="5432266899591255759">"Ավարտել գործողությունը` օգտագործելով"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Եզրափակել գործողությունը՝ օգտագործելով %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Ավարտել գործողությունը"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index b420b6e4f692..cc8071bf7b9a 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"MATI"</string> <string name="checked" msgid="9179896827054513119">"dicentang"</string> <string name="not_checked" msgid="7972320087569023342">"tidak dicentang"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"dipilih"</string> + <string name="not_selected" msgid="410652016565864475">"tidak dipilih"</string> <string name="whichApplication" msgid="5432266899591255759">"Selesaikan tindakan menggunakan"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Selesaikan tindakan menggunakan %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Selesaikan tindakan"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index a4390e3f8eb9..5d1912236a99 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"SLÖKKT"</string> <string name="checked" msgid="9179896827054513119">"valið"</string> <string name="not_checked" msgid="7972320087569023342">"ekki valið"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"valið"</string> + <string name="not_selected" msgid="410652016565864475">"ekki valið"</string> <string name="whichApplication" msgid="5432266899591255759">"Ljúka aðgerð með"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Ljúka aðgerð með %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Ljúka aðgerð"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 9835e8b83347..a537e7ed38ac 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"OFF"</string> <string name="checked" msgid="9179896827054513119">"selezionato"</string> <string name="not_checked" msgid="7972320087569023342">"deselezionato"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"selezionato"</string> + <string name="not_selected" msgid="410652016565864475">"non selezionato"</string> <string name="whichApplication" msgid="5432266899591255759">"Completa l\'azione con"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Completamento azione con %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Completa azione"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index db190f7a3e04..422d810d3c09 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1169,10 +1169,8 @@ <string name="capital_off" msgid="7443704171014626777">"כבוי"</string> <string name="checked" msgid="9179896827054513119">"מסומן"</string> <string name="not_checked" msgid="7972320087569023342">"לא מסומן"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"נבחר"</string> + <string name="not_selected" msgid="410652016565864475">"לא נבחר"</string> <string name="whichApplication" msgid="5432266899591255759">"השלמת פעולה באמצעות"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"להשלמת הפעולה באמצעות %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"השלם פעולה"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index d9c74c500609..f5adb5962783 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"OFF"</string> <string name="checked" msgid="9179896827054513119">"ON"</string> <string name="not_checked" msgid="7972320087569023342">"OFF"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"選択済み"</string> + <string name="not_selected" msgid="410652016565864475">"未選択"</string> <string name="whichApplication" msgid="5432266899591255759">"アプリケーションを選択"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$sを使用してアクションを完了"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"アクションを実行"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 491793de3438..0c3e7b9f207c 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"გამორთ."</string> <string name="checked" msgid="9179896827054513119">"მონიშნულია"</string> <string name="not_checked" msgid="7972320087569023342">"არ არის მონიშნული"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"არჩეულია"</string> + <string name="not_selected" msgid="410652016565864475">"არ არის არჩეული"</string> <string name="whichApplication" msgid="5432266899591255759">"რა გამოვიყენოთ?"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"მოქმედების %1$s-ის გამოყენებით დასრულება"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"მოქმედების დასრულება"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 857892b37389..093daf1c0069 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"Өшірулі"</string> <string name="checked" msgid="9179896827054513119">"белгіленген"</string> <string name="not_checked" msgid="7972320087569023342">"белгіленбеген"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"таңдалған"</string> + <string name="not_selected" msgid="410652016565864475">"таңдалмаған"</string> <string name="whichApplication" msgid="5432266899591255759">"Әрекетті аяқтау"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Әрекетті %1$s қолданбасын пайдаланып аяқтау"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Әрекетті аяқтау"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 45d7ff73862f..82a27a85a264 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"បិទ"</string> <string name="checked" msgid="9179896827054513119">"បានធីក"</string> <string name="not_checked" msgid="7972320087569023342">"មិនបានធីក"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"បានជ្រើសរើស"</string> + <string name="not_selected" msgid="410652016565864475">"មិនបានជ្រើសរើសទេ"</string> <string name="whichApplication" msgid="5432266899591255759">"បញ្ចប់សកម្មភាពដោយប្រើ"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"បញ្ចប់សកម្មភាពដោយប្រើ %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"បញ្ចប់សកម្មភាព"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 0e746f9733de..f08ed6c253f1 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"OFF"</string> <string name="checked" msgid="9179896827054513119">"선택함"</string> <string name="not_checked" msgid="7972320087569023342">"선택 안함"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"선택됨"</string> + <string name="not_selected" msgid="410652016565864475">"선택되지 않음"</string> <string name="whichApplication" msgid="5432266899591255759">"작업을 수행할 때 사용하는 애플리케이션"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s을(를) 사용하여 작업 완료"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"작업 완료"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index d12ec8b4db75..451821681f0b 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ӨЧҮК"</string> <string name="checked" msgid="9179896827054513119">"белгиленген"</string> <string name="not_checked" msgid="7972320087569023342">"белгилене элек"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"тандалган"</string> + <string name="not_selected" msgid="410652016565864475">"тандалган жок"</string> <string name="whichApplication" msgid="5432266899591255759">"Кайсынысын колдоносуз?"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s аркылуу аракетти аягына чейин чыгаруу"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Аракетти аягына чыгаруу"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 5d15180db8aa..35d2e2d9857b 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ປິດ"</string> <string name="checked" msgid="9179896827054513119">"ໝາຍຖືກແລ້ວ"</string> <string name="not_checked" msgid="7972320087569023342">"ບໍ່ໄດ້ໝາຍຖືກ"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"ເລືອກແລ້ວ"</string> + <string name="not_selected" msgid="410652016565864475">"ບໍ່ໄດ້ເລືອກແລ້ວ"</string> <string name="whichApplication" msgid="5432266899591255759">"ດຳເນີນການໂດຍໃຊ້"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"ສຳເລັດການດຳເນີນການໂດຍໃຊ້ %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"ສຳເລັດຄຳສັ່ງ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index bef1f26d50bc..99e8b1f7277f 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1169,10 +1169,8 @@ <string name="capital_off" msgid="7443704171014626777">"IŠJ."</string> <string name="checked" msgid="9179896827054513119">"pažymėta"</string> <string name="not_checked" msgid="7972320087569023342">"nepažymėta"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"pasirinkta"</string> + <string name="not_selected" msgid="410652016565864475">"nepasirinkta"</string> <string name="whichApplication" msgid="5432266899591255759">"Užbaigti veiksmą naudojant"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Užbaigti veiksmą naudojant %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Užbaigti veiksmą"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 44cf3a2db1bb..95752c336749 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1149,10 +1149,8 @@ <string name="capital_off" msgid="7443704171014626777">"IZSL."</string> <string name="checked" msgid="9179896827054513119">"atzīmēts"</string> <string name="not_checked" msgid="7972320087569023342">"nav atzīmēts"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"atlasīts"</string> + <string name="not_selected" msgid="410652016565864475">"nav atlasīts"</string> <string name="whichApplication" msgid="5432266899591255759">"Izvēlieties lietotni"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Pabeigt darbību, izmantojot %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Pabeigt darbību"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 15c7ebafe850..5e62762dc787 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ИСКЛУЧЕНО"</string> <string name="checked" msgid="9179896827054513119">"штиклирано"</string> <string name="not_checked" msgid="7972320087569023342">"не е штиклирано"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"избрано"</string> + <string name="not_selected" msgid="410652016565864475">"не е избрано"</string> <string name="whichApplication" msgid="5432266899591255759">"Активирај со"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Остварете го дејството со %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Заврши го дејството"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 314442bfe97c..85a797547475 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ഓഫ്"</string> <string name="checked" msgid="9179896827054513119">"പരിശോധിച്ചത്"</string> <string name="not_checked" msgid="7972320087569023342">"പരിശോധിക്കാത്തത്"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"തിരഞ്ഞെടുത്തു"</string> + <string name="not_selected" msgid="410652016565864475">"തിരഞ്ഞെടുത്തിട്ടില്ല"</string> <string name="whichApplication" msgid="5432266899591255759">"പൂർണ്ണമായ പ്രവർത്തനം ഉപയോഗിക്കുന്നു"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ഉപയോഗിച്ച് പ്രവർത്തനം പൂർത്തിയാക്കുക"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"പ്രവർത്തനം പൂർത്തിയാക്കുക"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index f4c78e837b53..bbcfc63b3a38 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"Идэвхгүй"</string> <string name="checked" msgid="9179896827054513119">"тэмдэглэсэн"</string> <string name="not_checked" msgid="7972320087569023342">"тэмдэглээгүй"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"сонгосон"</string> + <string name="not_selected" msgid="410652016565864475">"сонгоогүй"</string> <string name="whichApplication" msgid="5432266899591255759">"Үйлдлийг дуусгах"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ашиглан үйлдлийг гүйцээх"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Үйлдлийг дуусгах"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 6d33cfadd511..b38dec2c25ba 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"MATIKAN"</string> <string name="checked" msgid="9179896827054513119">"ditandai"</string> <string name="not_checked" msgid="7972320087569023342">"tidak ditandai"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"dipilih"</string> + <string name="not_selected" msgid="410652016565864475">"tidak dipilih"</string> <string name="whichApplication" msgid="5432266899591255759">"Selesaikan tindakan menggunakan"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Selesaikan tindakan menggunakan %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Selesaikan tindakan"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index df33b37f9b0b..e1f3dcf31a49 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ပိတ်"</string> <string name="checked" msgid="9179896827054513119">"အမှန်ခြစ်ပြီး"</string> <string name="not_checked" msgid="7972320087569023342">"ခြစ် မထား"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"ရွေးချယ်ထားသည်"</string> + <string name="not_selected" msgid="410652016565864475">"ရွေးချယ်မထားပါ"</string> <string name="whichApplication" msgid="5432266899591255759">"အောက်ပါတို့ကို အသုံးပြုမှု အပြီးသတ်ခြင်း"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ကို သုံးပြီး လုပ်ဆောင်ချက် ပြီးဆုံးပါစေ"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"လုပ်ဆောင်ချက်ကို အပြီးသတ်ပါ"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index e62bf51dfe63..1c2e5c03d658 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"Av"</string> <string name="checked" msgid="9179896827054513119">"avmerket"</string> <string name="not_checked" msgid="7972320087569023342">"ikke avmerket"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"valgt"</string> + <string name="not_selected" msgid="410652016565864475">"ikke valgt"</string> <string name="whichApplication" msgid="5432266899591255759">"Fullfør med"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Fullfør handlingen med %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Fullfør handlingen"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index c041cb55a485..f768c833da66 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"UIT"</string> <string name="checked" msgid="9179896827054513119">"aangevinkt"</string> <string name="not_checked" msgid="7972320087569023342">"niet aangevinkt"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"geselecteerd"</string> + <string name="not_selected" msgid="410652016565864475">"niet geselecteerd"</string> <string name="whichApplication" msgid="5432266899591255759">"Actie voltooien met"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Actie voltooien via %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Actie voltooien"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 81a967625535..520673279ce7 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ବନ୍ଦ"</string> <string name="checked" msgid="9179896827054513119">"ଯାଞ୍ଚ ହୋଇଛି"</string> <string name="not_checked" msgid="7972320087569023342">"ଯାଞ୍ଚ ହୋଇନାହିଁ"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"ଚୟନ କରାଯାଇଛି"</string> + <string name="not_selected" msgid="410652016565864475">"ଚୟନ କରାଯାଇନାହିଁ"</string> <string name="whichApplication" msgid="5432266899591255759">"ବ୍ୟବହାର କରି କାର୍ଯ୍ୟ ସମ୍ପୂର୍ଣ୍ଣ କରନ୍ତୁ"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ବ୍ୟବହାର କରି କାର୍ଯ୍ୟ ସମ୍ପୂର୍ଣ୍ଣ କରନ୍ତୁ"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"କାର୍ଯ୍ୟ ସମ୍ପୂର୍ଣ୍ଣ କରନ୍ତୁ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 3962f743b9fa..07773da7f933 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1169,10 +1169,8 @@ <string name="capital_off" msgid="7443704171014626777">"Wył."</string> <string name="checked" msgid="9179896827054513119">"wybrano"</string> <string name="not_checked" msgid="7972320087569023342">"nie wybrano"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"wybrano"</string> + <string name="not_selected" msgid="410652016565864475">"nie wybrano"</string> <string name="whichApplication" msgid="5432266899591255759">"Wykonaj czynność przez..."</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Wykonaj czynność w aplikacji %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Wykonaj działanie"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 72a867ed2901..bfd32f35c993 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"DESL"</string> <string name="checked" msgid="9179896827054513119">"marcado"</string> <string name="not_checked" msgid="7972320087569023342">"não marcado"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"selecionado"</string> + <string name="not_selected" msgid="410652016565864475">"não selecionado"</string> <string name="whichApplication" msgid="5432266899591255759">"Complete a ação usando"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Concluir a ação usando %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Concluir ação"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 28b83c1a637c..e83d5578cb32 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"Desativado"</string> <string name="checked" msgid="9179896827054513119">"selecionado"</string> <string name="not_checked" msgid="7972320087569023342">"não selecionado"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"selecionado"</string> + <string name="not_selected" msgid="410652016565864475">"não selecionado"</string> <string name="whichApplication" msgid="5432266899591255759">"Concluir ação utilizando"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Concluir ação utilizando %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Concluir ação"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 72a867ed2901..bfd32f35c993 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"DESL"</string> <string name="checked" msgid="9179896827054513119">"marcado"</string> <string name="not_checked" msgid="7972320087569023342">"não marcado"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"selecionado"</string> + <string name="not_selected" msgid="410652016565864475">"não selecionado"</string> <string name="whichApplication" msgid="5432266899591255759">"Complete a ação usando"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Concluir a ação usando %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Concluir ação"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index bbe35ed00b73..fcd70eb61a25 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1149,10 +1149,8 @@ <string name="capital_off" msgid="7443704171014626777">"NU"</string> <string name="checked" msgid="9179896827054513119">"bifat"</string> <string name="not_checked" msgid="7972320087569023342">"nebifat"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"selectat"</string> + <string name="not_selected" msgid="410652016565864475">"neselectat"</string> <string name="whichApplication" msgid="5432266899591255759">"Finalizare acțiune utilizând"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Finalizați acțiunea utilizând %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Finalizați acțiunea"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 2903ba215cdd..3a8b28b8c7bf 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1169,10 +1169,8 @@ <string name="capital_off" msgid="7443704171014626777">"O"</string> <string name="checked" msgid="9179896827054513119">"отмечено"</string> <string name="not_checked" msgid="7972320087569023342">"не отмечено"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"выбрано"</string> + <string name="not_selected" msgid="410652016565864475">"не выбрано"</string> <string name="whichApplication" msgid="5432266899591255759">"Что использовать?"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Выполнить с помощью приложения \"%1$s\""</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Выполнить действие"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index f6c1b89c09f7..cef059d8cfde 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1169,10 +1169,8 @@ <string name="capital_off" msgid="7443704171014626777">"O"</string> <string name="checked" msgid="9179896827054513119">"začiarknuté"</string> <string name="not_checked" msgid="7972320087569023342">"nezačiarknuté"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"vybrané"</string> + <string name="not_selected" msgid="410652016565864475">"nevybrané"</string> <string name="whichApplication" msgid="5432266899591255759">"Dokončiť akciu pomocou aplikácie"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Dokončiť akciu pomocou aplikácie %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Dokončiť akciu"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 2f2fcc214627..b29748c1360f 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1169,10 +1169,8 @@ <string name="capital_off" msgid="7443704171014626777">"IZKLOPLJENO"</string> <string name="checked" msgid="9179896827054513119">"potrjeno"</string> <string name="not_checked" msgid="7972320087569023342">"ni potrjeno"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"izbrano"</string> + <string name="not_selected" msgid="410652016565864475">"ni izbrano"</string> <string name="whichApplication" msgid="5432266899591255759">"Dokončanje dejanja z aplikacijo"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Dokončanje dejanja z aplikacijo %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Izvedba dejanja"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index a36e860cc80b..c852d277a92f 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"Çaktivizuar"</string> <string name="checked" msgid="9179896827054513119">"u përzgjodh"</string> <string name="not_checked" msgid="7972320087569023342">"nuk u përzgjodh"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"i zgjedhur"</string> + <string name="not_selected" msgid="410652016565864475">"i pazgjedhur"</string> <string name="whichApplication" msgid="5432266899591255759">"Përfundo veprimin duke përdorur"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Përfundo veprimin duke përdorur %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Përfundo veprimin"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index f9968ef1499a..6a66c1be3d07 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1149,10 +1149,8 @@ <string name="capital_off" msgid="7443704171014626777">"НЕ"</string> <string name="checked" msgid="9179896827054513119">"означено је"</string> <string name="not_checked" msgid="7972320087569023342">"није означено"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"изабрано"</string> + <string name="not_selected" msgid="410652016565864475">"није изабрано"</string> <string name="whichApplication" msgid="5432266899591255759">"Доврши радњу преко"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Завршите радњу помоћу апликације %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Заврши радњу"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index de346c6be54d..8c28252bdfd3 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"AV"</string> <string name="checked" msgid="9179896827054513119">"markerad"</string> <string name="not_checked" msgid="7972320087569023342">"inte markerad"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"valt"</string> + <string name="not_selected" msgid="410652016565864475">"inte valt"</string> <string name="whichApplication" msgid="5432266899591255759">"Slutför åtgärd genom att använda"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Slutför åtgärden med %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Slutför åtgärd"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 0d56560bc40c..9124c1231988 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ZIMA"</string> <string name="checked" msgid="9179896827054513119">"imeteuliwa"</string> <string name="not_checked" msgid="7972320087569023342">"haijateuliwa"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"imechaguliwa"</string> + <string name="not_selected" msgid="410652016565864475">"haijachaguliwa"</string> <string name="whichApplication" msgid="5432266899591255759">"Kamilisha kitendo ukitumia"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Kamilisha kitendo ukitumia %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Kamilisha kitendo"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index f69414484f4f..4db2bec7cad1 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ஆஃப்"</string> <string name="checked" msgid="9179896827054513119">"இயக்கப்பட்டுள்ளது"</string> <string name="not_checked" msgid="7972320087569023342">"முடக்கப்பட்டுள்ளது"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"தேர்ந்தெடுக்கப்பட்டது"</string> + <string name="not_selected" msgid="410652016565864475">"தேர்ந்தெடுக்கப்படவில்லை"</string> <string name="whichApplication" msgid="5432266899591255759">"இதைப் பயன்படுத்தி செயலை நிறைவுசெய்"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ஐப் பயன்படுத்தி செயலை முடிக்கவும்"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"செயலை முடி"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 4cc2e16e202f..5102f148bb7c 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"ปิด"</string> <string name="checked" msgid="9179896827054513119">"เลือกไว้"</string> <string name="not_checked" msgid="7972320087569023342">"ยังไม่เลือก"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"เลือกไว้"</string> + <string name="not_selected" msgid="410652016565864475">"ไม่ได้เลือกไว้"</string> <string name="whichApplication" msgid="5432266899591255759">"ทำงานให้เสร็จโดยใช้"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"ดำเนินการให้เสร็จสมบูรณ์โดยใช้ %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"ทำงานให้เสร็จสิ้น"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 02c6f875c23c..6a15ffc38432 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"I-OFF"</string> <string name="checked" msgid="9179896827054513119">"nilagyan ng check"</string> <string name="not_checked" msgid="7972320087569023342">"hindi nilagyan ng check"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"pinili"</string> + <string name="not_selected" msgid="410652016565864475">"hindi pinili"</string> <string name="whichApplication" msgid="5432266899591255759">"Kumpletuhin ang pagkilos gamit ang"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Tapusin ang pagkilos gamit ang %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Gawin ang pagkilos"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 08f07f2076fb..8ee1d30a11bc 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"KAPALI"</string> <string name="checked" msgid="9179896827054513119">"işaretli"</string> <string name="not_checked" msgid="7972320087569023342">"işaretli değil"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"seçili"</string> + <string name="not_selected" msgid="410652016565864475">"seçili değil"</string> <string name="whichApplication" msgid="5432266899591255759">"İşlemi şunu kullanarak tamamla"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"İşlemi %1$s kullanarak tamamla"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"İşlemi tamamla"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index a8029337cf45..5ad2ea188200 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1169,10 +1169,8 @@ <string name="capital_off" msgid="7443704171014626777">"ВИМК"</string> <string name="checked" msgid="9179896827054513119">"вибрано"</string> <string name="not_checked" msgid="7972320087569023342">"не вибрано"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"вибрано"</string> + <string name="not_selected" msgid="410652016565864475">"не вибрано"</string> <string name="whichApplication" msgid="5432266899591255759">"Що використовувати?"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Завершити дію за допомогою %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Завершити дію"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index e2901bc9f907..78c9330a85e9 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"آف"</string> <string name="checked" msgid="9179896827054513119">"چیک کیا گیا"</string> <string name="not_checked" msgid="7972320087569023342">"چیک نہیں کیا گیا"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"منتخب کردہ"</string> + <string name="not_selected" msgid="410652016565864475">"غیر منتخب کردہ"</string> <string name="whichApplication" msgid="5432266899591255759">"اس کا استعمال کرکے کارروائی مکمل کریں"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s کا استعمال کر کے کارروائی مکمل کریں"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"کارروائی مکمل کریں"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index f49db4540a37..229e225ab63d 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"O"</string> <string name="checked" msgid="9179896827054513119">"belgilandi"</string> <string name="not_checked" msgid="7972320087569023342">"belgilanmadi"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"tanlangan"</string> + <string name="not_selected" msgid="410652016565864475">"tanlanmagan"</string> <string name="whichApplication" msgid="5432266899591255759">"Nima ishlatilsin?"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"“%1$s” bilan ochish"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Amalni bajarish"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 17ef57670c95..050fa0b24cc4 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"TẮT"</string> <string name="checked" msgid="9179896827054513119">"đã chọn"</string> <string name="not_checked" msgid="7972320087569023342">"chưa chọn"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"đã chọn"</string> + <string name="not_selected" msgid="410652016565864475">"chưa được chọn"</string> <string name="whichApplication" msgid="5432266899591255759">"Hoàn tất thao tác bằng"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Hoàn tất thao tác bằng %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Hoàn thành tác vụ"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 0fe62a9d631d..ec01ae3acbd7 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"关闭"</string> <string name="checked" msgid="9179896827054513119">"已勾选"</string> <string name="not_checked" msgid="7972320087569023342">"未勾选"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"已选择"</string> + <string name="not_selected" msgid="410652016565864475">"未选择"</string> <string name="whichApplication" msgid="5432266899591255759">"选择要使用的应用:"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"使用%1$s完成操作"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"完成操作"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 8f9c7c439dc1..58232b912b7f 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"關"</string> <string name="checked" msgid="9179896827054513119">"已勾選"</string> <string name="not_checked" msgid="7972320087569023342">"未勾選"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"揀咗"</string> + <string name="not_selected" msgid="410652016565864475">"未揀"</string> <string name="whichApplication" msgid="5432266899591255759">"完成操作需使用"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"完成操作需使用 %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"完成操作"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index eba79789a630..617a671500ec 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"關閉"</string> <string name="checked" msgid="9179896827054513119">"已勾選"</string> <string name="not_checked" msgid="7972320087569023342">"未勾選"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"已選取"</string> + <string name="not_selected" msgid="410652016565864475">"未選取"</string> <string name="whichApplication" msgid="5432266899591255759">"選擇要使用的應用程式"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"完成操作需使用 %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"完成操作"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 0f6fcb5c85d6..fab89962ef69 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1129,10 +1129,8 @@ <string name="capital_off" msgid="7443704171014626777">"VALIWE"</string> <string name="checked" msgid="9179896827054513119">"kuhloliwe"</string> <string name="not_checked" msgid="7972320087569023342">"akuhloliwe"</string> - <!-- no translation found for selected (6614607926197755875) --> - <skip /> - <!-- no translation found for not_selected (410652016565864475) --> - <skip /> + <string name="selected" msgid="6614607926197755875">"okukhethiwe"</string> + <string name="not_selected" msgid="410652016565864475">"akukhethiwe"</string> <string name="whichApplication" msgid="5432266899591255759">"Qedela isenzo usebenzisa"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Qedela isenzo usebenzisa i-%1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Qedela isenzo"</string> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index b74f96de33b1..03e64a4038ad 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2181,6 +2181,10 @@ the decor view. --> <attr name="windowLightNavigationBar" format="boolean" /> + <!-- @hide --> + <attr name="windowBackgroundBlurRadius" format="dimension"/> + + <!-- Controls how the window is laid out if there is a {@code DisplayCutout}. <p> Defaults to {@code default}. diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index e3ddbd8d25a2..f8266ba177ca 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -3202,10 +3202,23 @@ <attr name="minHeight" /> <!-- Window layout affinity of this activity. Activities with the same window layout - affinity will share the same layout record. If an activity is launched in freeform window, - the activity will be launched to the latest position and size where any task, if the root - activity of that task shares the same window layout affinity with the activity being - launched. Window layout affinity is shared only among activities with the same UID. + affinity will share the same layout record. That is, if a user is opening an activity in + a new task on a display that can host freeform windows, and the user had opened a task + before and that task had a root activity who had the same window layout affinity, the + new task's window will be created in the same window mode and around the location which + the previously opened task was in. + + <p>For example, if a user maximizes a task with root activity A and opens another + activity B that has the same window layout affinity as activity A has, activity B will + be created in fullscreen window mode. Similarly, if they move/resize a task with root + activity C and open another activity D that has the same window layout affinity as + activity C has, activity D will be in freeform window mode and as close to the position + of activity C as conditions permit. It doesn't require the user to keep the task with + activity A or activity C open. It won't, however, put any task into split-screen or PIP + window mode on launch. + + <p>If the user is opening an activity with its window layout affinity for the first time, + the window mode and position is OEM defined. <p>By default activity doesn't share any affinity with other activities. --> <attr name="windowLayoutAffinity" format="string" /> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 8d5129465b0e..df03ccc784d4 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3358,6 +3358,10 @@ ratio larger than this is considered to wide and short to be usable. Currently 2.39:1. --> <item name="config_pictureInPictureMaxAspectRatio" format="float" type="dimen">2.39</item> + <!-- The maximum number of actions that is supported for picture-in-picture. This number + must be no less than 3 for back compatibility. --> + <integer name="config_pictureInPictureMaxNumberOfActions">3</integer> + <!-- Controls the snap mode for the docked stack divider 0 - 3 snap targets: left/top has 16:9 ratio, 1:1, and right/bottom has 16:9 ratio 1 - 3 snap targets: fixed ratio, 1:1, (1 - fixed ratio) @@ -4469,4 +4473,10 @@ TODO: b/170470621 - remove once we can have multiple Internal displays in DMS as well as a notification from DisplayStateManager. --> <string-array name="config_internalFoldedPhysicalDisplayIds" translatable="false" /> + + <!-- Aspect ratio of task level letterboxing. Values <= 1.0 will be ignored. + Note: Activity min/max aspect ratio restrictions will still be respected by the + activity-level letterboxing (size-compat mode). Therefore this override can control the + maximum screen area that can be occupied by the app in the letterbox mode. --> + <item name="config_taskLetterboxAspectRatio" format="float" type="dimen">0.0</item> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 39989dd24a23..1e9a747d30dc 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3047,6 +3047,8 @@ <public name="rollbackDataPolicy" /> <public name="allowClickWhenDisabled" /> <public name="windowLayoutAffinity" /> + <!-- @hide --> + <public name="windowBackgroundBlurRadius"/> </public-group> <public-group type="drawable" first-id="0x010800b5"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 697f7e0e898a..a716875b068f 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -409,6 +409,7 @@ <java-symbol type="integer" name="config_defaultPictureInPictureGravity" /> <java-symbol type="dimen" name="config_pictureInPictureMinAspectRatio" /> <java-symbol type="dimen" name="config_pictureInPictureMaxAspectRatio" /> + <java-symbol type="integer" name="config_pictureInPictureMaxNumberOfActions" /> <java-symbol type="dimen" name="config_closeToSquareDisplayMaxAspectRatio" /> <java-symbol type="integer" name="config_bluetooth_max_advertisers" /> <java-symbol type="integer" name="config_bluetooth_max_scan_filters" /> @@ -4084,4 +4085,6 @@ <java-symbol type="dimen" name="controls_thumbnail_image_max_height" /> <java-symbol type="dimen" name="controls_thumbnail_image_max_width" /> + + <java-symbol type="dimen" name="config_taskLetterboxAspectRatio" /> </resources> diff --git a/core/tests/BTtraffic/Android.bp b/core/tests/BTtraffic/Android.bp deleted file mode 100644 index e508570daf03..000000000000 --- a/core/tests/BTtraffic/Android.bp +++ /dev/null @@ -1,7 +0,0 @@ -android_app { - name: "bttraffic", - srcs: ["src/**/*.java"], - resource_dirs: ["res"], - sdk_version: "current", - certificate: "platform", -} diff --git a/core/tests/BTtraffic/AndroidManifest.xml b/core/tests/BTtraffic/AndroidManifest.xml deleted file mode 100644 index 00d9707de2bf..000000000000 --- a/core/tests/BTtraffic/AndroidManifest.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.experimental.bttraffic" > - - <uses-permission android:name="android.permission.BLUETOOTH"/> - <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/> - - <uses-sdk - android:minSdkVersion="18" - android:targetSdkVersion="18" - /> - <application - android:allowBackup="false" - android:label="@string/app_name" > - <service - android:name=".BTtraffic" - android:enabled="true" - android:exported="true" > - </service> - </application> - -</manifest> diff --git a/core/tests/BTtraffic/README b/core/tests/BTtraffic/README deleted file mode 100644 index 430488f656f9..000000000000 --- a/core/tests/BTtraffic/README +++ /dev/null @@ -1,45 +0,0 @@ -This is a tool to generate classic Bluetooth traffic with specified period and package size. -Together with the SvcMonitor, which will be called automatically in this android service, can be -used to measure the CPU usage from the Java layer Bluetooth code and the underlying system service -com.android.bluetooth. - -1. Server (Listener) - Client (Sender) model. Both run as an Android service. -2. No pairing needed. Communicate via unsecured RFcomm. Client establishes the connection by -providing the MAC addr of the server. -3. Bluetooth has to be turned on on both side. -4. Client can configure the traffic by specifying the transfer period and package size. -5. A separate monitor process will be automatically forked and will be reading from /proc file -system to calculate the cpu usage. The measurement is updated once per second. -6. The monitor process (com.google.android.experimental.svcmonitor/.ScvMonitor) can be run as an -independent service to measure cpu usage on any similarly configured tests (e.g. wifi, BLE). Refer -to SvcMonitor's README for usage and details. - -Usage: -To instal the test: -On both the server and client device, install the 2 apk: -$ adb install $OUT/system/app/bttraffic/bttraffic.apk -$ adb install $OUT/system/app/svcmonitor/svcmonitor.apk - -To start the service on the SERVER side: -$ adb shell am startservice -a start --ez ack true \ -com.google.android.experimental.bttraffic/.BTtraffic - -To start the service on the CLIENT side: -$ adb shell am startservice -a start \ --e addr "F8:A9:D0:A8:74:8E" --ei size 1000 --ei period 15 \ -com.google.android.experimental.bttraffic/.BTtraffic - -To stop the test: -On either the server or client: -$ adb shell am startservice -a stop \ -com.google.android.experimental.bttraffic/.BTtraffic - -To look at the data: -$ adb logcat | grep bttraffic - -Options: --e addr: MAC addr of the server, in uppercase letter. ---ei size: package size, unit: byte; default: 1024, MAX: 20MB ---ei period: system sleep time between sending each package, unit: ms, default: 5000 - ** if -1 is provided, client will only send the package once. ---ez ack: whether acknowledge is required (true/false) diff --git a/core/tests/BTtraffic/res/values/strings.xml b/core/tests/BTtraffic/res/values/strings.xml deleted file mode 100644 index e70276e03647..000000000000 --- a/core/tests/BTtraffic/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ -<resources> - <string name="app_name">Bluetooth Test</string> -</resources> diff --git a/core/tests/BTtraffic/src/com/android/google/experimental/bttraffic/BTtraffic.java b/core/tests/BTtraffic/src/com/android/google/experimental/bttraffic/BTtraffic.java deleted file mode 100644 index 286c0aa2915f..000000000000 --- a/core/tests/BTtraffic/src/com/android/google/experimental/bttraffic/BTtraffic.java +++ /dev/null @@ -1,328 +0,0 @@ -package com.google.android.experimental.bttraffic; - -import android.app.Service; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothServerSocket; -import android.bluetooth.BluetoothSocket; -import android.content.Intent; -import android.os.Bundle; -import android.os.IBinder; -import android.os.SystemClock; -import android.util.Log; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.Exception; -import java.lang.Runtime; -import java.lang.RuntimeException; -import java.lang.Process; -import java.nio.ByteBuffer; -import java.util.Random; -import java.util.Set; -import java.util.UUID; - -public class BTtraffic extends Service { - public static final String TAG = "bttraffic"; - static final String SERVICE_NAME = "bttraffic"; - static final String SYS_SERVICE_NAME = "com.android.bluetooth"; - static final UUID SERVICE_UUID = UUID.fromString("5e8945b0-1234-5432-a5e2-0800200c9a67"); - volatile Thread mWorkerThread; - volatile boolean isShuttingDown = false; - volatile boolean isServer = false; - - public BTtraffic() {} - - static void safeClose(Closeable closeable) { - try { - closeable.close(); - } catch (IOException e) { - Log.d(TAG, "Unable to close resource.\n"); - } - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (intent == null) { - stopSelf(); - return 0; - } - if ("stop".equals(intent.getAction())) { - stopService(); - } else if ("start".equals(intent.getAction())) { - startWorker(intent); - } else { - Log.d(TAG, "unknown action: + " + intent.getAction()); - } - return 0; - } - - private void startWorker(Intent intent) { - if (mWorkerThread != null) { - Log.d(TAG, "worker thread already active"); - return; - } - isShuttingDown = false; - String remoteAddr = intent.getStringExtra("addr"); - Log.d(TAG, "startWorker: addr=" + remoteAddr); - Runnable worker = - remoteAddr == null - ? new ListenerRunnable(this, intent) - : new SenderRunnable(this, remoteAddr, intent); - isServer = remoteAddr == null ? true: false; - mWorkerThread = new Thread(worker, "BTtrafficWorker"); - try { - startMonitor(); - Log.d(TAG, "Monitor service started"); - mWorkerThread.start(); - Log.d(TAG, "Worker thread started"); - } catch (Exception e) { - Log.d(TAG, "Failed to start service", e); - } - } - - private void startMonitor() - throws Exception { - if (isServer) { - Log.d(TAG, "Start monitor on server"); - String[] startmonitorCmd = { - "/system/bin/am", - "startservice", - "-a", "start", - "-e", "java", SERVICE_NAME, - "-e", "hal", SYS_SERVICE_NAME, - "com.google.android.experimental.svcmonitor/.SvcMonitor" - }; - Process ps = new ProcessBuilder() - .command(startmonitorCmd) - .redirectErrorStream(true) - .start(); - } else { - Log.d(TAG, "No need to start SvcMonitor on client"); - } - } - - private void stopMonitor() - throws Exception { - if (isServer) { - Log.d(TAG, "StopMonitor on server"); - String[] stopmonitorCmd = { - "/system/bin/am", - "startservice", - "-a", "stop", - "com.google.android.experimental.svcmonitor/.SvcMonitor" - }; - Process ps = new ProcessBuilder() - .command(stopmonitorCmd) - .redirectErrorStream(true) - .start(); - } else { - Log.d(TAG, "No need to stop Svcmonitor on client"); - } - } - - public void stopService() { - if (mWorkerThread == null) { - Log.d(TAG, "no active thread"); - return; - } - - isShuttingDown = true; - - try { - stopMonitor(); - } catch (Exception e) { - Log.d(TAG, "Unable to stop SvcMonitor!", e); - } - - if (Thread.currentThread() != mWorkerThread) { - mWorkerThread.interrupt(); - Log.d(TAG, "Interrupting thread"); - try { - mWorkerThread.join(); - } catch (InterruptedException e) { - Log.d(TAG, "Unable to join thread!"); - } - } - - mWorkerThread = null; - stopSelf(); - Log.d(TAG, "Service stopped"); - } - - @Override - public void onDestroy() { - super.onDestroy(); - } - - @Override - public IBinder onBind(Intent intent) { - throw new UnsupportedOperationException("Not yet implemented"); - } - - public static class ListenerRunnable implements Runnable { - private final BTtraffic bttraffic; - private final boolean sendAck; - private Intent intent; - private final int maxbuffersize = 20 * 1024 * 1024; - - public ListenerRunnable(BTtraffic bttraffic, Intent intent) { - this.bttraffic = bttraffic; - this.sendAck = intent.getBooleanExtra("ack", true); - this.intent = intent; - } - - @Override - public void run() { - BluetoothServerSocket serverSocket; - - try { - Log.d(TAG, "getting server socket"); - serverSocket = BluetoothAdapter.getDefaultAdapter() - .listenUsingInsecureRfcommWithServiceRecord( - SERVICE_NAME, SERVICE_UUID); - } catch (IOException e) { - Log.d(TAG, "error creating server socket, stopping thread"); - bttraffic.stopService(); - return; - } - - Log.d(TAG, "got server socket, starting accept loop"); - BluetoothSocket socket = null; - try { - Log.d(TAG, "accepting"); - socket = serverSocket.accept(); - - if (!Thread.interrupted()) { - Log.d(TAG, "accepted, listening"); - doListening(socket.getInputStream(), socket.getOutputStream()); - Log.d(TAG, "listen finished"); - } - } catch (IOException e) { - Log.d(TAG, "error while accepting or listening", e); - } finally { - Log.d(TAG, "Linster interruped"); - Log.d(TAG, "closing socket and stopping service"); - safeClose(serverSocket); - safeClose(socket); - if (!bttraffic.isShuttingDown) - bttraffic.stopService(); - } - - } - - private void doListening(InputStream inputStream, OutputStream outputStream) - throws IOException { - ByteBuffer byteBuffer = ByteBuffer.allocate(maxbuffersize); - - while (!Thread.interrupted()) { - readBytesIntoBuffer(inputStream, byteBuffer, 4); - byteBuffer.flip(); - int length = byteBuffer.getInt(); - if (Thread.interrupted()) - break; - readBytesIntoBuffer(inputStream, byteBuffer, length); - - if (sendAck) - outputStream.write(0x55); - } - } - - void readBytesIntoBuffer(InputStream inputStream, ByteBuffer byteBuffer, int numToRead) - throws IOException { - byteBuffer.clear(); - while (true) { - int position = byteBuffer.position(); - int remaining = numToRead - position; - if (remaining == 0) { - break; - } - int count = inputStream.read(byteBuffer.array(), position, remaining); - if (count < 0) { - throw new IOException("read the EOF"); - } - byteBuffer.position(position + count); - } - } - } - - public static class SenderRunnable implements Runnable { - private final BTtraffic bttraffic; - private final String remoteAddr; - private final int pkgsize, period; - private final int defaultpkgsize = 1024; - private final int defaultperiod = 5000; - private static ByteBuffer lengthBuffer = ByteBuffer.allocate(4); - - public SenderRunnable(BTtraffic bttraffic, String remoteAddr, Intent intent) { - this.bttraffic = bttraffic; - this.remoteAddr = remoteAddr; - this.pkgsize = intent.getIntExtra("size", defaultpkgsize); - this.period = intent.getIntExtra("period", defaultperiod); - } - - @Override - public void run() { - BluetoothDevice device = null; - try { - device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(remoteAddr); - } catch (IllegalArgumentException e) { - Log.d(TAG, "Invalid BT MAC address!\n"); - } - if (device == null) { - Log.d(TAG, "can't find matching device, stopping thread and service"); - bttraffic.stopService(); - return; - } - - BluetoothSocket socket = null; - try { - Log.d(TAG, "connecting to device with MAC addr: " + remoteAddr); - socket = device.createInsecureRfcommSocketToServiceRecord(SERVICE_UUID); - socket.connect(); - Log.d(TAG, "connected, starting to send"); - doSending(socket.getOutputStream()); - Log.d(TAG, "send stopped, stopping service"); - } catch (Exception e) { - Log.d(TAG, "error while sending", e); - } finally { - Log.d(TAG, "finishing, closing thread and service"); - safeClose(socket); - if (!bttraffic.isShuttingDown) - bttraffic.stopService(); - } - } - - private void doSending(OutputStream outputStream) throws IOException { - Log.w(TAG, "doSending"); - try { - Random random = new Random(System.currentTimeMillis()); - - byte[] bytes = new byte[pkgsize]; - random.nextBytes(bytes); - while (!Thread.interrupted()) { - writeBytes(outputStream, bytes.length); - outputStream.write(bytes, 0, bytes.length); - if (period < 0) - break; - if (period == 0) - continue; - - SystemClock.sleep(period); - } - Log.d(TAG, "Sender interrupted"); - } catch (IOException e) { - Log.d(TAG, "doSending got error", e); - } - } - - private static void writeBytes(OutputStream outputStream, int value) throws IOException { - lengthBuffer.putInt(value); - lengthBuffer.flip(); - outputStream.write(lengthBuffer.array(), lengthBuffer.position(), lengthBuffer.limit()); - } - } - -} diff --git a/core/tests/SvcMonitor/Android.bp b/core/tests/SvcMonitor/Android.bp deleted file mode 100644 index 606e87cb0f4d..000000000000 --- a/core/tests/SvcMonitor/Android.bp +++ /dev/null @@ -1,7 +0,0 @@ -android_app { - name: "svcmonitor", - srcs: ["src/**/*.java"], - resource_dirs: ["res"], - sdk_version: "current", - certificate: "platform", -} diff --git a/core/tests/SvcMonitor/AndroidManifest.xml b/core/tests/SvcMonitor/AndroidManifest.xml deleted file mode 100644 index de5a9bdaed41..000000000000 --- a/core/tests/SvcMonitor/AndroidManifest.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.experimental.svcmonitor" > - - <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/> - - <uses-sdk - android:minSdkVersion="18" - android:targetSdkVersion="18" - /> - <application - android:allowBackup="false" - android:label="@string/app_name" > - <service - android:name=".SvcMonitor" - android:enabled="true" - android:exported="true" > - </service> - </application> - -</manifest> diff --git a/core/tests/SvcMonitor/README b/core/tests/SvcMonitor/README deleted file mode 100644 index 13a4380589b4..000000000000 --- a/core/tests/SvcMonitor/README +++ /dev/null @@ -1,27 +0,0 @@ -This Android service measures CPU usage of a program and an underlying system service it relies on. -An example of this would be an android app XYZ communicates to some other device via Bluetooth. The -SvcMonitor service can monitor the CPU usage of XYZ and com.android.bluetooth. - -Usage: - -To start the service: -$ adb shell am startservice -a start \ --e java XYZ -e hal com.android.bluetooth \ -com.google.android.experimental.svcmonitor/.SvcMonitor - -To stop the service: -$ adb shell am startservice -a stop \ -com.google.android.experimental.svcmonitor/.SvcMonitor - -To stop the service config: -$ adb shell am startservice -a change \ --e java NewName -e hal NewService \ -com.google.android.experimental.svcmonitor/.SvcMonitor - -To monitor the data: -$ adb logcat | grep XYZ - -Options: --e java NameOfProgram: any running process’s name. --e hal NameOfSysService: name of the system service the previous process relies on. ---ei period: period between each measurement (frequency). Unit: ms, Default:1000, Min: 100 diff --git a/core/tests/SvcMonitor/res/values/strings.xml b/core/tests/SvcMonitor/res/values/strings.xml deleted file mode 100644 index e70276e03647..000000000000 --- a/core/tests/SvcMonitor/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ -<resources> - <string name="app_name">Bluetooth Test</string> -</resources> diff --git a/core/tests/SvcMonitor/src/com/android/google/experimental/svcmoniter/SvcMonitor.java b/core/tests/SvcMonitor/src/com/android/google/experimental/svcmoniter/SvcMonitor.java deleted file mode 100644 index a451445530cd..000000000000 --- a/core/tests/SvcMonitor/src/com/android/google/experimental/svcmoniter/SvcMonitor.java +++ /dev/null @@ -1,209 +0,0 @@ -package com.google.android.experimental.svcmonitor; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; -import android.os.SystemClock; -import android.util.Log; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.lang.Runnable; -import java.lang.Thread; -import java.util.Set; - -public class SvcMonitor extends Service { - public static final String TAG = "svcmonitor"; - String javaProc, halProc; - volatile Thread tMonitor; - int period; - - public SvcMonitor() {}; - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (intent == null) { - stopSelf(); - return 0; - } - Log.d(TAG, "Starting SvcMonitor"); - if ("stop".equals(intent.getAction())) { - stopService(); - } else if ("start".equals(intent.getAction())) { - startMonitor(intent); - } else if ("change".equals(intent.getAction())) { - changeConfig(intent); - } else { - Log.d(TAG, "unknown action: + " + intent.getAction()); - } - return 0; - } - - private void changeConfig(Intent intent) { - if (tMonitor == null) { - Log.d(TAG, "Service not active. Start service first"); - return; - } - stopThread(); - startMonitor(intent); - } - - private void startMonitor(Intent intent) { - if (tMonitor != null) { - Log.d(TAG, "thread already active"); - return; - } - javaProc = intent.getStringExtra("java"); - halProc = intent.getStringExtra("hal"); - period = intent.getIntExtra("period", 1000); - if (javaProc == null || halProc == null || period < 100) { - Log.d(TAG, "Failed starting monitor, invalid arguments."); - stopSelf(); - return; - } - Runnable monitor = new MonitorRunnable(this); - tMonitor = new Thread(monitor); - tMonitor.start(); - } - - private void stopService() { - stopThread(); - stopSelf(); - Log.d(TAG, "SvcMonitor stopped"); - } - - private void stopThread() { - if (tMonitor == null) { - Log.d(TAG, "no active thread"); - return; - } - Log.d(TAG, "interrupting monitor thread"); - tMonitor.interrupt(); - try { - tMonitor.join(); - } catch (InterruptedException e) { - Log.d(TAG, "Unable to finish monitor thread"); - } - tMonitor = null; - } - - @Override - public void onDestroy() { - super.onDestroy(); - } - - @Override - public IBinder onBind(Intent intent) { - throw new UnsupportedOperationException("Not yet implemented"); - } - - public static class MonitorRunnable implements Runnable { - long java_time_old, hal_time_old, cpu_time_old = -1; - String javaPID, halPID; - SvcMonitor svcmonitor; - static String javaProcTAG; - int period; - - public MonitorRunnable(SvcMonitor svcmonitor) { - this.svcmonitor = svcmonitor; - this.period = svcmonitor.period; - javaPID = getPIDof(svcmonitor.javaProc); - halPID = getPIDof(svcmonitor.halProc); - java_time_old = getPsTime(javaPID); - hal_time_old = getPsTime(halPID); - cpu_time_old = getPsTime(""); - javaProcTAG = String.valueOf(svcmonitor.javaProc.toCharArray()); - } - - @Override - public void run() { - if (halPID.isEmpty() || javaPID.isEmpty()) { - Log.d(javaProcTAG, "No such process: " + - (halPID.isEmpty() ? svcmonitor.halProc : svcmonitor.javaProc)); - return; - } - while (!Thread.interrupted()) { - calculateUsage(); - SystemClock.sleep(period); - } - Log.d(TAG, "Stopping monitor thread"); - } - - private void calculateUsage() { - long java_time = getPsTime(javaPID); - long hal_time = getPsTime(halPID); - long cpu_time = getPsTime(""); - - if (cpu_time_old >= 0) { - float java_diff = (float) (java_time - java_time_old); - float hal_diff = (float) (hal_time - hal_time_old); - float cpu_diff = (float) (cpu_time - cpu_time_old); - Log.w(javaProcTAG, "\n----------------\n"); - Log.w(javaProcTAG, "JAVA level CPU: " - + (java_diff * 100.0 / cpu_diff) + "%\n"); - Log.w(javaProcTAG, " HAL level CPU: " - + (hal_diff * 100.0 / cpu_diff) + "%\n"); - Log.w(javaProcTAG, " SYS level CPU: " - + ((java_diff + hal_diff) * 100.0 / cpu_diff) + "%\n"); - } else { - Log.w(TAG, "Waiting for status\n"); - } - - java_time_old = java_time; - hal_time_old = hal_time; - cpu_time_old = cpu_time; - } - - private String getPIDof(String psName) { - String pid = ""; - - try { - String[] cmd = {"/system/bin/sh", "-c", "ps | grep " + psName}; - Process ps = Runtime.getRuntime().exec(cmd); - BufferedReader in = new BufferedReader( - new InputStreamReader(ps.getInputStream())); - String temp = in.readLine(); - if (temp == null || temp.isEmpty()) - throw new IOException("No such process: " + psName); - pid = temp.split(" +")[1]; - in.close(); - } catch (IOException e) { - Log.d(javaProcTAG, "Error finding PID of process: " + psName + "\n", e); - } - return pid; - } - - private long getPsTime(String pid) { - String psStat = getPsStat("/" + pid); - String[] statBreakDown = psStat.split(" +"); - long psTime; - - if (pid.isEmpty()) { - psTime = Long.parseLong(statBreakDown[1]) - + Long.parseLong(statBreakDown[2]) - + Long.parseLong(statBreakDown[3]) - + Long.parseLong(statBreakDown[4]); - } else { - psTime = Long.parseLong(statBreakDown[13]) - + Long.parseLong(statBreakDown[14]); - } - - return psTime; - } - - private String getPsStat(String psname) { - String stat = ""; - try { - FileInputStream fs = new FileInputStream("/proc" + psname + "/stat"); - BufferedReader br = new BufferedReader(new InputStreamReader(fs)); - stat = br.readLine(); - fs.close(); - } catch (IOException e) { - Log.d(TAG, "Error retreiving stat. \n"); - } - return stat; - } - } -} diff --git a/core/tests/coretests/src/android/content/ContentResolverTest.java b/core/tests/coretests/src/android/content/ContentResolverTest.java index f48e66681cc7..b517428f5b59 100644 --- a/core/tests/coretests/src/android/content/ContentResolverTest.java +++ b/core/tests/coretests/src/android/content/ContentResolverTest.java @@ -261,4 +261,12 @@ public class ContentResolverTest { // Expected } } + + @Test + public void testUncanonicalize() { + Uri uncanonical = mResolver.uncanonicalize( + Uri.parse("content://android.content.FakeProviderRemote/something")); + assertThat(uncanonical).isEqualTo( + Uri.parse("content://android.content.FakeProviderRemote/uncanonical")); + } } diff --git a/core/tests/coretests/src/android/content/FakeProviderRemote.java b/core/tests/coretests/src/android/content/FakeProviderRemote.java index 2c92da34d9a4..d0bb78101ee4 100644 --- a/core/tests/coretests/src/android/content/FakeProviderRemote.java +++ b/core/tests/coretests/src/android/content/FakeProviderRemote.java @@ -66,4 +66,13 @@ public class FakeProviderRemote extends ContentProvider { return new Uri.Builder().scheme(uri.getScheme()).authority(uri.getAuthority()) .appendPath("canonical").build(); } + + @Override + public Uri uncanonicalize(Uri uri) { + if (uri.getPath() != null && uri.getPath().contains("error")) { + throw new IllegalArgumentException("Expected exception"); + } + return new Uri.Builder().scheme(uri.getScheme()).authority(uri.getAuthority()) + .appendPath("uncanonical").build(); + } } diff --git a/core/tests/coretests/src/android/widget/TextViewOnReceiveContentCallbackTest.java b/core/tests/coretests/src/android/widget/TextViewOnReceiveContentCallbackTest.java index 5112326ea0b6..ef659af6c570 100644 --- a/core/tests/coretests/src/android/widget/TextViewOnReceiveContentCallbackTest.java +++ b/core/tests/coretests/src/android/widget/TextViewOnReceiveContentCallbackTest.java @@ -66,8 +66,8 @@ import org.mockito.Mockito; * {@link android.widget.cts.TextViewOnReceiveContentCallbackTest}. This class tests some internal * implementation details, e.g. fallback to the keyboard image API. */ -@RunWith(AndroidJUnit4.class) @MediumTest +@RunWith(AndroidJUnit4.class) public class TextViewOnReceiveContentCallbackTest { private static final Uri SAMPLE_CONTENT_URI = Uri.parse("content://com.example/path"); @@ -101,7 +101,7 @@ public class TextViewOnReceiveContentCallbackTest { // Assert that the callback returns the MIME types declared in the EditorInfo in addition to // the default. - assertThat(mDefaultCallback.getSupportedMimeTypes(mEditText)).containsExactly( + assertThat(mDefaultCallback.getMimeTypes(mEditText)).containsExactly( "text/*", "image/gif", "image/png"); } @@ -118,7 +118,7 @@ public class TextViewOnReceiveContentCallbackTest { onView(withId(mEditText.getId())).perform(clickOnTextAtIndex(0)); // Assert that the callback returns the default MIME types. - assertThat(mDefaultCallback.getSupportedMimeTypes(mEditText)).containsExactly("text/*"); + assertThat(mDefaultCallback.getMimeTypes(mEditText)).containsExactly("text/*"); } @Test diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index a430dcdda247..e51bf5e4e1f6 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -2923,6 +2923,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/TaskDisplayArea.java" }, + "1396893178": { + "message": "createRootTask unknown displayId=%d", + "level": "ERROR", + "group": "WM_DEBUG_WINDOW_ORGANIZER", + "at": "com\/android\/server\/wm\/TaskOrganizerController.java" + }, "1401295262": { "message": "Mode default, asking user", "level": "WARN", diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 4f95a53e0ec8..055e5ad17def 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -80,7 +80,7 @@ public final class Bitmap implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769491) private byte[] mNinePatchChunk; // may be null - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private NinePatch.InsetStruct mNinePatchInsets; // may be null @UnsupportedAppUsage private int mWidth; @@ -176,7 +176,7 @@ public final class Bitmap implements Parcelable { * width/height values */ @SuppressWarnings("unused") // called from JNI - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void reinit(int width, int height, boolean requestPremultiplied) { mWidth = width; mHeight = height; diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index bad487b47682..ef1e7bfc6651 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -23,6 +23,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.content.res.Resources; +import android.os.Build; import android.os.Trace; import android.util.DisplayMetrics; import android.util.Log; @@ -875,7 +876,7 @@ public class BitmapFactory { @UnsupportedAppUsage private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd, Rect padding, Options opts, long inBitmapHandle, long colorSpaceHandle); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native Bitmap nativeDecodeAsset(long nativeAsset, Rect padding, Options opts, long inBitmapHandle, long colorSpaceHandle); @UnsupportedAppUsage diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 829d0f4be513..42e6ab9c830c 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1355,7 +1355,7 @@ public class Canvas extends BaseCanvas { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void release() { mNativeCanvasWrapper = 0; if (mFinalizer != null) { @@ -1379,7 +1379,7 @@ public class Canvas extends BaseCanvas { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void freeTextLayoutCaches() { nFreeTextLayoutCaches(); } diff --git a/graphics/java/android/graphics/CanvasProperty.java b/graphics/java/android/graphics/CanvasProperty.java index 4263772c1c2c..e949584b0659 100644 --- a/graphics/java/android/graphics/CanvasProperty.java +++ b/graphics/java/android/graphics/CanvasProperty.java @@ -17,6 +17,7 @@ package android.graphics; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import com.android.internal.util.VirtualRefBasePtr; @@ -28,12 +29,12 @@ public final class CanvasProperty<T> { private VirtualRefBasePtr mProperty; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static CanvasProperty<Float> createFloat(float initialValue) { return new CanvasProperty<Float>(nCreateFloat(initialValue)); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static CanvasProperty<Paint> createPaint(Paint initialValue) { return new CanvasProperty<Paint>(nCreatePaint(initialValue.getNativeInstance())); } diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java index a8b18a9fcb1f..90ff1899f34d 100644 --- a/graphics/java/android/graphics/ColorMatrixColorFilter.java +++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java @@ -19,6 +19,7 @@ package android.graphics; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * A color filter that transforms colors through a 4x5 color matrix. This filter @@ -107,7 +108,7 @@ public class ColorMatrixColorFilter extends ColorFilter { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setColorMatrixArray(@Nullable float[] array) { // called '...Array' so that passing null isn't ambiguous discardNativeInstance(); diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java index c146bbd4441b..0782f8dfd9d3 100644 --- a/graphics/java/android/graphics/FontListParser.java +++ b/graphics/java/android/graphics/FontListParser.java @@ -18,6 +18,7 @@ package android.graphics; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.fonts.FontVariationAxis; +import android.os.Build; import android.text.FontConfig; import android.util.Xml; @@ -38,7 +39,7 @@ import java.util.regex.Pattern; public class FontListParser { /* Parse fallback list (no names) */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException { return parse(in, "/system/fonts"); } diff --git a/graphics/java/android/graphics/GraphicBuffer.java b/graphics/java/android/graphics/GraphicBuffer.java index 2c25f4546771..f9113a21405c 100644 --- a/graphics/java/android/graphics/GraphicBuffer.java +++ b/graphics/java/android/graphics/GraphicBuffer.java @@ -18,6 +18,7 @@ package android.graphics; import android.compat.annotation.UnsupportedAppUsage; import android.hardware.HardwareBuffer; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -55,7 +56,7 @@ public class GraphicBuffer implements Parcelable { private final int mFormat; private final int mUsage; // Note: do not rename, this field is used by native code - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final long mNativeObject; // These two fields are only used by lock/unlockCanvas() @@ -87,7 +88,7 @@ public class GraphicBuffer implements Parcelable { /** * Private use only. See {@link #create(int, int, int, int)}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private GraphicBuffer(int width, int height, int format, int usage, long nativeObject) { mWidth = width; mHeight = height; diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java index 221dfa192795..df91c5d492bd 100644 --- a/graphics/java/android/graphics/LightingColorFilter.java +++ b/graphics/java/android/graphics/LightingColorFilter.java @@ -23,6 +23,7 @@ package android.graphics; import android.annotation.ColorInt; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * A color filter that can be used to simulate simple lighting effects. @@ -73,7 +74,7 @@ public class LightingColorFilter extends ColorFilter { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setColorMultiply(@ColorInt int mul) { if (mMul != mul) { mMul = mul; @@ -99,7 +100,7 @@ public class LightingColorFilter extends ColorFilter { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setColorAdd(@ColorInt int add) { if (mAdd != add) { mAdd = add; diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java index ebe34cad0654..4eedbf563865 100644 --- a/graphics/java/android/graphics/LinearGradient.java +++ b/graphics/java/android/graphics/LinearGradient.java @@ -21,20 +21,21 @@ import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; public class LinearGradient extends Shader { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mX0; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mY0; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mX1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mY1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float[] mPositions; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private TileMode mTileMode; // @ColorInts are replaced by @ColorLongs, but these remain due to @UnsupportedAppUsage. @@ -44,7 +45,7 @@ public class LinearGradient extends Shader { @UnsupportedAppUsage @ColorInt private int mColor0; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @ColorInt private int mColor1; diff --git a/graphics/java/android/graphics/Movie.java b/graphics/java/android/graphics/Movie.java index 4b3924f0d55f..9c9535d16aab 100644 --- a/graphics/java/android/graphics/Movie.java +++ b/graphics/java/android/graphics/Movie.java @@ -28,7 +28,7 @@ import java.io.InputStream; */ @Deprecated public class Movie { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeMovie; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index a191fe56b31d..4b6e4d124b48 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -53,7 +53,7 @@ import java.util.Locale; */ public class Paint { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativePaint; private long mNativeShader; private long mNativeColorFilter; diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java index 7811671b80d6..e5ef10d1d555 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; @@ -48,12 +49,12 @@ public class Path { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isSimplePath = true; /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Region rects; private Direction mLastDirection = null; diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java index 50ecb62e7fcc..0700f217ecf0 100644 --- a/graphics/java/android/graphics/PorterDuffColorFilter.java +++ b/graphics/java/android/graphics/PorterDuffColorFilter.java @@ -19,6 +19,7 @@ package android.graphics; import android.annotation.ColorInt; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * A color filter that can be used to tint the source pixels using a single @@ -64,7 +65,7 @@ public class PorterDuffColorFilter extends ColorFilter { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PorterDuff.Mode getMode() { return mMode; } diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java index 864331a9674e..dd1be1570d79 100644 --- a/graphics/java/android/graphics/RadialGradient.java +++ b/graphics/java/android/graphics/RadialGradient.java @@ -22,17 +22,18 @@ import android.annotation.FloatRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; public class RadialGradient extends Shader { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mX; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mY; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mRadius; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float[] mPositions; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private TileMode mTileMode; private final float mFocalX; @@ -40,13 +41,13 @@ public class RadialGradient extends Shader { private final float mFocalRadius; // @ColorInts are replaced by @ColorLongs, but these remain due to @UnsupportedAppUsage. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @ColorInt private int[] mColors; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @ColorInt private int mCenterColor; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @ColorInt private int mEdgeColor; diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java index 43373ffbd3f4..29708738d2db 100644 --- a/graphics/java/android/graphics/Region.java +++ b/graphics/java/android/graphics/Region.java @@ -18,6 +18,7 @@ package android.graphics; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.Pools.SynchronizedPool; @@ -32,7 +33,7 @@ public class Region implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long mNativeRegion; // the native values for these must match up with the enum in SkRegion.h @@ -337,7 +338,7 @@ public class Region implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void recycle() { setEmpty(); sPool.release(this); @@ -411,7 +412,7 @@ public class Region implements Parcelable { /* Add an unused parameter so constructor can be called from jni without triggering 'not cloneable' exception */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Region(long ni, int unused) { this(ni); } diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index 228d03a1dd10..7a2e5843ffc7 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -18,6 +18,7 @@ package android.graphics; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -69,17 +70,17 @@ import java.lang.ref.WeakReference; */ public class SurfaceTexture { private final Looper mCreatorLooper; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Handler mOnFrameAvailableHandler; /** * These fields are used by native code, do not access or modify. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mSurfaceTexture; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mProducer; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mFrameAvailableListener; private boolean mIsSingleBuffered; @@ -390,7 +391,7 @@ public class SurfaceTexture { * This method is invoked from native code only. */ @SuppressWarnings({"UnusedDeclaration"}) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void postEventFromNative(WeakReference<SurfaceTexture> weakSelf) { SurfaceTexture st = weakSelf.get(); if (st != null) { diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java index f1ca1986bfa0..22807805e7fa 100644 --- a/graphics/java/android/graphics/SweepGradient.java +++ b/graphics/java/android/graphics/SweepGradient.java @@ -21,23 +21,24 @@ import android.annotation.ColorLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; public class SweepGradient extends Shader { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mCx; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mCy; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float[] mPositions; // @ColorInts are replaced by @ColorLongs, but these remain due to @UnsupportedAppUsage. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @ColorInt private int[] mColors; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @ColorInt private int mColor0; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @ColorInt private int mColor1; diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index ecb0ff43a9e2..b143be7b4d6a 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -1217,7 +1217,7 @@ public class Typeface { long native_instance, List<FontVariationAxis> axes); @UnsupportedAppUsage private static native long nativeCreateWeightAlias(long native_instance, int weight); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native long nativeCreateFromArray(long[] familyArray, int weight, int italic); private static native int[] nativeGetSupportedAxes(long native_instance); diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java index e79fb76d806e..81769e2e21bf 100644 --- a/graphics/java/android/graphics/Xfermode.java +++ b/graphics/java/android/graphics/Xfermode.java @@ -22,6 +22,7 @@ package android.graphics; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * Xfermode is the base class for objects that are called to implement custom @@ -32,6 +33,6 @@ import android.compat.annotation.UnsupportedAppUsage; */ public class Xfermode { static final int DEFAULT = PorterDuff.Mode.SRC_OVER.nativeInt; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int porterDuffMode = DEFAULT; } diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java index 06159d8a0558..33a6d38b698d 100644 --- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java @@ -561,9 +561,9 @@ public class AnimatedStateListDrawable extends StateListDrawable { int[] mAnimThemeAttrs; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) LongSparseLongArray mTransitions; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) SparseIntArray mStateIds; AnimatedStateListState(@Nullable AnimatedStateListState orig, diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 73dbe65bd25b..33b09b8831ce 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -315,7 +315,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { */ private Resources mRes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private AnimatedVectorDrawableState mAnimatedVectorState; /** The animator set that is parsed from the xml. */ @@ -1773,7 +1773,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { } // onFinished: should be called from native - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void callOnFinished(VectorDrawableAnimatorRT set, int id) { set.mHandler.post(() -> set.onAnimationEnd(id)); } diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index 2457ab85144f..f8dc61526ce6 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -34,6 +34,7 @@ import android.graphics.Outline; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Xfermode; +import android.os.Build; import android.util.AttributeSet; import android.view.ViewDebug; @@ -53,7 +54,7 @@ import java.io.IOException; * @attr ref android.R.styleable#ColorDrawable_color */ public class ColorDrawable extends Drawable { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); @ViewDebug.ExportedProperty(deepExport = true, prefix = "state_") diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index ed210ab40b7a..28b3b04b827d 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -45,6 +45,7 @@ import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Xfermode; +import android.os.Build; import android.os.Trace; import android.util.AttributeSet; import android.util.DisplayMetrics; @@ -1715,7 +1716,7 @@ public abstract class Drawable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static BlendMode parseBlendMode(int value, BlendMode defaultMode) { switch (value) { case 3: return BlendMode.SRC_OVER; diff --git a/graphics/java/android/graphics/drawable/DrawableInflater.java b/graphics/java/android/graphics/drawable/DrawableInflater.java index 3408b64e7536..66752a2536d3 100644 --- a/graphics/java/android/graphics/drawable/DrawableInflater.java +++ b/graphics/java/android/graphics/drawable/DrawableInflater.java @@ -23,6 +23,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.Resources.Theme; +import android.os.Build; import android.util.AttributeSet; import android.view.InflateException; @@ -50,7 +51,7 @@ public final class DrawableInflater { new HashMap<>(); private final Resources mRes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final ClassLoader mClassLoader; /** diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java index 98c38214adab..ebde75775e84 100644 --- a/graphics/java/android/graphics/drawable/DrawableWrapper.java +++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java @@ -32,6 +32,7 @@ import android.graphics.Outline; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Xfermode; +import android.os.Build; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.View; @@ -47,7 +48,7 @@ import java.io.IOException; * Drawable container with only one child element. */ public abstract class DrawableWrapper extends Drawable implements Drawable.Callback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private DrawableWrapperState mState; private Drawable mDrawable; private boolean mMutated; diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index abf0e8a1fe89..32b310353b6c 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -170,7 +170,7 @@ public final class Icon implements Parcelable { * @return The length of the compressed bitmap byte array held by this {@link #TYPE_DATA} Icon. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getDataLength() { if (mType != TYPE_DATA) { throw new IllegalStateException("called getDataLength() on " + this); @@ -599,7 +599,7 @@ public final class Icon implements Parcelable { * Version of createWithResource that takes Resources. Do not use. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static Icon createWithResource(Resources res, @DrawableRes int resId) { if (res == null) { throw new IllegalArgumentException("Resource must not be null."); @@ -771,7 +771,7 @@ public final class Icon implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean hasTint() { return (mTintList != null) || (mBlendMode != DEFAULT_BLEND_MODE); } diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java index 005a4d175fd5..87c0a061c9f2 100644 --- a/graphics/java/android/graphics/drawable/InsetDrawable.java +++ b/graphics/java/android/graphics/drawable/InsetDrawable.java @@ -27,6 +27,7 @@ import android.graphics.Insets; import android.graphics.Outline; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.os.Build; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.TypedValue; @@ -58,7 +59,7 @@ public class InsetDrawable extends DrawableWrapper { private final Rect mTmpRect = new Rect(); private final Rect mTmpInsetRect = new Rect(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private InsetState mState; /** diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 19f29aed203f..a03f8b566ddd 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -30,6 +30,7 @@ import android.graphics.ColorFilter; import android.graphics.Outline; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.os.Build; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.LayoutDirection; @@ -434,7 +435,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { * @param layer The layer to add. * @return The index of the layer. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int addLayer(@NonNull ChildDrawable layer) { final LayerState st = mLayerState; final int N = st.mChildren != null ? st.mChildren.length : 0; diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 16ffd132a41b..8677fb1b7c1e 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -36,6 +36,7 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.Shader; +import android.os.Build; import android.util.AttributeSet; import com.android.internal.R; @@ -121,7 +122,7 @@ public class RippleDrawable extends LayerDrawable { private final Rect mDirtyBounds = new Rect(); /** Mirrors mLayerState with some extra information. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private RippleState mState; /** The masking layer, e.g. the layer with id R.id.mask. */ @@ -159,7 +160,7 @@ public class RippleDrawable extends LayerDrawable { private Paint mRipplePaint; /** Target density of the display into which ripples are drawn. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mDensity; /** Whether bounds are being overridden. */ @@ -979,7 +980,7 @@ public class RippleDrawable extends LayerDrawable { static class RippleState extends LayerState { int[] mTouchThemeAttrs; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) ColorStateList mColor = ColorStateList.valueOf(Color.MAGENTA); int mMaxRadius = RADIUS_AUTO; diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java index af7eed4b3897..7e246e552bec 100644 --- a/graphics/java/android/graphics/drawable/ScaleDrawable.java +++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java @@ -25,6 +25,7 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.os.Build; import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; @@ -67,7 +68,7 @@ public class ScaleDrawable extends DrawableWrapper { private final Rect mTmpRect = new Rect(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private ScaleState mState; ScaleDrawable() { diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java index 88cd4625394b..af69029da9d7 100644 --- a/graphics/java/android/graphics/drawable/StateListDrawable.java +++ b/graphics/java/android/graphics/drawable/StateListDrawable.java @@ -22,6 +22,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; +import android.os.Build; import android.util.AttributeSet; import android.util.StateSet; @@ -130,7 +131,7 @@ public class StateListDrawable extends DrawableContainer { /** * Updates the constant state from the values in the typed array. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void updateStateFromTypedArray(TypedArray a) { final StateListState state = mStateListState; @@ -208,7 +209,7 @@ public class StateListDrawable extends DrawableContainer { * @param attrs The attribute set. * @return An array of state_ attributes. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int[] extractStateSet(AttributeSet attrs) { int j = 0; final int numAttrs = attrs.getAttributeCount(); diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index a1ccc7b7b5e4..6dcc251c2ddc 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -34,6 +34,7 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.Shader; +import android.os.Build; import android.os.Trace; import android.util.ArrayMap; import android.util.AttributeSet; @@ -324,7 +325,7 @@ public class VectorDrawable extends Drawable { private VectorDrawableState mVectorState; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private PorterDuffColorFilter mTintFilter; private BlendModeColorFilter mBlendModeColorFilter; diff --git a/graphics/java/android/graphics/fonts/FontVariationAxis.java b/graphics/java/android/graphics/fonts/FontVariationAxis.java index 4e6580ea5f53..7bd581723d18 100644 --- a/graphics/java/android/graphics/fonts/FontVariationAxis.java +++ b/graphics/java/android/graphics/fonts/FontVariationAxis.java @@ -33,7 +33,7 @@ public final class FontVariationAxis { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final int mTag; private final String mTagString; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final float mStyleValue; /** diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java index 43de4699381f..4666963b5dd4 100644 --- a/graphics/java/android/graphics/pdf/PdfRenderer.java +++ b/graphics/java/android/graphics/pdf/PdfRenderer.java @@ -25,6 +25,7 @@ import android.graphics.Bitmap.Config; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; +import android.os.Build; import android.os.ParcelFileDescriptor; import android.system.ErrnoException; import android.system.Os; @@ -121,7 +122,7 @@ public final class PdfRenderer implements AutoCloseable { private ParcelFileDescriptor mInput; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Page mCurrentPage; /** @hide */ @@ -246,7 +247,7 @@ public final class PdfRenderer implements AutoCloseable { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void doClose() { if (mCurrentPage != null) { mCurrentPage.close(); diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java index f53a7dc922f0..8f5982cd4528 100644 --- a/keystore/java/android/security/Credentials.java +++ b/keystore/java/android/security/Credentials.java @@ -17,6 +17,7 @@ package android.security; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import com.android.org.bouncycastle.util.io.pem.PemObject; import com.android.org.bouncycastle.util.io.pem.PemReader; @@ -137,7 +138,7 @@ public class Credentials { * Convert objects to a PEM format which is used for * CA_CERTIFICATE and USER_CERTIFICATE entries. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static byte[] convertToPem(Certificate... objects) throws IOException, CertificateEncodingException { ByteArrayOutputStream bao = new ByteArrayOutputStream(); diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 88b614dc7eef..c70c986fcd6b 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -71,7 +71,7 @@ public class KeyStore { private static final String TAG = "KeyStore"; // ResponseCodes - see system/security/keystore/include/keystore/keystore.h - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int NO_ERROR = 1; public static final int LOCKED = 2; public static final int UNINITIALIZED = 3; @@ -191,7 +191,7 @@ public class KeyStore { return mToken; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public State state(int userId) { final int ret; try { @@ -222,7 +222,7 @@ public class KeyStore { return get(key, uid, false); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public byte[] get(String key) { return get(key, UID_SELF); } @@ -282,7 +282,7 @@ public class KeyStore { return ret == NO_ERROR || ret == KEY_NOT_FOUND; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean delete(String key) { return delete(key, UID_SELF); } @@ -319,7 +319,7 @@ public class KeyStore { * List uids of all keys that are auth bound to the current user. * Only system is allowed to call this method. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int[] listUidsOfAuthBoundKeys() { // uids are returned as a list of strings because list of integers // as an output parameter is not supported by aidl-cpp. @@ -386,7 +386,7 @@ public class KeyStore { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean unlock(String password) { return unlock(UserHandle.getUserId(Process.myUid()), password); } @@ -1262,7 +1262,7 @@ public class KeyStore { * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error * code. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static KeyStoreException getKeyStoreException(int errorCode) { if (errorCode > 0) { // KeyStore layer error diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_controls.xml b/libs/WindowManager/Shell/res/layout/tv_pip_controls.xml index d2f235e273d5..9157f63ce1b3 100644 --- a/libs/WindowManager/Shell/res/layout/tv_pip_controls.xml +++ b/libs/WindowManager/Shell/res/layout/tv_pip_controls.xml @@ -16,7 +16,6 @@ --> <!-- Layout for {@link com.android.wm.shell.pip.tv.PipControlsView}. --> <merge xmlns:android="http://schemas.android.com/apk/res/android"> - <com.android.wm.shell.pip.tv.PipControlButtonView android:id="@+id/full_button" android:layout_width="@dimen/picture_in_picture_button_width" @@ -31,13 +30,4 @@ android:layout_marginStart="@dimen/picture_in_picture_button_start_margin" android:src="@drawable/pip_ic_close_white" android:text="@string/pip_close" /> - - <com.android.wm.shell.pip.tv.PipControlButtonView - android:id="@+id/play_pause_button" - android:layout_width="@dimen/picture_in_picture_button_width" - android:layout_height="wrap_content" - android:layout_marginStart="@dimen/picture_in_picture_button_start_margin" - android:src="@drawable/pip_ic_pause_white" - android:text="@string/pip_pause" - android:visibility="gone" /> </merge> diff --git a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json index f8db4477d87a..bee9f4163b04 100644 --- a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json +++ b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json @@ -37,6 +37,18 @@ "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, + "-1325223370": { + "message": "Task appeared taskId=%d listener=%s", + "level": "VERBOSE", + "group": "WM_SHELL_TASK_ORG", + "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" + }, + "-1312360667": { + "message": "createRootTask() displayId=%d winMode=%d listener=%s", + "level": "VERBOSE", + "group": "WM_SHELL_TASK_ORG", + "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" + }, "-1006733970": { "message": "Display added: %d", "level": "VERBOSE", @@ -55,6 +67,18 @@ "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, + "-848099324": { + "message": "Letterbox Task Appeared: #%d", + "level": "VERBOSE", + "group": "WM_SHELL_TASK_ORG", + "at": "com\/android\/wm\/shell\/LetterboxTaskListener.java" + }, + "-842742255": { + "message": "%s onTaskAppeared unknown taskId=%d winMode=%d", + "level": "VERBOSE", + "group": "WM_SHELL_TASK_ORG", + "at": "com\/android\/wm\/shell\/splitscreen\/SplitScreenTaskListener.java" + }, "-712674749": { "message": "Clip description: %s", "level": "VERBOSE", @@ -67,11 +91,11 @@ "group": "WM_SHELL_DRAG_AND_DROP", "at": "com\/android\/wm\/shell\/draganddrop\/DragLayout.java" }, - "-460572385": { - "message": "Task appeared taskId=%d", + "-679492476": { + "message": "%s onTaskAppeared Primary taskId=%d", "level": "VERBOSE", "group": "WM_SHELL_TASK_ORG", - "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" + "at": "com\/android\/wm\/shell\/splitscreen\/SplitScreenTaskListener.java" }, "-191422040": { "message": "Transition animations finished, notifying core %s", @@ -79,6 +103,12 @@ "group": "WM_SHELL_TRANSITIONS", "at": "com\/android\/wm\/shell\/Transitions.java" }, + "154313206": { + "message": "%s onTaskAppeared Secondary taskId=%d", + "level": "VERBOSE", + "group": "WM_SHELL_TASK_ORG", + "at": "com\/android\/wm\/shell\/splitscreen\/SplitScreenTaskListener.java" + }, "157713005": { "message": "Task info changed taskId=%d", "level": "VERBOSE", @@ -115,18 +145,36 @@ "group": "WM_SHELL_TASK_ORG", "at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java" }, + "1104702476": { + "message": "Letterbox Task Changed: #%d", + "level": "VERBOSE", + "group": "WM_SHELL_TASK_ORG", + "at": "com\/android\/wm\/shell\/LetterboxTaskListener.java" + }, "1184615936": { "message": "Set drop target window visibility: displayId=%d visibility=%d", "level": "VERBOSE", "group": "WM_SHELL_DRAG_AND_DROP", "at": "com\/android\/wm\/shell\/draganddrop\/DragAndDropController.java" }, + "1218010718": { + "message": "Letterbox Task Vanished: #%d", + "level": "VERBOSE", + "group": "WM_SHELL_TASK_ORG", + "at": "com\/android\/wm\/shell\/LetterboxTaskListener.java" + }, "1481772149": { "message": "Current target: %s", "level": "VERBOSE", "group": "WM_SHELL_DRAG_AND_DROP", "at": "com\/android\/wm\/shell\/draganddrop\/DragLayout.java" }, + "1842752748": { + "message": "Clip description: handlingDrag=%b mimeTypes=%s", + "level": "VERBOSE", + "group": "WM_SHELL_DRAG_AND_DROP", + "at": "com\/android\/wm\/shell\/draganddrop\/DragAndDropController.java" + }, "1862198614": { "message": "Drag event: action=%s x=%f y=%f xOffset=%f yOffset=%f", "level": "VERBOSE", @@ -144,6 +192,12 @@ "level": "VERBOSE", "group": "WM_SHELL_DRAG_AND_DROP", "at": "com\/android\/wm\/shell\/draganddrop\/DragAndDropController.java" + }, + "2135461748": { + "message": "%s onTaskAppeared Supported", + "level": "VERBOSE", + "group": "WM_SHELL_TASK_ORG", + "at": "com\/android\/wm\/shell\/splitscreen\/SplitScreenTaskListener.java" } }, "groups": { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java index 5bd693a9311e..fc0a76e8d286 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java @@ -20,9 +20,7 @@ import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCR import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString; import android.app.ActivityManager; -import android.content.res.Configuration; -import android.graphics.Rect; -import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Slog; import android.view.SurfaceControl; @@ -39,7 +37,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { private final SyncTransactionQueue mSyncQueue; - private final ArrayMap<Integer, SurfaceControl> mTasks = new ArrayMap<>(); + private final ArraySet<Integer> mTasks = new ArraySet<>(); FullscreenTaskListener(SyncTransactionQueue syncQueue) { mSyncQueue = syncQueue; @@ -48,17 +46,17 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { synchronized (mTasks) { - if (mTasks.containsKey(taskInfo.taskId)) { + if (mTasks.contains(taskInfo.taskId)) { throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId); } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d", taskInfo.taskId); - mTasks.put(taskInfo.taskId, leash); + mTasks.add(taskInfo.taskId); mSyncQueue.runInSync(t -> { // Reset several properties back to fullscreen (PiP, for example, leaves all these // properties in a bad state). - updateSurfacePosition(t, taskInfo, leash); t.setWindowCrop(leash, null); + t.setPosition(leash, 0, 0); // TODO(shell-transitions): Eventually set everything in transition so there's no // SF Transaction here. if (!Transitions.ENABLE_SHELL_TRANSITIONS) { @@ -73,7 +71,7 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { @Override public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { synchronized (mTasks) { - if (mTasks.remove(taskInfo.taskId) == null) { + if (!mTasks.remove(taskInfo.taskId)) { Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId); return; } @@ -83,23 +81,6 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { } @Override - public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { - synchronized (mTasks) { - if (!mTasks.containsKey(taskInfo.taskId)) { - Slog.e(TAG, "Changed Task wasn't appeared or already vanished: #" - + taskInfo.taskId); - return; - } - final SurfaceControl leash = mTasks.get(taskInfo.taskId); - mSyncQueue.runInSync(t -> { - // Reposition the task in case the bounds has been changed (such as Task level - // letterboxing). - updateSurfacePosition(t, taskInfo, leash); - }); - } - } - - @Override public void dump(@NonNull PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; final String childPrefix = innerPrefix + " "; @@ -112,12 +93,4 @@ class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN); } - /** Places the Task surface to the latest position. */ - private static void updateSurfacePosition(SurfaceControl.Transaction t, - ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { - // TODO(170725334) drop this after ag/12876439 - final Configuration config = taskInfo.getConfiguration(); - final Rect bounds = config.windowConfiguration.getBounds(); - t.setPosition(leash, bounds.left, bounds.top); - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/LetterboxTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/LetterboxTaskListener.java new file mode 100644 index 000000000000..9010c2088c34 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/LetterboxTaskListener.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell; + +import android.app.ActivityManager; +import android.graphics.Point; +import android.graphics.Rect; +import android.util.Slog; +import android.util.SparseArray; +import android.view.SurfaceControl; + +import com.android.internal.protolog.common.ProtoLog; +import com.android.wm.shell.common.SyncTransactionQueue; +import com.android.wm.shell.protolog.ShellProtoLogGroup; + +/** + * Organizes a task in {@link android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN} when + * it's presented in the letterbox mode either because orientations of a top activity and a device + * don't match or because a top activity is in a size compat mode. + */ +final class LetterboxTaskListener implements ShellTaskOrganizer.TaskListener { + private static final String TAG = "LetterboxTaskListener"; + + private final SyncTransactionQueue mSyncQueue; + + private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>(); + + LetterboxTaskListener(SyncTransactionQueue syncQueue) { + mSyncQueue = syncQueue; + } + + @Override + public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { + synchronized (mLeashByTaskId) { + if (mLeashByTaskId.get(taskInfo.taskId) != null) { + throw new RuntimeException("Task appeared more than once: #" + taskInfo.taskId); + } + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Appeared: #%d", + taskInfo.taskId); + mLeashByTaskId.put(taskInfo.taskId, leash); + final Rect taskBounds = taskInfo.getConfiguration().windowConfiguration.getBounds(); + final Rect activtyBounds = taskInfo.letterboxActivityBounds; + final Point taskPositionInParent = taskInfo.positionInParent; + mSyncQueue.runInSync(t -> { + setPositionAndWindowCrop( + t, leash, activtyBounds, taskBounds, taskPositionInParent); + if (!Transitions.ENABLE_SHELL_TRANSITIONS) { + t.setAlpha(leash, 1f); + t.setMatrix(leash, 1, 0, 0, 1); + t.show(leash); + } + }); + } + } + + @Override + public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { + synchronized (mLeashByTaskId) { + if (mLeashByTaskId.get(taskInfo.taskId) == null) { + Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId); + return; + } + mLeashByTaskId.remove(taskInfo.taskId); + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Vanished: #%d", + taskInfo.taskId); + } + } + + @Override + public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { + synchronized (mLeashByTaskId) { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Letterbox Task Changed: #%d", + taskInfo.taskId); + final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId); + final Rect taskBounds = taskInfo.getConfiguration().windowConfiguration.getBounds(); + final Rect activtyBounds = taskInfo.letterboxActivityBounds; + final Point taskPositionInParent = taskInfo.positionInParent; + mSyncQueue.runInSync(t -> { + setPositionAndWindowCrop( + t, leash, activtyBounds, taskBounds, taskPositionInParent); + }); + } + } + + private static void setPositionAndWindowCrop( + SurfaceControl.Transaction transaction, + SurfaceControl leash, + final Rect activityBounds, + final Rect taskBounds, + final Point taskPositionInParent) { + Rect activtyInTaskCoordinates = new Rect(activityBounds); + activtyInTaskCoordinates.offset(-taskBounds.left, -taskBounds.top); + transaction.setPosition(leash, taskPositionInParent.x, taskPositionInParent.y); + transaction.setWindowCrop(leash, activtyInTaskCoordinates); + } +} 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 cbc1c8d6d310..d4ff275d426d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -20,8 +20,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; -import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG; @@ -29,6 +27,7 @@ import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG import android.annotation.IntDef; import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration.WindowingMode; +import android.os.Binder; import android.os.IBinder; import android.util.ArrayMap; import android.util.Log; @@ -45,7 +44,6 @@ import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; -import com.android.wm.shell.protolog.ShellProtoLogGroup; import java.io.PrintWriter; import java.util.ArrayList; @@ -64,14 +62,14 @@ public class ShellTaskOrganizer extends TaskOrganizer { public static final int TASK_LISTENER_TYPE_FULLSCREEN = -2; public static final int TASK_LISTENER_TYPE_MULTI_WINDOW = -3; public static final int TASK_LISTENER_TYPE_PIP = -4; - public static final int TASK_LISTENER_TYPE_SPLIT_SCREEN = -5; + public static final int TASK_LISTENER_TYPE_LETTERBOX = -5; @IntDef(prefix = {"TASK_LISTENER_TYPE_"}, value = { TASK_LISTENER_TYPE_UNDEFINED, TASK_LISTENER_TYPE_FULLSCREEN, TASK_LISTENER_TYPE_MULTI_WINDOW, TASK_LISTENER_TYPE_PIP, - TASK_LISTENER_TYPE_SPLIT_SCREEN, + TASK_LISTENER_TYPE_LETTERBOX, }) public @interface TaskListenerType {} @@ -118,6 +116,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { ShellExecutor mainExecutor, ShellExecutor animExecutor) { super(taskOrganizerController, mainExecutor); addListenerForType(new FullscreenTaskListener(syncQueue), TASK_LISTENER_TYPE_FULLSCREEN); + addListenerForType(new LetterboxTaskListener(syncQueue), TASK_LISTENER_TYPE_LETTERBOX); mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor); if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions); } @@ -137,6 +136,14 @@ public class ShellTaskOrganizer extends TaskOrganizer { } } + public void createRootTask(int displayId, int windowingMode, TaskListener listener) { + ProtoLog.v(WM_SHELL_TASK_ORG, "createRootTask() displayId=%d winMode=%d listener=%s", + displayId, windowingMode, listener.toString()); + final IBinder cookie = new Binder(); + setPendingLaunchCookieListener(cookie, listener); + super.createRootTask(displayId, windowingMode, cookie); + } + /** * Adds a listener for a specific task id. */ @@ -236,10 +243,10 @@ public class ShellTaskOrganizer extends TaskOrganizer { private void onTaskAppeared(TaskAppearedInfo info) { final int taskId = info.getTaskInfo().taskId; - ProtoLog.v(WM_SHELL_TASK_ORG, "Task appeared taskId=%d", taskId); mTasks.put(taskId, info); final TaskListener listener = getTaskListener(info.getTaskInfo(), true /*removeLaunchCookieIfNeeded*/); + ProtoLog.v(WM_SHELL_TASK_ORG, "Task appeared taskId=%d listener=%s", taskId, listener); if (listener != null) { listener.onTaskAppeared(info.getTaskInfo(), info.getLeash()); } @@ -329,26 +336,25 @@ public class ShellTaskOrganizer extends TaskOrganizer { if (listener != null) return listener; // Next we try type specific listeners. - final int windowingMode = getWindowingMode(runningTaskInfo); - final int taskListenerType = windowingModeToTaskListenerType(windowingMode); + final int taskListenerType = taskInfoToTaskListenerType(runningTaskInfo); return mTaskListeners.get(taskListenerType); } @WindowingMode - private static int getWindowingMode(RunningTaskInfo taskInfo) { + public static int getWindowingMode(RunningTaskInfo taskInfo) { return taskInfo.configuration.windowConfiguration.getWindowingMode(); } - private static @TaskListenerType int windowingModeToTaskListenerType( - @WindowingMode int windowingMode) { + @VisibleForTesting + static @TaskListenerType int taskInfoToTaskListenerType(RunningTaskInfo runningTaskInfo) { + final int windowingMode = getWindowingMode(runningTaskInfo); switch (windowingMode) { case WINDOWING_MODE_FULLSCREEN: - return TASK_LISTENER_TYPE_FULLSCREEN; + return runningTaskInfo.letterboxActivityBounds != null + ? TASK_LISTENER_TYPE_LETTERBOX + : TASK_LISTENER_TYPE_FULLSCREEN; case WINDOWING_MODE_MULTI_WINDOW: return TASK_LISTENER_TYPE_MULTI_WINDOW; - case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: - case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: - return TASK_LISTENER_TYPE_SPLIT_SCREEN; case WINDOWING_MODE_PINNED: return TASK_LISTENER_TYPE_PIP; case WINDOWING_MODE_FREEFORM: @@ -362,10 +368,10 @@ public class ShellTaskOrganizer extends TaskOrganizer { switch (type) { case TASK_LISTENER_TYPE_FULLSCREEN: return "TASK_LISTENER_TYPE_FULLSCREEN"; + case TASK_LISTENER_TYPE_LETTERBOX: + return "TASK_LISTENER_TYPE_LETTERBOX"; case TASK_LISTENER_TYPE_MULTI_WINDOW: return "TASK_LISTENER_TYPE_MULTI_WINDOW"; - case TASK_LISTENER_TYPE_SPLIT_SCREEN: - return "TASK_LISTENER_TYPE_SPLIT_SCREEN"; case TASK_LISTENER_TYPE_PIP: return "TASK_LISTENER_TYPE_PIP"; case TASK_LISTENER_TYPE_UNDEFINED: diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java index 8f8b98bbfbae..bf5b1d8a4bcc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java @@ -16,8 +16,17 @@ package com.android.wm.shell.draganddrop; +import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.content.ClipDescription.EXTRA_ACTIVITY_OPTIONS; +import static android.content.ClipDescription.EXTRA_PENDING_INTENT; import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY; +import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT; +import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK; +import static android.content.Intent.EXTRA_PACKAGE_NAME; +import static android.content.Intent.EXTRA_SHORTCUT_ID; +import static android.content.Intent.EXTRA_TASK_ID; +import static android.content.Intent.EXTRA_USER; import static android.view.DragEvent.ACTION_DRAG_ENDED; import static android.view.DragEvent.ACTION_DRAG_ENTERED; import static android.view.DragEvent.ACTION_DRAG_EXITED; @@ -33,15 +42,24 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityOptions; +import android.app.ActivityTaskManager; import android.app.PendingIntent; +import android.content.ActivityNotFoundException; import android.content.ClipData; import android.content.ClipDescription; import android.content.Context; import android.content.Intent; +import android.content.pm.LauncherApps; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.os.Binder; +import android.os.Bundle; +import android.os.Handler; +import android.os.RemoteException; +import android.os.UserHandle; import android.util.Slog; import android.util.SparseArray; import android.view.DragEvent; @@ -68,6 +86,7 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange private static final String TAG = DragAndDropController.class.getSimpleName(); + private final Context mContext; private final DisplayController mDisplayController; private SplitScreen mSplitScreen; @@ -76,7 +95,8 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange private DragLayout mDragLayout; private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction(); - public DragAndDropController(DisplayController displayController) { + public DragAndDropController(Context context, DisplayController displayController) { + mContext = context; mDisplayController = displayController; mDisplayController.addDisplayWindowListener(this); } @@ -135,13 +155,16 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange event.getOffsetX(), event.getOffsetY()); final int displayId = target.getDisplay().getDisplayId(); final PerDisplay pd = mDisplayDropTargets.get(displayId); + final ClipDescription description = event.getClipDescription(); if (event.getAction() == ACTION_DRAG_STARTED) { - final ClipDescription description = event.getClipDescription(); - final boolean hasValidClipData = description.hasMimeType(MIMETYPE_APPLICATION_ACTIVITY); + final boolean hasValidClipData = description.hasMimeType(MIMETYPE_APPLICATION_ACTIVITY) + || description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT) + || description.hasMimeType(MIMETYPE_APPLICATION_TASK); mIsHandlingDrag = hasValidClipData; - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Clip description: %s", - getMimeTypes(description)); + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, + "Clip description: handlingDrag=%b mimeTypes=%s", + mIsHandlingDrag, getMimeTypes(description)); } if (!mIsHandlingDrag) { @@ -163,31 +186,7 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange mDragLayout.update(event); break; case ACTION_DROP: { - final SurfaceControl dragSurface = event.getDragSurface(); - final View dragLayout = mDragLayout; - final ClipData data = event.getClipData(); - return mDragLayout.drop(event, dragSurface, (dropTargetBounds) -> { - if (dropTargetBounds != null) { - // TODO(b/169894807): Properly handle the drop, for now just launch it - if (data.getItemCount() > 0) { - Intent intent = data.getItemAt(0).getIntent(); - PendingIntent pi = intent.getParcelableExtra( - ClipDescription.EXTRA_PENDING_INTENT); - try { - pi.send(); - } catch (PendingIntent.CanceledException e) { - Slog.e(TAG, "Failed to launch activity", e); - } - } - } - - setDropTargetWindowVisibility(pd, View.INVISIBLE); - pd.dropTarget.removeView(dragLayout); - - // Clean up the drag surface - mTransaction.reparent(dragSurface, null); - mTransaction.apply(); - }); + return handleDrop(event, pd); } case ACTION_DRAG_EXITED: { // Either one of DROP or EXITED will happen, and when EXITED we won't consume @@ -211,6 +210,62 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange return true; } + /** + * Handles dropping on the drop target. + */ + private boolean handleDrop(DragEvent event, PerDisplay pd) { + final ClipData data = event.getClipData(); + final ClipDescription description = event.getClipDescription(); + final SurfaceControl dragSurface = event.getDragSurface(); + final View dragLayout = mDragLayout; + final boolean isTask = description.hasMimeType(MIMETYPE_APPLICATION_TASK); + final boolean isShortcut = description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT); + return mDragLayout.drop(event, dragSurface, (dropTargetBounds) -> { + if (dropTargetBounds != null && data.getItemCount() > 0) { + final Intent intent = data.getItemAt(0).getIntent(); + // TODO(b/169894807): Properly handle the drop, for now just launch it + if (isTask) { + int taskId = intent.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID); + try { + ActivityTaskManager.getService().startActivityFromRecents( + taskId, null); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to launch task", e); + } + } else if (isShortcut) { + try { + Bundle opts = intent.hasExtra(EXTRA_ACTIVITY_OPTIONS) + ? intent.getBundleExtra(EXTRA_ACTIVITY_OPTIONS) + : null; + LauncherApps launcherApps = + mContext.getSystemService(LauncherApps.class); + launcherApps.startShortcut( + intent.getStringExtra(EXTRA_PACKAGE_NAME), + intent.getStringExtra(EXTRA_SHORTCUT_ID), + null /* sourceBounds */, opts, + intent.getParcelableExtra(EXTRA_USER)); + } catch (ActivityNotFoundException e) { + Slog.e(TAG, "Failed to launch shortcut", e); + } + } else { + PendingIntent pi = intent.getParcelableExtra(EXTRA_PENDING_INTENT); + try { + pi.send(); + } catch (PendingIntent.CanceledException e) { + Slog.e(TAG, "Failed to launch activity", e); + } + } + } + + setDropTargetWindowVisibility(pd, View.INVISIBLE); + pd.dropTarget.removeView(dragLayout); + + // Clean up the drag surface + mTransaction.reparent(dragSurface, null); + mTransaction.apply(); + }); + } + private void setDropTargetWindowVisibility(PerDisplay pd, int visibility) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Set drop target window visibility: displayId=%d visibility=%d", diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java index 17418f934691..bd6c1e096d01 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java @@ -30,6 +30,7 @@ import android.os.SystemProperties; import android.util.ArrayMap; import android.util.Log; import android.view.SurfaceControl; +import android.window.DisplayAreaAppearedInfo; import android.window.DisplayAreaInfo; import android.window.DisplayAreaOrganizer; import android.window.WindowContainerTransaction; @@ -189,6 +190,17 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { } @Override + public List<DisplayAreaAppearedInfo> registerOrganizer(int displayAreaFeature) { + final List<DisplayAreaAppearedInfo> displayAreaInfos = + super.registerOrganizer(displayAreaFeature); + for (int i = 0; i < displayAreaInfos.size(); i++) { + final DisplayAreaAppearedInfo info = displayAreaInfos.get(i); + onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash()); + } + return displayAreaInfos; + } + + @Override public void unregisterOrganizer() { super.unregisterOrganizer(); mUpdateHandler.post(() -> resetWindowsOffset(null)); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java index 3ded4091ec11..8d5da1a5ffcb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java @@ -22,10 +22,8 @@ import android.app.PictureInPictureParams; import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.graphics.Rect; -import android.media.session.MediaController; import com.android.wm.shell.pip.phone.PipTouchHandler; -import com.android.wm.shell.pip.tv.PipController; import java.io.PrintWriter; import java.util.function.Consumer; @@ -35,19 +33,6 @@ import java.util.function.Consumer; */ public interface Pip { /** - * Registers {@link com.android.wm.shell.pip.tv.PipController.Listener} that gets called. - * whenever receiving notification on changes in PIP. - */ - default void addListener(PipController.Listener listener) { - } - - /** - * Registers a {@link PipController.MediaListener} to PipController. - */ - default void addMediaListener(PipController.MediaListener listener) { - } - - /** * Closes PIP (PIPed activity and PIP system UI). */ default void closePip() { @@ -68,17 +53,8 @@ public interface Pip { } /** - * Get current play back state. (e.g: Used in TV) - * - * @return The state of defined in PipController. - */ - default int getPlaybackState() { - return -1; - } - - /** * Get the touch handler which manages all the touch handling for PIP on the Phone, - * including moving, dismissing and expanding the PIP. (Do not used in TV) + * including moving, dismissing and expanding the PIP. (Do not use in TV) * * @return */ @@ -87,15 +63,6 @@ public interface Pip { } /** - * Get MediaController. - * - * @return The MediaController instance. - */ - default MediaController getMediaController() { - return null; - } - - /** * Hides the PIP menu. */ default void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {} @@ -171,18 +138,6 @@ public interface Pip { } /** - * Removes a {@link PipController.Listener} from PipController. - */ - default void removeListener(PipController.Listener listener) { - } - - /** - * Removes a {@link PipController.MediaListener} from PipController. - */ - default void removeMediaListener(PipController.MediaListener listener) { - } - - /** * Resize the Pip to the appropriate size for the input state. * * @param state In Pip state also used to determine the new size for the Pip. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java index 64e3758fd81a..a7c34fd4465a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java @@ -14,12 +14,11 @@ * limitations under the License. */ -package com.android.wm.shell.pip.phone; +package com.android.wm.shell.pip; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; -import android.app.IActivityManager; import android.app.PendingIntent; import android.app.RemoteAction; import android.content.BroadcastReceiver; @@ -28,11 +27,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.drawable.Icon; +import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.os.UserHandle; +import androidx.annotation.Nullable; + import com.android.wm.shell.R; import java.util.ArrayList; @@ -46,10 +48,10 @@ import java.util.List; */ public class PipMediaController { - private static final String ACTION_PLAY = "com.android.wm.shell.pip.phone.PLAY"; - private static final String ACTION_PAUSE = "com.android.wm.shell.pip.phone.PAUSE"; - private static final String ACTION_NEXT = "com.android.wm.shell.pip.phone.NEXT"; - private static final String ACTION_PREV = "com.android.wm.shell.pip.phone.PREV"; + private static final String ACTION_PLAY = "com.android.wm.shell.pip.PLAY"; + private static final String ACTION_PAUSE = "com.android.wm.shell.pip.PAUSE"; + private static final String ACTION_NEXT = "com.android.wm.shell.pip.NEXT"; + private static final String ACTION_PREV = "com.android.wm.shell.pip.PREV"; /** * A listener interface to receive notification on changes to the media actions. @@ -61,8 +63,17 @@ public class PipMediaController { void onMediaActionsChanged(List<RemoteAction> actions); } + /** + * A listener interface to receive notification on changes to the media metadata. + */ + public interface MetadataListener { + /** + * Called when the media metadata changes. + */ + void onMediaMetadataChanged(MediaMetadata metadata); + } + private final Context mContext; - private final IActivityManager mActivityManager; private final MediaSessionManager mMediaSessionManager; private MediaController mMediaController; @@ -94,16 +105,21 @@ public class PipMediaController { public void onPlaybackStateChanged(PlaybackState state) { notifyActionsChanged(); } + + @Override + public void onMetadataChanged(@Nullable MediaMetadata metadata) { + notifyMetadataChanged(metadata); + } }; private final MediaSessionManager.OnActiveSessionsChangedListener mSessionsChangedListener = - controllers -> resolveActiveMediaController(controllers); + this::resolveActiveMediaController; - private ArrayList<ActionListener> mListeners = new ArrayList<>(); + private final ArrayList<ActionListener> mActionListeners = new ArrayList<>(); + private final ArrayList<MetadataListener> mMetadataListeners = new ArrayList<>(); - public PipMediaController(Context context, IActivityManager activityManager) { + public PipMediaController(Context context) { mContext = context; - mActivityManager = activityManager; IntentFilter mediaControlFilter = new IntentFilter(); mediaControlFilter.addAction(ACTION_PLAY); mediaControlFilter.addAction(ACTION_PAUSE); @@ -113,8 +129,7 @@ public class PipMediaController { UserHandle.USER_ALL); createMediaActions(); - mMediaSessionManager = - (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE); + mMediaSessionManager = context.getSystemService(MediaSessionManager.class); } /** @@ -129,9 +144,9 @@ public class PipMediaController { /** * Adds a new media action listener. */ - public void addListener(ActionListener listener) { - if (!mListeners.contains(listener)) { - mListeners.add(listener); + public void addActionListener(ActionListener listener) { + if (!mActionListeners.contains(listener)) { + mActionListeners.add(listener); listener.onMediaActionsChanged(getMediaActions()); } } @@ -139,9 +154,31 @@ public class PipMediaController { /** * Removes a media action listener. */ - public void removeListener(ActionListener listener) { - listener.onMediaActionsChanged(Collections.EMPTY_LIST); - mListeners.remove(listener); + public void removeActionListener(ActionListener listener) { + listener.onMediaActionsChanged(Collections.emptyList()); + mActionListeners.remove(listener); + } + + /** + * Adds a new media metadata listener. + */ + public void addMetadataListener(MetadataListener listener) { + if (!mMetadataListeners.contains(listener)) { + mMetadataListeners.add(listener); + listener.onMediaMetadataChanged(getMediaMetadata()); + } + } + + /** + * Removes a media metadata listener. + */ + public void removeMetadataListener(MetadataListener listener) { + listener.onMediaMetadataChanged(null); + mMetadataListeners.remove(listener); + } + + private MediaMetadata getMediaMetadata() { + return mMediaController != null ? mMediaController.getMetadata() : null; } /** @@ -149,7 +186,7 @@ public class PipMediaController { */ private List<RemoteAction> getMediaActions() { if (mMediaController == null || mMediaController.getPlaybackState() == null) { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } ArrayList<RemoteAction> mediaActions = new ArrayList<>(); @@ -216,8 +253,7 @@ public class PipMediaController { */ private void resolveActiveMediaController(List<MediaController> controllers) { if (controllers != null) { - final ComponentName topActivity = PipUtils.getTopPipActivity(mContext, - mActivityManager).first; + final ComponentName topActivity = PipUtils.getTopPipActivity(mContext).first; if (topActivity != null) { for (int i = 0; i < controllers.size(); i++) { final MediaController controller = controllers.get(i); @@ -244,6 +280,7 @@ public class PipMediaController { controller.registerCallback(mPlaybackChangedListener); } notifyActionsChanged(); + notifyMetadataChanged(getMediaMetadata()); // TODO(winsonc): Consider if we want to close the PIP after a timeout (like on TV) } @@ -253,9 +290,18 @@ public class PipMediaController { * Notifies all listeners that the actions have changed. */ private void notifyActionsChanged() { - if (!mListeners.isEmpty()) { + if (!mActionListeners.isEmpty()) { List<RemoteAction> actions = getMediaActions(); - mListeners.forEach(l -> l.onMediaActionsChanged(actions)); + mActionListeners.forEach(l -> l.onMediaActionsChanged(actions)); + } + } + + /** + * Notifies all listeners that the metadata have changed. + */ + private void notifyMetadataChanged(MediaMetadata metadata) { + if (!mMetadataListeners.isEmpty()) { + mMetadataListeners.forEach(l -> l.onMediaMetadataChanged(metadata)); } } } 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 a05aac9dfe3e..d223934fcf34 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 @@ -60,6 +60,7 @@ import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransactionCallback; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.os.SomeArgs; import com.android.wm.shell.R; @@ -550,7 +551,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, return null; } - private void enterPipWithAlphaAnimation(Rect destinationBounds, long durationMs) { + @VisibleForTesting + void enterPipWithAlphaAnimation(Rect destinationBounds, long durationMs) { // If we are fading the PIP in, then we should move the pip to the final location as // soon as possible, but set the alpha immediately since the transaction can take a // while to process diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java index bd2ba32912bc..da6d9804b29d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipUtils.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUtils.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.android.wm.shell.pip.phone; +package com.android.wm.shell.pip; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import android.app.ActivityTaskManager; import android.app.ActivityTaskManager.RootTaskInfo; -import android.app.IActivityManager; import android.content.ComponentName; import android.content.Context; import android.os.RemoteException; import android.util.Log; import android.util.Pair; +/** A class that includes convenience methods. */ public class PipUtils { private static final String TAG = "PipUtils"; @@ -35,8 +35,7 @@ public class PipUtils { * @return the ComponentName and user id of the top non-SystemUI activity in the pinned stack. * The component name may be null if no such activity exists. */ - public static Pair<ComponentName, Integer> getTopPipActivity(Context context, - IActivityManager activityManager) { + public static Pair<ComponentName, Integer> getTopPipActivity(Context context) { try { final String sysUiPackageName = context.getPackageName(); final RootTaskInfo pinnedTaskInfo = ActivityTaskManager.getService().getRootTaskInfo( diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java index 6b6b5211b10a..2cd010796799 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java @@ -29,6 +29,8 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.os.Handler; import android.util.Pair; +import com.android.wm.shell.pip.PipUtils; + public class PipAppOpsListener { private static final String TAG = PipAppOpsListener.class.getSimpleName(); @@ -44,7 +46,7 @@ public class PipAppOpsListener { try { // Dismiss the PiP once the user disables the app ops setting for that package final Pair<ComponentName, Integer> topPipActivityInfo = - PipUtils.getTopPipActivity(mContext, mActivityManager); + PipUtils.getTopPipActivity(mContext); if (topPipActivityInfo.first != null) { final ApplicationInfo appInfo = mContext.getPackageManager() .getApplicationInfoAsUser(packageName, 0, topPipActivityInfo.second); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 823979b861b4..37a5919b1c9e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -29,7 +29,6 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ParceledListSlice; import android.graphics.Rect; -import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; @@ -45,10 +44,12 @@ import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.pip.PinnedStackListenerForwarder; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipBoundsHandler; import com.android.wm.shell.pip.PipBoundsState; +import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipTaskOrganizer; import java.io.PrintWriter; @@ -61,7 +62,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private static final String TAG = "PipController"; private Context mContext; - private Handler mHandler = new Handler(); + private ShellExecutor mMainExecutor; private final DisplayInfo mTmpDisplayInfo = new DisplayInfo(); private final Rect mTmpInsetBounds = new Rect(); @@ -81,6 +82,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac protected PipMenuActivityController mMenuController; protected PipTaskOrganizer mPipTaskOrganizer; + protected PinnedStackListenerForwarder.PinnedStackListener mPinnedStackListener = + new PipControllerPinnedStackListener(); /** * Handler for display rotation changes. @@ -149,12 +152,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PinnedStackListenerForwarder.PinnedStackListener { @Override public void onListenerRegistered(IPinnedStackController controller) { - mHandler.post(() -> mTouchHandler.setPinnedStackController(controller)); + mMainExecutor.execute(() -> mTouchHandler.setPinnedStackController(controller)); } @Override public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { mPipBoundsHandler.onImeVisibilityChanged(imeVisible, imeHeight); mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight); }); @@ -162,19 +165,19 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onMovementBoundsChanged(boolean fromImeAdjustment) { - mHandler.post(() -> updateMovementBounds(null /* toBounds */, + mMainExecutor.execute(() -> updateMovementBounds(null /* toBounds */, false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */, null /* windowContainerTransaction */)); } @Override public void onActionsChanged(ParceledListSlice<RemoteAction> actions) { - mHandler.post(() -> mMenuController.setAppActions(actions)); + mMainExecutor.execute(() -> mMenuController.setAppActions(actions)); } @Override public void onActivityHidden(ComponentName componentName) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { if (componentName.equals(mPipBoundsState.getLastPipComponentName())) { // The activity was removed, we don't want to restore to the reentry state // saved for this component anymore. @@ -185,12 +188,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onDisplayInfoChanged(DisplayInfo displayInfo) { - mHandler.post(() -> mPipBoundsState.setDisplayInfo(displayInfo)); + mMainExecutor.execute(() -> mPipBoundsState.setDisplayInfo(displayInfo)); } @Override public void onConfigurationChanged() { - mHandler.post(() -> { + mMainExecutor.execute(() -> { mPipBoundsHandler.onConfigurationChanged(mContext); mTouchHandler.onConfigurationChanged(); }); @@ -200,7 +203,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac public void onAspectRatioChanged(float aspectRatio) { // TODO(b/169373982): Remove this callback as it is redundant with PipTaskOrg params // change. - mHandler.post(() -> { + mMainExecutor.execute(() -> { mPipBoundsState.setAspectRatio(aspectRatio); mTouchHandler.onAspectRatioChanged(); }); @@ -216,7 +219,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, - WindowManagerShellWrapper windowManagerShellWrapper + WindowManagerShellWrapper windowManagerShellWrapper, + ShellExecutor mainExecutor ) { // Ensure that we are the primary user's SystemUI. final int processUser = UserManager.get(context).getUserHandle(); @@ -230,6 +234,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mPipBoundsHandler = pipBoundsHandler; mPipBoundsState = pipBoundsState; mPipTaskOrganizer = pipTaskOrganizer; + mMainExecutor = mainExecutor; mPipTaskOrganizer.registerPipTransitionCallback(this); mPipTaskOrganizer.registerOnDisplayIdChangeCallback((int displayId) -> { final DisplayInfo newDisplayInfo = new DisplayInfo(); @@ -253,8 +258,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mPipBoundsState.setDisplayInfo(displayInfo); try { - mWindowManagerShellWrapper.addPinnedStackListener( - new PipControllerPinnedStackListener()); + mWindowManagerShellWrapper.addPinnedStackListener(mPinnedStackListener); } catch (RemoteException e) { Slog.e(TAG, "Failed to register pinned stack listener", e); } @@ -262,14 +266,14 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onDensityOrFontScaleChanged() { - mHandler.post(() -> { + mMainExecutor.execute(() -> { mPipTaskOrganizer.onDensityOrFontScaleChanged(mContext); }); } @Override public void onActivityPinned(String packageName) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { mTouchHandler.onActivityPinned(); mMediaController.onActivityPinned(); mMenuController.onActivityPinned(); @@ -279,7 +283,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onActivityUnpinned(ComponentName topActivity) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { mMenuController.onActivityUnpinned(); mTouchHandler.onActivityUnpinned(topActivity); mAppOpsListener.onActivityUnpinned(); @@ -298,7 +302,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onOverlayChanged() { - mHandler.post(() -> { + mMainExecutor.execute(() -> { mPipBoundsState.setDisplayLayout(new DisplayLayout(mContext, mContext.getDisplay())); updateMovementBounds(null /* toBounds */, false /* fromRotation */, false /* fromImeAdjustment */, @@ -357,7 +361,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac */ @Override public void setShelfHeight(boolean visible, int height) { - mHandler.post(() -> setShelfHeightLocked(visible, height)); + mMainExecutor.execute(() -> setShelfHeightLocked(visible, height)); } private void setShelfHeightLocked(boolean visible, int height) { @@ -373,12 +377,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void setPinnedStackAnimationType(int animationType) { - mHandler.post(() -> mPipTaskOrganizer.setOneShotAnimationType(animationType)); + mMainExecutor.execute(() -> mPipTaskOrganizer.setOneShotAnimationType(animationType)); } @Override public void setPinnedStackAnimationListener(Consumer<Boolean> callback) { - mHandler.post(() -> mPinnedStackAnimationRecentsCallback = callback); + mMainExecutor.execute(() -> mPinnedStackAnimationRecentsCallback = callback); } @Override @@ -475,7 +479,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PipBoundsState pipBoundsState, PipMediaController pipMediaController, PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, - WindowManagerShellWrapper windowManagerShellWrapper) { + WindowManagerShellWrapper windowManagerShellWrapper, + ShellExecutor mainExecutor) { if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { Slog.w(TAG, "Device doesn't support Pip feature"); return null; @@ -483,6 +488,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac return new PipController(context, displayController, pipAppOpsListener, pipBoundsHandler, pipBoundsState, pipMediaController, pipMenuActivityController, - pipTaskOrganizer, pipTouchHandler, windowManagerShellWrapper); + pipTaskOrganizer, pipTouchHandler, windowManagerShellWrapper, mainExecutor); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java index cd47d55da7f0..a87fa20a7f11 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java @@ -34,8 +34,9 @@ import android.view.MotionEvent; import android.view.WindowManager; import android.view.WindowManagerGlobal; +import com.android.wm.shell.pip.PipMediaController; +import com.android.wm.shell.pip.PipMediaController.ActionListener; import com.android.wm.shell.pip.PipTaskOrganizer; -import com.android.wm.shell.pip.phone.PipMediaController.ActionListener; import java.io.PrintWriter; import java.util.ArrayList; @@ -342,11 +343,11 @@ public class PipMenuActivityController { if (menuState == MENU_STATE_FULL) { // Once visible, start listening for media action changes. This call will trigger // the menu actions to be updated again. - mMediaController.addListener(mMediaActionListener); + mMediaController.addActionListener(mMediaActionListener); } else { // Once hidden, stop listening for media action changes. This call will trigger // the menu actions to be updated again. - mMediaController.removeListener(mMediaActionListener); + mMediaController.removeActionListener(mMediaActionListener); } try { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java index 51951409f76c..3e06ec44989e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java @@ -32,7 +32,6 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; -import android.app.ActivityManager; import android.app.PendingIntent.CanceledException; import android.app.RemoteAction; import android.content.ComponentName; @@ -61,6 +60,7 @@ import android.widget.LinearLayout; import com.android.wm.shell.R; import com.android.wm.shell.animation.Interpolators; +import com.android.wm.shell.pip.PipUtils; import java.util.ArrayList; import java.util.List; @@ -452,7 +452,7 @@ public class PipMenuView extends FrameLayout { private void showSettings() { final Pair<ComponentName, Integer> topPipActivityInfo = - PipUtils.getTopPipActivity(mContext, ActivityManager.getService()); + PipUtils.getTopPipActivity(mContext); if (topPipActivityInfo.first != null) { final Intent settingsIntent = new Intent(ACTION_PICTURE_IN_PICTURE_SETTINGS, Uri.fromParts("package", topPipActivityInfo.first.getPackageName(), null)); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java index b27af656f209..3468b888c06a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java @@ -38,9 +38,6 @@ import android.content.pm.ParceledListSlice; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; -import android.media.session.MediaController; -import android.media.session.MediaSessionManager; -import android.media.session.PlaybackState; import android.os.Debug; import android.os.Handler; import android.os.RemoteException; @@ -55,6 +52,7 @@ import com.android.wm.shell.pip.PinnedStackListenerForwarder; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipBoundsHandler; import com.android.wm.shell.pip.PipBoundsState; +import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipTaskOrganizer; import java.util.ArrayList; @@ -106,26 +104,23 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private int mSuspendPipResizingReason; - private Context mContext; - private PipBoundsState mPipBoundsState; - private PipBoundsHandler mPipBoundsHandler; - private PipTaskOrganizer mPipTaskOrganizer; + private final Context mContext; + private final PipBoundsState mPipBoundsState; + private final PipBoundsHandler mPipBoundsHandler; + private final PipTaskOrganizer mPipTaskOrganizer; + private final PipMediaController mPipMediaController; + private IActivityTaskManager mActivityTaskManager; - private MediaSessionManager mMediaSessionManager; private int mState = STATE_NO_PIP; private int mResumeResizePinnedStackRunnableState = STATE_NO_PIP; private final Handler mHandler = new Handler(); private List<Listener> mListeners = new ArrayList<>(); - private List<MediaListener> mMediaListeners = new ArrayList<>(); private Rect mPipBounds; private Rect mDefaultPipBounds = new Rect(); private Rect mMenuModePipBounds; private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED; - private boolean mInitialized; private int mPipTaskId = TASK_ID_NO_PIP; private int mPinnedStackId = INVALID_STACK_ID; - private ComponentName mPipComponentName; - private MediaController mPipMediaController; private String[] mLastPackagesResourceGranted; private PipNotification mPipNotification; private ParceledListSlice<RemoteAction> mCustomActions; @@ -168,17 +163,13 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } } }; - private final MediaSessionManager.OnActiveSessionsChangedListener mActiveMediaSessionListener = - controllers -> updateMediaController(controllers); + private final PinnedStackListenerForwarder.PinnedStackListener mPinnedStackListener = new PipControllerPinnedStackListener(); @Override public void registerSessionListenerForCurrentUser() { - // TODO Need confirm if TV have to re-registers when switch user - mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveMediaSessionListener); - mMediaSessionManager.addOnActiveSessionsChangedListener(mActiveMediaSessionListener, null, - UserHandle.USER_CURRENT, null); + mPipMediaController.registerSessionListenerForCurrentUser(); } /** @@ -232,48 +223,48 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PipBoundsState pipBoundsState, PipBoundsHandler pipBoundsHandler, PipTaskOrganizer pipTaskOrganizer, - WindowManagerShellWrapper windowManagerShellWrapper - ) { - if (!mInitialized) { - mInitialized = true; - mContext = context; - mPipBoundsState = pipBoundsState; - mPipNotification = new PipNotification(context, this); - mPipBoundsHandler = pipBoundsHandler; - // Ensure that we have the display info in case we get calls to update the bounds - // before the listener calls back - final DisplayInfo displayInfo = new DisplayInfo(); - context.getDisplay().getDisplayInfo(displayInfo); - mPipBoundsState.setDisplayInfo(displayInfo); - - mResizeAnimationDuration = context.getResources() - .getInteger(R.integer.config_pipResizeAnimationDuration); - mPipTaskOrganizer = pipTaskOrganizer; - mPipTaskOrganizer.registerPipTransitionCallback(this); - mActivityTaskManager = ActivityTaskManager.getService(); - - final IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(ACTION_CLOSE); - intentFilter.addAction(ACTION_MENU); - intentFilter.addAction(ACTION_MEDIA_RESOURCE_GRANTED); - mContext.registerReceiver(mBroadcastReceiver, intentFilter, UserHandle.USER_ALL); - - // Initialize the last orientation and apply the current configuration - Configuration initialConfig = mContext.getResources().getConfiguration(); - mLastOrientation = initialConfig.orientation; - loadConfigurationsAndApply(initialConfig); - - mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class); - mWindowManagerShellWrapper = windowManagerShellWrapper; - try { - mWindowManagerShellWrapper.addPinnedStackListener(mPinnedStackListener); - } catch (RemoteException e) { - Log.e(TAG, "Failed to register pinned stack listener", e); - } - - // TODO(b/169395392) Refactor PipMenuActivity to PipMenuView - PipMenuActivity.setPipController(this); + PipMediaController pipMediaController, + PipNotification pipNotification, + WindowManagerShellWrapper windowManagerShellWrapper) { + mContext = context; + mPipBoundsState = pipBoundsState; + mPipNotification = pipNotification; + mPipBoundsHandler = pipBoundsHandler; + mPipMediaController = pipMediaController; + // Ensure that we have the display info in case we get calls to update the bounds + // before the listener calls back + final DisplayInfo displayInfo = new DisplayInfo(); + context.getDisplay().getDisplayInfo(displayInfo); + mPipBoundsState.setDisplayInfo(displayInfo); + + mResizeAnimationDuration = context.getResources() + .getInteger(R.integer.config_pipResizeAnimationDuration); + mPipTaskOrganizer = pipTaskOrganizer; + mPipTaskOrganizer.registerPipTransitionCallback(this); + mActivityTaskManager = ActivityTaskManager.getService(); + + addListener(mPipNotification); + + final IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(ACTION_CLOSE); + intentFilter.addAction(ACTION_MENU); + intentFilter.addAction(ACTION_MEDIA_RESOURCE_GRANTED); + mContext.registerReceiver(mBroadcastReceiver, intentFilter, UserHandle.USER_ALL); + + // Initialize the last orientation and apply the current configuration + Configuration initialConfig = mContext.getResources().getConfiguration(); + mLastOrientation = initialConfig.orientation; + loadConfigurationsAndApply(initialConfig); + + mWindowManagerShellWrapper = windowManagerShellWrapper; + try { + mWindowManagerShellWrapper.addPinnedStackListener(mPinnedStackListener); + } catch (RemoteException e) { + Log.e(TAG, "Failed to register pinned stack listener", e); } + + // TODO(b/169395392) Refactor PipMenuActivity to PipMenuView + PipMenuActivity.setPipController(this); } private void loadConfigurationsAndApply(Configuration newConfig) { @@ -332,8 +323,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mState = STATE_NO_PIP; mPipTaskId = TASK_ID_NO_PIP; - mPipMediaController = null; - mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveMediaSessionListener); if (removePipStack) { try { mActivityTaskManager.removeTask(mPinnedStackId); @@ -374,13 +363,9 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac if (DEBUG) Log.d(TAG, "PINNED_STACK:" + taskInfo); mPinnedStackId = taskInfo.taskId; mPipTaskId = taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1]; - mPipComponentName = ComponentName.unflattenFromString( - taskInfo.childTaskNames[taskInfo.childTaskNames.length - 1]); // Set state to STATE_PIP so we show it when the pinned stack animation ends. mState = STATE_PIP; - mMediaSessionManager.addOnActiveSessionsChangedListener( - mActiveMediaSessionListener, null); - updateMediaController(mMediaSessionManager.getActiveSessions(null)); + mPipMediaController.onActivityPinned(); for (int i = mListeners.size() - 1; i >= 0; i--) { mListeners.get(i).onPipEntered(packageName); } @@ -545,32 +530,18 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac /** * Adds a {@link Listener} to PipController. */ - public void addListener(Listener listener) { + void addListener(Listener listener) { mListeners.add(listener); } /** * Removes a {@link Listener} from PipController. */ - public void removeListener(Listener listener) { + void removeListener(Listener listener) { mListeners.remove(listener); } /** - * Adds a {@link MediaListener} to PipController. - */ - public void addMediaListener(MediaListener listener) { - mMediaListeners.add(listener); - } - - /** - * Removes a {@link MediaListener} from PipController. - */ - public void removeMediaListener(MediaListener listener) { - mMediaListeners.remove(listener); - } - - /** * Returns {@code true} if PIP is shown. */ public boolean isPipShown() { @@ -611,69 +582,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } } - private void updateMediaController(List<MediaController> controllers) { - MediaController mediaController = null; - if (controllers != null && getState() != STATE_NO_PIP && mPipComponentName != null) { - for (int i = controllers.size() - 1; i >= 0; i--) { - MediaController controller = controllers.get(i); - // We assumes that an app with PIPable activity - // keeps the single instance of media controller especially when PIP is on. - if (controller.getPackageName().equals(mPipComponentName.getPackageName())) { - mediaController = controller; - break; - } - } - } - if (mPipMediaController != mediaController) { - mPipMediaController = mediaController; - for (int i = mMediaListeners.size() - 1; i >= 0; i--) { - mMediaListeners.get(i).onMediaControllerChanged(); - } - if (mPipMediaController == null) { - mHandler.postDelayed(mClosePipRunnable, - CLOSE_PIP_WHEN_MEDIA_SESSION_GONE_TIMEOUT_MS); - } else { - mHandler.removeCallbacks(mClosePipRunnable); - } - } - } - - /** - * Gets the {@link android.media.session.MediaController} for the PIPed activity. - */ - public MediaController getMediaController() { - return mPipMediaController; - } - @Override public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) { - } - /** - * Returns the PIPed activity's playback state. - * This returns one of {@link #PLAYBACK_STATE_PLAYING}, {@link #PLAYBACK_STATE_PAUSED}, - * or {@link #PLAYBACK_STATE_UNAVAILABLE}. - */ - public int getPlaybackState() { - if (mPipMediaController == null || mPipMediaController.getPlaybackState() == null) { - return PLAYBACK_STATE_UNAVAILABLE; - } - int state = mPipMediaController.getPlaybackState().getState(); - boolean isPlaying = (state == PlaybackState.STATE_BUFFERING - || state == PlaybackState.STATE_CONNECTING - || state == PlaybackState.STATE_PLAYING - || state == PlaybackState.STATE_FAST_FORWARDING - || state == PlaybackState.STATE_REWINDING - || state == PlaybackState.STATE_SKIPPING_TO_PREVIOUS - || state == PlaybackState.STATE_SKIPPING_TO_NEXT); - long actions = mPipMediaController.getPlaybackState().getActions(); - if (!isPlaying && ((actions & PlaybackState.ACTION_PLAY) != 0)) { - return PLAYBACK_STATE_PAUSED; - } else if (isPlaying && ((actions & PlaybackState.ACTION_PAUSE) != 0)) { - return PLAYBACK_STATE_PLAYING; - } - return PLAYBACK_STATE_UNAVAILABLE; + PipMediaController getPipMediaController() { + return mPipMediaController; } @Override @@ -721,14 +635,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac void onPipResizeAboutToStart(); } - /** - * A listener interface to receive change in PIP's media controller - */ - public interface MediaListener { - /** Invoked when the MediaController on PIPed activity is changed. */ - void onMediaControllerChanged(); - } - private String getStateDescription() { if (mSuspendPipResizingReason == 0) { return stateToName(mState); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsView.java index 14960c38fd43..95d9b77c513e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsView.java @@ -51,15 +51,11 @@ public class PipControlsView extends LinearLayout { setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL); } - PipControlButtonView getFullButtonView() { + PipControlButtonView getFullscreenButton() { return findViewById(R.id.full_button); } - PipControlButtonView getCloseButtonView() { + PipControlButtonView getCloseButton() { return findViewById(R.id.close_button); } - - PipControlButtonView getPlayPauseButtonView() { - return findViewById(R.id.play_pause_button); - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsViewController.java index f66e9025a9ed..5265e7705ed9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsViewController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsViewController.java @@ -18,10 +18,10 @@ package com.android.wm.shell.pip.tv; import android.app.PendingIntent; import android.app.RemoteAction; +import android.content.Context; import android.graphics.Color; -import android.media.session.MediaController; -import android.media.session.PlaybackState; import android.os.Handler; +import android.os.Looper; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -29,9 +29,8 @@ import android.view.View; import com.android.wm.shell.R; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; /** @@ -42,213 +41,118 @@ public class PipControlsViewController { private static final float DISABLED_ACTION_ALPHA = 0.54f; - private final PipControlsView mView; - private final LayoutInflater mLayoutInflater; - private final Handler mHandler; private final PipController mPipController; - private final PipControlButtonView mPlayPauseButtonView; - private MediaController mMediaController; - private PipControlButtonView mFocusedChild; - private Listener mListener; - private ArrayList<PipControlButtonView> mCustomButtonViews = new ArrayList<>(); - private List<RemoteAction> mCustomActions = new ArrayList<>(); - - public PipControlsView getView() { - return mView; - } - - /** - * An interface to listen user action. - */ - public interface Listener { - /** - * Called when a user clicks close PIP button. - */ - void onClosed(); - } - private View.OnAttachStateChangeListener - mOnAttachStateChangeListener = - new View.OnAttachStateChangeListener() { - @Override - public void onViewAttachedToWindow(View v) { - updateMediaController(); - mPipController.addMediaListener(mPipMediaListener); - } + private final Context mContext; + private final Handler mUiThreadHandler; + private final PipControlsView mView; + private final List<PipControlButtonView> mAdditionalButtons = new ArrayList<>(); - @Override - public void onViewDetachedFromWindow(View v) { - mPipController.removeMediaListener(mPipMediaListener); - } - }; + private final List<RemoteAction> mCustomActions = new ArrayList<>(); + private final List<RemoteAction> mMediaActions = new ArrayList<>(); - private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() { - @Override - public void onPlaybackStateChanged(PlaybackState state) { - updateUserActions(); - } - }; - - private final PipController.MediaListener mPipMediaListener = this::updateMediaController; - - private final View.OnFocusChangeListener - mFocusChangeListener = - new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View view, boolean hasFocus) { - if (hasFocus) { - mFocusedChild = (PipControlButtonView) view; - } else if (mFocusedChild == view) { - mFocusedChild = null; - } - } - }; - - public PipControlsViewController(PipControlsView view, PipController pipController, - LayoutInflater layoutInflater, Handler handler) { - super(); - mView = view; + public PipControlsViewController(PipControlsView view, PipController pipController) { + mContext = view.getContext(); + mUiThreadHandler = new Handler(Looper.getMainLooper()); mPipController = pipController; - mLayoutInflater = layoutInflater; - mHandler = handler; - - mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener); - if (mView.isAttachedToWindow()) { - mOnAttachStateChangeListener.onViewAttachedToWindow(mView); - } - - View fullButtonView = mView.getFullButtonView(); - fullButtonView.setOnFocusChangeListener(mFocusChangeListener); - fullButtonView.setOnClickListener(mView -> mPipController.movePipToFullscreen()); - - View closeButtonView = mView.getCloseButtonView(); - closeButtonView.setOnFocusChangeListener(mFocusChangeListener); - closeButtonView.setOnClickListener(v -> { - mPipController.closePip(); - if (mListener != null) { - mListener.onClosed(); - } - }); + mView = view; - mPlayPauseButtonView = mView.getPlayPauseButtonView(); - mPlayPauseButtonView.setOnFocusChangeListener(mFocusChangeListener); - mPlayPauseButtonView.setOnClickListener(v -> { - if (mMediaController == null || mMediaController.getPlaybackState() == null) { - return; - } - final int playbackState = mPipController.getPlaybackState(); - if (playbackState == PipController.PLAYBACK_STATE_PAUSED) { - mMediaController.getTransportControls().play(); - } else if (playbackState == PipController.PLAYBACK_STATE_PLAYING) { - mMediaController.getTransportControls().pause(); - } + mView.getFullscreenButton().setOnClickListener(v -> mPipController.movePipToFullscreen()); + mView.getCloseButton().setOnClickListener(v -> mPipController.closePip()); - // View will be updated later in {@link mMediaControllerCallback} - }); + mPipController.getPipMediaController().addActionListener(this::onMediaActionsChanged); } - private void updateMediaController() { - AtomicReference<MediaController> newController = new AtomicReference<>(); - newController.set(mPipController.getMediaController()); + PipControlsView getView() { + return mView; + } - if (newController.get() == null || mMediaController == newController.get()) { + /** + * Updates the set of activity-defined actions. + */ + void setCustomActions(List<? extends RemoteAction> actions) { + if (mCustomActions.isEmpty() && actions.isEmpty()) { + // Nothing changed - return early. return; } - if (mMediaController != null) { - mMediaController.unregisterCallback(mMediaControllerCallback); + mCustomActions.clear(); + mCustomActions.addAll(actions); + updateAdditionalActions(); + } + + private void onMediaActionsChanged(List<RemoteAction> actions) { + if (mMediaActions.isEmpty() && actions.isEmpty()) { + // Nothing changed - return early. + return; } - mMediaController = newController.get(); - if (mMediaController != null) { - mMediaController.registerCallback(mMediaControllerCallback); + mMediaActions.clear(); + mMediaActions.addAll(actions); + + // Update the view only if there are no custom actions (media actions are only shown when + // there no custom actions). + if (mCustomActions.isEmpty()) { + updateAdditionalActions(); } - updateUserActions(); } - /** - * Updates the actions for the PIP. If there are no custom actions, then the media session - * actions are shown. - */ - private void updateUserActions() { + private void updateAdditionalActions() { + final List<RemoteAction> actionsToDisplay; if (!mCustomActions.isEmpty()) { - // Ensure we have as many buttons as actions - while (mCustomButtonViews.size() < mCustomActions.size()) { - PipControlButtonView buttonView = (PipControlButtonView) mLayoutInflater.inflate( + // If there are custom actions: show them. + actionsToDisplay = mCustomActions; + } else if (!mMediaActions.isEmpty()) { + // If there are no custom actions, but there media actions: show them. + actionsToDisplay = mMediaActions; + } else { + // If there no custom actions and no media actions: clean up all the additional buttons. + actionsToDisplay = Collections.emptyList(); + } + + // Make sure we exactly as many additional buttons as we have actions to display. + final int actionsNumber = actionsToDisplay.size(); + int buttonsNumber = mAdditionalButtons.size(); + if (actionsNumber > buttonsNumber) { + final LayoutInflater layoutInflater = LayoutInflater.from(mContext); + // Add buttons until we have enough to display all of the actions. + while (actionsNumber > buttonsNumber) { + final PipControlButtonView button = (PipControlButtonView) layoutInflater.inflate( R.layout.tv_pip_custom_control, mView, false); - mView.addView(buttonView); - mCustomButtonViews.add(buttonView); - } + mView.addView(button); + mAdditionalButtons.add(button); - // Update the visibility of all views - for (int i = 0; i < mCustomButtonViews.size(); i++) { - mCustomButtonViews.get(i).setVisibility( - i < mCustomActions.size() ? View.VISIBLE : View.GONE); + buttonsNumber++; } - - // Update the state and visibility of the action buttons, and hide the rest - for (int i = 0; i < mCustomActions.size(); i++) { - final RemoteAction action = mCustomActions.get(i); - PipControlButtonView actionView = mCustomButtonViews.get(i); - - // TODO: Check if the action drawable has changed before we reload it - action.getIcon().loadDrawableAsync(mView.getContext(), d -> { - d.setTint(Color.WHITE); - actionView.setImageDrawable(d); - }, mHandler); - actionView.setText(action.getContentDescription()); - if (action.isEnabled()) { - actionView.setOnClickListener(v -> { - try { - action.getActionIntent().send(); - } catch (PendingIntent.CanceledException e) { - Log.w(TAG, "Failed to send action", e); - } - }); - } - actionView.setEnabled(action.isEnabled()); - actionView.setAlpha(action.isEnabled() ? 1f : DISABLED_ACTION_ALPHA); + } else if (actionsNumber < buttonsNumber) { + // Hide buttons until we as many as the actions. + while (actionsNumber < buttonsNumber) { + final View button = mAdditionalButtons.get(buttonsNumber - 1); + button.setVisibility(View.GONE); + button.setOnClickListener(null); + + buttonsNumber--; } + } - // Hide the media session buttons - mPlayPauseButtonView.setVisibility(View.GONE); - } else { - AtomicInteger state = new AtomicInteger(PipController.STATE_UNKNOWN); - state.set(mPipController.getPlaybackState()); - if (state.get() == PipController.STATE_UNKNOWN - || state.get() == PipController.PLAYBACK_STATE_UNAVAILABLE) { - mPlayPauseButtonView.setVisibility(View.GONE); - } else { - mPlayPauseButtonView.setVisibility(View.VISIBLE); - if (state.get() == PipController.PLAYBACK_STATE_PLAYING) { - mPlayPauseButtonView.setImageResource(R.drawable.pip_ic_pause_white); - mPlayPauseButtonView.setText(R.string.pip_pause); - } else { - mPlayPauseButtonView.setImageResource(R.drawable.pip_ic_play_arrow_white); - mPlayPauseButtonView.setText(R.string.pip_play); + // "Assign" actions to the buttons. + for (int index = 0; index < actionsNumber; index++) { + final RemoteAction action = actionsToDisplay.get(index); + final PipControlButtonView button = mAdditionalButtons.get(index); + button.setVisibility(View.VISIBLE); // Ensure the button is visible. + button.setText(action.getContentDescription()); + button.setEnabled(action.isEnabled()); + button.setAlpha(action.isEnabled() ? 1f : DISABLED_ACTION_ALPHA); + button.setOnClickListener(v -> { + try { + action.getActionIntent().send(); + } catch (PendingIntent.CanceledException e) { + Log.w(TAG, "Failed to send action", e); } - } + }); - // Hide all the custom action buttons - for (int i = 0; i < mCustomButtonViews.size(); i++) { - mCustomButtonViews.get(i).setVisibility(View.GONE); - } + action.getIcon().loadDrawableAsync(mContext, drawable -> { + drawable.setTint(Color.WHITE); + button.setImageDrawable(drawable); + }, mUiThreadHandler); } } - - - /** - * Sets the {@link Listener} to listen user actions. - */ - public void setListener(Listener listener) { - mListener = listener; - } - - - /** - * Updates the set of activity-defined actions. - */ - public void setActions(List<? extends RemoteAction> actions) { - mCustomActions.clear(); - mCustomActions.addAll(actions); - updateUserActions(); - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java index e185a9604449..d2270c278161 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java @@ -56,8 +56,7 @@ public class PipMenuActivity extends Activity implements PipController.Listener } setContentView(R.layout.tv_pip_menu); mPipControlsViewController = new PipControlsViewController( - findViewById(R.id.pip_controls), sPipController, - getLayoutInflater(), getApplicationContext().getMainThreadHandler()); + findViewById(R.id.pip_controls), sPipController); sPipController.addListener(this); mRestorePipSizeWhenClose = true; mFadeInAnimation = AnimatorInflater.loadAnimator( @@ -141,7 +140,7 @@ public class PipMenuActivity extends Activity implements PipController.Listener if (DEBUG) Log.d(TAG, "onPipMenuActionsChanged()"); boolean hasCustomActions = actions != null && !actions.getList().isEmpty(); - mPipControlsViewController.setActions( + mPipControlsViewController.setCustomActions( hasCustomActions ? actions.getList() : Collections.emptyList()); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java index f5bbd23fa1d6..b30dee4f331f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java @@ -28,36 +28,33 @@ import android.content.pm.ParceledListSlice; import android.content.res.Resources; import android.graphics.Bitmap; import android.media.MediaMetadata; -import android.media.session.MediaController; -import android.media.session.PlaybackState; import android.text.TextUtils; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.wm.shell.R; +import com.android.wm.shell.pip.PipMediaController; + +import java.util.Objects; /** * A notification that informs users that PIP is running and also provides PIP controls. * <p>Once it's created, it will manage the PIP notification UI by itself except for handling * configuration changes. */ -public class PipNotification { +public class PipNotification implements PipController.Listener { + private static final boolean DEBUG = PipController.DEBUG; private static final String TAG = "PipNotification"; + private static final String NOTIFICATION_TAG = PipNotification.class.getSimpleName(); - private static final boolean DEBUG = PipController.DEBUG; + public static final String NOTIFICATION_CHANNEL_TVPIP = "TPP"; static final String ACTION_MENU = "PipNotification.menu"; static final String ACTION_CLOSE = "PipNotification.close"; - public static final String NOTIFICATION_CHANNEL_TVPIP = "TPP"; - private final PackageManager mPackageManager; - - private final PipController mPipController; - private final NotificationManager mNotificationManager; private final Notification.Builder mNotificationBuilder; - private MediaController mMediaController; private String mDefaultTitle; private int mDefaultIconResId; @@ -67,87 +64,9 @@ public class PipNotification { private String mMediaTitle; private Bitmap mArt; - private PipController.Listener mPipListener = new PipController.Listener() { - @Override - public void onPipEntered(String packageName) { - mPackageName = packageName; - updateMediaControllerMetadata(); - notifyPipNotification(); - } - - @Override - public void onPipActivityClosed() { - dismissPipNotification(); - mPackageName = null; - } - - @Override - public void onShowPipMenu() { - // no-op. - } - - @Override - public void onPipMenuActionsChanged(ParceledListSlice<RemoteAction> actions) { - // no-op. - } - - @Override - public void onMoveToFullscreen() { - dismissPipNotification(); - mPackageName = null; - } - - @Override - public void onPipResizeAboutToStart() { - // no-op. - } - }; - - private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() { - @Override - public void onPlaybackStateChanged(PlaybackState state) { - if (updateMediaControllerMetadata() && mNotified) { - // update notification - notifyPipNotification(); - } - } - - @Override - public void onMetadataChanged(MediaMetadata metadata) { - if (updateMediaControllerMetadata() && mNotified) { - // update notification - notifyPipNotification(); - } - } - }; - - private final PipController.MediaListener mPipMediaListener = - new PipController.MediaListener() { - @Override - public void onMediaControllerChanged() { - MediaController newController = mPipController.getMediaController(); - if (newController == null || mMediaController == newController) { - return; - } - if (mMediaController != null) { - mMediaController.unregisterCallback(mMediaControllerCallback); - } - mMediaController = newController; - if (mMediaController != null) { - mMediaController.registerCallback(mMediaControllerCallback); - } - if (updateMediaControllerMetadata() && mNotified) { - // update notification - notifyPipNotification(); - } - } - }; - - public PipNotification(Context context, PipController pipController) { + public PipNotification(Context context, PipMediaController pipMediaController) { mPackageManager = context.getPackageManager(); - - mNotificationManager = (NotificationManager) context.getSystemService( - Context.NOTIFICATION_SERVICE); + mNotificationManager = context.getSystemService(NotificationManager.class); mNotificationBuilder = new Notification.Builder(context, NOTIFICATION_CHANNEL_TVPIP) .setLocalOnly(true) @@ -157,13 +76,51 @@ public class PipNotification { .setContentIntent(createPendingIntent(context, ACTION_MENU)) .setDeleteIntent(createPendingIntent(context, ACTION_CLOSE))); - mPipController = pipController; - pipController.addListener(mPipListener); - pipController.addMediaListener(mPipMediaListener); + pipMediaController.addMetadataListener(this::onMediaMetadataChanged); onConfigurationChanged(context); } + @Override + public void onPipEntered(String packageName) { + mPackageName = packageName; + notifyPipNotification(); + } + + @Override + public void onPipActivityClosed() { + dismissPipNotification(); + mPackageName = null; + } + + @Override + public void onShowPipMenu() { + // no-op. + } + + @Override + public void onPipMenuActionsChanged(ParceledListSlice<RemoteAction> actions) { + // no-op. + } + + @Override + public void onMoveToFullscreen() { + dismissPipNotification(); + mPackageName = null; + } + + @Override + public void onPipResizeAboutToStart() { + // no-op. + } + + private void onMediaMetadataChanged(MediaMetadata metadata) { + if (updateMediaControllerMetadata(metadata) && mNotified) { + // update notification + notifyPipNotification(); + } + } + /** * Called by {@link PipController} when the configuration is changed. */ @@ -199,28 +156,28 @@ public class PipNotification { mNotificationManager.cancel(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP); } - private boolean updateMediaControllerMetadata() { + private boolean updateMediaControllerMetadata(MediaMetadata metadata) { String title = null; Bitmap art = null; - if (mPipController.getMediaController() != null) { - MediaMetadata metadata = mPipController.getMediaController().getMetadata(); - if (metadata != null) { - title = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE); - if (TextUtils.isEmpty(title)) { - title = metadata.getString(MediaMetadata.METADATA_KEY_TITLE); - } - art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); - if (art == null) { - art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART); - } + if (metadata != null) { + title = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE); + if (TextUtils.isEmpty(title)) { + title = metadata.getString(MediaMetadata.METADATA_KEY_TITLE); + } + art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); + if (art == null) { + art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART); } } - if (!TextUtils.equals(title, mMediaTitle) || art != mArt) { - mMediaTitle = title; - mArt = art; - return true; + + if (TextUtils.equals(title, mMediaTitle) && Objects.equals(art, mArt)) { + return false; } - return false; + + mMediaTitle = title; + mArt = art; + + return true; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerImeController.java index ff617ed466d1..eb82357f2dea 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerImeController.java @@ -40,7 +40,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor private static final float ADJUSTED_NONFOCUS_DIM = 0.3f; - private final SplitScreenTaskOrganizer mSplits; + private final SplitScreenTaskListener mSplits; private final TransactionPool mTransactionPool; private final Handler mHandler; private final TaskOrganizer mTaskOrganizer; @@ -92,7 +92,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor private boolean mPausedTargetAdjusted = false; private boolean mAdjustedWhileHidden = false; - DividerImeController(SplitScreenTaskOrganizer splits, TransactionPool pool, Handler handler, + DividerImeController(SplitScreenTaskListener splits, TransactionPool pool, Handler handler, TaskOrganizer taskOrganizer) { mSplits = splits; mTransactionPool = pool; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerView.java index 2b14e8bf88d6..c6496ad6246f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerView.java @@ -155,7 +155,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, private boolean mAdjustedForIme; private DividerState mState; - private SplitScreenTaskOrganizer mTiles; + private SplitScreenTaskListener mTiles; boolean mFirstLayout = true; int mDividerPositionX; int mDividerPositionY; @@ -354,7 +354,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, void injectDependencies(SplitScreenController splitScreenController, DividerWindowManager windowManager, DividerState dividerState, - DividerCallbacks callback, SplitScreenTaskOrganizer tiles, SplitDisplayLayout sdl, + DividerCallbacks callback, SplitScreenTaskListener tiles, SplitDisplayLayout sdl, DividerImeController imeController, WindowManagerProxy wmProxy) { mSplitScreenController = splitScreenController; mWindowManager = windowManager; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitDisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitDisplayLayout.java index 3c0f93906795..7d5e1a84a38d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitDisplayLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitDisplayLayout.java @@ -47,7 +47,7 @@ public class SplitDisplayLayout { private static final int DIVIDER_WIDTH_INACTIVE_DP = 4; - SplitScreenTaskOrganizer mTiles; + SplitScreenTaskListener mTiles; DisplayLayout mDisplayLayout; Context mContext; @@ -62,7 +62,7 @@ public class SplitDisplayLayout { Rect mAdjustedPrimary = null; Rect mAdjustedSecondary = null; - public SplitDisplayLayout(Context ctx, DisplayLayout dl, SplitScreenTaskOrganizer taskTiles) { + public SplitDisplayLayout(Context ctx, DisplayLayout dl, SplitScreenTaskListener taskTiles) { mTiles = taskTiles; mDisplayLayout = dl; mContext = ctx; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index 43e4d62baaf6..69d428a3ae1f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -75,7 +75,7 @@ public class SplitScreenController implements SplitScreen, private final DividerState mDividerState = new DividerState(); private final ForcedResizableInfoActivityController mForcedResizableController; private final Handler mHandler; - private final SplitScreenTaskOrganizer mSplits; + private final SplitScreenTaskListener mSplits; private final SystemWindows mSystemWindows; final TransactionPool mTransactionPool; private final WindowManagerProxy mWindowManagerProxy; @@ -117,7 +117,7 @@ public class SplitScreenController implements SplitScreen, mTransactionPool = transactionPool; mWindowManagerProxy = new WindowManagerProxy(syncQueue, shellTaskOrganizer); mTaskOrganizer = shellTaskOrganizer; - mSplits = new SplitScreenTaskOrganizer(this, shellTaskOrganizer); + mSplits = new SplitScreenTaskListener(this, shellTaskOrganizer); mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler, shellTaskOrganizer); mRotationController = @@ -164,6 +164,14 @@ public class SplitScreenController implements SplitScreen, // Don't initialize the divider or anything until we get the default display. } + void onSplitScreenSupported() { + // Set starting tile bounds based on middle target + final WindowContainerTransaction tct = new WindowContainerTransaction(); + int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position; + mSplitLayout.resizeSplits(midPos, tct); + mTaskOrganizer.applyTransaction(tct); + } + @Override public boolean isSplitScreenSupported() { return mSplits.isSplitScreenSupported(); @@ -196,11 +204,6 @@ public class SplitScreenController implements SplitScreen, } try { mSplits.init(); - // Set starting tile bounds based on middle target - final WindowContainerTransaction tct = new WindowContainerTransaction(); - int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position; - mSplitLayout.resizeSplits(midPos, tct); - mTaskOrganizer.applyTransaction(tct); } catch (Exception e) { Slog.e(TAG, "Failed to register docked stack listener", e); removeDivider(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskListener.java index f763d6d714c4..191a317452e3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTaskListener.java @@ -23,25 +23,24 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.view.Display.DEFAULT_DISPLAY; -import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_SPLIT_SCREEN; -import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString; +import static com.android.wm.shell.ShellTaskOrganizer.getWindowingMode; +import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG; import android.app.ActivityManager.RunningTaskInfo; import android.graphics.Rect; -import android.os.RemoteException; import android.util.Log; -import android.view.Display; import android.view.SurfaceControl; import android.view.SurfaceSession; import androidx.annotation.NonNull; +import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.ShellTaskOrganizer; import java.io.PrintWriter; -class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener { - private static final String TAG = "SplitScreenTaskOrg"; +class SplitScreenTaskListener implements ShellTaskOrganizer.TaskListener { + private static final String TAG = "SplitScreenTaskListener"; private static final boolean DEBUG = SplitScreenController.DEBUG; private final ShellTaskOrganizer mTaskOrganizer; @@ -58,20 +57,19 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener { final SurfaceSession mSurfaceSession = new SurfaceSession(); - SplitScreenTaskOrganizer(SplitScreenController splitScreenController, + SplitScreenTaskListener(SplitScreenController splitScreenController, ShellTaskOrganizer shellTaskOrganizer) { mSplitScreenController = splitScreenController; mTaskOrganizer = shellTaskOrganizer; - mTaskOrganizer.addListenerForType(this, TASK_LISTENER_TYPE_SPLIT_SCREEN); } - void init() throws RemoteException { + void init() { synchronized (this) { try { - mPrimary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, - WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); - mSecondary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY, - WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); + mTaskOrganizer.createRootTask( + DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, this); + mTaskOrganizer.createRootTask( + DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, this); } catch (Exception e) { // teardown to prevent callbacks mTaskOrganizer.removeListener(this); @@ -95,19 +93,26 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener { @Override public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) { synchronized (this) { - if (mPrimary == null || mSecondary == null) { - Log.w(TAG, "Received onTaskAppeared before creating root tasks " + taskInfo); - return; - } - - if (taskInfo.token.equals(mPrimary.token)) { + final int winMode = getWindowingMode(taskInfo); + if (winMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { + ProtoLog.v(WM_SHELL_TASK_ORG, + "%s onTaskAppeared Primary taskId=%d", TAG, taskInfo.taskId); + mPrimary = taskInfo; mPrimarySurface = leash; - } else if (taskInfo.token.equals(mSecondary.token)) { + } else if (winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) { + ProtoLog.v(WM_SHELL_TASK_ORG, + "%s onTaskAppeared Secondary taskId=%d", TAG, taskInfo.taskId); + mSecondary = taskInfo; mSecondarySurface = leash; + } else { + ProtoLog.v(WM_SHELL_TASK_ORG, "%s onTaskAppeared unknown taskId=%d winMode=%d", + TAG, taskInfo.taskId, winMode); } if (!mSplitScreenSupported && mPrimarySurface != null && mSecondarySurface != null) { mSplitScreenSupported = true; + mSplitScreenController.onSplitScreenSupported(); + ProtoLog.v(WM_SHELL_TASK_ORG, "%s onTaskAppeared Supported", TAG); // Initialize dim surfaces: mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession) @@ -240,10 +245,13 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener { final String innerPrefix = prefix + " "; final String childPrefix = innerPrefix + " "; pw.println(prefix + this); + pw.println(innerPrefix + "mSplitScreenSupported=" + mSplitScreenSupported); + if (mPrimary != null) pw.println(innerPrefix + "mPrimary.taskId=" + mPrimary.taskId); + if (mSecondary != null) pw.println(innerPrefix + "mSecondary.taskId=" + mSecondary.taskId); } @Override public String toString() { - return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_SPLIT_SCREEN); + return TAG; } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java index 47e7c99d2268..c51bbeb7b6c2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java @@ -88,7 +88,7 @@ class WindowManagerProxy { mTaskOrganizer = taskOrganizer; } - void dismissOrMaximizeDocked(final SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout, + void dismissOrMaximizeDocked(final SplitScreenTaskListener tiles, SplitDisplayLayout layout, final boolean dismissOrMaximize) { mExecutor.execute(() -> applyDismissSplit(tiles, layout, dismissOrMaximize)); } @@ -189,7 +189,7 @@ class WindowManagerProxy { * * @return whether the home stack is resizable */ - boolean applyEnterSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) { + boolean applyEnterSplit(SplitScreenTaskListener tiles, SplitDisplayLayout layout) { // Set launchtile first so that any stack created after // getAllRootTaskInfos and before reparent (even if unlikely) are placed // correctly. @@ -242,7 +242,7 @@ class WindowManagerProxy { * split (thus resulting in the top of the secondary split becoming * fullscreen. {@code false} resolves the other way. */ - void applyDismissSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout, + void applyDismissSplit(SplitScreenTaskListener tiles, SplitDisplayLayout layout, boolean dismissOrMaximize) { // Set launch root first so that any task created after getChildContainers and // before reparent (pretty unlikely) are put into fullscreen. diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/LetterboxTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/LetterboxTaskListenerTest.java new file mode 100644 index 000000000000..45d4d5d347dd --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/LetterboxTaskListenerTest.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.android.wm.shell; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; + +import static org.mockito.ArgumentMatchers.eq; + +import android.app.ActivityManager.RunningTaskInfo; +import android.graphics.Point; +import android.graphics.Rect; +import android.os.Handler; +import android.os.Looper; +import android.view.SurfaceControl; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import com.android.wm.shell.common.SyncTransactionQueue; +import com.android.wm.shell.common.TransactionPool; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Tests for {@link LetterboxTaskListener}. + */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class LetterboxTaskListenerTest { + + private static final Rect ACTIVITY_BOUNDS = new Rect(300, 200, 700, 400); + private static final Rect TASK_BOUNDS = new Rect(200, 100, 800, 500); + private static final Rect TASK_BOUNDS_2 = new Rect(300, 200, 800, 500); + private static final Point TASK_POSITION_IN_PARENT = new Point(100, 50); + private static final Point TASK_POSITION_IN_PARENT_2 = new Point(200, 100); + + private static final Rect EXPECTED_WINDOW_CROP = new Rect(100, 100, 500, 300); + private static final Rect EXPECTED_WINDOW_CROP_2 = new Rect(0, 0, 400, 200); + + private static final RunningTaskInfo TASK_INFO = createTaskInfo( + /* taskId */ 1, ACTIVITY_BOUNDS, TASK_BOUNDS, TASK_POSITION_IN_PARENT); + + private static final RunningTaskInfo TASK_INFO_2 = createTaskInfo( + /* taskId */ 1, ACTIVITY_BOUNDS, TASK_BOUNDS_2, TASK_POSITION_IN_PARENT_2); + + @Mock private SurfaceControl mLeash; + @Mock private SurfaceControl.Transaction mTransaction; + private LetterboxTaskListener mLetterboxTaskListener; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mLetterboxTaskListener = new LetterboxTaskListener( + new SyncTransactionQueue( + new TransactionPool() { + @Override + public SurfaceControl.Transaction acquire() { + return mTransaction; + } + + @Override + public void release(SurfaceControl.Transaction t) { + } + }, + new Handler(Looper.getMainLooper()))); + } + + @Test + public void testOnTaskAppearedAndonTaskInfoChanged_setCorrectPositionAndCrop() { + mLetterboxTaskListener.onTaskAppeared(TASK_INFO, mLeash); + + verify(mTransaction).setPosition( + eq(mLeash), + eq((float) TASK_POSITION_IN_PARENT.x), + eq((float) TASK_POSITION_IN_PARENT.y)); + // Should return activty coordinates offset by task coordinates + verify(mTransaction).setWindowCrop(eq(mLeash), eq(EXPECTED_WINDOW_CROP)); + + mLetterboxTaskListener.onTaskInfoChanged(TASK_INFO_2); + + verify(mTransaction).setPosition( + eq(mLeash), + eq((float) TASK_POSITION_IN_PARENT_2.x), + eq((float) TASK_POSITION_IN_PARENT_2.y)); + // Should return activty coordinates offset by task coordinates + verify(mTransaction).setWindowCrop(eq(mLeash), eq(EXPECTED_WINDOW_CROP_2)); + } + + @Test(expected = RuntimeException.class) + public void testOnTaskAppeared_calledSecondTimeWithSameTaskId_throwsException() { + mLetterboxTaskListener.onTaskAppeared(TASK_INFO, mLeash); + mLetterboxTaskListener.onTaskAppeared(TASK_INFO, mLeash); + } + + private static RunningTaskInfo createTaskInfo( + int taskId, + final Rect activityBounds, + final Rect taskBounds, + final Point taskPositionInParent) { + RunningTaskInfo taskInfo = new RunningTaskInfo(); + taskInfo.taskId = taskId; + taskInfo.configuration.windowConfiguration.setBounds(taskBounds); + taskInfo.letterboxActivityBounds = Rect.copyOrNull(activityBounds); + taskInfo.positionInParent = new Point(taskPositionInParent); + return taskInfo; + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java index 07a6bda239c7..35a2293cbf13 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java @@ -16,15 +16,18 @@ package com.android.wm.shell; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW; -import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP; - import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; +import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN; +import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_LETTERBOX; +import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW; +import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -34,6 +37,7 @@ import static org.mockito.Mockito.verify; import android.app.ActivityManager.RunningTaskInfo; import android.content.pm.ParceledListSlice; +import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; @@ -42,6 +46,7 @@ import android.window.ITaskOrganizer; import android.window.ITaskOrganizerController; import android.window.TaskAppearedInfo; +import androidx.annotation.Nullable; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; @@ -242,10 +247,41 @@ public class ShellTaskOrganizerTests { assertTrue(gotException); } - private RunningTaskInfo createTaskInfo(int taskId, int windowingMode) { + @Test + public void testTaskInfoToTaskListenerType_whenLetterboxBoundsPassed_returnsLetterboxType() { + RunningTaskInfo taskInfo = createTaskInfo( + /* taskId */ 1, + WINDOWING_MODE_FULLSCREEN, + /* letterboxActivityBounds */ new Rect(1, 1, 1, 1)); + + assertEquals( + ShellTaskOrganizer.taskInfoToTaskListenerType(taskInfo), + TASK_LISTENER_TYPE_LETTERBOX); + } + + @Test + public void testTaskInfoToTaskListenerType_whenLetterboxBoundsIsNull_returnsFullscreenType() { + RunningTaskInfo taskInfo = createTaskInfo( + /* taskId */ 1, WINDOWING_MODE_FULLSCREEN, /* letterboxActivityBounds */ null); + + assertEquals( + ShellTaskOrganizer.taskInfoToTaskListenerType(taskInfo), + TASK_LISTENER_TYPE_FULLSCREEN); + } + + private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode) { + RunningTaskInfo taskInfo = new RunningTaskInfo(); + taskInfo.taskId = taskId; + taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode); + return taskInfo; + } + + private static RunningTaskInfo createTaskInfo( + int taskId, int windowingMode, @Nullable Rect letterboxActivityBounds) { RunningTaskInfo taskInfo = new RunningTaskInfo(); taskInfo.taskId = taskId; taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode); + taskInfo.letterboxActivityBounds = Rect.copyOrNull(letterboxActivityBounds); return taskInfo; } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java index 54543d25b401..1d10a84c53b9 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java @@ -16,14 +16,28 @@ package com.android.wm.shell.pip; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import android.app.ActivityManager; +import android.app.PictureInPictureParams; +import android.content.ComponentName; +import android.graphics.Rect; import android.os.RemoteException; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import android.util.Rational; +import android.view.DisplayInfo; +import android.window.WindowContainerToken; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; @@ -52,14 +66,21 @@ public class PipTaskOrganizerTest extends PipTestCase { @Mock private PipUiEventLogger mMockPipUiEventLogger; @Mock private Optional<SplitScreen> mMockOptionalSplitScreen; @Mock private ShellTaskOrganizer mMockShellTaskOrganizer; - @Mock private PipBoundsState mMockPipBoundsState; + private PipBoundsState mPipBoundsState; + + private ComponentName mComponent1; + private ComponentName mComponent2; @Before public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); - mSpiedPipTaskOrganizer = new PipTaskOrganizer(mContext, mMockPipBoundsState, + mComponent1 = new ComponentName(mContext, "component1"); + mComponent2 = new ComponentName(mContext, "component2"); + mPipBoundsState = new PipBoundsState(); + mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipBoundsState, mMockPipBoundsHandler, mMockPipSurfaceTransactionHelper, mMockOptionalSplitScreen, - mMockdDisplayController, mMockPipUiEventLogger, mMockShellTaskOrganizer); + mMockdDisplayController, mMockPipUiEventLogger, mMockShellTaskOrganizer)); + preparePipTaskOrg(); } @Test @@ -71,4 +92,89 @@ public class PipTaskOrganizerTest extends PipTestCase { public void instantiatePipTaskOrganizer_addsDisplayWindowListener() { verify(mMockdDisplayController).addDisplayWindowListener(any()); } + + @Test + public void startSwipePipToHome_updatesAspectRatio() { + final Rational aspectRatio = new Rational(2, 1); + + mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, null, createPipParams(aspectRatio)); + + assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); + } + + @Test + public void startSwipePipToHome_updatesLastPipComponentName() { + mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, null, null); + + assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); + } + + @Test + public void onTaskAppeared_updatesAspectRatio() { + final Rational aspectRatio = new Rational(2, 1); + + mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, + createPipParams(aspectRatio)), null /* leash */); + + assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); + } + + @Test + public void onTaskAppeared_updatesLastPipComponentName() { + mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), + null /* leash */); + + assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); + } + + @Test + public void onTaskInfoChanged_updatesAspectRatioIfChanged() { + final Rational startAspectRatio = new Rational(2, 1); + final Rational newAspectRatio = new Rational(1, 2); + mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, + createPipParams(startAspectRatio)), null /* leash */); + + mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, + createPipParams(newAspectRatio))); + + assertEquals(newAspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); + } + + @Test + public void onTaskInfoChanged_updatesLastPipComponentName() { + mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, + createPipParams(null)), null /* leash */); + + mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, + createPipParams(null))); + + assertEquals(mComponent2, mPipBoundsState.getLastPipComponentName()); + } + + private void preparePipTaskOrg() { + final DisplayInfo info = new DisplayInfo(); + mPipBoundsState.setDisplayInfo(info); + when(mMockPipBoundsHandler.getDestinationBounds(any(), any())).thenReturn(new Rect()); + when(mMockPipBoundsHandler.getDestinationBounds(any(), any(), anyBoolean())) + .thenReturn(new Rect()); + mPipBoundsState.setDisplayInfo(info); + mSpiedPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA); + doNothing().when(mSpiedPipTaskOrganizer).enterPipWithAlphaAnimation(any(), anyLong()); + doNothing().when(mSpiedPipTaskOrganizer).scheduleAnimateResizePip(any(), anyInt(), any()); + } + + private static ActivityManager.RunningTaskInfo createTaskInfo( + ComponentName componentName, PictureInPictureParams params) { + final ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo(); + info.token = mock(WindowContainerToken.class); + info.pictureInPictureParams = params; + info.topActivity = componentName; + return info; + } + + private static PictureInPictureParams createPipParams(Rational aspectRatio) { + return new PictureInPictureParams.Builder() + .setAspectRatio(aspectRatio) + .build(); + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java index a282a48e8494..5f0f1964814f 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java @@ -20,11 +20,14 @@ import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.os.RemoteException; @@ -34,8 +37,10 @@ import android.testing.TestableLooper; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.pip.PipBoundsHandler; import com.android.wm.shell.pip.PipBoundsState; +import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipTaskOrganizer; import com.android.wm.shell.pip.PipTestCase; @@ -63,6 +68,7 @@ public class PipControllerTest extends PipTestCase { @Mock private PipTouchHandler mMockPipTouchHandler; @Mock private WindowManagerShellWrapper mMockWindowManagerShellWrapper; @Mock private PipBoundsState mMockPipBoundsState; + @Mock private ShellExecutor mMockExecutor; @Before public void setUp() throws RemoteException { @@ -70,7 +76,11 @@ public class PipControllerTest extends PipTestCase { mPipController = new PipController(mContext, mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState, mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer, - mMockPipTouchHandler, mMockWindowManagerShellWrapper); + mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockExecutor); + doAnswer(invocation -> { + ((Runnable) invocation.getArgument(0)).run(); + return null; + }).when(mMockExecutor).execute(any()); } @Test @@ -98,6 +108,27 @@ public class PipControllerTest extends PipTestCase { assertNull(PipController.create(spyContext, mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState, mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer, - mMockPipTouchHandler, mMockWindowManagerShellWrapper)); + mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockExecutor)); + } + + @Test + public void onActivityHidden_isLastPipComponentName_clearLastPipComponent() { + final ComponentName component1 = new ComponentName(mContext, "component1"); + when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1); + + mPipController.mPinnedStackListener.onActivityHidden(component1); + + verify(mMockPipBoundsState).setLastPipComponentName(null); + } + + @Test + public void onActivityHidden_isNotLastPipComponentName_lastPipComponentNotCleared() { + final ComponentName component1 = new ComponentName(mContext, "component1"); + final ComponentName component2 = new ComponentName(mContext, "component2"); + when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1); + + mPipController.mPinnedStackListener.onActivityHidden(component2); + + verify(mMockPipBoundsState, never()).setLastPipComponentName(null); } } diff --git a/libs/hostgraphics/Android.bp b/libs/hostgraphics/Android.bp index 9d83e491fdc1..3a99d41448f2 100644 --- a/libs/hostgraphics/Android.bp +++ b/libs/hostgraphics/Android.bp @@ -7,6 +7,8 @@ cc_library_host_static { static_libs: [ "libbase", + "libmath", + "libutils", ], srcs: [ @@ -24,6 +26,7 @@ cc_library_host_static { "frameworks/native/libs/nativebase/include", "frameworks/native/libs/nativewindow/include", "frameworks/native/libs/arect/include", + "frameworks/native/libs/ui/include_private", ], export_include_dirs: ["."], diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java index cd2af1b85f50..bd46ffdf7e57 100644 --- a/location/java/android/location/GnssMeasurement.java +++ b/location/java/android/location/GnssMeasurement.java @@ -901,8 +901,59 @@ public final class GnssMeasurement implements Parcelable { /** * Gets 'Accumulated Delta Range' state. * - * <p>It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a - * cycle slip (indicating 'loss of lock'). + * <p>This indicates the state of the {@link #getAccumulatedDeltaRangeMeters()} measurement. See + * the table below for a detailed interpretation of each state. + * + * <table border="1"> + * <thead> + * <tr> + * <th>ADR_STATE</th> + * <th>Time of relevance</th> + * <th>Interpretation</th> + * </tr> + * </thead> + * <tbody> + * <tr> + * <td>UNKNOWN</td> + * <td>ADR(t)</td> + * <td>No valid carrier phase information is available at time t.</td> + * </tr> + * <tr> + * <td>VALID</td> + * <td>ADR(t)</td> + * <td>Valid carrier phase information is available at time t. This indicates that this + * measurement can be used as a reference for future measurements. However, to compare it to + * previous measurements to compute delta range, other bits should be checked. Specifically, + * it can be used for delta range computation if it is valid and has no reset or cycle slip at + * this epoch i.e. if VALID_BIT == 1 && CYCLE_SLIP_BIT == 0 && RESET_BIT == 0.</td> + * </tr> + * <tr> + * <td>RESET</td> + * <td>ADR(t) - ADR(t-1)</td> + * <td>Carrier phase accumulation has been restarted between current time t and previous time + * t-1. This indicates that this measurement can be used as a reference for future measurements, + * but it should not be compared to previous measurements to compute delta range.</td> + * </tr> + * <tr> + * <td>CYCLE_SLIP</td> + * <td>ADR(t) - ADR(t-1)</td> + * <td>Cycle slip(s) have been detected between the current time t and previous time t-1. This + * indicates that this measurement can be used as a reference for future measurements. Clients + * can use a measurement with a cycle slip to compute delta range against previous measurements + * at their own risk.</td> + * </tr> + * <tr> + * <td>HALF_CYCLE_RESOLVED</td> + * <td>ADR(t)</td> + * <td>Half cycle ambiguity is resolved at time t.</td> + * </tr> + * <tr> + * <td>HALF_CYCLE_REPORTED</td> + * <td>ADR(t)</td> + * <td>Half cycle ambiguity is reported at time t.</td> + * </tr> + * </tbody> + * </table> */ @AdrState public int getAccumulatedDeltaRangeState() { diff --git a/location/java/android/location/IGeofenceProvider.aidl b/location/java/android/location/IGeofenceProvider.aidl index 426ebef86b96..b1ef672024ac 100644 --- a/location/java/android/location/IGeofenceProvider.aidl +++ b/location/java/android/location/IGeofenceProvider.aidl @@ -24,6 +24,6 @@ import android.hardware.location.IGeofenceHardware; * {@hide} */ oneway interface IGeofenceProvider { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setGeofenceHardware(in IGeofenceHardware proxy); } diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index 42cf53b44f1e..3905e0b2b878 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -52,9 +52,11 @@ interface ILocationManager void registerLocationListener(String provider, in LocationRequest request, in ILocationListener listener, String packageName, String attributionTag, String listenerId); void unregisterLocationListener(in ILocationListener listener); - void registerLocationPendingIntent(String provider, in LocationRequest request, in PendingIntent intent, String packageName, String attributionTag); + void registerLocationPendingIntent(String provider, in LocationRequest request, in PendingIntent pendingIntent, String packageName, String attributionTag); void unregisterLocationPendingIntent(in PendingIntent intent); + void injectLocation(in Location location); + void requestGeofence(in Geofence geofence, in PendingIntent intent, String packageName, String attributionTag); void removeGeofence(in PendingIntent intent); @@ -89,7 +91,6 @@ interface ILocationManager void startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName, String attributionTag); void flushGnssBatch(); void stopGnssBatch(); - void injectLocation(in Location location); List<String> getAllProviders(); List<String> getProviders(in Criteria criteria, boolean enabledOnly); diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java index 62b4bc173bb9..20175d70e735 100644 --- a/location/java/android/location/Location.java +++ b/location/java/android/location/Location.java @@ -129,7 +129,7 @@ public class Location implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mProvider; private long mTime = 0; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mElapsedRealtimeNanos = 0; // Estimate of the relative precision of the alignment of this SystemClock // timestamp, with the reported measurements in nanoseconds (68% confidence). diff --git a/location/java/android/location/LocationListener.java b/location/java/android/location/LocationListener.java index 2738ff4ff38c..0ff0a723237b 100644 --- a/location/java/android/location/LocationListener.java +++ b/location/java/android/location/LocationListener.java @@ -19,12 +19,11 @@ package android.location; import android.annotation.NonNull; import android.os.Bundle; +import java.util.concurrent.Executor; + /** - * Used for receiving notifications from the LocationManager when - * the location has changed. These methods are called if the - * LocationListener has been registered with the location manager service - * using the {@link LocationManager#requestLocationUpdates(String, long, float, LocationListener)} - * method. + * Used for receiving notifications when the device location has changed. These methods are called + * when the listener has been registered with the LocationManager. * * <div class="special reference"> * <h3>Developer Guides</h3> @@ -32,6 +31,8 @@ import android.os.Bundle; * <a href="{@docRoot}guide/topics/location/obtaining-user-location.html">Obtaining User * Location</a> developer guide.</p> * </div> + * + * @see LocationManager#requestLocationUpdates(String, LocationRequest, Executor, LocationListener) */ public interface LocationListener { diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index ac775ca05cab..3493693ac67e 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -216,15 +216,15 @@ public class LocationManager { * Key used for an extra holding a boolean enabled/disabled status value when a provider * enabled/disabled event is broadcast using a PendingIntent. * - * @see #requestLocationUpdates(String, long, float, PendingIntent) + * @see #requestLocationUpdates(String, LocationRequest, PendingIntent) */ public static final String KEY_PROVIDER_ENABLED = "providerEnabled"; /** - * Key used for an extra holding a {@link Location} value when a location change is broadcast - * using a PendingIntent. + * Key used for an extra holding a {@link Location} value when a location change is sent using + * a PendingIntent. * - * @see #requestLocationUpdates(String, long, float, PendingIntent) + * @see #requestLocationUpdates(String, LocationRequest, PendingIntent) */ public static final String KEY_LOCATION_CHANGED = "location"; @@ -1322,27 +1322,26 @@ public class LocationManager { Preconditions.checkArgument(provider != null, "invalid null provider"); Preconditions.checkArgument(locationRequest != null, "invalid null location request"); - synchronized (sLocationListeners) { - WeakReference<LocationListenerTransport> reference = sLocationListeners.get(listener); - LocationListenerTransport transport = reference != null ? reference.get() : null; - if (transport == null) { - transport = new LocationListenerTransport(listener, executor); - sLocationListeners.put(listener, new WeakReference<>(transport)); - } else { - transport.setExecutor(executor); - } + try { + synchronized (sLocationListeners) { + WeakReference<LocationListenerTransport> reference = sLocationListeners.get( + listener); + LocationListenerTransport transport = reference != null ? reference.get() : null; + if (transport == null) { + transport = new LocationListenerTransport(listener, executor); + } else { + Preconditions.checkState(transport.isRegistered()); + transport.setExecutor(executor); + } - try { - // making the service call while under lock is less than ideal since LMS must - // make sure that callbacks are not made on the same thread - however it is the - // easiest way to guarantee that clients will not receive callbacks after - // unregistration is complete. mService.registerLocationListener(provider, locationRequest, transport, mContext.getPackageName(), mContext.getAttributionTag(), AppOpsManager.toReceiverId(listener)); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + + sLocationListeners.put(listener, new WeakReference<>(transport)); } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } @@ -1429,23 +1428,17 @@ public class LocationManager { public void removeUpdates(@NonNull LocationListener listener) { Preconditions.checkArgument(listener != null, "invalid null listener"); - synchronized (sLocationListeners) { - WeakReference<LocationListenerTransport> reference = sLocationListeners.remove( - listener); - LocationListenerTransport transport = reference != null ? reference.get() : null; - if (transport != null) { - transport.unregister(); - - try { - // making the service call while under lock is less than ideal since LMS must - // make sure that callbacks are not made on the same thread - however it is the - // easiest way to guarantee that clients will not receive callbacks after - // unregistration is complete. + try { + synchronized (sLocationListeners) { + WeakReference<LocationListenerTransport> ref = sLocationListeners.remove(listener); + LocationListenerTransport transport = ref != null ? ref.get() : null; + if (transport != null) { + transport.unregister(); mService.unregisterLocationListener(transport); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); } } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } @@ -2568,7 +2561,7 @@ public class LocationManager { @Nullable private volatile LocationListener mListener; LocationListenerTransport(LocationListener listener, Executor executor) { - Preconditions.checkArgument(listener != null, "invalid null listener/callback"); + Preconditions.checkArgument(listener != null, "invalid null listener"); mListener = listener; setExecutor(executor); } @@ -2578,6 +2571,10 @@ public class LocationManager { mExecutor = executor; } + boolean isRegistered() { + return mListener != null; + } + void unregister() { mListener = null; } diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java index 7a3a4b23d532..32ac374b33c2 100644 --- a/location/lib/java/com/android/location/provider/LocationProviderBase.java +++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java @@ -171,7 +171,9 @@ public abstract class LocationProviderBase { if (manager != null) { try { manager.onSetAllowed(mAllowed); - } catch (RemoteException | RuntimeException e) { + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (RuntimeException e) { Log.w(mTag, e); } } @@ -191,7 +193,9 @@ public abstract class LocationProviderBase { if (manager != null) { try { manager.onSetProperties(mProperties); - } catch (RemoteException | RuntimeException e) { + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (RuntimeException e) { Log.w(mTag, e); } } @@ -248,7 +252,9 @@ public abstract class LocationProviderBase { try { manager.onReportLocation(location); - } catch (RemoteException | RuntimeException e) { + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (RuntimeException e) { Log.w(mTag, e); } } @@ -339,6 +345,8 @@ public abstract class LocationProviderBase { manager.onSetProperties(mProperties); manager.onSetAllowed(mAllowed); } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (RuntimeException e) { Log.w(mTag, e); } diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 158482a6a833..717074cba26f 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -502,7 +502,7 @@ public final class AudioAttributes implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface CapturePolicy {} - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mUsage = USAGE_UNKNOWN; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mContentType = CONTENT_TYPE_UNKNOWN; @@ -511,7 +511,7 @@ public final class AudioAttributes implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mFlags = 0x0; private HashSet<String> mTags; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String mFormattedTags; private Bundle mBundle; // lazy-initialized, may be null diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java index f6b04540c5c7..0f79675862c7 100644 --- a/media/java/android/media/AudioDevicePort.java +++ b/media/java/android/media/AudioDevicePort.java @@ -18,6 +18,7 @@ package android.media; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.util.Arrays; @@ -41,7 +42,7 @@ public class AudioDevicePort extends AudioPort { private final int[] mEncapsulationModes; private final int[] mEncapsulationMetadataTypes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AudioDevicePort(AudioHandle handle, String deviceName, int[] samplingRates, int[] channelMasks, int[] channelIndexMasks, int[] formats, AudioGain[] gains, int type, String address, int[] encapsulationModes, diff --git a/media/java/android/media/AudioDevicePortConfig.java b/media/java/android/media/AudioDevicePortConfig.java index 51b8037b82f8..69fd82be179b 100644 --- a/media/java/android/media/AudioDevicePortConfig.java +++ b/media/java/android/media/AudioDevicePortConfig.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * An AudioDevicePortConfig describes a possible configuration of an output or input device @@ -28,7 +29,7 @@ import android.compat.annotation.UnsupportedAppUsage; */ public class AudioDevicePortConfig extends AudioPortConfig { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AudioDevicePortConfig(AudioDevicePort devicePort, int samplingRate, int channelMask, int format, AudioGainConfig gain) { super((AudioPort)devicePort, samplingRate, channelMask, format, gain); diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index 8a60bdebbf09..1d06e2837841 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -21,6 +21,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -685,7 +686,7 @@ public final class AudioFormat implements Parcelable { */ // Update sound trigger JNI in core/jni/android_hardware_SoundTrigger.cpp when modifying this // constructor - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private AudioFormat(int encoding, int sampleRate, int channelMask, int channelIndexMask) { this( AUDIO_FORMAT_HAS_PROPERTY_ENCODING @@ -744,11 +745,11 @@ public final class AudioFormat implements Parcelable { // This is an immutable class, all member variables are final. // Essential values. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mEncoding; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mSampleRate; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mChannelMask; private final int mChannelIndexMask; private final int mPropertySetMask; diff --git a/media/java/android/media/AudioGain.java b/media/java/android/media/AudioGain.java index cae1b59d46a7..98dc06a6a996 100644 --- a/media/java/android/media/AudioGain.java +++ b/media/java/android/media/AudioGain.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * The AudioGain describes a gain controller. Gain controllers are exposed by @@ -71,7 +72,7 @@ public class AudioGain { // The channel mask passed to the constructor is as specified in AudioFormat // (e.g. AudioFormat.CHANNEL_OUT_STEREO) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AudioGain(int index, int mode, int channelMask, int minValue, int maxValue, int defaultValue, int stepValue, int rampDurationMinMs, int rampDurationMaxMs) { diff --git a/media/java/android/media/AudioHandle.java b/media/java/android/media/AudioHandle.java index 8fc834f8d0a9..ce51b5a33a9a 100644 --- a/media/java/android/media/AudioHandle.java +++ b/media/java/android/media/AudioHandle.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * The AudioHandle is used by the audio framework implementation to @@ -28,7 +29,7 @@ class AudioHandle { @UnsupportedAppUsage private final int mId; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AudioHandle(int id) { mId = id; } diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 8b28cc45fda2..29477366379b 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -709,7 +709,7 @@ public class AudioManager { * @hide * For test purposes only, will throw NPE with some methods that require a Context. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public AudioManager() { } @@ -959,7 +959,7 @@ public class AudioManager { * @see #setRingerMode(int) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isValidRingerMode(int ringerMode) { if (ringerMode < 0 || ringerMode > RINGER_MODE_MAX) { return false; @@ -2478,7 +2478,7 @@ public class AudioManager { * @see #stopBluetoothSco() * @see #ACTION_SCO_AUDIO_STATE_UPDATED */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void startBluetoothScoVirtualCall() { final IAudioService service = getService(); try { @@ -2630,7 +2630,7 @@ public class AudioManager { * @param on set <var>true</var> to mute the microphone; * <var>false</var> to turn mute off */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setMicrophoneMuteFromSwitch(boolean on) { final IAudioService service = getService(); try { @@ -2890,7 +2890,7 @@ public class AudioManager { * display). Note that BT audio sinks are not considered remote devices. * @return true if {@link AudioManager#STREAM_MUSIC} is active on a remote device */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isMusicActiveRemotely() { return AudioSystem.isStreamActiveRemotely(STREAM_MUSIC, 0); } @@ -3041,7 +3041,7 @@ public class AudioManager { /** * @hide Number of sound effects */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int NUM_SOUND_EFFECTS = 10; /** @@ -3875,7 +3875,7 @@ public class AudioManager { * @param durationHint the type of focus request. AUDIOFOCUS_GAIN_TRANSIENT is recommended so * media applications resume after a call */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void requestAudioFocusForCall(int streamType, int durationHint) { final IAudioService service = getService(); try { @@ -3979,7 +3979,7 @@ public class AudioManager { * when ringing ends and the call is rejected or not answered. * Should match one or more calls to {@link #requestAudioFocusForCall(int, int)}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void abandonAudioFocusForCall() { final IAudioService service = getService(); try { @@ -4715,7 +4715,7 @@ public class AudioManager { * agent when audio settings are restored and causes the AudioService * to read and apply restored settings. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void reloadAudioSettings() { final IAudioService service = getService(); try { diff --git a/media/java/android/media/AudioMixPort.java b/media/java/android/media/AudioMixPort.java index 33d603f0b9da..0e286b0f1f89 100644 --- a/media/java/android/media/AudioMixPort.java +++ b/media/java/android/media/AudioMixPort.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * The AudioMixPort is a specialized type of AudioPort @@ -32,7 +33,7 @@ public class AudioMixPort extends AudioPort { private final int mIoHandle; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AudioMixPort(AudioHandle handle, int ioHandle, int role, String deviceName, int[] samplingRates, int[] channelMasks, int[] channelIndexMasks, int[] formats, AudioGain[] gains) { @@ -53,7 +54,7 @@ public class AudioMixPort extends AudioPort { /** * Get the device type (e.g AudioManager.DEVICE_OUT_SPEAKER) */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int ioHandle() { return mIoHandle; } diff --git a/media/java/android/media/AudioMixPortConfig.java b/media/java/android/media/AudioMixPortConfig.java index 9d8120624a45..483524a8c168 100644 --- a/media/java/android/media/AudioMixPortConfig.java +++ b/media/java/android/media/AudioMixPortConfig.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * An AudioMixPortConfig describes a possible configuration of an output or input mixer. @@ -28,7 +29,7 @@ import android.compat.annotation.UnsupportedAppUsage; public class AudioMixPortConfig extends AudioPortConfig { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AudioMixPortConfig(AudioMixPort mixPort, int samplingRate, int channelMask, int format, AudioGainConfig gain) { super((AudioPort)mixPort, samplingRate, channelMask, format, gain); diff --git a/media/java/android/media/AudioPatch.java b/media/java/android/media/AudioPatch.java index e5107d4e3309..99663bf3aab8 100644 --- a/media/java/android/media/AudioPatch.java +++ b/media/java/android/media/AudioPatch.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** @@ -36,7 +37,7 @@ public class AudioPatch { private final AudioPortConfig[] mSources; private final AudioPortConfig[] mSinks; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AudioPatch(AudioHandle patchHandle, AudioPortConfig[] sources, AudioPortConfig[] sinks) { mHandle = patchHandle; mSources = sources; diff --git a/media/java/android/media/AudioPort.java b/media/java/android/media/AudioPort.java index 7c3ca24e1c9a..e6dc622a11c1 100644 --- a/media/java/android/media/AudioPort.java +++ b/media/java/android/media/AudioPort.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * An audio port is a node of the audio framework or hardware that can be connected to or @@ -82,7 +83,7 @@ public class AudioPort { @UnsupportedAppUsage private AudioPortConfig mActiveConfig; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AudioPort(AudioHandle handle, int role, String name, int[] samplingRates, int[] channelMasks, int[] channelIndexMasks, int[] formats, AudioGain[] gains) { @@ -113,7 +114,7 @@ public class AudioPort { /** * Get the audio port role */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int role() { return mRole; } diff --git a/media/java/android/media/AudioPortConfig.java b/media/java/android/media/AudioPortConfig.java index 16fb5b80eb3e..4dd3cb699a7d 100644 --- a/media/java/android/media/AudioPortConfig.java +++ b/media/java/android/media/AudioPortConfig.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * An AudioPortConfig contains a possible configuration of an audio port chosen @@ -50,7 +51,7 @@ public class AudioPortConfig { static final int CHANNEL_MASK = 0x2; static final int FORMAT = 0x4; static final int GAIN = 0x8; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int mConfigMask; @UnsupportedAppUsage diff --git a/media/java/android/media/AudioPortEventHandler.java b/media/java/android/media/AudioPortEventHandler.java index 8e8dfaf24b9a..763eb2944d19 100644 --- a/media/java/android/media/AudioPortEventHandler.java +++ b/media/java/android/media/AudioPortEventHandler.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -54,7 +55,7 @@ class AudioPortEventHandler { * Accessed by native methods: JNI Callback context. */ @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mJniCallback; void init() { @@ -178,7 +179,7 @@ class AudioPortEventHandler { } @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void postEventFromNative(Object module_ref, int what, int arg1, int arg2, Object obj) { AudioPortEventHandler eventHandler = diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index c9cdbb0ed277..07c8ee514e07 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -30,6 +30,7 @@ import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioPolicy; import android.media.projection.MediaProjection; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -174,14 +175,14 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * Accessed by native methods: provides access to the callback data. */ @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeCallbackCookie; /** * Accessed by native methods: provides access to the JNIDeviceCallback instance. */ @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeDeviceCallback; @@ -261,7 +262,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, /** * AudioAttributes */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private AudioAttributes mAudioAttributes; private boolean mIsSubmixFullVolume = false; @@ -1965,7 +1966,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, // Java methods called from the native side //-------------------- @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void postEventFromNative(Object audiorecord_ref, int what, int arg1, int arg2, Object obj) { //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2); diff --git a/media/java/android/media/AudioRecordingConfiguration.java b/media/java/android/media/AudioRecordingConfiguration.java index 42841d178401..6febabe0aefc 100644 --- a/media/java/android/media/AudioRecordingConfiguration.java +++ b/media/java/android/media/AudioRecordingConfiguration.java @@ -23,6 +23,7 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.media.audiofx.AudioEffect; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; @@ -222,7 +223,7 @@ public final class AudioRecordingConfiguration implements Parcelable { * <br>When called without the permission, the result is an empty string. * @return the package name */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getClientPackageName() { return mClientPackageName; } /** diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 279ba0a55be0..39bdf9557595 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -25,6 +25,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.media.audiofx.AudioEffect; import android.media.audiopolicy.AudioMix; +import android.os.Build; import android.telephony.TelephonyManager; import android.util.Log; import android.util.Pair; @@ -83,7 +84,7 @@ public class AudioSystem public static final int STREAM_BLUETOOTH_SCO = 6; /** @hide Used to identify the volume of audio streams for enforced system sounds in certain * countries (e.g camera in Japan) */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int STREAM_SYSTEM_ENFORCED = 7; /** @hide Used to identify the volume of audio streams for DTMF tones */ public static final int STREAM_DTMF = 8; @@ -596,7 +597,7 @@ public class AudioSystem } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void dynamicPolicyCallbackFromNative(int event, String regId, int val) { DynamicPolicyCallback cb; @@ -673,7 +674,7 @@ public class AudioSystem * @param effects * @param activeSource */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void recordingCallbackFromNative(int event, int riid, int uid, int session, int source, int portId, boolean silenced, int[] recordingFormat, AudioEffect.Descriptor[] clientEffects, AudioEffect.Descriptor[] effects, @@ -1498,7 +1499,7 @@ public class AudioSystem @UnsupportedAppUsage public static native int setMasterMute(boolean mute); /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static native boolean getMasterMute(); /** @hide */ @UnsupportedAppUsage diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index fa6a4ff5af67..b2c2c4b1bbb4 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -27,6 +27,7 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -579,7 +580,7 @@ public class AudioTrack extends PlayerBase * the native AudioTrack object, but not stored in it). */ @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mJniData; @@ -875,7 +876,7 @@ public class AudioTrack extends PlayerBase /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ void deferred_connect(long nativeTrackInJavaObj) { if (mState != STATE_INITIALIZED) { // Note that for this native_setup, we are providing an already created/initialized @@ -4012,7 +4013,7 @@ public class AudioTrack extends PlayerBase // Java methods called from the native side //-------------------- @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void postEventFromNative(Object audiotrack_ref, int what, int arg1, int arg2, Object obj) { //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2); diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java index 45f1ca044afb..06bf5f70d9ec 100644 --- a/media/java/android/media/CamcorderProfile.java +++ b/media/java/android/media/CamcorderProfile.java @@ -565,7 +565,7 @@ public class CamcorderProfile // Methods implemented by JNI @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static native final void native_init(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native final CamcorderProfile native_get_camcorder_profile( int cameraId, int quality); private static native final boolean native_has_camcorder_profile( diff --git a/media/java/android/media/EncoderCapabilities.java b/media/java/android/media/EncoderCapabilities.java index 67ce0f7cc0b9..768b6431f1a9 100644 --- a/media/java/android/media/EncoderCapabilities.java +++ b/media/java/android/media/EncoderCapabilities.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.util.ArrayList; import java.util.List; @@ -44,19 +45,19 @@ public class EncoderCapabilities */ static public class VideoEncoderCap { // These are not modifiable externally, thus are public accessible - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int mCodec; // @see android.media.MediaRecorder.VideoEncoder public final int mMinBitRate; // min bit rate (bps) public final int mMaxBitRate; // max bit rate (bps) public final int mMinFrameRate; // min frame rate (fps) public final int mMaxFrameRate; // max frame rate (fps) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int mMinFrameWidth; // min frame width (pixel) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int mMaxFrameWidth; // max frame width (pixel) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int mMinFrameHeight; // min frame height (pixel) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int mMaxFrameHeight; // max frame height (pixel) // Private constructor called by JNI @@ -134,7 +135,7 @@ public class EncoderCapabilities * Returns the capabilities of the supported video encoders. * @see android.media.EncoderCapabilities.VideoEncoderCap */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static List<VideoEncoderCap> getVideoEncoders() { int nEncoders = native_get_num_video_encoders(); if (nEncoders == 0) return null; diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 47e60000cd04..5c012bef9a68 100755 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -79,7 +79,7 @@ interface IAudioService { void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setStreamVolume(int streamType, int index, int flags, String callingPackage); oneway void handleVolumeKey(in KeyEvent event, boolean isOnTv, diff --git a/media/java/android/media/IRemoteDisplayCallback.aidl b/media/java/android/media/IRemoteDisplayCallback.aidl index 584417d65121..75813c9ba593 100644 --- a/media/java/android/media/IRemoteDisplayCallback.aidl +++ b/media/java/android/media/IRemoteDisplayCallback.aidl @@ -22,6 +22,6 @@ import android.media.RemoteDisplayState; * {@hide} */ oneway interface IRemoteDisplayCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onStateChanged(in RemoteDisplayState state); } diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java index 84ee09b35b81..875c6f52d9b2 100644 --- a/media/java/android/media/JetPlayer.java +++ b/media/java/android/media/JetPlayer.java @@ -19,6 +19,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -130,7 +131,7 @@ public class JetPlayer * Accessed by native methods: provides access to C++ JetPlayer object */ @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativePlayerInJavaObj; @@ -564,7 +565,7 @@ public class JetPlayer // Called exclusively by native code //-------------------- @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void postEventFromNative(Object jetplayer_ref, int what, int arg1, int arg2) { //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2); diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java index 98ca2f9c4253..4b208ce1ec37 100644 --- a/media/java/android/media/MediaCas.java +++ b/media/java/android/media/MediaCas.java @@ -362,28 +362,34 @@ public final class MediaCas implements AutoCloseable { @Override public void onEvent(int event, int arg, @Nullable ArrayList<Byte> data) throws RemoteException { - mEventHandler.sendMessage(mEventHandler.obtainMessage( + if (mEventHandler != null) { + mEventHandler.sendMessage(mEventHandler.obtainMessage( EventHandler.MSG_CAS_EVENT, event, arg, data)); + } } @Override public void onSessionEvent(@NonNull ArrayList<Byte> sessionId, int event, int arg, @Nullable ArrayList<Byte> data) throws RemoteException { - Message msg = mEventHandler.obtainMessage(); - msg.what = EventHandler.MSG_CAS_SESSION_EVENT; - msg.arg1 = event; - msg.arg2 = arg; - Bundle bundle = new Bundle(); - bundle.putByteArray(EventHandler.SESSION_KEY, toBytes(sessionId)); - bundle.putByteArray(EventHandler.DATA_KEY, toBytes(data)); - msg.setData(bundle); - mEventHandler.sendMessage(msg); + if (mEventHandler != null) { + Message msg = mEventHandler.obtainMessage(); + msg.what = EventHandler.MSG_CAS_SESSION_EVENT; + msg.arg1 = event; + msg.arg2 = arg; + Bundle bundle = new Bundle(); + bundle.putByteArray(EventHandler.SESSION_KEY, toBytes(sessionId)); + bundle.putByteArray(EventHandler.DATA_KEY, toBytes(data)); + msg.setData(bundle); + mEventHandler.sendMessage(msg); + } } @Override public void onStatusUpdate(byte status, int arg) throws RemoteException { - mEventHandler.sendMessage(mEventHandler.obtainMessage( + if (mEventHandler != null) { + mEventHandler.sendMessage(mEventHandler.obtainMessage( EventHandler.MSG_CAS_STATUS_EVENT, status, arg)); + } } }; diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java index 78eeca1ccc05..9976fa11d177 100644 --- a/media/java/android/media/MediaMetadata.java +++ b/media/java/android/media/MediaMetadata.java @@ -26,6 +26,7 @@ import android.media.browse.MediaBrowser; import android.media.session.MediaController; import android.media.session.MediaSession; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -650,7 +651,7 @@ public final class MediaMetadata implements Parcelable { * @return The key used by this class or null if no mapping exists * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String getKeyFromMetadataEditorKey(int editorKey) { return EDITOR_KEY_MAPPING.get(editorKey, null); } diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java index 54675d018038..ac19c21ae085 100644 --- a/media/java/android/media/MediaMuxer.java +++ b/media/java/android/media/MediaMuxer.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; import android.media.MediaCodec.BufferInfo; +import android.os.Build; import dalvik.system.CloseGuard; @@ -286,10 +287,10 @@ final public class MediaMuxer { public @interface Format {} // All the native functions are listed here. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native long nativeSetup(@NonNull FileDescriptor fd, int format) throws IllegalArgumentException, IOException; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native void nativeRelease(long nativeObject); private static native void nativeStart(long nativeObject); private static native void nativeStop(long nativeObject); @@ -303,22 +304,22 @@ final public class MediaMuxer { int offset, int size, long presentationTimeUs, @MediaCodec.BufferFlag int flags); // Muxer internal states. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int MUXER_STATE_UNINITIALIZED = -1; private static final int MUXER_STATE_INITIALIZED = 0; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int MUXER_STATE_STARTED = 1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int MUXER_STATE_STOPPED = 2; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mState = MUXER_STATE_UNINITIALIZED; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final CloseGuard mCloseGuard = CloseGuard.get(); private int mLastTrackIndex = -1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeObject; private String convertMuxerStateCodeToString(int aState) { diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 47d276a50034..42e39101de13 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -31,6 +31,7 @@ import android.graphics.SurfaceTexture; import android.media.SubtitleController.Anchor; import android.media.SubtitleTrack.RenderingWidget; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.FileUtils; import android.os.Handler; @@ -1152,7 +1153,7 @@ public class MediaPlayer extends PlayerBase setDataSource(path, headers, null); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void setDataSource(String path, Map<String, String> headers, List<HttpCookie> cookies) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { @@ -1173,7 +1174,7 @@ public class MediaPlayer extends PlayerBase setDataSource(path, keys, values, cookies); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void setDataSource(String path, String[] keys, String[] values, List<HttpCookie> cookies) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { @@ -4410,7 +4411,7 @@ public class MediaPlayer extends PlayerBase * JAVA framework to avoid triggering track scanning. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803; /** Informs that audio is not playing. Note that playback of the video @@ -4430,7 +4431,7 @@ public class MediaPlayer extends PlayerBase * * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900; /** Subtitle track was not supported by the media framework. diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 1db02beaea1a..c61a2eb02921 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -108,7 +108,7 @@ public class MediaRecorder implements AudioRouting, private long mNativeContext; @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Surface mSurface; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 4d87fb3fa81f..4940c7647dbc 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -846,7 +846,7 @@ public class MediaRouter { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public RouteInfo getSelectedRoute() { return getSelectedRoute(ROUTE_TYPE_ANY); } @@ -1776,7 +1776,7 @@ public class MediaRouter { return getName(context.getResources()); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) CharSequence getName(Resources res) { if (mNameResId != 0) { return res.getText(mNameResId); diff --git a/media/java/android/media/MicrophoneInfo.java b/media/java/android/media/MicrophoneInfo.java index acd284f3fad9..9e2e25fa1a7f 100644 --- a/media/java/android/media/MicrophoneInfo.java +++ b/media/java/android/media/MicrophoneInfo.java @@ -19,6 +19,7 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.util.Pair; import java.lang.annotation.Retention; @@ -164,7 +165,7 @@ public final class MicrophoneInfo { private int mType; private int mDirectionality; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) MicrophoneInfo(String deviceId, int type, String address, int location, int group, int indexInTheGroup, Coordinate3F position, Coordinate3F orientation, List<Pair<Float, Float>> frequencyResponse, diff --git a/media/java/android/media/PlaybackParams.java b/media/java/android/media/PlaybackParams.java index f24f831d0333..080b9a4513ee 100644 --- a/media/java/android/media/PlaybackParams.java +++ b/media/java/android/media/PlaybackParams.java @@ -87,23 +87,23 @@ public final class PlaybackParams implements Parcelable { public static final int AUDIO_STRETCH_MODE_VOICE = 1; // flags to indicate which params are actually set - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int SET_SPEED = 1 << 0; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int SET_PITCH = 1 << 1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int SET_AUDIO_FALLBACK_MODE = 1 << 2; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final int SET_AUDIO_STRETCH_MODE = 1 << 3; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mSet = 0; // params - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mAudioFallbackMode = AUDIO_FALLBACK_MODE_DEFAULT; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mAudioStretchMode = AUDIO_STRETCH_MODE_DEFAULT; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mPitch = 1.0f; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private float mSpeed = 1.0f; diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java index c5fd3c30236d..60a00529cb5d 100644 --- a/media/java/android/media/RemoteControlClient.java +++ b/media/java/android/media/RemoteControlClient.java @@ -24,6 +24,7 @@ import android.graphics.Bitmap; import android.media.session.MediaSession; import android.media.session.MediaSessionLegacyHelper; import android.media.session.PlaybackState; +import android.os.Build; import android.os.Bundle; import android.os.Looper; import android.os.SystemClock; @@ -816,7 +817,7 @@ import android.util.Log; * position updates. The playback position being "readable" is considered from the application's * point of view. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int MEDIA_POSITION_READABLE = 1 << 0; /** * @hide @@ -824,7 +825,7 @@ import android.util.Log; * playback position updates. The playback position being "writable" * is considered from the application's point of view. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int MEDIA_POSITION_WRITABLE = 1 << 1; /** @hide */ diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java index 35cfaca8562a..00fc2757a702 100644 --- a/media/java/android/media/RemoteController.java +++ b/media/java/android/media/RemoteController.java @@ -26,6 +26,7 @@ import android.media.session.MediaSession; import android.media.session.MediaSessionLegacyHelper; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -78,7 +79,7 @@ import java.util.List; private int mArtworkHeight = -1; private boolean mEnabled = true; // synchronized on mInfoLock, for USE_SESSION apis. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private MediaController mCurrentSession; /** diff --git a/media/java/android/media/RemoteDisplay.java b/media/java/android/media/RemoteDisplay.java index e529af9da935..2a0e54d1b767 100644 --- a/media/java/android/media/RemoteDisplay.java +++ b/media/java/android/media/RemoteDisplay.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Handler; import android.view.Surface; @@ -127,7 +128,7 @@ public final class RemoteDisplay { } // Called from native. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void notifyDisplayConnected(final Surface surface, final int width, final int height, final int flags, final int session) { mHandler.post(new Runnable() { @@ -139,7 +140,7 @@ public final class RemoteDisplay { } // Called from native. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void notifyDisplayDisconnected() { mHandler.post(new Runnable() { @Override @@ -150,7 +151,7 @@ public final class RemoteDisplay { } // Called from native. - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void notifyDisplayError(final int error) { mHandler.post(new Runnable() { @Override diff --git a/media/java/android/media/RemoteDisplayState.java b/media/java/android/media/RemoteDisplayState.java index fed361a960e6..370f5b1326f8 100644 --- a/media/java/android/media/RemoteDisplayState.java +++ b/media/java/android/media/RemoteDisplayState.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -41,10 +42,10 @@ public final class RemoteDisplayState implements Parcelable { /** * A list of all remote displays. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final ArrayList<RemoteDisplayInfo> displays; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public RemoteDisplayState() { displays = new ArrayList<RemoteDisplayInfo>(); } diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java index d02b49697821..bd783ce9f6b2 100644 --- a/media/java/android/media/Ringtone.java +++ b/media/java/android/media/Ringtone.java @@ -26,6 +26,7 @@ import android.content.res.Resources.NotFoundException; import android.database.Cursor; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.RemoteException; import android.provider.MediaStore; import android.provider.MediaStore.MediaColumns; @@ -73,7 +74,7 @@ public class Ringtone { private final IRingtonePlayer mRemotePlayer; private final Binder mRemoteToken; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private MediaPlayer mLocalPlayer; private final MyOnCompletionListener mCompletionListener = new MyOnCompletionListener(); diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 9deeb8fbab16..e2e13b048cf7 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -36,6 +36,7 @@ import android.content.res.AssetFileDescriptor; import android.database.Cursor; import android.database.StaleDataException; import android.net.Uri; +import android.os.Build; import android.os.Environment; import android.os.FileUtils; import android.os.IBinder; @@ -585,7 +586,7 @@ public class RingtoneManager { return new ExternalRingtonesCursorWrapper(res, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Cursor getMediaRingtones(Context context) { // MediaStore now returns ringtones on other storage devices, even when // we don't have storage or audio permissions @@ -728,7 +729,7 @@ public class RingtoneManager { * @param volumeShaperConfig config for volume shaper of the ringtone if applied. * @see #getRingtone(Context, Uri) */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static Ringtone getRingtone( final Context context, Uri ringtoneUri, int streamType, @Nullable VolumeShaper.Configuration volumeShaperConfig) { diff --git a/media/java/android/media/TimedText.java b/media/java/android/media/TimedText.java index 120642a8e7cb..fd615472903d 100644 --- a/media/java/android/media/TimedText.java +++ b/media/java/android/media/TimedText.java @@ -18,6 +18,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Rect; +import android.os.Build; import android.os.Parcel; import android.util.Log; @@ -736,7 +737,7 @@ public final class TimedText * List of CharPos, Karaoke, Font, Style, and HyperText, or 3) an instance of * Justification. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Object getObject(final int key) { if (containsKey(key)) { return mKeyObjectMap.get(key); diff --git a/media/java/android/media/ToneGenerator.java b/media/java/android/media/ToneGenerator.java index cc114a9092e1..140e70d32c78 100644 --- a/media/java/android/media/ToneGenerator.java +++ b/media/java/android/media/ToneGenerator.java @@ -17,6 +17,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; @@ -895,6 +896,6 @@ public class ToneGenerator protected void finalize() { native_finalize(); } @SuppressWarnings("unused") - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long mNativeContext; // accessed by native methods } diff --git a/media/java/android/media/TtmlRenderer.java b/media/java/android/media/TtmlRenderer.java index e5782642f4eb..3a6c3909bbaf 100644 --- a/media/java/android/media/TtmlRenderer.java +++ b/media/java/android/media/TtmlRenderer.java @@ -18,6 +18,7 @@ package android.media; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; @@ -49,7 +50,7 @@ public class TtmlRenderer extends SubtitleController.Renderer { private TtmlRenderingWidget mRenderingWidget; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public TtmlRenderer(Context context) { mContext = context; } diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java index 99dfe1e8e32f..df8d08e8e846 100644 --- a/media/java/android/media/VolumeShaper.java +++ b/media/java/android/media/VolumeShaper.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -413,23 +414,23 @@ public final class VolumeShaper implements AutoCloseable { */ // type of VolumeShaper - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mType; // valid when mType is TYPE_ID - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mId; // valid when mType is TYPE_SCALE - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mOptionFlags; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final double mDurationMs; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mInterpolatorType; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final float[] mTimes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final float[] mVolumes; @Override @@ -572,7 +573,7 @@ public final class VolumeShaper implements AutoCloseable { * Direct constructor for VolumeShaper. * Use the Builder instead. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Configuration(@Type int type, int id, @OptionFlag int optionFlags, @@ -1132,11 +1133,11 @@ public final class VolumeShaper implements AutoCloseable { private static final int FLAG_PUBLIC_ALL = FLAG_REVERSE | FLAG_TERMINATE; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mFlags; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mReplaceId; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final float mXOffset; @Override @@ -1198,7 +1199,7 @@ public final class VolumeShaper implements AutoCloseable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Operation(@Flag int flags, int replaceId, float xOffset) { mFlags = flags; mReplaceId = replaceId; @@ -1358,9 +1359,9 @@ public final class VolumeShaper implements AutoCloseable { * Not for public use. */ public static final class State implements Parcelable { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mVolume; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private float mXOffset; @Override @@ -1411,7 +1412,7 @@ public final class VolumeShaper implements AutoCloseable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) /* package */ State(float volume, float xOffset) { mVolume = volume; mXOffset = xOffset; diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java index f4fd1fca2ff9..67a4a4b1f851 100644 --- a/media/java/android/media/audiofx/AudioEffect.java +++ b/media/java/android/media/audiofx/AudioEffect.java @@ -914,7 +914,7 @@ public class AudioEffect { * In case of success, the returns the number of meaningful integers in value array. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getParameter(int[] param, int[] value) throws IllegalStateException { if (param.length > 2 || value.length > 2) { @@ -983,7 +983,7 @@ public class AudioEffect { * @see #getParameter(byte[], byte[]) * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getParameter(int[] param, byte[] value) throws IllegalStateException { if (param.length > 2) { diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java index 4e451c6e42b1..221147dcad8f 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -23,6 +23,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.media.AudioDeviceInfo; import android.media.AudioFormat; import android.media.AudioSystem; +import android.os.Build; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -34,24 +35,24 @@ import java.util.Objects; @SystemApi public class AudioMix { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private AudioMixingRule mRule; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private AudioFormat mFormat; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mRouteFlags; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mMixType = MIX_TYPE_INVALID; // written by AudioPolicy int mMixState = MIX_STATE_DISABLED; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int mCallbackFlags; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) String mDeviceAddress; // initialized in constructor, read by AudioPolicyConfig - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final int mDeviceSystemType; // an AudioSystem.DEVICE_* value, not AudioDeviceInfo.TYPE_* /** diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java index f6f982a4ebe2..de153135eeb9 100644 --- a/media/java/android/media/audiopolicy/AudioMixingRule.java +++ b/media/java/android/media/audiopolicy/AudioMixingRule.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.media.AudioAttributes; +import android.os.Build; import android.os.Parcel; import android.util.Log; @@ -109,11 +110,11 @@ public class AudioMixingRule { /** @hide */ public static final class AudioMixMatchCriterion { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final AudioAttributes mAttr; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final int mIntProp; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final int mRule; /** input parameters must be valid */ @@ -199,13 +200,13 @@ public class AudioMixingRule { private final int mTargetMixType; int getTargetMixType() { return mTargetMixType; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final ArrayList<AudioMixMatchCriterion> mCriteria; /** @hide */ public ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mAllowPrivilegedPlaybackCapture = false; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mVoiceCommunicationCaptureAllowed = false; /** @hide */ diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index 3af2e17960ae..38e2bdfc308d 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -22,7 +22,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.PendingIntent; -import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; @@ -462,21 +461,14 @@ public final class MediaController { return mTag; } - /* - * @hide - */ - ISessionController getSessionBinder() { - return mSessionBinder; - } - /** - * @hide + * Returns whether this and {@code other} media controller controls the same session. + * @deprecated Check equality of {@link #getSessionToken() tokens} instead. */ - @UnsupportedAppUsage(publicAlternatives = "Check equality of {@link #getSessionToken() tokens}" - + "instead.") - public boolean controlsSameSession(MediaController other) { + @Deprecated + public boolean controlsSameSession(@Nullable MediaController other) { if (other == null) return false; - return mSessionBinder.asBinder() == other.getSessionBinder().asBinder(); + return mToken.equals(other.mToken); } private void addCallbackLocked(Callback cb, Handler handler) { diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index f582d2addf17..14b236890e4a 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -33,6 +33,7 @@ import android.media.VolumeProvider; import android.media.session.MediaSessionManager.RemoteUserInfo; import android.net.Uri; import android.os.BadParcelableException; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -1390,7 +1391,7 @@ public final class MediaSession { public static final int UNKNOWN_ID = -1; private final MediaDescription mDescription; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final long mId; /** diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java index 16a517b72119..0a1eefae59d6 100644 --- a/media/java/android/media/soundtrigger/SoundTriggerDetector.java +++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java @@ -28,6 +28,7 @@ import android.hardware.soundtrigger.SoundTrigger; import android.hardware.soundtrigger.SoundTrigger.ModuleProperties; import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig; import android.media.AudioFormat; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -192,7 +193,7 @@ public final class SoundTriggerDetector { * @hide */ @Nullable - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public byte[] getData() { if (!mTriggerAvailable) { return mData; @@ -220,7 +221,7 @@ public final class SoundTriggerDetector { * @hide */ @Nullable - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Integer getCaptureSession() { if (mCaptureAvailable) { return mCaptureSession; diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java index 0ff8d9e96220..00e3bcebd0f3 100644 --- a/media/java/android/media/soundtrigger/SoundTriggerManager.java +++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java @@ -38,6 +38,7 @@ import android.media.permission.ClearCallingIdentityContext; import android.media.permission.Identity; import android.media.permission.SafeCloseable; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.ParcelUuid; @@ -382,7 +383,7 @@ public final class SoundTriggerManager { * @hide */ @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int stopRecognition(UUID soundModelId) { if (soundModelId == null) { return STATUS_ERROR; @@ -399,7 +400,7 @@ public final class SoundTriggerManager { * @hide */ @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int unloadSoundModel(UUID soundModelId) { if (soundModelId == null) { return STATUS_ERROR; diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java index 377b2bc19c6b..195ad5bc10f9 100644 --- a/media/java/android/media/tv/TvInputInfo.java +++ b/media/java/android/media/tv/TvInputInfo.java @@ -38,6 +38,7 @@ import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.HdmiUtils; import android.hardware.hdmi.HdmiUtils.HdmiAddressRelativePosition; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -326,7 +327,7 @@ public final class TvInputInfo implements Parcelable { * Returns the component of the service that implements this TV input. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ComponentName getComponent() { return new ComponentName(mService.serviceInfo.packageName, mService.serviceInfo.name); } diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 95c4f2a025d7..945fb3bff936 100755 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -34,6 +34,7 @@ import android.hardware.hdmi.HdmiDeviceInfo; import android.media.PlaybackParams; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -406,7 +407,7 @@ public abstract class TvInputService extends Service { private OverlayViewCleanUpTask mOverlayViewCleanUpTask; private boolean mOverlayViewEnabled; private IBinder mWindowToken; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Rect mOverlayFrame; private long mStartPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME; private long mCurrentPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME; diff --git a/media/java/android/media/tv/tuner/filter/AvSettings.java b/media/java/android/media/tv/tuner/filter/AvSettings.java index 5d9d53174b3e..e482875c38d3 100644 --- a/media/java/android/media/tv/tuner/filter/AvSettings.java +++ b/media/java/android/media/tv/tuner/filter/AvSettings.java @@ -199,6 +199,7 @@ public class AvSettings extends Settings { /** * Get the Audio Stream Type. */ + @AudioStreamType public int getAudioStreamType() { return mAudioStreamType; } @@ -206,6 +207,7 @@ public class AvSettings extends Settings { /** * Get the Video Stream Type. */ + @VideoStreamType public int getVideoStreamType() { return mVideoStreamType; } diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java index 1386cba5f9ca..ee70714ce763 100644 --- a/media/java/android/service/media/MediaBrowserService.java +++ b/media/java/android/service/media/MediaBrowserService.java @@ -32,6 +32,7 @@ import android.media.session.MediaSession; import android.media.session.MediaSessionManager; import android.media.session.MediaSessionManager.RemoteUserInfo; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -87,7 +88,7 @@ public abstract class MediaBrowserService extends Service { * A key for passing the MediaItem to the ResultReceiver in getItem. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String KEY_MEDIA_ITEM = "media_item"; private static final int RESULT_FLAG_OPTION_NOT_HANDLED = 1 << 0; diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index 677d3c00062f..ff2e1d490c2e 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -97,6 +97,7 @@ package android { field public static final String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE"; field public static final String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS"; field public static final String MANAGE_EXTERNAL_STORAGE = "android.permission.MANAGE_EXTERNAL_STORAGE"; + field public static final String MANAGE_ONGOING_CALLS = "android.permission.MANAGE_ONGOING_CALLS"; field public static final String MANAGE_OWN_CALLS = "android.permission.MANAGE_OWN_CALLS"; field public static final String MASTER_CLEAR = "android.permission.MASTER_CLEAR"; field public static final String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL"; @@ -17846,6 +17847,7 @@ package android.hardware.camera2 { public class CaptureResult extends android.hardware.camera2.CameraMetadata<android.hardware.camera2.CaptureResult.Key<?>> { method @Nullable public <T> T get(android.hardware.camera2.CaptureResult.Key<T>); + method @NonNull public String getCameraId(); method public long getFrameNumber(); method @NonNull public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getKeys(); method @NonNull public android.hardware.camera2.CaptureRequest getRequest(); @@ -28569,6 +28571,7 @@ package android.media.session { public final class MediaController { ctor public MediaController(@NonNull android.content.Context, @NonNull android.media.session.MediaSession.Token); method public void adjustVolume(int, int); + method @Deprecated public boolean controlsSameSession(@Nullable android.media.session.MediaController); method public boolean dispatchMediaButtonEvent(@NonNull android.view.KeyEvent); method @Nullable public android.os.Bundle getExtras(); method public long getFlags(); @@ -37407,6 +37410,9 @@ package android.provider { ctor public CallLog.Calls(); method public static String getLastOutgoingCall(android.content.Context); field public static final int ANSWERED_EXTERNALLY_TYPE = 7; // 0x7 + field public static final long AUTO_MISSED_EMERGENCY_CALL = 1L; // 0x1L + field public static final long AUTO_MISSED_MAXIMUM_DIALING = 4L; // 0x4L + field public static final long AUTO_MISSED_MAXIMUM_RINGING = 2L; // 0x2L field public static final int BLOCKED_TYPE = 6; // 0x6 field public static final String BLOCK_REASON = "block_reason"; field public static final int BLOCK_REASON_BLOCKED_NUMBER = 3; // 0x3 @@ -37452,6 +37458,8 @@ package android.provider { field public static final String IS_READ = "is_read"; field public static final String LAST_MODIFIED = "last_modified"; field public static final String LIMIT_PARAM_KEY = "limit"; + field public static final String MISSED_REASON = "missed_reason"; + field public static final long MISSED_REASON_NOT_MISSED = 0L; // 0x0L field public static final int MISSED_TYPE = 3; // 0x3 field public static final String NEW = "new"; field public static final String NUMBER = "number"; @@ -37468,6 +37476,13 @@ package android.provider { field public static final int REJECTED_TYPE = 5; // 0x5 field public static final String TRANSCRIPTION = "transcription"; field public static final String TYPE = "type"; + field public static final long USER_MISSED_CALL_FILTERS_TIMEOUT = 4194304L; // 0x400000L + field public static final long USER_MISSED_CALL_SCREENING_SERVICE_SILENCED = 2097152L; // 0x200000L + field public static final long USER_MISSED_DND_MODE = 262144L; // 0x40000L + field public static final long USER_MISSED_LOW_RING_VOLUME = 524288L; // 0x80000L + field public static final long USER_MISSED_NO_ANSWER = 65536L; // 0x10000L + field public static final long USER_MISSED_NO_VIBRATE = 1048576L; // 0x100000L + field public static final long USER_MISSED_SHORT_RING = 131072L; // 0x20000L field public static final String VIA_NUMBER = "via_number"; field public static final int VOICEMAIL_TYPE = 4; // 0x4 field public static final String VOICEMAIL_URI = "voicemail_uri"; @@ -42261,13 +42276,13 @@ package android.service.notification { method public boolean canBubble(); method public boolean canShowBadge(); method public android.app.NotificationChannel getChannel(); + method @Nullable public android.content.pm.ShortcutInfo getConversationShortcutInfo(); method public int getImportance(); method public CharSequence getImportanceExplanation(); method public String getKey(); method public long getLastAudiblyAlertedMillis(); method public String getOverrideGroupKey(); method public int getRank(); - method @Nullable public android.content.pm.ShortcutInfo getShortcutInfo(); method @NonNull public java.util.List<android.app.Notification.Action> getSmartActions(); method @NonNull public java.util.List<java.lang.CharSequence> getSmartReplies(); method public int getSuppressedVisualEffects(); @@ -44621,6 +44636,7 @@ package android.telecom { method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber(android.telecom.PhoneAccountHandle); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String, android.telecom.PhoneAccountHandle); + method public boolean hasCompanionInCallServiceAccess(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInCall(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInManagedCall(); method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle); @@ -46018,6 +46034,7 @@ package android.telephony { method @NonNull public java.util.List<java.lang.Integer> getAvailableServices(); method @Nullable public android.telephony.CellIdentity getCellIdentity(); method public int getDomain(); + method public int getNrState(); method @Nullable public String getRegisteredPlmn(); method public int getTransportType(); method public boolean isRegistered(); @@ -51882,7 +51899,6 @@ package android.view { } public interface OnReceiveContentCallback<T extends android.view.View> { - method @NonNull public java.util.Set<java.lang.String> getSupportedMimeTypes(@NonNull T); method public boolean onReceiveContent(@NonNull T, @NonNull android.view.OnReceiveContentCallback.Payload); } @@ -52460,7 +52476,7 @@ package android.view { method @IdRes public int getNextFocusRightId(); method @IdRes public int getNextFocusUpId(); method public android.view.View.OnFocusChangeListener getOnFocusChangeListener(); - method @Nullable public android.view.OnReceiveContentCallback<? extends android.view.View> getOnReceiveContentCallback(); + method @Nullable public String[] getOnReceiveContentMimeTypes(); method @ColorInt public int getOutlineAmbientShadowColor(); method public android.view.ViewOutlineProvider getOutlineProvider(); method @ColorInt public int getOutlineSpotShadowColor(); @@ -52655,6 +52671,7 @@ package android.view { method public void onProvideContentCaptureStructure(@NonNull android.view.ViewStructure, int); method public void onProvideStructure(android.view.ViewStructure); method public void onProvideVirtualStructure(android.view.ViewStructure); + method public boolean onReceiveContent(@NonNull android.view.OnReceiveContentCallback.Payload); method public android.view.PointerIcon onResolvePointerIcon(android.view.MotionEvent, int); method @CallSuper protected void onRestoreInstanceState(android.os.Parcelable); method public void onRtlPropertiesChanged(int); @@ -52812,7 +52829,7 @@ package android.view { method public void setOnHoverListener(android.view.View.OnHoverListener); method public void setOnKeyListener(android.view.View.OnKeyListener); method public void setOnLongClickListener(@Nullable android.view.View.OnLongClickListener); - method public void setOnReceiveContentCallback(@Nullable android.view.OnReceiveContentCallback<? extends android.view.View>); + method public void setOnReceiveContentCallback(@Nullable String[], @Nullable android.view.OnReceiveContentCallback); method public void setOnScrollChangeListener(android.view.View.OnScrollChangeListener); method @Deprecated public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener); method public void setOnTouchListener(android.view.View.OnTouchListener); @@ -59642,7 +59659,6 @@ package android.widget { method public int getMinWidth(); method public final android.text.method.MovementMethod getMovementMethod(); method public int getOffsetForPosition(float, float); - method @Nullable public android.view.OnReceiveContentCallback<android.widget.TextView> getOnReceiveContentCallback(); method public android.text.TextPaint getPaint(); method public int getPaintFlags(); method public String getPrivateImeOptions(); @@ -59831,7 +59847,6 @@ package android.widget { public class TextViewOnReceiveContentCallback implements android.view.OnReceiveContentCallback<android.widget.TextView> { ctor public TextViewOnReceiveContentCallback(); - method @NonNull public java.util.Set<java.lang.String> getSupportedMimeTypes(@NonNull android.widget.TextView); method public boolean onReceiveContent(@NonNull android.widget.TextView, @NonNull android.view.OnReceiveContentCallback.Payload); } diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt index ae6ecc763aef..06e6d9ccbbf0 100644 --- a/non-updatable-api/module-lib-current.txt +++ b/non-updatable-api/module-lib-current.txt @@ -130,6 +130,7 @@ package android.provider { public final class DeviceConfig { field public static final String NAMESPACE_ALARM_MANAGER = "alarm_manager"; + field public static final String NAMESPACE_APP_STANDBY = "app_standby"; field public static final String NAMESPACE_DEVICE_IDLE = "device_idle"; } diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index ca70c7b13547..217c4b0674f5 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -109,7 +109,8 @@ package android { field public static final String LOCK_DEVICE = "android.permission.LOCK_DEVICE"; field public static final String LOOP_RADIO = "android.permission.LOOP_RADIO"; field public static final String MANAGE_ACCESSIBILITY = "android.permission.MANAGE_ACCESSIBILITY"; - field public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; + field @Deprecated public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; + field public static final String MANAGE_ACTIVITY_TASKS = "android.permission.MANAGE_ACTIVITY_TASKS"; field public static final String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS"; field public static final String MANAGE_APP_PREDICTIONS = "android.permission.MANAGE_APP_PREDICTIONS"; field public static final String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS"; @@ -403,6 +404,7 @@ package android.app { field public static final String OPSTR_LOADER_USAGE_STATS = "android:loader_usage_stats"; field public static final String OPSTR_MANAGE_EXTERNAL_STORAGE = "android:manage_external_storage"; field public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels"; + field public static final String OPSTR_MANAGE_ONGOING_CALLS = "android:manage_ongoing_calls"; field public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone"; field public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells"; field public static final String OPSTR_PLAY_AUDIO = "android:play_audio"; @@ -865,6 +867,7 @@ package android.app.admin { field public static final int PROVISIONING_TRIGGER_QR_CODE = 2; // 0x2 field public static final int PROVISIONING_TRIGGER_UNSPECIFIED = 0; // 0x0 field public static final int STATE_USER_PROFILE_COMPLETE = 4; // 0x4 + field public static final int STATE_USER_PROFILE_FINALIZED = 5; // 0x5 field public static final int STATE_USER_SETUP_COMPLETE = 2; // 0x2 field public static final int STATE_USER_SETUP_FINALIZED = 3; // 0x3 field public static final int STATE_USER_SETUP_INCOMPLETE = 1; // 0x1 @@ -2139,6 +2142,7 @@ package android.content.pm { method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable String); method @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable android.content.pm.SuspendDialogInfo); method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public void setSyntheticAppDetailsActivityEnabled(@NonNull String, boolean); + method public void setSystemAppState(@NonNull String, int); method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public abstract void setUpdateAvailable(@NonNull String, boolean); method @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public abstract boolean updateIntentVerificationStatusAsUser(@NonNull String, int, int); method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle); @@ -2217,11 +2221,16 @@ package android.content.pm { field @Deprecated public static final int MASK_PERMISSION_FLAGS = 255; // 0xff field public static final int MATCH_ANY_USER = 4194304; // 0x400000 field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000 + field public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 536870912; // 0x20000000 field public static final int MATCH_INSTANT = 8388608; // 0x800000 field public static final int MODULE_APEX_NAME = 1; // 0x1 field public static final int RESTRICTION_HIDE_FROM_SUGGESTIONS = 1; // 0x1 field public static final int RESTRICTION_HIDE_NOTIFICATIONS = 2; // 0x2 field public static final int RESTRICTION_NONE = 0; // 0x0 + field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN = 0; // 0x0 + field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE = 1; // 0x1 + field public static final int SYSTEM_APP_STATE_INSTALLED = 2; // 0x2 + field public static final int SYSTEM_APP_STATE_UNINSTALLED = 3; // 0x3 } public abstract static class PackageManager.DexModuleRegisterCallback { @@ -6634,6 +6643,7 @@ package android.net { method @NonNull public int[] getTransportTypes(); method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities); field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16 + field public static final int NET_CAPABILITY_OEM_PRIVATE = 26; // 0x1a field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18 } @@ -8879,6 +8889,7 @@ package android.service.autofill { public static final class Dataset.Builder { ctor public Dataset.Builder(@NonNull android.service.autofill.InlinePresentation); + method @NonNull public android.service.autofill.Dataset.Builder setContent(@NonNull android.view.autofill.AutofillId, @Nullable android.content.ClipData); method @NonNull public android.service.autofill.Dataset.Builder setFieldInlinePresentation(@NonNull android.view.autofill.AutofillId, @Nullable android.view.autofill.AutofillValue, @Nullable java.util.regex.Pattern, @NonNull android.service.autofill.InlinePresentation); } @@ -10658,6 +10669,7 @@ package android.telephony { method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMobileDataPolicyEnabled(int); + method public boolean isNrDualConnectivityEnabled(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String); @@ -10691,6 +10703,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabledStatus(int, boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean); + method public int setNrDualConnectivityState(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean); @@ -10730,6 +10743,11 @@ package android.telephony { field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1 field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0 field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE = 4; // 0x4 + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED = 1; // 0x1 + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR = 3; // 0x3 + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE = 2; // 0x2 + field public static final int ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS = 0; // 0x0 field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION"; field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID"; field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE"; @@ -10762,6 +10780,9 @@ package android.telephony { field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L + field public static final int NR_DUAL_CONNECTIVITY_DISABLE = 2; // 0x2 + field public static final int NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE = 3; // 0x3 + field public static final int NR_DUAL_CONNECTIVITY_ENABLE = 1; // 0x1 field public static final int RADIO_POWER_OFF = 0; // 0x0 field public static final int RADIO_POWER_ON = 1; // 0x1 field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2 @@ -10873,7 +10894,8 @@ package android.telephony.data { method public int getMtuV6(); method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses(); method public int getProtocolType(); - method public int getSuggestedRetryTime(); + method public long getRetryIntervalMillis(); + method @Deprecated public int getSuggestedRetryTime(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR; field public static final int HANDOVER_FAILURE_MODE_DO_FALLBACK = 1; // 0x1 @@ -10885,6 +10907,7 @@ package android.telephony.data { field public static final int LINK_STATUS_DORMANT = 1; // 0x1 field public static final int LINK_STATUS_INACTIVE = 0; // 0x0 field public static final int LINK_STATUS_UNKNOWN = -1; // 0xffffffff + field public static final int RETRY_INTERVAL_UNDEFINED = -1; // 0xffffffff } public static final class DataCallResponse.Builder { @@ -10903,7 +10926,8 @@ package android.telephony.data { method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>); method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int); - method @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setRetryIntervalMillis(long); + method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int); } public final class DataProfile implements android.os.Parcelable { diff --git a/opengl/java/android/opengl/EGL14.java b/opengl/java/android/opengl/EGL14.java index 90b46fd5901a..80e64e01559a 100644 --- a/opengl/java/android/opengl/EGL14.java +++ b/opengl/java/android/opengl/EGL14.java @@ -20,6 +20,7 @@ package android.opengl; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.SurfaceTexture; +import android.os.Build; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; @@ -164,7 +165,7 @@ public static final int EGL_CORE_NATIVE_ENGINE = 0x305B; /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static native EGLDisplay eglGetDisplay( long display_id ); diff --git a/opengl/java/javax/microedition/khronos/egl/EGL10.java b/opengl/java/javax/microedition/khronos/egl/EGL10.java index ea571c7311a1..abdbd11828db 100644 --- a/opengl/java/javax/microedition/khronos/egl/EGL10.java +++ b/opengl/java/javax/microedition/khronos/egl/EGL10.java @@ -17,6 +17,7 @@ package javax.microedition.khronos.egl; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; public interface EGL10 extends EGL { int EGL_SUCCESS = 0x3000; @@ -116,7 +117,7 @@ public interface EGL10 extends EGL { String eglQueryString(EGLDisplay display, int name); boolean eglQuerySurface(EGLDisplay display, EGLSurface surface, int attribute, int[] value); /** @hide **/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) boolean eglReleaseThread(); boolean eglSwapBuffers(EGLDisplay display, EGLSurface surface); boolean eglTerminate(EGLDisplay display); diff --git a/packages/CarSystemUI/res/values-af/strings.xml b/packages/CarSystemUI/res/values-af/strings.xml index b377ec47f6c6..cf288d74d61c 100644 --- a/packages/CarSystemUI/res/values-af/strings.xml +++ b/packages/CarSystemUI/res/values-af/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Enige gebruiker kan programme vir al die ander gebruikers opdateer."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Laai tans"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Laai tans gebruiker (van <xliff:g id="FROM_USER">%1$d</xliff:g> na <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Maak toe"</string> </resources> diff --git a/packages/CarSystemUI/res/values-am/strings.xml b/packages/CarSystemUI/res/values-am/strings.xml index 4f2bba8aa1de..8281631312b7 100644 --- a/packages/CarSystemUI/res/values-am/strings.xml +++ b/packages/CarSystemUI/res/values-am/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"ማንኛውም ተጠቃሚ መተግበሪያዎችን ለሌሎች ተጠቃሚዎች ሁሉ ማዘመን ይችላል።"</string> <string name="car_loading_profile" msgid="4507385037552574474">"በመጫን ላይ"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ተጠቃሚን (ከ<xliff:g id="FROM_USER">%1$d</xliff:g> ወደ <xliff:g id="TO_USER">%2$d</xliff:g>) በመጫን ላይ"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ዝጋ"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ar/strings.xml b/packages/CarSystemUI/res/values-ar/strings.xml index 61a08a4eae49..d9abb0af5608 100644 --- a/packages/CarSystemUI/res/values-ar/strings.xml +++ b/packages/CarSystemUI/res/values-ar/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"يمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين."</string> <string name="car_loading_profile" msgid="4507385037552574474">"جارٍ التحميل"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"جارٍ تحميل الملف الشخصي الجديد للمستخدم (من <xliff:g id="FROM_USER">%1$d</xliff:g> إلى <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"إغلاق"</string> </resources> diff --git a/packages/CarSystemUI/res/values-as/strings.xml b/packages/CarSystemUI/res/values-as/strings.xml index edc36215bcce..d8710555149b 100644 --- a/packages/CarSystemUI/res/values-as/strings.xml +++ b/packages/CarSystemUI/res/values-as/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"যিকোনো ব্যৱহাৰকাৰীয়ে অন্য ব্যৱহাৰকাৰীৰ বাবে এপ্সমূহ আপডে’ট কৰিব পাৰে।"</string> <string name="car_loading_profile" msgid="4507385037552574474">"ল’ড হৈ আছে"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ব্যৱহাৰকাৰী ল’ড হৈ আছে (<xliff:g id="FROM_USER">%1$d</xliff:g>ৰ পৰা to <xliff:g id="TO_USER">%2$d</xliff:g>লৈ)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"বন্ধ কৰক"</string> </resources> diff --git a/packages/CarSystemUI/res/values-az/strings.xml b/packages/CarSystemUI/res/values-az/strings.xml index 398f5c38c03e..89c9eb4ee258 100644 --- a/packages/CarSystemUI/res/values-az/strings.xml +++ b/packages/CarSystemUI/res/values-az/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"İstənilən istifadəçi digər bütün istifadəçilər üçün tətbiqləri güncəlləyə bilər."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Yüklənir"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"İstifadəçi yüklənir (<xliff:g id="FROM_USER">%1$d</xliff:g>-<xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Qapadın"</string> </resources> diff --git a/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml b/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml index 6c1979f7a95a..6aee01321ade 100644 --- a/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Svaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Učitava se"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Profil korisnika se učitava (iz<xliff:g id="FROM_USER">%1$d</xliff:g> u <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zatvori"</string> </resources> diff --git a/packages/CarSystemUI/res/values-be/strings.xml b/packages/CarSystemUI/res/values-be/strings.xml index 4e9794855e47..fde42732283f 100644 --- a/packages/CarSystemUI/res/values-be/strings.xml +++ b/packages/CarSystemUI/res/values-be/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Кожны карыстальнік прылады можа абнаўляць праграмы для ўсіх іншых карыстальнікаў."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Ідзе загрузка"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ідзе загрузка профілю карыстальніка (ад <xliff:g id="FROM_USER">%1$d</xliff:g> да <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Закрыць"</string> </resources> diff --git a/packages/CarSystemUI/res/values-bg/strings.xml b/packages/CarSystemUI/res/values-bg/strings.xml index 7dfab54b8add..25f284515b9f 100644 --- a/packages/CarSystemUI/res/values-bg/strings.xml +++ b/packages/CarSystemUI/res/values-bg/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Всеки потребител може да актуализира приложенията за всички останали потребители."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Зарежда се"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Потребителят се зарежда (от <xliff:g id="FROM_USER">%1$d</xliff:g> до <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Затваряне"</string> </resources> diff --git a/packages/CarSystemUI/res/values-bn/strings.xml b/packages/CarSystemUI/res/values-bn/strings.xml index a45e66e8c2f2..5664cc12e109 100644 --- a/packages/CarSystemUI/res/values-bn/strings.xml +++ b/packages/CarSystemUI/res/values-bn/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"যেকোনও ব্যবহারকারী বাকি সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন।"</string> <string name="car_loading_profile" msgid="4507385037552574474">"লোড হচ্ছে"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ব্যবহারকারীর প্রোফাইল লোড করা হচ্ছে (<xliff:g id="FROM_USER">%1$d</xliff:g> থেকে <xliff:g id="TO_USER">%2$d</xliff:g>-এ)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"বন্ধ করুন"</string> </resources> diff --git a/packages/CarSystemUI/res/values-bs/strings.xml b/packages/CarSystemUI/res/values-bs/strings.xml index 119f2d7bf793..588771e41740 100644 --- a/packages/CarSystemUI/res/values-bs/strings.xml +++ b/packages/CarSystemUI/res/values-bs/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Bilo koji korisnik može ažurirati aplikacije za sve druge korisnike."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Učitavanje"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Učitavanje korisnika (od korisnika <xliff:g id="FROM_USER">%1$d</xliff:g> do korisnika <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zatvori"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ca/strings.xml b/packages/CarSystemUI/res/values-ca/strings.xml index b1e722e95c58..cbd469b68a62 100644 --- a/packages/CarSystemUI/res/values-ca/strings.xml +++ b/packages/CarSystemUI/res/values-ca/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string> <string name="car_loading_profile" msgid="4507385037552574474">"S\'està carregant"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"S\'està carregant l\'usuari (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Tanca"</string> </resources> diff --git a/packages/CarSystemUI/res/values-cs/strings.xml b/packages/CarSystemUI/res/values-cs/strings.xml index dd4472f06aa3..7657e32b0223 100644 --- a/packages/CarSystemUI/res/values-cs/strings.xml +++ b/packages/CarSystemUI/res/values-cs/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Každý uživatel může aktualizovat aplikace všech ostatních uživatelů."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Načítání"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Načítání uživatele (předchozí: <xliff:g id="FROM_USER">%1$d</xliff:g>, následující: <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zavřít"</string> </resources> diff --git a/packages/CarSystemUI/res/values-da/strings.xml b/packages/CarSystemUI/res/values-da/strings.xml index 6c08aa56bc7e..120929e34347 100644 --- a/packages/CarSystemUI/res/values-da/strings.xml +++ b/packages/CarSystemUI/res/values-da/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Alle brugere kan opdatere apps for alle andre brugere."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Indlæser"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Indlæser bruger (fra <xliff:g id="FROM_USER">%1$d</xliff:g> til <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Luk"</string> </resources> diff --git a/packages/CarSystemUI/res/values-de/strings.xml b/packages/CarSystemUI/res/values-de/strings.xml index 131dee19b0ca..e2437f0c55cb 100644 --- a/packages/CarSystemUI/res/values-de/strings.xml +++ b/packages/CarSystemUI/res/values-de/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Jeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Wird geladen"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Nutzer wird geladen (von <xliff:g id="FROM_USER">%1$d</xliff:g> bis <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Schließen"</string> </resources> diff --git a/packages/CarSystemUI/res/values-el/strings.xml b/packages/CarSystemUI/res/values-el/strings.xml index 66f8d18472c9..9b24fa488923 100644 --- a/packages/CarSystemUI/res/values-el/strings.xml +++ b/packages/CarSystemUI/res/values-el/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Οποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Φόρτωση"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Φόρτωση χρήστη (από <xliff:g id="FROM_USER">%1$d</xliff:g> έως <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Κλείσιμο"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rAU/strings.xml b/packages/CarSystemUI/res/values-en-rAU/strings.xml index b3e358fbb6ef..8eb76c20d8a2 100644 --- a/packages/CarSystemUI/res/values-en-rAU/strings.xml +++ b/packages/CarSystemUI/res/values-en-rAU/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rCA/strings.xml b/packages/CarSystemUI/res/values-en-rCA/strings.xml index b3e358fbb6ef..8eb76c20d8a2 100644 --- a/packages/CarSystemUI/res/values-en-rCA/strings.xml +++ b/packages/CarSystemUI/res/values-en-rCA/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rGB/strings.xml b/packages/CarSystemUI/res/values-en-rGB/strings.xml index b3e358fbb6ef..8eb76c20d8a2 100644 --- a/packages/CarSystemUI/res/values-en-rGB/strings.xml +++ b/packages/CarSystemUI/res/values-en-rGB/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rIN/strings.xml b/packages/CarSystemUI/res/values-en-rIN/strings.xml index b3e358fbb6ef..8eb76c20d8a2 100644 --- a/packages/CarSystemUI/res/values-en-rIN/strings.xml +++ b/packages/CarSystemUI/res/values-en-rIN/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rXC/strings.xml b/packages/CarSystemUI/res/values-en-rXC/strings.xml index eaf6f51d3092..37a568bf3e5a 100644 --- a/packages/CarSystemUI/res/values-en-rXC/strings.xml +++ b/packages/CarSystemUI/res/values-en-rXC/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Close"</string> </resources> diff --git a/packages/CarSystemUI/res/values-es-rUS/strings.xml b/packages/CarSystemUI/res/values-es-rUS/strings.xml index 6a5f8ce43318..16aba86f3c3f 100644 --- a/packages/CarSystemUI/res/values-es-rUS/strings.xml +++ b/packages/CarSystemUI/res/values-es-rUS/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario podrá actualizar las apps de otras personas."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Cerrar"</string> </resources> diff --git a/packages/CarSystemUI/res/values-es/strings.xml b/packages/CarSystemUI/res/values-es/strings.xml index c43d7e54d559..8aad2cad9cf2 100644 --- a/packages/CarSystemUI/res/values-es/strings.xml +++ b/packages/CarSystemUI/res/values-es/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Cerrar"</string> </resources> diff --git a/packages/CarSystemUI/res/values-et/strings.xml b/packages/CarSystemUI/res/values-et/strings.xml index ad82d5fc230b..14ec9df45c2d 100644 --- a/packages/CarSystemUI/res/values-et/strings.xml +++ b/packages/CarSystemUI/res/values-et/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Iga kasutaja saab rakendusi värskendada kõigi teiste kasutajate jaoks."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Laadimine"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Kasutaja laadimine (<xliff:g id="FROM_USER">%1$d</xliff:g> > <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Sule"</string> </resources> diff --git a/packages/CarSystemUI/res/values-eu/strings.xml b/packages/CarSystemUI/res/values-eu/strings.xml index 5d2ca3548af2..9139e650187e 100644 --- a/packages/CarSystemUI/res/values-eu/strings.xml +++ b/packages/CarSystemUI/res/values-eu/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Edozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Kargatzen"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Erabiltzailea kargatzen (<xliff:g id="FROM_USER">%1$d</xliff:g> izatetik<xliff:g id="TO_USER">%2$d</xliff:g> izatera igaroko da)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Itxi"</string> </resources> diff --git a/packages/CarSystemUI/res/values-fa/strings.xml b/packages/CarSystemUI/res/values-fa/strings.xml index ef37b654bde9..3f53b1145b96 100644 --- a/packages/CarSystemUI/res/values-fa/strings.xml +++ b/packages/CarSystemUI/res/values-fa/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"هر کاربری میتواند برنامهها را برای همه کاربران دیگر بهروزرسانی کند."</string> <string name="car_loading_profile" msgid="4507385037552574474">"درحال بارگیری"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"بارگیری کاربر (از <xliff:g id="FROM_USER">%1$d</xliff:g> تا <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"بستن"</string> </resources> diff --git a/packages/CarSystemUI/res/values-fi/strings.xml b/packages/CarSystemUI/res/values-fi/strings.xml index 10bb0c5b782c..79b53f6daa2c 100644 --- a/packages/CarSystemUI/res/values-fi/strings.xml +++ b/packages/CarSystemUI/res/values-fi/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Ladataan"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ladataan käyttäjäprofiilia (<xliff:g id="FROM_USER">%1$d</xliff:g>–<xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Sulje"</string> </resources> diff --git a/packages/CarSystemUI/res/values-fr-rCA/strings.xml b/packages/CarSystemUI/res/values-fr-rCA/strings.xml index bebd3f441410..b1905490f229 100644 --- a/packages/CarSystemUI/res/values-fr-rCA/strings.xml +++ b/packages/CarSystemUI/res/values-fr-rCA/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Tout utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Chargement en cours…"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Chargement de l\'utilisateur (de <xliff:g id="FROM_USER">%1$d</xliff:g> vers <xliff:g id="TO_USER">%2$d</xliff:g>) en cours…"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Fermer"</string> </resources> diff --git a/packages/CarSystemUI/res/values-fr/strings.xml b/packages/CarSystemUI/res/values-fr/strings.xml index 3d498d2f9ca7..5a905a000c42 100644 --- a/packages/CarSystemUI/res/values-fr/strings.xml +++ b/packages/CarSystemUI/res/values-fr/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"N\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Chargement…"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Chargement de l\'utilisateur (de <xliff:g id="FROM_USER">%1$d</xliff:g> à <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Fermer"</string> </resources> diff --git a/packages/CarSystemUI/res/values-gl/strings.xml b/packages/CarSystemUI/res/values-gl/strings.xml index e4586cc17a73..e77df4f50272 100644 --- a/packages/CarSystemUI/res/values-gl/strings.xml +++ b/packages/CarSystemUI/res/values-gl/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Calquera usuario pode actualizar as aplicacións para o resto dos usuarios."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (do <xliff:g id="FROM_USER">%1$d</xliff:g> ao <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Pechar"</string> </resources> diff --git a/packages/CarSystemUI/res/values-gu/strings.xml b/packages/CarSystemUI/res/values-gu/strings.xml index ba884e410187..174d7a724240 100644 --- a/packages/CarSystemUI/res/values-gu/strings.xml +++ b/packages/CarSystemUI/res/values-gu/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"કોઈપણ વપરાશકર્તા અન્ય બધા વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string> <string name="car_loading_profile" msgid="4507385037552574474">"લોડ કરી રહ્યાં છીએ"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"વપરાશકર્તાને લોડ કરી રહ્યાં છીએ (<xliff:g id="FROM_USER">%1$d</xliff:g>માંથી <xliff:g id="TO_USER">%2$d</xliff:g>માં)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"બંધ કરો"</string> </resources> diff --git a/packages/CarSystemUI/res/values-hi/strings.xml b/packages/CarSystemUI/res/values-hi/strings.xml index 95454a53709f..83321fd630b9 100644 --- a/packages/CarSystemUI/res/values-hi/strings.xml +++ b/packages/CarSystemUI/res/values-hi/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"कोई भी उपयोगकर्ता, बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string> <string name="car_loading_profile" msgid="4507385037552574474">"लोड हो रही है"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"उपयोगकर्ता को लोड किया जा रहा है (<xliff:g id="FROM_USER">%1$d</xliff:g> से <xliff:g id="TO_USER">%2$d</xliff:g> पर)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"बंद करें"</string> </resources> diff --git a/packages/CarSystemUI/res/values-hr/strings.xml b/packages/CarSystemUI/res/values-hr/strings.xml index f3aaf63eac18..872fc69d8cfb 100644 --- a/packages/CarSystemUI/res/values-hr/strings.xml +++ b/packages/CarSystemUI/res/values-hr/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Svaki korisnik može ažurirati aplikacije za ostale korisnike."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Učitavanje"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Učitavanje korisnika (od <xliff:g id="FROM_USER">%1$d</xliff:g> do <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zatvori"</string> </resources> diff --git a/packages/CarSystemUI/res/values-hu/strings.xml b/packages/CarSystemUI/res/values-hu/strings.xml index b63ba8b8ed60..63328f370ed3 100644 --- a/packages/CarSystemUI/res/values-hu/strings.xml +++ b/packages/CarSystemUI/res/values-hu/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Bármely felhasználó frissítheti az alkalmazásokat az összes felhasználó számára."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Betöltés"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Felhasználó betöltése (<xliff:g id="FROM_USER">%1$d</xliff:g> → <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Bezárás"</string> </resources> diff --git a/packages/CarSystemUI/res/values-hy/strings.xml b/packages/CarSystemUI/res/values-hy/strings.xml index e2a2c6bf459c..778f6954da3d 100644 --- a/packages/CarSystemUI/res/values-hy/strings.xml +++ b/packages/CarSystemUI/res/values-hy/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Ցանկացած օգտատեր կարող է թարմացնել հավելվածները բոլոր մյուս հաշիվների համար։"</string> <string name="car_loading_profile" msgid="4507385037552574474">"Բեռնում"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Օգտատերը բեռնվում է (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Փակել"</string> </resources> diff --git a/packages/CarSystemUI/res/values-in/strings.xml b/packages/CarSystemUI/res/values-in/strings.xml index 0a70d261b77d..386d79e0e88b 100644 --- a/packages/CarSystemUI/res/values-in/strings.xml +++ b/packages/CarSystemUI/res/values-in/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Setiap pengguna dapat mengupdate aplikasi untuk semua pengguna lain."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Memuat"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Memuat pengguna (dari <xliff:g id="FROM_USER">%1$d</xliff:g> menjadi <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Tutup"</string> </resources> diff --git a/packages/CarSystemUI/res/values-is/strings.xml b/packages/CarSystemUI/res/values-is/strings.xml index ea6b031c72b9..5a927aa0928a 100644 --- a/packages/CarSystemUI/res/values-is/strings.xml +++ b/packages/CarSystemUI/res/values-is/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Allir notendur geta uppfært forrit fyrir alla aðra notendur."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Hleður"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Hleður notanda (frá <xliff:g id="FROM_USER">%1$d</xliff:g> til <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Loka"</string> </resources> diff --git a/packages/CarSystemUI/res/values-it/strings.xml b/packages/CarSystemUI/res/values-it/strings.xml index ecbcd5d9dadd..41d7ad4f70ee 100644 --- a/packages/CarSystemUI/res/values-it/strings.xml +++ b/packages/CarSystemUI/res/values-it/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsiasi utente può aggiornare le app per tutti gli altri."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Caricamento"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Caricamento dell\'utente (da <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Chiudi"</string> </resources> diff --git a/packages/CarSystemUI/res/values-iw/strings.xml b/packages/CarSystemUI/res/values-iw/strings.xml index fe182a3b7251..f419cac56d48 100644 --- a/packages/CarSystemUI/res/values-iw/strings.xml +++ b/packages/CarSystemUI/res/values-iw/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"כל משתמש יכול לעדכן אפליקציות לכל שאר המשתמשים."</string> <string name="car_loading_profile" msgid="4507385037552574474">"בטעינה"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"המשתמש בטעינה (מהמשתמש <xliff:g id="FROM_USER">%1$d</xliff:g> אל <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"סגירה"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ja/strings.xml b/packages/CarSystemUI/res/values-ja/strings.xml index 14486758dcd1..9cf056fdf7c6 100644 --- a/packages/CarSystemUI/res/values-ja/strings.xml +++ b/packages/CarSystemUI/res/values-ja/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"どのユーザーも他のすべてのユーザーに代わってアプリを更新できます。"</string> <string name="car_loading_profile" msgid="4507385037552574474">"読み込んでいます"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ユーザーを読み込んでいます(<xliff:g id="FROM_USER">%1$d</xliff:g>~<xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"閉じる"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ka/strings.xml b/packages/CarSystemUI/res/values-ka/strings.xml index 0fef7e55f27e..7d62c62a8abe 100644 --- a/packages/CarSystemUI/res/values-ka/strings.xml +++ b/packages/CarSystemUI/res/values-ka/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"ნებისმიერ მომხმარებელს შეუძლია აპები ყველა სხვა მომხმარებლისათვის განაახლოს."</string> <string name="car_loading_profile" msgid="4507385037552574474">"იტვირთება"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"იტვირთება მომხმარებელი (<xliff:g id="FROM_USER">%1$d</xliff:g>-დან <xliff:g id="TO_USER">%2$d</xliff:g>-მდე)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"დახურვა"</string> </resources> diff --git a/packages/CarSystemUI/res/values-kk/strings.xml b/packages/CarSystemUI/res/values-kk/strings.xml index a4cf78709515..2dd1b66f1778 100644 --- a/packages/CarSystemUI/res/values-kk/strings.xml +++ b/packages/CarSystemUI/res/values-kk/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Кез келген пайдаланушы қолданбаларды басқа пайдаланушылар үшін жаңарта алады."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Жүктелуде"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Пайдаланушы профилі жүктелуде (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Жабу"</string> </resources> diff --git a/packages/CarSystemUI/res/values-km/strings.xml b/packages/CarSystemUI/res/values-km/strings.xml index 7b9a093d7f39..709cfe572ce9 100644 --- a/packages/CarSystemUI/res/values-km/strings.xml +++ b/packages/CarSystemUI/res/values-km/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"អ្នកប្រើប្រាស់ណាក៏អាចដំឡើងកំណែកម្មវិធីសម្រាប់អ្នកប្រើប្រាស់ទាំងអស់ផ្សេងទៀតបានដែរ។"</string> <string name="car_loading_profile" msgid="4507385037552574474">"កំពុងផ្ទុក"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"កំពុងផ្ទុកអ្នកប្រើប្រាស់ (ពី <xliff:g id="FROM_USER">%1$d</xliff:g> ដល់ <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"បិទ"</string> </resources> diff --git a/packages/CarSystemUI/res/values-kn/strings.xml b/packages/CarSystemUI/res/values-kn/strings.xml index 34a83553d5c0..b9667df3afb3 100644 --- a/packages/CarSystemUI/res/values-kn/strings.xml +++ b/packages/CarSystemUI/res/values-kn/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"ಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಆ್ಯಪ್ಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು."</string> <string name="car_loading_profile" msgid="4507385037552574474">"ಲೋಡ್ ಆಗುತ್ತಿದೆ"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ಬಳಕೆದಾರರನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ (<xliff:g id="FROM_USER">%1$d</xliff:g> ನಿಂದ <xliff:g id="TO_USER">%2$d</xliff:g> ವರೆಗೆ)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ಮುಚ್ಚಿರಿ"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ko/strings.xml b/packages/CarSystemUI/res/values-ko/strings.xml index b570c5c6b81e..17a24667b547 100644 --- a/packages/CarSystemUI/res/values-ko/strings.xml +++ b/packages/CarSystemUI/res/values-ko/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"누구나 다른 모든 사용자를 위해 앱을 업데이트할 수 있습니다."</string> <string name="car_loading_profile" msgid="4507385037552574474">"로드 중"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"사용자 로드 중(<xliff:g id="FROM_USER">%1$d</xliff:g>님에서 <xliff:g id="TO_USER">%2$d</xliff:g>님으로)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"닫기"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ky/strings.xml b/packages/CarSystemUI/res/values-ky/strings.xml index c66b34ffb9c1..dd9225a1aa0b 100644 --- a/packages/CarSystemUI/res/values-ky/strings.xml +++ b/packages/CarSystemUI/res/values-ky/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу калган бардык колдонуучулар үчүн да жаңырта алат."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Жүктөлүүдө"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Колдонуучу тууралуу маалымат жүктөлүүдө (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Жабуу"</string> </resources> diff --git a/packages/CarSystemUI/res/values-lo/strings.xml b/packages/CarSystemUI/res/values-lo/strings.xml index 2bf19e03b82a..bc94a5104c6b 100644 --- a/packages/CarSystemUI/res/values-lo/strings.xml +++ b/packages/CarSystemUI/res/values-lo/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"ຜູ້ໃຊ້ຕ່າງໆສາມາດອັບເດດແອັບສຳລັບຜູ້ໃຊ້ອື່ນທັງໝົດໄດ້."</string> <string name="car_loading_profile" msgid="4507385037552574474">"ກຳລັງໂຫຼດ"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ກຳລັງໂຫຼດຜູ້ໃຊ້ (ຈາກ <xliff:g id="FROM_USER">%1$d</xliff:g> ໄປຍັງ <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ປິດ"</string> </resources> diff --git a/packages/CarSystemUI/res/values-lt/strings.xml b/packages/CarSystemUI/res/values-lt/strings.xml index 1cae1e907193..a47ad5909f12 100644 --- a/packages/CarSystemUI/res/values-lt/strings.xml +++ b/packages/CarSystemUI/res/values-lt/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Bet kuris naudotojas gali atnaujinti visų kitų naudotojų programas."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Įkeliama"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Įkeliamas naudotojo profilis (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Uždaryti"</string> </resources> diff --git a/packages/CarSystemUI/res/values-lv/strings.xml b/packages/CarSystemUI/res/values-lv/strings.xml index 62b8bf8d98eb..cb7c8b9f1575 100644 --- a/packages/CarSystemUI/res/values-lv/strings.xml +++ b/packages/CarSystemUI/res/values-lv/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Ikviens lietotājs var atjaunināt lietotnes visu lietotāju vārdā."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Notiek ielāde…"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Notiek lietotāja profila ielāde (<xliff:g id="FROM_USER">%1$d</xliff:g>–<xliff:g id="TO_USER">%2$d</xliff:g>)…"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Aizvērt"</string> </resources> diff --git a/packages/CarSystemUI/res/values-mk/strings.xml b/packages/CarSystemUI/res/values-mk/strings.xml index 3e7ad63ae2d9..cd2ae973a078 100644 --- a/packages/CarSystemUI/res/values-mk/strings.xml +++ b/packages/CarSystemUI/res/values-mk/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Секој корисник може да ажурира апликации за сите други корисници."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Се вчитува"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Се вчитува корисникот (од <xliff:g id="FROM_USER">%1$d</xliff:g> до <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Затвори"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ml/strings.xml b/packages/CarSystemUI/res/values-ml/strings.xml index 3bc7557b5484..613ea59874bc 100644 --- a/packages/CarSystemUI/res/values-ml/strings.xml +++ b/packages/CarSystemUI/res/values-ml/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"ഏതൊരു ഉപയോക്താവിനും മറ്റെല്ലാ ഉപയോക്താക്കൾക്കുമായി ആപ്പുകൾ അപ്ഡേറ്റ് ചെയ്യാനാവും."</string> <string name="car_loading_profile" msgid="4507385037552574474">"ലോഡ് ചെയ്യുന്നു"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ഉപയോക്തൃ പ്രൊഫൈൽ ലോഡ് ചെയ്യുന്നു (<xliff:g id="FROM_USER">%1$d</xliff:g> എന്നതിൽ നിന്ന് <xliff:g id="TO_USER">%2$d</xliff:g> എന്നതിലേക്ക്)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"അടയ്ക്കുക"</string> </resources> diff --git a/packages/CarSystemUI/res/values-mn/strings.xml b/packages/CarSystemUI/res/values-mn/strings.xml index 45921d26172e..33bcd275117d 100644 --- a/packages/CarSystemUI/res/values-mn/strings.xml +++ b/packages/CarSystemUI/res/values-mn/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Бусад бүх хэрэглэгчийн аппыг дурын хэрэглэгч шинэчлэх боломжтой."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Ачаалж байна"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Хэрэглэгчийг ачаалж байна (<xliff:g id="FROM_USER">%1$d</xliff:g>-с <xliff:g id="TO_USER">%2$d</xliff:g> хүртэл)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Хаах"</string> </resources> diff --git a/packages/CarSystemUI/res/values-mr/strings.xml b/packages/CarSystemUI/res/values-mr/strings.xml index fdbab4fbc4f2..b1c8a72a04df 100644 --- a/packages/CarSystemUI/res/values-mr/strings.xml +++ b/packages/CarSystemUI/res/values-mr/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"कोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अॅप्स अपडेट करू शकतो."</string> <string name="car_loading_profile" msgid="4507385037552574474">"लोड करत आहे"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"वापरकर्ता लोड करत आहे (<xliff:g id="FROM_USER">%1$d</xliff:g> पासून <xliff:g id="TO_USER">%2$d</xliff:g> पर्यंत)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"बंद करा"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ms/strings.xml b/packages/CarSystemUI/res/values-ms/strings.xml index 1a43d9c7cdef..0bb683b0a58d 100644 --- a/packages/CarSystemUI/res/values-ms/strings.xml +++ b/packages/CarSystemUI/res/values-ms/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Mana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Memuatkan"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Memuatkan pengguna (daripada <xliff:g id="FROM_USER">%1$d</xliff:g> hingga <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Tutup"</string> </resources> diff --git a/packages/CarSystemUI/res/values-my/strings.xml b/packages/CarSystemUI/res/values-my/strings.xml index 4f3922b373b5..4e7ca39a2b12 100644 --- a/packages/CarSystemUI/res/values-my/strings.xml +++ b/packages/CarSystemUI/res/values-my/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"မည်သူမဆို အသုံးပြုသူအားလုံးအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်နိုင်သည်။"</string> <string name="car_loading_profile" msgid="4507385037552574474">"ဖွင့်နေသည်"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"အသုံးပြုသူကို ဖွင့်နေသည် (<xliff:g id="FROM_USER">%1$d</xliff:g> မှ <xliff:g id="TO_USER">%2$d</xliff:g> သို့)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ပိတ်ရန်"</string> </resources> diff --git a/packages/CarSystemUI/res/values-nb/strings.xml b/packages/CarSystemUI/res/values-nb/strings.xml index 5b6166feba0f..0b2856f0d7b2 100644 --- a/packages/CarSystemUI/res/values-nb/strings.xml +++ b/packages/CarSystemUI/res/values-nb/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Alle brukere kan oppdatere apper for alle andre brukere."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Laster inn"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Laster inn brukeren (fra <xliff:g id="FROM_USER">%1$d</xliff:g> til <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Lukk"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ne/strings.xml b/packages/CarSystemUI/res/values-ne/strings.xml index e9eb4d8bdac7..3a25d6e05db6 100644 --- a/packages/CarSystemUI/res/values-ne/strings.xml +++ b/packages/CarSystemUI/res/values-ne/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"सबै प्रयोगकर्ताले अन्य प्रयोगकर्ताका अनुप्रयोगहरू अद्यावधिक गर्न सक्छन्।"</string> <string name="car_loading_profile" msgid="4507385037552574474">"लोड गरिँदै"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"प्रयोगकर्तासम्बन्धी जानकारी लोड गरिँदै (<xliff:g id="FROM_USER">%1$d</xliff:g> बाट <xliff:g id="TO_USER">%2$d</xliff:g> मा)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"बन्द गर्नुहोस्"</string> </resources> diff --git a/packages/CarSystemUI/res/values-nl/strings.xml b/packages/CarSystemUI/res/values-nl/strings.xml index d79f2b1d10f4..4765f71b8b61 100644 --- a/packages/CarSystemUI/res/values-nl/strings.xml +++ b/packages/CarSystemUI/res/values-nl/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Elke gebruiker kan apps updaten voor alle andere gebruikers"</string> <string name="car_loading_profile" msgid="4507385037552574474">"Laden"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Gebruiker laden (van <xliff:g id="FROM_USER">%1$d</xliff:g> naar <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Sluiten"</string> </resources> diff --git a/packages/CarSystemUI/res/values-or/strings.xml b/packages/CarSystemUI/res/values-or/strings.xml index 58f59e4c4dbf..4168d5a109b8 100644 --- a/packages/CarSystemUI/res/values-or/strings.xml +++ b/packages/CarSystemUI/res/values-or/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଆପଗୁଡ଼ିକୁ ଅପଡେଟ୍ କରିପାରିବେ।"</string> <string name="car_loading_profile" msgid="4507385037552574474">"ଲୋଡ୍ କରାଯାଉଛି"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଲୋଡ୍ କରାଯାଉଛି (<xliff:g id="FROM_USER">%1$d</xliff:g>ଙ୍କ ଠାରୁ <xliff:g id="TO_USER">%2$d</xliff:g> ପର୍ଯ୍ୟନ୍ତ)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ବନ୍ଦ କରନ୍ତୁ"</string> </resources> diff --git a/packages/CarSystemUI/res/values-pa/strings.xml b/packages/CarSystemUI/res/values-pa/strings.xml index e73e20a5fc85..3d9d3a597c07 100644 --- a/packages/CarSystemUI/res/values-pa/strings.xml +++ b/packages/CarSystemUI/res/values-pa/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"ਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਹੋਰ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string> <string name="car_loading_profile" msgid="4507385037552574474">"ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ਵਰਤੋਂਕਾਰ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ (<xliff:g id="FROM_USER">%1$d</xliff:g> ਤੋਂ <xliff:g id="TO_USER">%2$d</xliff:g> ਤੱਕ)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ਬੰਦ ਕਰੋ"</string> </resources> diff --git a/packages/CarSystemUI/res/values-pl/strings.xml b/packages/CarSystemUI/res/values-pl/strings.xml index dd8c1892b63e..52b90f1b5b96 100644 --- a/packages/CarSystemUI/res/values-pl/strings.xml +++ b/packages/CarSystemUI/res/values-pl/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Każdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Ładuję"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ładuję użytkownika (od <xliff:g id="FROM_USER">%1$d</xliff:g> do <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zamknij"</string> </resources> diff --git a/packages/CarSystemUI/res/values-pt-rPT/strings.xml b/packages/CarSystemUI/res/values-pt-rPT/strings.xml index c7f5ecf00707..2dffa17e8f1c 100644 --- a/packages/CarSystemUI/res/values-pt-rPT/strings.xml +++ b/packages/CarSystemUI/res/values-pt-rPT/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualquer utilizador pode atualizar apps para todos os outros utilizadores."</string> <string name="car_loading_profile" msgid="4507385037552574474">"A carregar…"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"A carregar o utilizador (de <xliff:g id="FROM_USER">%1$d</xliff:g> para <xliff:g id="TO_USER">%2$d</xliff:g>)…"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Fechar"</string> </resources> diff --git a/packages/CarSystemUI/res/values-pt/strings.xml b/packages/CarSystemUI/res/values-pt/strings.xml index 0712fb82f7fd..a7c44d2522d6 100644 --- a/packages/CarSystemUI/res/values-pt/strings.xml +++ b/packages/CarSystemUI/res/values-pt/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualquer usuário pode atualizar apps para os demais usuários."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Carregando"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Carregando usuário (de <xliff:g id="FROM_USER">%1$d</xliff:g> para <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Fechar"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ro/strings.xml b/packages/CarSystemUI/res/values-ro/strings.xml index 60fd4fef41c0..1a4e71d9eea8 100644 --- a/packages/CarSystemUI/res/values-ro/strings.xml +++ b/packages/CarSystemUI/res/values-ro/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Orice utilizator poate actualiza aplicațiile pentru toți ceilalți utilizatori."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Se încarcă"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Se încarcă utilizatorul (de la <xliff:g id="FROM_USER">%1$d</xliff:g> la <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Închideți"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ru/strings.xml b/packages/CarSystemUI/res/values-ru/strings.xml index a043d24789a9..330ba2f0bdbd 100644 --- a/packages/CarSystemUI/res/values-ru/strings.xml +++ b/packages/CarSystemUI/res/values-ru/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Любой пользователь устройства может обновлять приложения для всех аккаунтов."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Загрузка…"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Загрузка профиля пользователя (с <xliff:g id="FROM_USER">%1$d</xliff:g> по <xliff:g id="TO_USER">%2$d</xliff:g>)…"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Закрыть"</string> </resources> diff --git a/packages/CarSystemUI/res/values-si/strings.xml b/packages/CarSystemUI/res/values-si/strings.xml index e14f64a7bca8..6391d28e9568 100644 --- a/packages/CarSystemUI/res/values-si/strings.xml +++ b/packages/CarSystemUI/res/values-si/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"සියලුම අනෙක් පරිශීලකයින් සඳහා ඕනෑම පරිශීලකයෙකුට යෙදුම් යාවත්කාලීන කළ හැක."</string> <string name="car_loading_profile" msgid="4507385037552574474">"පූරණය වෙමින්"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"පරිශීලකයා පූරණය වෙමින් (<xliff:g id="FROM_USER">%1$d</xliff:g> සිට <xliff:g id="TO_USER">%2$d</xliff:g> වෙත)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"වසන්න"</string> </resources> diff --git a/packages/CarSystemUI/res/values-sk/strings.xml b/packages/CarSystemUI/res/values-sk/strings.xml index 8f98983877d9..b100a5d4cf5d 100644 --- a/packages/CarSystemUI/res/values-sk/strings.xml +++ b/packages/CarSystemUI/res/values-sk/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Ktorýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Načítava sa"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Načítava sa používateľ (predchádzajúci: <xliff:g id="FROM_USER">%1$d</xliff:g>, nasledujúci: <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zavrieť"</string> </resources> diff --git a/packages/CarSystemUI/res/values-sl/strings.xml b/packages/CarSystemUI/res/values-sl/strings.xml index 6b471845b657..b67002bec7d4 100644 --- a/packages/CarSystemUI/res/values-sl/strings.xml +++ b/packages/CarSystemUI/res/values-sl/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Vsak uporabnik lahko posodobi aplikacije za vse druge uporabnike."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Nalaganje"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Nalaganje uporabnika (od uporabnika <xliff:g id="FROM_USER">%1$d</xliff:g> do uporabnika <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Zapri"</string> </resources> diff --git a/packages/CarSystemUI/res/values-sq/strings.xml b/packages/CarSystemUI/res/values-sq/strings.xml index 18ea40131817..d19e1583664b 100644 --- a/packages/CarSystemUI/res/values-sq/strings.xml +++ b/packages/CarSystemUI/res/values-sq/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Çdo përdorues mund t\'i përditësojë aplikacionet për të gjithë përdoruesit e tjerë."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Po ngarkohet"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Përdoruesi po ngarkohet (nga <xliff:g id="FROM_USER">%1$d</xliff:g> te <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Mbyll"</string> </resources> diff --git a/packages/CarSystemUI/res/values-sr/strings.xml b/packages/CarSystemUI/res/values-sr/strings.xml index 878a1c1aa425..a5fb5b4f6ad6 100644 --- a/packages/CarSystemUI/res/values-sr/strings.xml +++ b/packages/CarSystemUI/res/values-sr/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Сваки корисник може да ажурира апликације за све остале кориснике."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Учитава се"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Профил корисника се учитава (из<xliff:g id="FROM_USER">%1$d</xliff:g> у <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Затвори"</string> </resources> diff --git a/packages/CarSystemUI/res/values-sv/strings.xml b/packages/CarSystemUI/res/values-sv/strings.xml index 905dd445eeab..8a942d6af080 100644 --- a/packages/CarSystemUI/res/values-sv/strings.xml +++ b/packages/CarSystemUI/res/values-sv/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Alla användare kan uppdatera appar för andra användare."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Läser in"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Läser in användare (från <xliff:g id="FROM_USER">%1$d</xliff:g> till <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Stäng"</string> </resources> diff --git a/packages/CarSystemUI/res/values-sw/strings.xml b/packages/CarSystemUI/res/values-sw/strings.xml index 3cb6098a3f1b..be03373c48a1 100644 --- a/packages/CarSystemUI/res/values-sw/strings.xml +++ b/packages/CarSystemUI/res/values-sw/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Mtumiaji yeyote anaweza kusasisha programu za watumiaji wengine."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Inapakia"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Inapakia wasifu wa mtumiaji (kutoka <xliff:g id="FROM_USER">%1$d</xliff:g> kuwa <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Funga"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ta/strings.xml b/packages/CarSystemUI/res/values-ta/strings.xml index de52edee1621..a82a2f856bd4 100644 --- a/packages/CarSystemUI/res/values-ta/strings.xml +++ b/packages/CarSystemUI/res/values-ta/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"எந்தப் பயனரும் பிற பயனர்கள் சார்பாக ஆப்ஸைப் புதுப்பிக்க முடியும்."</string> <string name="car_loading_profile" msgid="4507385037552574474">"ஏற்றுகிறது"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"பயனர் தகவலை ஏற்றுகிறது (<xliff:g id="FROM_USER">%1$d</xliff:g>லிருந்து <xliff:g id="TO_USER">%2$d</xliff:g> வரை)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"மூடுக"</string> </resources> diff --git a/packages/CarSystemUI/res/values-te/strings.xml b/packages/CarSystemUI/res/values-te/strings.xml index fff0845dfb6c..cf74f8053349 100644 --- a/packages/CarSystemUI/res/values-te/strings.xml +++ b/packages/CarSystemUI/res/values-te/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"ఏ యూజర్ అయినా మిగతా యూజర్ల కోసం యాప్లను అప్డేట్ చేయవచ్చు."</string> <string name="car_loading_profile" msgid="4507385037552574474">"లోడ్ అవుతోంది"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"యూజర్ను లోడ్ చేస్తోంది (<xliff:g id="FROM_USER">%1$d</xliff:g> నుండి <xliff:g id="TO_USER">%2$d</xliff:g> వరకు)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"మూసివేయి"</string> </resources> diff --git a/packages/CarSystemUI/res/values-th/strings.xml b/packages/CarSystemUI/res/values-th/strings.xml index 8f3012b5b4a5..dacf605888f5 100644 --- a/packages/CarSystemUI/res/values-th/strings.xml +++ b/packages/CarSystemUI/res/values-th/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"ผู้ใช้ทุกคนจะอัปเดตแอปให้แก่ผู้ใช้คนอื่นๆ ได้"</string> <string name="car_loading_profile" msgid="4507385037552574474">"กำลังโหลด"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"กำลังโหลดผู้ใช้ (จาก <xliff:g id="FROM_USER">%1$d</xliff:g> ถึง <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"ปิด"</string> </resources> diff --git a/packages/CarSystemUI/res/values-tl/strings.xml b/packages/CarSystemUI/res/values-tl/strings.xml index 5b0e3b3cf19c..89d8cd201e5f 100644 --- a/packages/CarSystemUI/res/values-tl/strings.xml +++ b/packages/CarSystemUI/res/values-tl/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Puwedeng i-update ng sinumang user ang mga app para sa lahat ng iba pang user."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Naglo-load"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Nilo-load ang user (mula kay <xliff:g id="FROM_USER">%1$d</xliff:g> papunta kay <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Isara"</string> </resources> diff --git a/packages/CarSystemUI/res/values-tr/strings.xml b/packages/CarSystemUI/res/values-tr/strings.xml index 81fa01c16058..36bf694f30ab 100644 --- a/packages/CarSystemUI/res/values-tr/strings.xml +++ b/packages/CarSystemUI/res/values-tr/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Herhangi bir kullanıcı, diğer tüm kullanıcılar için uygulamaları güncelleyebilir."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Yükleniyor"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Kullanıcı yükleniyor (<xliff:g id="FROM_USER">%1$d</xliff:g> kullanıcısından <xliff:g id="TO_USER">%2$d</xliff:g> kullanıcısına)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Kapat"</string> </resources> diff --git a/packages/CarSystemUI/res/values-uk/strings.xml b/packages/CarSystemUI/res/values-uk/strings.xml index b7031c698815..391513f1b57a 100644 --- a/packages/CarSystemUI/res/values-uk/strings.xml +++ b/packages/CarSystemUI/res/values-uk/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Усі користувачі можуть оновлювати додатки для решти людей."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Завантаження"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Завантаження профілю користувача (від <xliff:g id="FROM_USER">%1$d</xliff:g> до <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Закрити"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ur/strings.xml b/packages/CarSystemUI/res/values-ur/strings.xml index ef65c7516956..abe9214181a2 100644 --- a/packages/CarSystemUI/res/values-ur/strings.xml +++ b/packages/CarSystemUI/res/values-ur/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"کوئی بھی صارف دیگر سبھی صارفین کے لیے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string> <string name="car_loading_profile" msgid="4507385037552574474">"لوڈ ہو رہی ہے"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"صارف کی نئی پروفائل لوڈ ہو رہی ہے (<xliff:g id="FROM_USER">%1$d</xliff:g> سے <xliff:g id="TO_USER">%2$d</xliff:g> کو)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"بند کریں"</string> </resources> diff --git a/packages/CarSystemUI/res/values-uz/strings.xml b/packages/CarSystemUI/res/values-uz/strings.xml index 471e4591265a..398d1f5ce29e 100644 --- a/packages/CarSystemUI/res/values-uz/strings.xml +++ b/packages/CarSystemUI/res/values-uz/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Qurilmaning istalgan foydalanuvchisi ilovalarni barcha hisoblar uchun yangilashi mumkin."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Yuklanmoqda"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Foydalanuvchi profili yuklanmoqda (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Yopish"</string> </resources> diff --git a/packages/CarSystemUI/res/values-vi/strings.xml b/packages/CarSystemUI/res/values-vi/strings.xml index 26bdddc750cd..f15320fd1dcd 100644 --- a/packages/CarSystemUI/res/values-vi/strings.xml +++ b/packages/CarSystemUI/res/values-vi/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Bất kỳ người dùng nào cũng có thể cập nhật ứng dụng cho tất cả những người dùng khác."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Đang tải"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Đang tải hồ sơ người dùng (từ <xliff:g id="FROM_USER">%1$d</xliff:g> sang <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Đóng"</string> </resources> diff --git a/packages/CarSystemUI/res/values-zh-rCN/strings.xml b/packages/CarSystemUI/res/values-zh-rCN/strings.xml index e7ca871337fa..a91f48c8b378 100644 --- a/packages/CarSystemUI/res/values-zh-rCN/strings.xml +++ b/packages/CarSystemUI/res/values-zh-rCN/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"任何用户均可为所有其他用户更新应用。"</string> <string name="car_loading_profile" msgid="4507385037552574474">"正在加载"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"正在加载用户(从 <xliff:g id="FROM_USER">%1$d</xliff:g> 到 <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"关闭"</string> </resources> diff --git a/packages/CarSystemUI/res/values-zh-rHK/strings.xml b/packages/CarSystemUI/res/values-zh-rHK/strings.xml index 268243fea6f7..7aa611606274 100644 --- a/packages/CarSystemUI/res/values-zh-rHK/strings.xml +++ b/packages/CarSystemUI/res/values-zh-rHK/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"任何使用者都可以為所有其他使用者更新應用程式。"</string> <string name="car_loading_profile" msgid="4507385037552574474">"正在載入"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"正在載入使用者 (由 <xliff:g id="FROM_USER">%1$d</xliff:g> 至 <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"關閉"</string> </resources> diff --git a/packages/CarSystemUI/res/values-zh-rTW/strings.xml b/packages/CarSystemUI/res/values-zh-rTW/strings.xml index 9dc0f1a03d3a..c062463905d7 100644 --- a/packages/CarSystemUI/res/values-zh-rTW/strings.xml +++ b/packages/CarSystemUI/res/values-zh-rTW/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"任何使用者都能為所有其他使用者更新應用程式。"</string> <string name="car_loading_profile" msgid="4507385037552574474">"載入中"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"正在載入使用者 (從 <xliff:g id="FROM_USER">%1$d</xliff:g> 到 <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"關閉"</string> </resources> diff --git a/packages/CarSystemUI/res/values-zu/strings.xml b/packages/CarSystemUI/res/values-zu/strings.xml index 8845ff71c1bb..2dd33d827324 100644 --- a/packages/CarSystemUI/res/values-zu/strings.xml +++ b/packages/CarSystemUI/res/values-zu/strings.xml @@ -28,6 +28,5 @@ <string name="user_add_user_message_update" msgid="7061671307004867811">"Noma yimuphi umsebenzisi angabuyekeza izinhlelo zokusebenza zabanye abasebenzisi."</string> <string name="car_loading_profile" msgid="4507385037552574474">"Iyalayisha"</string> <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Ilayisha umsebenzisi (kusuka ku-<xliff:g id="FROM_USER">%1$d</xliff:g> kuya ku-<xliff:g id="TO_USER">%2$d</xliff:g>)"</string> - <!-- no translation found for rear_view_camera_close_button_text (8430918817320533693) --> - <skip /> + <string name="rear_view_camera_close_button_text" msgid="8430918817320533693">"Vala"</string> </resources> diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java index 02f4457bffdb..bdfbf82145c7 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java @@ -17,6 +17,9 @@ package com.android.companiondevicemanager; import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress; +import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; + +import static java.util.Objects.requireNonNull; import android.app.Activity; import android.companion.CompanionDeviceManager; @@ -57,6 +60,8 @@ public class DeviceChooserActivity extends Activity { Log.e(LOG_TAG, "About to show UI, but no devices to show"); } + getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); + if (getService().mRequest.isSingleDevice()) { setContentView(R.layout.device_confirmation); final DeviceFilterPair selectedDevice = getService().mDevicesFound.get(0); @@ -126,6 +131,11 @@ public class DeviceChooserActivity extends Activity { } @Override + public String getCallingPackage() { + return requireNonNull(getService().mRequest.getCallingPackage()); + } + + @Override public void setTitle(CharSequence title) { final TextView titleView = findViewById(R.id.title); final int padding = getPadding(getResources()); diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java index f7f3cbb7d332..12505bc55b15 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java @@ -422,7 +422,7 @@ public class DynamicSystemInstallationService extends Service private PendingIntent createPendingIntent(String action) { Intent intent = new Intent(this, DynamicSystemInstallationService.class); intent.setAction(action); - return PendingIntent.getService(this, 0, intent, 0); + return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_IMMUTABLE); } private Notification buildNotification(int status, int cause) { diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index 32f6aa7774a7..6e4ce03c5d93 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -473,7 +473,7 @@ <string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"Najveći"</string> <string name="screen_zoom_summary_custom" msgid="3468154096832912210">"Prilagodi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="content_description_menu_button" msgid="6254844309171779931">"Meni"</string> - <string name="retail_demo_reset_message" msgid="5392824901108195463">"Unesite lozinku da izvršite vraćanje na fabričke postavke u načinu demonstracije"</string> + <string name="retail_demo_reset_message" msgid="5392824901108195463">"Unesite lozinku da izvršite vraćanje na fabričke postavke u načinu rada za demonstraciju"</string> <string name="retail_demo_reset_next" msgid="3688129033843885362">"Naprijed"</string> <string name="retail_demo_reset_title" msgid="1866911701095959800">"Potrebna je lozinka"</string> <string name="active_input_method_subtypes" msgid="4232680535471633046">"Aktivne metode unosa"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index f6157b42312f..1d9994d52e5d 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -510,7 +510,7 @@ <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Altavoz del teléfono"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"No se ha podido conectar; reinicia el dispositivo"</string> <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string> - <string name="help_label" msgid="3528360748637781274">"Ayuda y sugerencias"</string> + <string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string> <string name="storage_category" msgid="2287342585424631813">"Almacenamiento"</string> <string name="shared_data_title" msgid="1017034836800864953">"Datos compartidos"</string> <string name="shared_data_summary" msgid="5516326713822885652">"Ver y modificar los datos compartidos"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index b68aab46c028..8e13afd480f7 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"Вибрати профіль"</string> <string name="category_personal" msgid="6236798763159385225">"Особисте"</string> - <string name="category_work" msgid="4014193632325996115">"Робота"</string> + <string name="category_work" msgid="4014193632325996115">"Робоче"</string> <string name="development_settings_title" msgid="140296922921597393">"Параметри розробника"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Увімкнути параметри розробника"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Установити параметри для розробки програми"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index 2fd46d94d5cc..3cbf2685af26 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -15,6 +15,9 @@ import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.location.LocationManager; @@ -308,6 +311,36 @@ public class Utils { } /** + * Create a color matrix suitable for a ColorMatrixColorFilter that modifies only the color but + * preserves the alpha for a given drawable + * @param color + * @return a color matrix that uses the source alpha and given color + */ + public static ColorMatrix getAlphaInvariantColorMatrixForColor(@ColorInt int color) { + int r = Color.red(color); + int g = Color.green(color); + int b = Color.blue(color); + + ColorMatrix cm = new ColorMatrix(new float[] { + 0, 0, 0, 0, r, + 0, 0, 0, 0, g, + 0, 0, 0, 0, b, + 0, 0, 0, 1, 0 }); + + return cm; + } + + /** + * Create a ColorMatrixColorFilter to tint a drawable but retain its alpha characteristics + * + * @return a ColorMatrixColorFilter which changes the color of the output but is invariant on + * the source alpha + */ + public static ColorFilter getAlphaInvariantColorFilterForColor(@ColorInt int color) { + return new ColorMatrixColorFilter(getAlphaInvariantColorMatrixForColor(color)); + } + + /** * Determine whether a package is a "system package", in which case certain things (like * disabling notifications or disabling the package altogether) should be disallowed. */ diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt index a5b5312707d0..5fa04f93e993 100644 --- a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt +++ b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt @@ -108,6 +108,7 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int) private val fillColorStrokePaint = Paint(Paint.ANTI_ALIAS_FLAG).also { p -> p.color = frameColor + p.alpha = 255 p.isDither = true p.strokeWidth = 5f p.style = Paint.Style.STROKE @@ -145,7 +146,7 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int) // Only used if dualTone is set to true private val dualToneBackgroundFill = Paint(Paint.ANTI_ALIAS_FLAG).also { p -> p.color = frameColor - p.alpha = 255 + p.alpha = 85 // ~0.3 alpha by default p.isDither = true p.strokeWidth = 0f p.style = Paint.Style.FILL_AND_STROKE diff --git a/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING b/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING new file mode 100644 index 000000000000..71cbcb54a1ff --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING @@ -0,0 +1,12 @@ +{ + "presubmit": [ + { + "name": "SettingsLibTests", + "options": [ + { + "include-filter": "com.android.settingslib.users." + } + ] + } + ] +}
\ No newline at end of file diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index c4b36fb1ab29..b9e30fb950c6 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -175,8 +175,8 @@ public class SecureSettings { Settings.Secure.ONE_HANDED_MODE_TIMEOUT, Settings.Secure.TAPS_APP_TO_EXIT, Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, - Settings.Secure.PANIC_GESTURE_ENABLED, - Settings.Secure.PANIC_SOUND_ENABLED, + Settings.Secure.EMERGENCY_GESTURE_ENABLED, + Settings.Secure.EMERGENCY_GESTURE_SOUND_ENABLED, Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED, Settings.Secure.ASSIST_HANDLES_LEARNING_TIME_ELAPSED_MILLIS, Settings.Secure.ASSIST_HANDLES_LEARNING_EVENT_COUNT diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 7f694ad5d375..721bf730a343 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -264,8 +264,8 @@ public class SecureSettingsValidators { VALIDATORS.put(Secure.ONE_HANDED_MODE_TIMEOUT, ANY_INTEGER_VALIDATOR); VALIDATORS.put(Secure.TAPS_APP_TO_EXIT, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, BOOLEAN_VALIDATOR); - VALIDATORS.put(Secure.PANIC_GESTURE_ENABLED, BOOLEAN_VALIDATOR); - VALIDATORS.put(Secure.PANIC_SOUND_ENABLED, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.EMERGENCY_GESTURE_ENABLED, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.EMERGENCY_GESTURE_SOUND_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ADAPTIVE_CONNECTIVITY_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put( Secure.ASSIST_HANDLES_LEARNING_TIME_ELAPSED_MILLIS, NONE_NEGATIVE_LONG_VALIDATOR); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 94de48595b0d..38ff447a71b5 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -52,6 +52,8 @@ class SettingsProtoDumpUtil { ConfigSettingsProto.ALARM_MANAGER_SETTINGS); namespaceToFieldMap.put(DeviceConfig.NAMESPACE_APP_COMPAT, ConfigSettingsProto.APP_COMPAT_SETTINGS); + namespaceToFieldMap.put(DeviceConfig.NAMESPACE_APP_STANDBY, + ConfigSettingsProto.APP_STANDBY_SETTINGS); namespaceToFieldMap.put(DeviceConfig.NAMESPACE_AUTOFILL, ConfigSettingsProto.AUTOFILL_SETTINGS); namespaceToFieldMap.put(DeviceConfig.NAMESPACE_BLOBSTORE, @@ -220,9 +222,6 @@ class SettingsProtoDumpUtil { final long appToken = p.start(GlobalSettingsProto.APP); dumpSetting(s, p, - Settings.Global.APP_IDLE_CONSTANTS, - GlobalSettingsProto.App.IDLE_CONSTANTS); - dumpSetting(s, p, Settings.Global.APP_STANDBY_ENABLED, GlobalSettingsProto.App.STANDBY_ENABLED); dumpSetting(s, p, @@ -863,9 +862,6 @@ class SettingsProtoDumpUtil { p.end(intentFirewallToken); dumpSetting(s, p, - Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS, - GlobalSettingsProto.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS); - dumpSetting(s, p, Settings.Global.KEEP_PROFILE_IN_BACKGROUND, GlobalSettingsProto.KEEP_PROFILE_IN_BACKGROUND); @@ -2035,11 +2031,11 @@ class SettingsProtoDumpUtil { final long emergencyResponseToken = p.start(SecureSettingsProto.EMERGENCY_RESPONSE); dumpSetting(s, p, - Settings.Secure.PANIC_GESTURE_ENABLED, - SecureSettingsProto.EmergencyResponse.PANIC_GESTURE_ENABLED); + Settings.Secure.EMERGENCY_GESTURE_ENABLED, + SecureSettingsProto.EmergencyResponse.EMERGENCY_GESTURE_ENABLED); dumpSetting(s, p, - Settings.Secure.PANIC_SOUND_ENABLED, - SecureSettingsProto.EmergencyResponse.PANIC_SOUND_ENABLED); + Settings.Secure.EMERGENCY_GESTURE_SOUND_ENABLED, + SecureSettingsProto.EmergencyResponse.EMERGENCY_GESTURE_SOUND_ENABLED); p.end(emergencyResponseToken); dumpSetting(s, p, diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 10d2eab167e7..baa266a6e5cd 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -127,7 +127,6 @@ public class SettingsBackupTest { Settings.Global.APN_DB_UPDATE_CONTENT_URL, Settings.Global.APN_DB_UPDATE_METADATA_URL, Settings.Global.APP_BINDING_CONSTANTS, - Settings.Global.APP_IDLE_CONSTANTS, Settings.Global.APP_OPS_CONSTANTS, Settings.Global.APP_STANDBY_ENABLED, Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE, @@ -293,6 +292,7 @@ public class SettingsBackupTest { Settings.Global.GNSS_SATELLITE_BLACKLIST, Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS, Settings.Global.HDMI_CEC_SWITCH_ENABLED, + Settings.Global.HDMI_CEC_VERSION, Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED, Settings.Global.HDMI_CONTROL_ENABLED, @@ -309,7 +309,6 @@ public class SettingsBackupTest { Settings.Global.INSTANT_APP_DEXOPT_ENABLED, Settings.Global.INTENT_FIREWALL_UPDATE_CONTENT_URL, Settings.Global.INTENT_FIREWALL_UPDATE_METADATA_URL, - Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS, Settings.Global.KEEP_PROFILE_IN_BACKGROUND, Settings.Global.KERNEL_CPU_THREAD_READER, Settings.Global.LANG_ID_UPDATE_CONTENT_URL, @@ -443,6 +442,7 @@ public class SettingsBackupTest { Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, Settings.Global.SHOW_PEOPLE_SPACE, Settings.Global.SHOW_NEW_LOCKSCREEN, + Settings.Global.SHOW_NEW_NOTIF_DISMISS, Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG, Settings.Global.SHOW_TEMPERATURE_WARNING, Settings.Global.SHOW_USB_TEMPERATURE_ALARM, @@ -745,7 +745,6 @@ public class SettingsBackupTest { Settings.Secure.FACE_UNLOCK_RE_ENROLL, Settings.Secure.TAP_GESTURE, Settings.Secure.NEARBY_SHARING_COMPONENT, // not user configurable - Settings.Secure.WINDOW_MAGNIFICATION, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER, Settings.Secure.SUPPRESS_DOZE, Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 5f018a0322a3..ec47c717ac3c 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -143,7 +143,7 @@ <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.ACCESS_VIBRATOR_STATE" /> - <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" /> <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" /> <uses-permission android:name="android.permission.ACTIVITY_EMBEDDING" /> @@ -338,6 +338,9 @@ <!-- Permissions required for CTS test - NotificationManagerTest --> <uses-permission android:name="android.permission.MANAGE_NOTIFICATION_LISTENERS" /> + <!-- Allows overriding the system's device state from the shell --> + <uses-permission android:name="android.permission.CONTROL_DEVICE_STATE"/> + <application android:label="@string/app_label" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:defaultToDeviceProtectedStorage="true" diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index ddd0dac0e9db..f9268eece293 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -99,7 +99,7 @@ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" /> - <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> <uses-permission android:name="android.permission.START_ACTIVITY_AS_CALLER" /> <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" /> <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" /> diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml index e0333eb82d51..1b5f9c1ced8f 100644 --- a/packages/SystemUI/res/layout/global_screenshot.xml +++ b/packages/SystemUI/res/layout/global_screenshot.xml @@ -27,14 +27,6 @@ android:alpha="0.0" android:src="@drawable/screenshot_actions_background_protection"/> <ImageView - android:id="@+id/global_screenshot_animated_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="top|start" - android:visibility="gone" - android:elevation="@dimen/screenshot_preview_elevation" - android:background="@drawable/screenshot_rounded_corners" /> - <ImageView android:id="@+id/global_screenshot_flash" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/packages/SystemUI/res/layout/quick_settings_footer_dialog_parental_controls.xml b/packages/SystemUI/res/layout/quick_settings_footer_dialog_parental_controls.xml new file mode 100644 index 000000000000..1a356769d334 --- /dev/null +++ b/packages/SystemUI/res/layout/quick_settings_footer_dialog_parental_controls.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +** Copyright 2020, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +--> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/scrollView" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:clipToPadding="false"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="?android:attr/dialogPreferredPadding" + android:paddingRight="?android:attr/dialogPreferredPadding" + android:paddingLeft="?android:attr/dialogPreferredPadding" + android:orientation="vertical"> + <ImageView + android:id="@+id/parental_controls_icon" + android:layout_width="36dip" + android:layout_height="36dip" + android:layout_gravity="center_horizontal" + + /> + <LinearLayout + android:id="@+id/parental_controls_disclosures" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="?android:attr/dialogPreferredPadding" + android:orientation="vertical"> + <TextView + android:id="@+id/parental_controls_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/monitoring_title_device_owned" + style="@style/DeviceManagementDialogTitle" + android:paddingBottom="@dimen/qs_footer_dialog_subtitle_padding" + /> + <TextView + android:id="@+id/parental_controls_warning" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.DeviceManagementDialog.Content" + android:text="@string/monitoring_description_parental_controls" + /> + </LinearLayout> + </LinearLayout> +</ScrollView> diff --git a/packages/SystemUI/res/layout/udfps_view.xml b/packages/SystemUI/res/layout/udfps_view.xml index 31a33fbfc308..ccd235d54c0b 100644 --- a/packages/SystemUI/res/layout/udfps_view.xml +++ b/packages/SystemUI/res/layout/udfps_view.xml @@ -5,6 +5,4 @@ android:id="@+id/udfps_view" android:layout_width="match_parent" android:layout_height="match_parent" - systemui:sensorRadius="130px" - systemui:sensorCenterY="1636px" systemui:sensorTouchAreaCoefficient="0.5"/> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 4ce5496f2186..75a2d1cc4ea8 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -650,9 +650,9 @@ <string name="quick_settings" msgid="6211774484997470203">"Brze postavke"</string> <string name="status_bar" msgid="4357390266055077437">"Statusna traka"</string> <string name="overview" msgid="3522318590458536816">"Pregled"</string> - <string name="demo_mode" msgid="263484519766901593">"Način demonstracije Sistemskog UI-a"</string> - <string name="enable_demo_mode" msgid="3180345364745966431">"Omogući način demonstracije"</string> - <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži način demonstracije"</string> + <string name="demo_mode" msgid="263484519766901593">"Način rada za demonstraciju Sistemskog UI-a"</string> + <string name="enable_demo_mode" msgid="3180345364745966431">"Omogući način rada za demonstraciju"</string> + <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži način rada za demonstraciju"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string> <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string> <string name="status_bar_work" msgid="5238641949837091056">"Profil za posao"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 2a6ed6e9bf65..cd757612073a 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -774,7 +774,7 @@ <item quantity="one">%d മിനിറ്റ്</item> </plurals> <string name="battery_panel_title" msgid="5931157246673665963">"ബാറ്ററി ഉപയോഗം"</string> - <string name="battery_detail_charging_summary" msgid="8821202155297559706">"ചാർജുചെയ്യുന്ന സമയത്ത് ബാറ്ററി ലാഭിക്കൽ നടക്കില്ല"</string> + <string name="battery_detail_charging_summary" msgid="8821202155297559706">"ചാർജ് ചെയ്യുമ്പോൾ ബാറ്ററി ലാഭിക്കൽ സാധ്യമല്ല"</string> <string name="battery_detail_switch_title" msgid="6940976502957380405">"ബാറ്ററി ലാഭിക്കൽ"</string> <string name="battery_detail_switch_summary" msgid="3668748557848025990">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്ക്കുന്നു"</string> <string name="keyboard_key_button_template" msgid="8005673627272051429">"ബട്ടൺ <xliff:g id="NAME">%1$s</xliff:g>"</string> @@ -966,7 +966,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ബാറ്ററി ചാർജ് തീരാൻ സാധ്യതയുണ്ടെങ്കിൽ ഓണാക്കുക"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"വേണ്ട"</string> <string name="auto_saver_enabled_title" msgid="4294726198280286333">"ബാറ്ററി ലാഭിക്കൽ ഷെഡ്യൂൾ ഓണാക്കുക"</string> - <string name="auto_saver_enabled_text" msgid="7889491183116752719">"ബാറ്ററി <xliff:g id="PERCENTAGE">%d</xliff:g>%% ൽ താഴെയാകുമ്പോൾ, ബാറ്ററി ലാഭിക്കൽ സ്വമേധയാ ഓണാകും."</string> + <string name="auto_saver_enabled_text" msgid="7889491183116752719">"ബാറ്ററി <xliff:g id="PERCENTAGE">%d</xliff:g>%% ൽ താഴെയാകുമ്പോൾ, ബാറ്ററി ലാഭിക്കൽ സ്വയമേവ ഓണാകും."</string> <string name="open_saver_setting_action" msgid="2111461909782935190">"ക്രമീകരണം"</string> <string name="auto_saver_okay_action" msgid="7815925750741935386">"മനസ്സിലായി"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ഹീപ്പ് ഡമ്പ് ചെയ്യുക"</string> diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index a62502965dd2..78d92c4b47e2 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -158,8 +158,6 @@ </declare-styleable> <declare-styleable name="UdfpsView"> - <attr name="sensorRadius" format="dimension"/> - <attr name="sensorCenterY" format="dimension"/> <attr name="sensorPressureCoefficient" format="float"/> <attr name="sensorTouchAreaCoefficient" format="float"/> </declare-styleable> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 4b1ed0a25c90..1ab776b2a0a8 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1218,6 +1218,8 @@ <dimen name="bubble_message_padding">4dp</dimen> <!-- Offset between bubbles in their stacked position. --> <dimen name="bubble_stack_offset">10dp</dimen> + <!-- Offset between stack y and animation y for bubble swap. --> + <dimen name="bubble_swap_animation_offset">15dp</dimen> <!-- How far offscreen the bubble stack rests. Cuts off padding and part of icon bitmap. --> <dimen name="bubble_stack_offscreen">9dp</dimen> <!-- How far down the screen the stack starts. --> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index e2ba615e84e6..2be89c1dff63 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1286,6 +1286,9 @@ <!-- Footer vpn present text [CHAR LIMIT=50] --> <string name="branded_vpn_footer">Network may be monitored</string> + <!-- Disclosure at the bottom of Quick Settings that indicates that parental controls are enabled. [CHAR LIMIT=100] --> + <string name="quick_settings_disclosure_parental_controls">This device is managed by your parent</string> + <!-- Disclosure at the bottom of Quick Settings that indicates that the user's device belongs to their organization, and the organization can monitor network traffic on that device. [CHAR LIMIT=100] --> <string name="quick_settings_disclosure_management_monitoring">Your organization owns this device and may monitor network traffic</string> @@ -1359,6 +1362,9 @@ <!-- Monitoring dialog label for button opening a page with more information on the admin's abilities [CHAR LIMIT=30] --> <string name="monitoring_button_view_policies">View Policies</string> + <!-- Monitoring dialog label for button opening a page with more information on parental controls [CHAR LIMIT=30] --> + <string name="monitoring_button_view_controls">View controls</string> + <!-- Dialog that a user can access via Quick Settings. The dialog describes what the IT admin can monitor (and the changes they can make) on the user's device. [CHAR LIMIT=NONE]--> <string name="monitoring_description_named_management">This device belongs to <xliff:g id="organization_name" example="Foo, Inc.">%1$s</xliff:g>.\n\nYour IT admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nFor more information, contact your IT admin.</string> @@ -1428,6 +1434,10 @@ <!-- Monitoring dialog VPN with profile owner text [CHAR LIMIT=400] --> <string name="monitoring_description_vpn_profile_owned">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour admin is capable of monitoring your network activity including emails, apps, and websites.\n\nFor more information, contact your admin.\n\nYou\'re also connected to a VPN, which can monitor your network activity.</string> + <!-- Dialog that a user can access via Quick Settings. [CHAR LIMIT=NONE]--> + <string name="monitoring_description_parental_controls">This device is managed by your parent. Your parent can see and manage information such as the apps you use, your location, and your screen time.</string> + + <!-- Name for a generic legacy VPN connection [CHAR LIMIT=20] --> <string name="legacy_vpn_name">VPN</string> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java new file mode 100644 index 000000000000..22ffd2819c48 --- /dev/null +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shared.pip; + +import android.graphics.Matrix; +import android.graphics.Rect; +import android.graphics.RectF; +import android.view.SurfaceControl; + +/** + * TODO(b/171721389): unify this class with + * {@link com.android.wm.shell.pip.PipSurfaceTransactionHelper}, for instance, there should be one + * source of truth on enabling/disabling and the actual value of corner radius. + */ +public class PipSurfaceTransactionHelper { + private final Matrix mTmpTransform = new Matrix(); + private final float[] mTmpFloat9 = new float[9]; + private final RectF mTmpSourceRectF = new RectF(); + private final Rect mTmpDestinationRect = new Rect(); + + public void scaleAndCrop(SurfaceControl.Transaction tx, SurfaceControl leash, + Rect sourceBounds, Rect destinationBounds, Rect insets) { + mTmpSourceRectF.set(sourceBounds); + mTmpDestinationRect.set(sourceBounds); + mTmpDestinationRect.inset(insets); + // Scale by the shortest edge and offset such that the top/left of the scaled inset + // source rect aligns with the top/left of the destination bounds + final float scale = sourceBounds.width() <= sourceBounds.height() + ? (float) destinationBounds.width() / sourceBounds.width() + : (float) destinationBounds.height() / sourceBounds.height(); + final float left = destinationBounds.left - insets.left * scale; + final float top = destinationBounds.top - insets.top * scale; + mTmpTransform.setScale(scale, scale); + tx.setMatrix(leash, mTmpTransform, mTmpFloat9) + .setWindowCrop(leash, mTmpDestinationRect) + .setPosition(leash, left, top); + } + + public void reset(SurfaceControl.Transaction tx, SurfaceControl leash, Rect destinationBounds) { + resetScale(tx, leash, destinationBounds); + resetCornerRadius(tx, leash); + crop(tx, leash, destinationBounds); + } + + public void resetScale(SurfaceControl.Transaction tx, SurfaceControl leash, + Rect destinationBounds) { + tx.setMatrix(leash, Matrix.IDENTITY_MATRIX, mTmpFloat9) + .setPosition(leash, destinationBounds.left, destinationBounds.top); + } + + public void resetCornerRadius(SurfaceControl.Transaction tx, SurfaceControl leash) { + tx.setCornerRadius(leash, 0); + } + + public void crop(SurfaceControl.Transaction tx, SurfaceControl leash, + Rect destinationBounds) { + tx.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height()) + .setPosition(leash, destinationBounds.left, destinationBounds.top); + } +} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ClipDescriptionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ClipDescriptionCompat.java new file mode 100644 index 000000000000..0b1141ee9b30 --- /dev/null +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ClipDescriptionCompat.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.shared.system; + +import android.content.ClipDescription; +import android.content.Intent; + +/** + * Wrapper around ClipDescription. + */ +public abstract class ClipDescriptionCompat { + + public static String MIMETYPE_APPLICATION_ACTIVITY = + ClipDescription.MIMETYPE_APPLICATION_ACTIVITY; + + public static String MIMETYPE_APPLICATION_SHORTCUT = + ClipDescription.MIMETYPE_APPLICATION_SHORTCUT; + + public static String MIMETYPE_APPLICATION_TASK = + ClipDescription.MIMETYPE_APPLICATION_TASK; + + public static String EXTRA_PENDING_INTENT = ClipDescription.EXTRA_PENDING_INTENT; + + public static String EXTRA_TASK_ID = Intent.EXTRA_TASK_ID; +} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherAppsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherAppsCompat.java new file mode 100644 index 000000000000..d24c779b1416 --- /dev/null +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherAppsCompat.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.shared.system; + +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.pm.LauncherApps; +import android.os.Bundle; +import android.os.UserHandle; + +/** + * Wrapper around LauncherApps. + */ +public abstract class LauncherAppsCompat { + + public static PendingIntent getMainActivityLaunchIntent(LauncherApps launcherApps, + ComponentName component, Bundle startActivityOptions, UserHandle user) { + return launcherApps.getMainActivityLaunchIntent(component, startActivityOptions, user); + } +} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java index 326c2aa37175..7b9ebc0d4656 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java @@ -17,8 +17,11 @@ package com.android.systemui.shared.system; import android.app.ActivityManager; +import android.app.PictureInPictureParams; import android.app.TaskInfo; import android.content.ComponentName; +import android.content.pm.ActivityInfo; +import android.graphics.Rect; public class TaskInfoCompat { @@ -34,6 +37,10 @@ public class TaskInfoCompat { return info.configuration.windowConfiguration.getWindowingMode(); } + public static Rect getWindowConfigurationBounds(TaskInfo info) { + return info.configuration.windowConfiguration.getBounds(); + } + public static boolean supportsSplitScreenMultiWindow(TaskInfo info) { return info.supportsSplitScreenMultiWindow; } @@ -45,4 +52,16 @@ public class TaskInfoCompat { public static ActivityManager.TaskDescription getTaskDescription(TaskInfo info) { return info.taskDescription; } + + public static ActivityInfo getTopActivityInfo(TaskInfo info) { + return info.topActivityInfo; + } + + public static boolean isAutoEnterPipEnabled(PictureInPictureParams params) { + return params.isAutoEnterEnabled(); + } + + public static Rect getPipSourceRectHint(PictureInPictureParams params) { + return params.getSourceRectHint(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 8ac6edb9dfa2..cf576dd6b964 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -37,7 +37,6 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.systemui.appops.AppOpsController; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; -import com.android.systemui.bubbles.Bubbles; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; @@ -308,7 +307,6 @@ public class Dependency { @Inject Lazy<KeyguardDismissUtil> mKeyguardDismissUtil; @Inject Lazy<SmartReplyController> mSmartReplyController; @Inject Lazy<RemoteInputQuickSettingsDisabler> mRemoteInputQuickSettingsDisabler; - @Inject Lazy<Bubbles> mBubbles; @Inject Lazy<NotificationEntryManager> mNotificationEntryManager; @Inject Lazy<SensorPrivacyManager> mSensorPrivacyManager; @Inject Lazy<AutoHideController> mAutoHideController; @@ -506,7 +504,6 @@ public class Dependency { mProviders.put(SmartReplyController.class, mSmartReplyController::get); mProviders.put(RemoteInputQuickSettingsDisabler.class, mRemoteInputQuickSettingsDisabler::get); - mProviders.put(Bubbles.class, mBubbles::get); mProviders.put(NotificationEntryManager.class, mNotificationEntryManager::get); mProviders.put(ForegroundServiceNotificationListener.class, mForegroundServiceNotificationListener::get); diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index e709830342b5..bf42a60ac033 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -34,6 +34,7 @@ import android.provider.Settings; import android.util.Log; import android.util.TimingsTraceLog; +import com.android.internal.protolog.common.ProtoLog; import com.android.systemui.dagger.ContextComponentHelper; import com.android.systemui.dagger.GlobalRootComponent; import com.android.systemui.dagger.SysUIComponent; @@ -69,6 +70,8 @@ public class SystemUIApplication extends Application implements public SystemUIApplication() { super(); Log.v(TAG, "SystemUIApplication constructed."); + // SysUI may be building without protolog preprocessing in some cases + ProtoLog.REQUIRE_PROTOLOGTOOL = false; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index 187c31f43a64..4f9d84de36a2 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -101,11 +101,13 @@ public class SystemUIFactory { if (initializeComponents) { // Only initialize when not starting from tests since this currently initializes some // components that shouldn't be run in the test environment - builder = builder.setPip(mWMComponent.getPip()) + builder = prepareSysUIComponentBuilder(builder, mWMComponent) + .setPip(mWMComponent.getPip()) .setSplitScreen(mWMComponent.getSplitScreen()) .setOneHanded(mWMComponent.getOneHanded()) .setShellDump(mWMComponent.getShellDump()); } else { + // TODO: Call on prepareSysUIComponentBuilder but not with real components. builder = builder.setPip(Optional.ofNullable(null)) .setSplitScreen(Optional.ofNullable(null)) .setOneHanded(Optional.ofNullable(null)) diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java index c6e5f09af572..64a2acab79ee 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java @@ -24,6 +24,7 @@ import android.content.pm.ActivityInfo; import android.graphics.PixelFormat; import android.graphics.PointF; import android.os.Bundle; +import android.os.UserHandle; import android.provider.Settings; import android.util.MathUtils; import android.view.Gravity; @@ -232,8 +233,11 @@ class MagnificationModeSwitch { mMagnificationMode ^ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL; mMagnificationMode = newMode; mImageView.setImageResource(getIconResId(newMode)); - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, newMode); + Settings.Secure.putIntForUser( + mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, + newMode, + UserHandle.USER_CURRENT); } private void handleSingleTap() { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index ab4025f7ef9d..24ab6355c2bd 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -24,6 +24,9 @@ import android.graphics.PixelFormat; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.PromptInfo; +import android.hardware.face.FaceSensorPropertiesInternal; +import android.hardware.fingerprint.FingerprintSensorProperties; +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Binder; import android.os.Bundle; import android.os.Handler; @@ -51,6 +54,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.List; /** * Top level container/controller for the BiometricPrompt UI. @@ -76,6 +80,8 @@ public class AuthContainerView extends LinearLayout final Config mConfig; final int mEffectiveUserId; + @Nullable private final List<FingerprintSensorPropertiesInternal> mFpProps; + @Nullable private final List<FaceSensorPropertiesInternal> mFaceProps; private final Handler mHandler; private final Injector mInjector; private final IBinder mWindowToken = new Binder(); @@ -111,7 +117,8 @@ public class AuthContainerView extends LinearLayout boolean mRequireConfirmation; int mUserId; String mOpPackageName; - @BiometricAuthenticator.Modality int mModalityMask; + int[] mSensorIds; + boolean mCredentialAllowed; boolean mSkipIntro; long mOperationId; } @@ -159,9 +166,12 @@ public class AuthContainerView extends LinearLayout return this; } - public AuthContainerView build(@BiometricAuthenticator.Modality int modalityMask) { - mConfig.mModalityMask = modalityMask; - return new AuthContainerView(mConfig, new Injector()); + public AuthContainerView build(int[] sensorIds, boolean credentialAllowed, + @Nullable List<FingerprintSensorPropertiesInternal> fpProps, + @Nullable List<FaceSensorPropertiesInternal> faceProps) { + mConfig.mSensorIds = sensorIds; + mConfig.mCredentialAllowed = credentialAllowed; + return new AuthContainerView(mConfig, new Injector(), fpProps, faceProps); } } @@ -242,11 +252,15 @@ public class AuthContainerView extends LinearLayout } @VisibleForTesting - AuthContainerView(Config config, Injector injector) { + AuthContainerView(Config config, Injector injector, + @Nullable List<FingerprintSensorPropertiesInternal> fpProps, + @Nullable List<FaceSensorPropertiesInternal> faceProps) { super(config.mContext); mConfig = config; mInjector = injector; + mFpProps = fpProps; + mFaceProps = faceProps; mEffectiveUserId = mInjector.getUserManager(mContext) .getCredentialOwnerProfile(mConfig.mUserId); @@ -269,24 +283,29 @@ public class AuthContainerView extends LinearLayout // Inflate biometric view only if necessary. if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) { - final @BiometricAuthenticator.Modality int biometricModality = - config.mModalityMask & ~BiometricAuthenticator.TYPE_CREDENTIAL; - - switch (biometricModality) { - case BiometricAuthenticator.TYPE_FINGERPRINT: + if (config.mSensorIds.length == 1) { + final int singleSensorAuthId = config.mSensorIds[0]; + if (Utils.containsSensorId(mFpProps, singleSensorAuthId)) { mBiometricView = (AuthBiometricFingerprintView) factory.inflate(R.layout.auth_biometric_fingerprint_view, null, false); - break; - case BiometricAuthenticator.TYPE_FACE: + } else if (Utils.containsSensorId(mFaceProps, singleSensorAuthId)) { mBiometricView = (AuthBiometricFaceView) factory.inflate(R.layout.auth_biometric_face_view, null, false); - break; - default: - Log.e(TAG, "Unsupported biometric modality: " + biometricModality); + } else { + // Unknown sensorId + Log.e(TAG, "Unknown sensorId: " + singleSensorAuthId); mBiometricView = null; mBackgroundView = null; mBiometricScrollView = null; return; + } + } else { + // The UI currently only supports authentication with a single sensor. + Log.e(TAG, "Unsupported sensor array, length: " + config.mSensorIds.length); + mBiometricView = null; + mBackgroundView = null; + mBiometricScrollView = null; + return; } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index a4aeb8a9a94d..874c73baf146 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -29,12 +29,12 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; -import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.PromptInfo; import android.hardware.face.FaceManager; +import android.hardware.face.FaceSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Bundle; @@ -74,8 +74,12 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, private final StatusBarStateController mStatusBarStateController; private final IActivityTaskManager mActivityTaskManager; @Nullable private final FingerprintManager mFingerprintManager; + @Nullable private final FaceManager mFaceManager; private final Provider<UdfpsController> mUdfpsControllerFactory; + @Nullable private final List<FingerprintSensorPropertiesInternal> mFpProps; + @Nullable private final List<FaceSensorPropertiesInternal> mFaceProps; + // TODO: These should just be saved from onSaveState private SomeArgs mCurrentDialogArgs; @VisibleForTesting @@ -285,14 +289,20 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, StatusBarStateController statusBarStateController, IActivityTaskManager activityTaskManager, @Nullable FingerprintManager fingerprintManager, + @Nullable FaceManager faceManager, Provider<UdfpsController> udfpsControllerFactory) { super(context); mCommandQueue = commandQueue; mStatusBarStateController = statusBarStateController; mActivityTaskManager = activityTaskManager; mFingerprintManager = fingerprintManager; + mFaceManager = faceManager; mUdfpsControllerFactory = udfpsControllerFactory; + mFpProps = mFingerprintManager != null ? mFingerprintManager.getSensorPropertiesInternal() + : null; + mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null; + IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); @@ -326,24 +336,30 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, @Override public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, - @BiometricAuthenticator.Modality int biometricModality, boolean requireConfirmation, + int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, String opPackageName, long operationId) { @Authenticators.Types final int authenticators = promptInfo.getAuthenticators(); if (DEBUG) { + StringBuilder ids = new StringBuilder(); + for (int sensorId : sensorIds) { + ids.append(sensorId).append(" "); + } Log.d(TAG, "showAuthenticationDialog, authenticators: " + authenticators - + ", biometricModality: " + biometricModality + + ", sensorIds: " + ids.toString() + + ", credentialAllowed: " + credentialAllowed + ", requireConfirmation: " + requireConfirmation + ", operationId: " + operationId); } SomeArgs args = SomeArgs.obtain(); args.arg1 = promptInfo; args.arg2 = receiver; - args.argi1 = biometricModality; - args.arg3 = requireConfirmation; - args.argi2 = userId; - args.arg4 = opPackageName; - args.arg5 = operationId; + args.arg3 = sensorIds; + args.arg4 = credentialAllowed; + args.arg5 = requireConfirmation; + args.argi1 = userId; + args.arg6 = opPackageName; + args.arg7 = operationId; boolean skipAnimation = false; if (mCurrentDialog != null) { @@ -467,25 +483,28 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, private void showDialog(SomeArgs args, boolean skipAnimation, Bundle savedState) { mCurrentDialogArgs = args; - final @BiometricAuthenticator.Modality int type = args.argi1; + final PromptInfo promptInfo = (PromptInfo) args.arg1; - final boolean requireConfirmation = (boolean) args.arg3; - final int userId = args.argi2; - final String opPackageName = (String) args.arg4; - final long operationId = (long) args.arg5; + final int[] sensorIds = (int[]) args.arg3; + final boolean credentialAllowed = (boolean) args.arg4; + final boolean requireConfirmation = (boolean) args.arg5; + final int userId = args.argi1; + final String opPackageName = (String) args.arg6; + final long operationId = (long) args.arg7; // Create a new dialog but do not replace the current one yet. final AuthDialog newDialog = buildDialog( promptInfo, requireConfirmation, userId, - type, + sensorIds, + credentialAllowed, opPackageName, skipAnimation, operationId); if (newDialog == null) { - Log.e(TAG, "Unsupported type: " + type); + Log.e(TAG, "Unsupported type configuration"); return; } @@ -493,8 +512,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, Log.d(TAG, "userId: " + userId + " savedState: " + savedState + " mCurrentDialog: " + mCurrentDialog - + " newDialog: " + newDialog - + " type: " + type); + + " newDialog: " + newDialog); } if (mCurrentDialog != null) { @@ -550,7 +568,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, } protected AuthDialog buildDialog(PromptInfo promptInfo, boolean requireConfirmation, - int userId, @BiometricAuthenticator.Modality int type, String opPackageName, + int userId, int[] sensorIds, boolean credentialAllowed, String opPackageName, boolean skipIntro, long operationId) { return new AuthContainerView.Builder(mContext) .setCallback(this) @@ -560,6 +578,6 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, .setOpPackageName(opPackageName) .setSkipIntro(skipIntro) .setOperationId(operationId) - .build(type); + .build(sensorIds, credentialAllowed, mFpProps, mFaceProps); } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index e3b00495f3dc..3c2e00869ab8 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -78,7 +78,7 @@ class UdfpsController implements DozeReceiver { // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple // sensors, this, in addition to a lot of the code here, will be updated. @VisibleForTesting - final int mUdfpsSensorId; + final FingerprintSensorPropertiesInternal mSensorProps; private final WindowManager mWindowManager; private final SystemSettings mSystemSettings; private final DelayableExecutor mFgExecutor; @@ -180,19 +180,12 @@ class UdfpsController implements DozeReceiver { mFgExecutor = fgExecutor; mLayoutParams = createLayoutParams(context); - int udfpsSensorId = -1; - for (FingerprintSensorPropertiesInternal props : - mFingerprintManager.getSensorPropertiesInternal()) { - if (props.isAnyUdfpsType()) { - udfpsSensorId = props.sensorId; - break; - } - } + mSensorProps = findFirstUdfps(); // At least one UDFPS sensor exists - checkArgument(udfpsSensorId != -1); - mUdfpsSensorId = udfpsSensorId; + checkArgument(mSensorProps != null); mView = (UdfpsView) inflater.inflate(R.layout.udfps_view, null, false); + mView.setSensorProperties(mSensorProps); mHbmPath = resources.getString(R.string.udfps_hbm_sysfs_path); mHbmEnableCommand = resources.getString(R.string.udfps_hbm_enable_command); @@ -235,6 +228,17 @@ class UdfpsController implements DozeReceiver { mIsOverlayShowing = false; } + @Nullable + private FingerprintSensorPropertiesInternal findFirstUdfps() { + for (FingerprintSensorPropertiesInternal props : + mFingerprintManager.getSensorPropertiesInternal()) { + if (props.isAnyUdfpsType()) { + return props; + } + } + return null; + } + @Override public void dozeTimeTick() { mView.dozeTimeTick(); @@ -374,7 +378,7 @@ class UdfpsController implements DozeReceiver { fw.write(mHbmEnableCommand); fw.close(); } - mFingerprintManager.onPointerDown(mUdfpsSensorId, x, y, minor, major); + mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major); } catch (IOException e) { mView.hideScrimAndDot(); Log.e(TAG, "onFingerDown | failed to enable HBM: " + e.getMessage()); @@ -382,7 +386,7 @@ class UdfpsController implements DozeReceiver { } private void onFingerUp() { - mFingerprintManager.onPointerUp(mUdfpsSensorId); + mFingerprintManager.onPointerUp(mSensorProps.sensorId); // Hiding the scrim before disabling HBM results in less noticeable flicker. mView.hideScrimAndDot(); if (mHbmSupported) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java index d7e91384f049..0ed3bda40c4b 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java @@ -18,6 +18,7 @@ package com.android.systemui.biometrics; import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; +import android.annotation.NonNull; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; @@ -25,6 +26,7 @@ import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; @@ -55,8 +57,6 @@ public class UdfpsView extends View implements DozeReceiver, private final RectF mSensorRect; private final Paint mSensorPaint; - private final float mSensorRadius; - private final float mSensorCenterY; private final float mSensorTouchAreaCoefficient; private final int mMaxBurnInOffsetX; private final int mMaxBurnInOffsetY; @@ -64,9 +64,7 @@ public class UdfpsView extends View implements DozeReceiver, private final Rect mTouchableRegion; private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener; - // This is calculated from the screen's dimensions at runtime, as opposed to mSensorCenterY, - // which is defined in layout.xml - private float mSensorCenterX; + @NonNull private FingerprintSensorPropertiesInternal mProps; // AOD anti-burn-in offsets private float mInterpolatedDarkAmount; @@ -83,18 +81,10 @@ public class UdfpsView extends View implements DozeReceiver, TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.UdfpsView, 0, 0); try { - if (!a.hasValue(R.styleable.UdfpsView_sensorRadius)) { - throw new IllegalArgumentException("UdfpsView must contain sensorRadius"); - } - if (!a.hasValue(R.styleable.UdfpsView_sensorCenterY)) { - throw new IllegalArgumentException("UdfpsView must contain sensorMarginBottom"); - } if (!a.hasValue(R.styleable.UdfpsView_sensorTouchAreaCoefficient)) { throw new IllegalArgumentException( "UdfpsView must contain sensorTouchAreaCoefficient"); } - mSensorRadius = a.getDimension(R.styleable.UdfpsView_sensorRadius, 0f); - mSensorCenterY = a.getDimension(R.styleable.UdfpsView_sensorCenterY, 0f); mSensorTouchAreaCoefficient = a.getFloat( R.styleable.UdfpsView_sensorTouchAreaCoefficient, 0f); } finally { @@ -134,6 +124,10 @@ public class UdfpsView extends View implements DozeReceiver, mIsScrimShowing = false; } + void setSensorProperties(@NonNull FingerprintSensorPropertiesInternal properties) { + mProps = properties; + } + @Override public void dozeTimeTick() { updateAodPosition(); @@ -165,9 +159,10 @@ public class UdfpsView extends View implements DozeReceiver, final int h = getLayoutParams().height; final int w = getLayoutParams().width; mScrimRect.set(0 /* left */, 0 /* top */, w, h); - mSensorCenterX = w / 2f; - mSensorRect.set(mSensorCenterX - mSensorRadius, mSensorCenterY - mSensorRadius, - mSensorCenterX + mSensorRadius, mSensorCenterY + mSensorRadius); + mSensorRect.set(mProps.sensorLocationX - mProps.sensorRadius, + mProps.sensorLocationY - mProps.sensorRadius, + mProps.sensorLocationX + mProps.sensorRadius, + mProps.sensorLocationY + mProps.sensorRadius); // Sets mTouchableRegion with rounded up values from mSensorRect. mSensorRect.roundOut(mTouchableRegion); @@ -211,10 +206,10 @@ public class UdfpsView extends View implements DozeReceiver, } boolean isValidTouch(float x, float y, float pressure) { - return x > (mSensorCenterX - mSensorRadius * mSensorTouchAreaCoefficient) - && x < (mSensorCenterX + mSensorRadius * mSensorTouchAreaCoefficient) - && y > (mSensorCenterY - mSensorRadius * mSensorTouchAreaCoefficient) - && y < (mSensorCenterY + mSensorRadius * mSensorTouchAreaCoefficient); + return x > (mProps.sensorLocationX - mProps.sensorRadius * mSensorTouchAreaCoefficient) + && x < (mProps.sensorLocationX + mProps.sensorRadius * mSensorTouchAreaCoefficient) + && y > (mProps.sensorLocationY - mProps.sensorRadius * mSensorTouchAreaCoefficient) + && y < (mProps.sensorLocationY + mProps.sensorRadius * mSensorTouchAreaCoefficient); } void setScrimAlpha(int alpha) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java index 2e9afa58987a..fd5e85a953ad 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java @@ -20,9 +20,11 @@ import static android.hardware.biometrics.BiometricManager.Authenticators; import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE; import android.annotation.IntDef; +import android.annotation.Nullable; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.hardware.biometrics.PromptInfo; +import android.hardware.biometrics.SensorPropertiesInternal; import android.os.UserManager; import android.util.DisplayMetrics; import android.view.ViewGroup; @@ -33,6 +35,7 @@ import com.android.internal.widget.LockPatternUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.List; public class Utils { @@ -98,4 +101,19 @@ public class Utils { final UserManager userManager = context.getSystemService(UserManager.class); return userManager.isManagedProfile(userId); } + + static boolean containsSensorId(@Nullable List<? extends SensorPropertiesInternal> properties, + int sensorId) { + if (properties == null) { + return false; + } + + for (SensorPropertiesInternal prop : properties) { + if (prop.sensorId == sensorId) { + return true; + } + } + + return false; + } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java index 9f7358bf94ff..8bcffc8ece1a 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java @@ -113,6 +113,18 @@ public class BadgedImageView extends ImageView { setClickable(true); } + public void showDotAndBadge(boolean onLeft) { + removeDotSuppressionFlag(BadgedImageView.SuppressionFlag.BEHIND_STACK); + animateDotBadgePositions(onLeft); + + } + + public void hideDotAndBadge(boolean onLeft) { + addDotSuppressionFlag(BadgedImageView.SuppressionFlag.BEHIND_STACK); + mOnLeft = onLeft; + hideBadge(); + } + /** * Updates the view with provided info. */ diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java index 1891daf59007..09d9e03cb0cb 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java @@ -53,7 +53,8 @@ import java.util.Objects; /** * Encapsulates the data and UI elements of a bubble. */ -class Bubble implements BubbleViewProvider { +@VisibleForTesting +public class Bubble implements BubbleViewProvider { private static final String TAG = "Bubble"; private final String mKey; @@ -62,7 +63,7 @@ class Bubble implements BubbleViewProvider { private long mLastAccessed; @Nullable - private BubbleController.NotificationSuppressionChangedListener mSuppressionListener; + private Bubbles.NotificationSuppressionChangedListener mSuppressionListener; /** Whether the bubble should show a dot for the notification indicating updated content. */ private boolean mShowBubbleUpdateDot = true; @@ -173,8 +174,8 @@ class Bubble implements BubbleViewProvider { @VisibleForTesting(visibility = PRIVATE) Bubble(@NonNull final BubbleEntry entry, - @Nullable final BubbleController.NotificationSuppressionChangedListener listener, - final BubbleController.PendingIntentCanceledListener intentCancelListener) { + @Nullable final Bubbles.NotificationSuppressionChangedListener listener, + final Bubbles.PendingIntentCanceledListener intentCancelListener) { mKey = entry.getKey(); mSuppressionListener = listener; mIntentCancelListener = intent -> { @@ -309,11 +310,13 @@ class Bubble implements BubbleViewProvider { * * @param callback the callback to notify one the bubble is ready to be displayed. * @param context the context for the bubble. + * @param controller * @param stackView the stackView the bubble is eventually added to. * @param iconFactory the iconfactory use to create badged images for the bubble. */ void inflate(BubbleViewInfoTask.Callback callback, Context context, + BubbleController controller, BubbleStackView stackView, BubbleIconFactory iconFactory, boolean skipInflation) { @@ -322,6 +325,7 @@ class Bubble implements BubbleViewProvider { } mInflationTask = new BubbleViewInfoTask(this, context, + controller, stackView, iconFactory, skipInflation, @@ -403,7 +407,7 @@ class Bubble implements BubbleViewProvider { mInstanceId = entry.getStatusBarNotification().getInstanceId(); mFlyoutMessage = extractFlyoutMessage(entry); if (entry.getRanking() != null) { - mShortcutInfo = entry.getRanking().getShortcutInfo(); + mShortcutInfo = entry.getRanking().getConversationShortcutInfo(); mIsVisuallyInterruptive = entry.getRanking().visuallyInterruptive(); if (entry.getRanking().getChannel() != null) { mIsImportantConversation = @@ -522,7 +526,8 @@ class Bubble implements BubbleViewProvider { /** * Sets whether this notification should be suppressed in the shade. */ - void setSuppressNotification(boolean suppressNotification) { + @VisibleForTesting + public void setSuppressNotification(boolean suppressNotification) { boolean prevShowInShade = showInShade(); if (suppressNotification) { mFlags |= Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; @@ -559,7 +564,8 @@ class Bubble implements BubbleViewProvider { /** * Whether the flyout for the bubble should be shown. */ - boolean showFlyout() { + @VisibleForTesting + public boolean showFlyout() { return !mSuppressFlyout && !mShouldSuppressPeek && !shouldSuppressNotification() && !mShouldSuppressNotificationList; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 0c3dc8222a34..598a604099ac 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -17,39 +17,19 @@ package com.android.systemui.bubbles; import static android.app.ActivityTaskManager.INVALID_TASK_ID; -import static android.app.Notification.FLAG_BUBBLE; -import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; -import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; -import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; -import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL; import static android.service.notification.NotificationListenerService.REASON_CANCEL; -import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL; -import static android.service.notification.NotificationListenerService.REASON_CLICK; -import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; -import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE; -import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.systemui.statusbar.StatusBarState.SHADE; -import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON; - -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.ElementType.LOCAL_VARIABLE; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.NonNull; import android.annotation.UserIdInt; -import android.app.ActivityManager.RunningTaskInfo; +import android.app.ActivityManager; import android.app.ActivityTaskManager; -import android.app.INotificationManager; import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.pm.ActivityInfo; @@ -65,7 +45,6 @@ import android.os.ServiceManager; import android.os.UserHandle; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.RankingMap; -import android.service.notification.ZenModeConfig; import android.util.ArraySet; import android.util.Log; import android.util.Pair; @@ -74,45 +53,14 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; -import androidx.annotation.IntDef; import androidx.annotation.MainThread; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.statusbar.NotificationVisibility; -import com.android.systemui.Dumpable; import com.android.systemui.bubbles.dagger.BubbleModule; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.model.SysUiState; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.shared.system.QuickStepContract; -import com.android.systemui.shared.system.TaskStackChangeListener; -import com.android.systemui.shared.system.TaskStackChangeListeners; -import com.android.systemui.statusbar.FeatureFlags; -import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.NotificationRemoveInterceptor; -import com.android.systemui.statusbar.NotificationShadeWindowController; -import com.android.systemui.statusbar.ScrimView; -import com.android.systemui.statusbar.notification.NotificationChannelHelper; -import com.android.systemui.statusbar.notification.NotificationEntryListener; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.collection.NotifCollection; -import com.android.systemui.statusbar.notification.collection.NotifPipeline; -import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.coordinator.BubbleCoordinator; -import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; -import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; -import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; -import com.android.systemui.statusbar.notification.logging.NotificationLogger; -import com.android.systemui.statusbar.phone.ScrimController; -import com.android.systemui.statusbar.phone.ShadeController; -import com.android.systemui.statusbar.phone.StatusBar; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.ZenModeController; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.FloatingContentCoordinator; @@ -120,11 +68,10 @@ import com.android.wm.shell.pip.PinnedStackListenerForwarder; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.function.IntConsumer; /** * Bubbles are a special type of content that can "float" on top of other apps or System UI. @@ -132,52 +79,23 @@ import java.util.Objects; * * The controller manages addition, removal, and visible state of bubbles on screen. */ -public class BubbleController implements Bubbles, ConfigurationController.ConfigurationListener, - Dumpable { +public class BubbleController implements Bubbles { private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES; - @Retention(SOURCE) - @IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED, - DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE, - DISMISS_USER_CHANGED, DISMISS_GROUP_CANCELLED, DISMISS_INVALID_INTENT, - DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED, - DISMISS_NO_BUBBLE_UP}) - @Target({FIELD, LOCAL_VARIABLE, PARAMETER}) - @interface DismissReason {} - - static final int DISMISS_USER_GESTURE = 1; - static final int DISMISS_AGED = 2; - static final int DISMISS_TASK_FINISHED = 3; - static final int DISMISS_BLOCKED = 4; - static final int DISMISS_NOTIF_CANCEL = 5; - static final int DISMISS_ACCESSIBILITY_ACTION = 6; - static final int DISMISS_NO_LONGER_BUBBLE = 7; - static final int DISMISS_USER_CHANGED = 8; - static final int DISMISS_GROUP_CANCELLED = 9; - static final int DISMISS_INVALID_INTENT = 10; - static final int DISMISS_OVERFLOW_MAX_REACHED = 11; - static final int DISMISS_SHORTCUT_REMOVED = 12; - static final int DISMISS_PACKAGE_REMOVED = 13; - static final int DISMISS_NO_BUBBLE_UP = 14; - private final Context mContext; - private final NotificationEntryManager mNotificationEntryManager; - private final NotifPipeline mNotifPipeline; - private final BubbleTaskStackListener mTaskStackListener; private BubbleExpandListener mExpandListener; @Nullable private BubbleStackView.SurfaceSynchronizer mSurfaceSynchronizer; - private final NotificationGroupManagerLegacy mNotificationGroupManager; - private final ShadeController mShadeController; private final FloatingContentCoordinator mFloatingContentCoordinator; private final BubbleDataRepository mDataRepository; private BubbleLogger mLogger; private final Handler mMainHandler; private BubbleData mBubbleData; - private ScrimView mBubbleScrim; + private View mBubbleScrim; @Nullable private BubbleStackView mStackView; private BubbleIconFactory mBubbleIconFactory; private BubblePositioner mBubblePositioner; + private SysuiProxy mSysuiProxy; /** * The relative position of the stack when we removed it and nulled it out. If the stack is @@ -193,12 +111,6 @@ public class BubbleController implements Bubbles, ConfigurationController.Config // Used when ranking updates occur and we check if things should bubble / unbubble private NotificationListenerService.Ranking mTmpRanking; - // Bubbles get added to the status bar view - private final NotificationShadeWindowController mNotificationShadeWindowController; - private final ZenModeController mZenModeController; - private StatusBarStateListener mStatusBarStateListener; - private INotificationManager mINotificationManager; - // Callback that updates BubbleOverflowActivity on data change. @Nullable private BubbleData.Listener mOverflowListener = null; @@ -209,12 +121,10 @@ public class BubbleController implements Bubbles, ConfigurationController.Config * When the shade status changes to SHADE (from anything but SHADE, like LOCKED) we'll select * this bubble and expand the stack. */ - @Nullable private NotificationEntry mNotifEntryToExpandOnShadeUnlock; + @Nullable private BubbleEntry mNotifEntryToExpandOnShadeUnlock; - private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private IStatusBarService mBarService; private WindowManager mWindowManager; - private SysUiState mSysUiState; // Used to post to main UI thread private Handler mHandler = new Handler(); @@ -224,9 +134,6 @@ public class BubbleController implements Bubbles, ConfigurationController.Config /** Whether or not the BubbleStackView has been added to the WindowManager. */ private boolean mAddedToWindowManager = false; - // Listens to user switch so bubbles can be saved and restored. - private final NotificationLockscreenUserManager mNotifUserManager; - /** Last known orientation, used to detect orientation changes in {@link #onConfigChanged}. */ private int mOrientation = Configuration.ORIENTATION_UNDEFINED; @@ -247,9 +154,6 @@ public class BubbleController implements Bubbles, ConfigurationController.Config private ShellTaskOrganizer mTaskOrganizer; - // TODO (b/145659174): allow for multiple callbacks to support the "shadow" new notif pipeline - private final List<NotifCallback> mCallbacks = new ArrayList<>(); - /** * Whether the IME is visible, as reported by the BubbleStackView. If it is, we'll make the * Bubbles window NOT_FOCUSABLE so that touches on the Bubbles UI doesn't steal focus from the @@ -257,122 +161,15 @@ public class BubbleController implements Bubbles, ConfigurationController.Config */ private boolean mImeVisible = false; - /** - * Listener to find out about stack expansion / collapse events. - */ - public interface BubbleExpandListener { - /** - * Called when the expansion state of the bubble stack changes. - * - * @param isExpanding whether it's expanding or collapsing - * @param key the notification key associated with bubble being expanded - */ - void onBubbleExpandChanged(boolean isExpanding, String key); - } - - /** - * Listener to be notified when a bubbles' notification suppression state changes. - */ - public interface NotificationSuppressionChangedListener { - /** - * Called when the notification suppression state of a bubble changes. - */ - void onBubbleNotificationSuppressionChange(Bubble bubble); - } - - /** - * Listener to be notified when a pending intent has been canceled for a bubble. - */ - public interface PendingIntentCanceledListener { - /** - * Called when the pending intent for a bubble has been canceled. - */ - void onPendingIntentCanceled(Bubble bubble); - } - - /** - * Callback for when the BubbleController wants to interact with the notification pipeline to: - * - Remove a previously bubbled notification - * - Update the notification shade since bubbled notification should/shouldn't be showing - */ - public interface NotifCallback { - /** - * Called when a bubbled notification that was hidden from the shade is now being removed - * This can happen when an app cancels a bubbled notification or when the user dismisses a - * bubble. - */ - void removeNotification( - @NonNull NotificationEntry entry, - @NonNull DismissedByUserStats stats, - int reason); - - /** - * Called when a bubbled notification has changed whether it should be - * filtered from the shade. - */ - void invalidateNotifications(@NonNull String reason); - - /** - * Called on a bubbled entry that has been removed when there are no longer - * bubbled entries in its group. - * - * Checks whether its group has any other (non-bubbled) children. If it doesn't, - * removes all remnants of the group's summary from the notification pipeline. - * TODO: (b/145659174) Only old pipeline needs this - delete post-migration. - */ - void maybeCancelSummary(@NonNull NotificationEntry entry); - } - - /** - * Listens for the current state of the status bar and updates the visibility state - * of bubbles as needed. - */ - private class StatusBarStateListener implements StatusBarStateController.StateListener { - private int mState; - /** - * Returns the current status bar state. - */ - public int getCurrentState() { - return mState; - } - - @Override - public void onStateChanged(int newState) { - mState = newState; - boolean shouldCollapse = (mState != SHADE); - if (shouldCollapse) { - collapseStack(); - } - - if (mNotifEntryToExpandOnShadeUnlock != null) { - expandStackAndSelectBubble(mNotifEntryToExpandOnShadeUnlock); - mNotifEntryToExpandOnShadeUnlock = null; - } - - updateStack(); - } - } + /** true when user is in status bar unlock shade. */ + private boolean mIsStatusBarShade = true; /** * Injected constructor. See {@link BubbleModule}. */ public static BubbleController create(Context context, - NotificationShadeWindowController notificationShadeWindowController, - StatusBarStateController statusBarStateController, - ShadeController shadeController, @Nullable BubbleStackView.SurfaceSynchronizer synchronizer, - ConfigurationController configurationController, - NotificationInterruptStateProvider interruptionStateProvider, - ZenModeController zenModeController, - NotificationLockscreenUserManager notifUserManager, - NotificationGroupManagerLegacy groupManager, - NotificationEntryManager entryManager, - NotifPipeline notifPipeline, - FeatureFlags featureFlags, - DumpManager dumpManager, FloatingContentCoordinator floatingContentCoordinator, - SysUiState sysUiState, - INotificationManager notificationManager, @Nullable IStatusBarService statusBarService, WindowManager windowManager, WindowManagerShellWrapper windowManagerShellWrapper, @@ -381,39 +178,23 @@ public class BubbleController implements Bubbles, ConfigurationController.Config @Main Handler mainHandler, ShellTaskOrganizer organizer) { BubbleLogger logger = new BubbleLogger(uiEventLogger); - return new BubbleController(context, notificationShadeWindowController, - statusBarStateController, shadeController, new BubbleData(context, logger), - synchronizer, configurationController, interruptionStateProvider, zenModeController, - notifUserManager, groupManager, entryManager, notifPipeline, featureFlags, - dumpManager, floatingContentCoordinator, - new BubbleDataRepository(context, launcherApps), sysUiState, notificationManager, - statusBarService, windowManager, windowManagerShellWrapper, launcherApps, logger, - mainHandler, organizer, new BubblePositioner(context, windowManager)); + return new BubbleController(context, + new BubbleData(context, logger), synchronizer, + floatingContentCoordinator, new BubbleDataRepository(context, launcherApps), + statusBarService, windowManager, + windowManagerShellWrapper, launcherApps, logger, mainHandler, organizer, + new BubblePositioner(context, windowManager)); } /** * Testing constructor. */ @VisibleForTesting - BubbleController(Context context, - NotificationShadeWindowController notificationShadeWindowController, - StatusBarStateController statusBarStateController, - ShadeController shadeController, + public BubbleController(Context context, BubbleData data, @Nullable BubbleStackView.SurfaceSynchronizer synchronizer, - ConfigurationController configurationController, - NotificationInterruptStateProvider interruptionStateProvider, - ZenModeController zenModeController, - NotificationLockscreenUserManager notifUserManager, - NotificationGroupManagerLegacy groupManager, - NotificationEntryManager entryManager, - NotifPipeline notifPipeline, - FeatureFlags featureFlags, - DumpManager dumpManager, FloatingContentCoordinator floatingContentCoordinator, BubbleDataRepository dataRepository, - SysUiState sysUiState, - INotificationManager notificationManager, @Nullable IStatusBarService statusBarService, WindowManager windowManager, WindowManagerShellWrapper windowManagerShellWrapper, @@ -422,82 +203,35 @@ public class BubbleController implements Bubbles, ConfigurationController.Config Handler mainHandler, ShellTaskOrganizer organizer, BubblePositioner positioner) { - dumpManager.registerDumpable(TAG, this); mContext = context; - mShadeController = shadeController; - mNotificationInterruptStateProvider = interruptionStateProvider; - mNotifUserManager = notifUserManager; - mZenModeController = zenModeController; mFloatingContentCoordinator = floatingContentCoordinator; mDataRepository = dataRepository; - mINotificationManager = notificationManager; mLogger = bubbleLogger; mMainHandler = mainHandler; - mZenModeController.addCallback(new ZenModeController.Callback() { - @Override - public void onZenChanged(int zen) { - for (Bubble b : mBubbleData.getBubbles()) { - b.setShowDot(b.showInShade()); - } - } - - @Override - public void onConfigChanged(ZenModeConfig config) { - for (Bubble b : mBubbleData.getBubbles()) { - b.setShowDot(b.showInShade()); - } - } - }); - - configurationController.addCallback(this /* configurationListener */); - mSysUiState = sysUiState; mBubbleData = data; mBubbleData.setListener(mBubbleDataListener); - mBubbleData.setSuppressionChangedListener(new NotificationSuppressionChangedListener() { - @Override - public void onBubbleNotificationSuppressionChange(Bubble bubble) { - // Make sure NoMan knows it's not showing in the shade anymore so anyone querying it - // can tell. - try { - mBarService.onBubbleNotificationSuppressionChanged(bubble.getKey(), - !bubble.showInShade()); - } catch (RemoteException e) { - // Bad things have happened - } + mBubbleData.setSuppressionChangedListener(bubble -> { + // Make sure NoMan knows it's not showing in the shade anymore so anyone querying it + // can tell. + try { + mBarService.onBubbleNotificationSuppressionChanged(bubble.getKey(), + !bubble.showInShade()); + } catch (RemoteException e) { + // Bad things have happened } }); mBubbleData.setPendingIntentCancelledListener(bubble -> { if (bubble.getBubbleIntent() == null) { return; } - if (bubble.isIntentActive() - || mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) { + if (bubble.isIntentActive() || mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) { bubble.setPendingIntentCanceled(); return; } - mHandler.post( - () -> removeBubble(bubble.getKey(), - BubbleController.DISMISS_INVALID_INTENT)); + mHandler.post(() -> removeBubble(bubble.getKey(), DISMISS_INVALID_INTENT)); }); - mNotificationEntryManager = entryManager; - mNotificationGroupManager = groupManager; - mNotifPipeline = notifPipeline; - - if (!featureFlags.isNewNotifPipelineRenderingEnabled()) { - setupNEM(); - } else { - setupNotifPipeline(); - } - - mNotificationShadeWindowController = notificationShadeWindowController; - mStatusBarStateListener = new StatusBarStateListener(); - statusBarStateController.addCallback(mStatusBarStateListener); - - mTaskStackListener = new BubbleTaskStackListener(); - TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener); - try { windowManagerShellWrapper.addPinnedStackListener(new BubblesImeListener()); } catch (RemoteException e) { @@ -511,25 +245,10 @@ public class BubbleController implements Bubbles, ConfigurationController.Config ServiceManager.getService(Context.STATUS_BAR_SERVICE)) : statusBarService; - mBubbleScrim = new ScrimView(mContext); - mBubbleScrim.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); - mSavedBubbleKeysPerUser = new SparseSetArray<>(); - mCurrentUserId = mNotifUserManager.getCurrentUserId(); + mCurrentUserId = ActivityManager.getCurrentUser(); mBubbleData.setCurrentUserId(mCurrentUserId); - mNotifUserManager.addUserChangedListener( - new NotificationLockscreenUserManager.UserChangedListener() { - @Override - public void onUserChanged(int newUserId) { - BubbleController.this.saveBubbles(mCurrentUserId); - mBubbleData.dismissAll(DISMISS_USER_CHANGED); - BubbleController.this.restoreBubbles(newUserId); - mCurrentUserId = newUserId; - mBubbleData.setCurrentUserId(newUserId); - } - }); - mBubbleIconFactory = new BubbleIconFactory(context); mTaskOrganizer = organizer; mBubblePositioner = positioner; @@ -549,10 +268,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } @Override - public void onPackagesAvailable(String[] strings, UserHandle userHandle, - boolean b) { - - } + public void onPackagesAvailable(String[] strings, UserHandle userHandle, boolean b) {} @Override public void onPackagesUnavailable(String[] packages, UserHandle userHandle, @@ -577,17 +293,9 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } /** - * See {@link NotifCallback}. - */ - @Override - public void addNotifCallback(NotifCallback callback) { - mCallbacks.add(callback); - } - - /** * Hides the current input method, wherever it may be focused, via InputMethodManagerInternal. */ - public void hideCurrentInputMethod() { + void hideCurrentInputMethod() { try { mBarService.hideCurrentInputMethodForBubbles(); } catch (RemoteException e) { @@ -595,183 +303,6 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } } - private void onBubbleExpandChanged(boolean shouldExpand) { - mSysUiState - .setFlag(QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED, shouldExpand) - .commitUpdate(mContext.getDisplayId()); - } - - private void setupNEM() { - mNotificationEntryManager.addNotificationEntryListener( - new NotificationEntryListener() { - @Override - public void onPendingEntryAdded(NotificationEntry entry) { - onEntryAdded(entry); - } - - @Override - public void onPreEntryUpdated(NotificationEntry entry) { - onEntryUpdated(entry); - } - - @Override - public void onEntryRemoved( - NotificationEntry entry, - @android.annotation.Nullable NotificationVisibility visibility, - boolean removedByUser, - int reason) { - BubbleController.this.onEntryRemoved(entry); - } - - @Override - public void onNotificationRankingUpdated(RankingMap rankingMap) { - onRankingUpdated(rankingMap); - } - }); - - // The new pipeline takes care of this as a NotifDismissInterceptor BubbleCoordinator - mNotificationEntryManager.addNotificationRemoveInterceptor( - new NotificationRemoveInterceptor() { - @Override - public boolean onNotificationRemoveRequested( - String key, - NotificationEntry entry, - int dismissReason) { - final boolean isClearAll = dismissReason == REASON_CANCEL_ALL; - final boolean isUserDismiss = dismissReason == REASON_CANCEL - || dismissReason == REASON_CLICK; - final boolean isAppCancel = dismissReason == REASON_APP_CANCEL - || dismissReason == REASON_APP_CANCEL_ALL; - final boolean isSummaryCancel = - dismissReason == REASON_GROUP_SUMMARY_CANCELED; - - // Need to check for !appCancel here because the notification may have - // previously been dismissed & entry.isRowDismissed would still be true - boolean userRemovedNotif = - (entry != null && entry.isRowDismissed() && !isAppCancel) - || isClearAll || isUserDismiss || isSummaryCancel; - - if (userRemovedNotif) { - return handleDismissalInterception(entry); - } - return false; - } - }); - - mNotificationGroupManager.registerGroupChangeListener( - new NotificationGroupManagerLegacy.OnGroupChangeListener() { - @Override - public void onGroupSuppressionChanged( - NotificationGroupManagerLegacy.NotificationGroup group, - boolean suppressed) { - // More notifications could be added causing summary to no longer - // be suppressed -- in this case need to remove the key. - final String groupKey = group.summary != null - ? group.summary.getSbn().getGroupKey() - : null; - if (!suppressed && groupKey != null - && mBubbleData.isSummarySuppressed(groupKey)) { - mBubbleData.removeSuppressedSummary(groupKey); - } - } - }); - - addNotifCallback(new NotifCallback() { - @Override - public void removeNotification( - NotificationEntry entry, - DismissedByUserStats dismissedByUserStats, - int reason - ) { - mNotificationEntryManager.performRemoveNotification(entry.getSbn(), - dismissedByUserStats, reason); - } - - @Override - public void invalidateNotifications(String reason) { - mNotificationEntryManager.updateNotifications(reason); - } - - @Override - public void maybeCancelSummary(NotificationEntry entry) { - // Check if removed bubble has an associated suppressed group summary that needs - // to be removed now. - final String groupKey = entry.getSbn().getGroupKey(); - if (mBubbleData.isSummarySuppressed(groupKey)) { - mBubbleData.removeSuppressedSummary(groupKey); - - final NotificationEntry summary = - mNotificationEntryManager.getActiveNotificationUnfiltered( - mBubbleData.getSummaryKey(groupKey)); - if (summary != null) { - mNotificationEntryManager.performRemoveNotification( - summary.getSbn(), - getDismissedByUserStats(summary, false), - UNDEFINED_DISMISS_REASON); - } - } - - // Check if we still need to remove the summary from NoManGroup because the summary - // may not be in the mBubbleData.mSuppressedGroupKeys list and removed above. - // For example: - // 1. Bubbled notifications (group) is posted to shade and are visible bubbles - // 2. User expands bubbles so now their respective notifications in the shade are - // hidden, including the group summary - // 3. User removes all bubbles - // 4. We expect all the removed bubbles AND the summary (note: the summary was - // never added to the suppressedSummary list in BubbleData, so we add this check) - NotificationEntry summary = mNotificationGroupManager.getLogicalGroupSummary(entry); - if (summary != null) { - ArrayList<NotificationEntry> summaryChildren = - mNotificationGroupManager.getLogicalChildren(summary.getSbn()); - boolean isSummaryThisNotif = summary.getKey().equals(entry.getKey()); - if (!isSummaryThisNotif && (summaryChildren == null - || summaryChildren.isEmpty())) { - mNotificationEntryManager.performRemoveNotification( - summary.getSbn(), - getDismissedByUserStats(summary, false), - UNDEFINED_DISMISS_REASON); - } - } - } - }); - } - - private void setupNotifPipeline() { - mNotifPipeline.addCollectionListener(new NotifCollectionListener() { - @Override - public void onEntryAdded(NotificationEntry entry) { - BubbleController.this.onEntryAdded(entry); - } - - @Override - public void onEntryUpdated(NotificationEntry entry) { - BubbleController.this.onEntryUpdated(entry); - } - - @Override - public void onRankingUpdate(RankingMap rankingMap) { - onRankingUpdated(rankingMap); - } - - @Override - public void onEntryRemoved(NotificationEntry entry, - @NotifCollection.CancellationReason int reason) { - BubbleController.this.onEntryRemoved(entry); - } - }); - } - - /** - * Returns the scrim drawn behind the bubble stack. This is managed by {@link ScrimController} - * since we want the scrim's appearance and behavior to be identical to that of the notification - * shade scrim. - */ - @Override - public ScrimView getScrimForBubble() { - return mBubbleScrim; - } - /** * Called when the status bar has become visible or invisible (either permanently or * temporarily). @@ -785,16 +316,47 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } } + @Override + public void onZenStateChanged() { + for (Bubble b : mBubbleData.getBubbles()) { + b.setShowDot(b.showInShade()); + } + } + + @Override + public void onStatusBarStateChanged(boolean isShade) { + mIsStatusBarShade = isShade; + if (!mIsStatusBarShade) { + collapseStack(); + } + + if (mNotifEntryToExpandOnShadeUnlock != null) { + expandStackAndSelectBubble(mNotifEntryToExpandOnShadeUnlock); + mNotifEntryToExpandOnShadeUnlock = null; + } + + updateStack(); + } + + @Override + public void onUserChanged(int newUserId) { + saveBubbles(mCurrentUserId); + mBubbleData.dismissAll(DISMISS_USER_CHANGED); + restoreBubbles(newUserId); + mCurrentUserId = newUserId; + mBubbleData.setCurrentUserId(newUserId); + } + /** * Sets whether to perform inflation on the same thread as the caller. This method should only * be used in tests, not in production. */ @VisibleForTesting - void setInflateSynchronously(boolean inflateSynchronously) { + public void setInflateSynchronously(boolean inflateSynchronously) { mInflateSynchronously = inflateSynchronously; } - @Override + /** Set a listener to be notified of when overflow view update. */ public void setOverflowListener(BubbleData.Listener listener) { mOverflowListener = listener; } @@ -802,21 +364,24 @@ public class BubbleController implements Bubbles, ConfigurationController.Config /** * @return Bubbles for updating overflow. */ - @Override - public List<Bubble> getOverflowBubbles() { + List<Bubble> getOverflowBubbles() { return mBubbleData.getOverflowBubbles(); } - @Override + /** The task listener for events in bubble tasks. */ public ShellTaskOrganizer getTaskOrganizer() { return mTaskOrganizer; } - @Override - public BubblePositioner getPositioner() { + /** Contains information to help position things on the screen. */ + BubblePositioner getPositioner() { return mBubblePositioner; } + SysuiProxy getSysuiProxy() { + return mSysuiProxy; + } + /** * BubbleStackView is lazily created by this method the first time a Bubble is added. This * method initializes the stack view and adds it to the StatusBar just above the scrim. @@ -824,23 +389,14 @@ public class BubbleController implements Bubbles, ConfigurationController.Config private void ensureStackViewCreated() { if (mStackView == null) { mStackView = new BubbleStackView( - mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator, - this::onAllBubblesAnimatedOut, this::onImeVisibilityChanged, - this::hideCurrentInputMethod, this::onBubbleExpandChanged, mBubblePositioner); + mContext, this, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator); mStackView.setStackStartPosition(mPositionFromRemovedStack); mStackView.addView(mBubbleScrim); mStackView.onOrientationChanged(); if (mExpandListener != null) { mStackView.setExpandListener(mExpandListener); } - - mStackView.setUnbubbleConversationCallback(key -> { - final NotificationEntry entry = - mNotificationEntryManager.getPendingOrActiveNotif(key); - if (entry != null) { - onUserChangedBubble(entry, false /* shouldBubble */); - } - }); + mStackView.setUnbubbleConversationCallback(mSysuiProxy::onUnbubbleConversation); } addToWindowManagerMaybe(); @@ -882,7 +438,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } } - private void onImeVisibilityChanged(boolean imeVisible) { + void onImeVisibilityChanged(boolean imeVisible) { mImeVisible = imeVisible; } @@ -913,7 +469,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config * Called by the BubbleStackView and whenever all bubbles have animated out, and none have been * added in the meantime. */ - private void onAllBubblesAnimatedOut() { + void onAllBubblesAnimatedOut() { if (mStackView != null) { mStackView.setVisibility(INVISIBLE); removeFromWindowManagerMaybe(); @@ -946,12 +502,8 @@ public class BubbleController implements Bubbles, ConfigurationController.Config // There were no bubbles saved for this used. return; } - for (NotificationEntry e : - mNotificationEntryManager.getActiveNotificationsForCurrentUser()) { - if (savedBubbleKeys.contains(e.getKey()) - && mNotificationInterruptStateProvider.shouldBubbleUp(e) - && e.isBubble() - && canLaunchInActivityView(mContext, e)) { + for (BubbleEntry e : mSysuiProxy.getShouldRestoredEntries(savedBubbleKeys)) { + if (canLaunchInActivityView(mContext, e)) { updateBubble(e, true /* suppressFlyout */, false /* showInShade */); } } @@ -960,27 +512,18 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } @Override - public void onUiModeChanged() { - updateForThemeChanges(); - } - - @Override - public void onOverlayChanged() { - updateForThemeChanges(); - } - - private void updateForThemeChanges() { + public void updateForThemeChanges() { if (mStackView != null) { mStackView.onThemeChanged(); } mBubbleIconFactory = new BubbleIconFactory(mContext); // Reload each bubble for (Bubble b: mBubbleData.getBubbles()) { - b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory, + b.inflate(null /* callback */, mContext, this, mStackView, mBubbleIconFactory, false /* skipInflation */); } for (Bubble b: mBubbleData.getOverflowBubbles()) { - b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory, + b.inflate(null /* callback */, mContext, this, mStackView, mBubbleIconFactory, false /* skipInflation */); } } @@ -1012,9 +555,16 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } } - /** - * Set a listener to be notified of bubble expand events. - */ + @Override + public void setBubbleScrim(View view) { + mBubbleScrim = view; + } + + @Override + public void setSysuiProxy(SysuiProxy proxy) { + mSysuiProxy = proxy; + } + @Override public void setExpandListener(BubbleExpandListener listener) { mExpandListener = ((isExpanding, key) -> { @@ -1032,7 +582,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config * screen (e.g. if on AOD). */ @VisibleForTesting - boolean hasBubbles() { + public boolean hasBubbles() { if (mStackView == null) { return false; } @@ -1050,24 +600,37 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } @Override - public boolean isBubbleNotificationSuppressedFromShade(NotificationEntry entry) { - String key = entry.getKey(); + public boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey) { boolean isSuppressedBubble = (mBubbleData.hasAnyBubbleWithKey(key) && !mBubbleData.getAnyBubbleWithkey(key).showInShade()); - String groupKey = entry.getSbn().getGroupKey(); boolean isSuppressedSummary = mBubbleData.isSummarySuppressed(groupKey); boolean isSummary = key.equals(mBubbleData.getSummaryKey(groupKey)); return (isSummary && isSuppressedSummary) || isSuppressedBubble; } @Override - public boolean isBubbleExpanded(NotificationEntry entry) { - return isStackExpanded() && mBubbleData != null && mBubbleData.getSelectedBubble() != null - && mBubbleData.getSelectedBubble().getKey().equals(entry.getKey()); + public boolean isSummarySuppressed(String groupKey) { + return mBubbleData.isSummarySuppressed(groupKey); } @Override + public void removeSuppressedSummary(String groupKey) { + mBubbleData.removeSuppressedSummary(groupKey); + } + + @Override + public String getSummaryKey(String groupKey) { + return mBubbleData.getSummaryKey(groupKey); + } + + @Override + public boolean isBubbleExpanded(String key) { + return isStackExpanded() && mBubbleData != null && mBubbleData.getSelectedBubble() != null + && mBubbleData.getSelectedBubble().getKey().equals(key); + } + + /** Promote the provided bubble from the overflow view. */ public void promoteBubbleFromOverflow(Bubble bubble) { mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_BACK_TO_STACK); bubble.setInflateSynchronously(mInflateSynchronously); @@ -1077,8 +640,8 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } @Override - public void expandStackAndSelectBubble(NotificationEntry entry) { - if (mStatusBarStateListener.getCurrentState() == SHADE) { + public void expandStackAndSelectBubble(BubbleEntry entry) { + if (mIsStatusBarShade) { mNotifEntryToExpandOnShadeUnlock = null; String key = entry.getKey(); @@ -1104,27 +667,13 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } } - @Override - public void onUserChangedImportance(NotificationEntry entry) { - try { - int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; - flags |= Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE; - mBarService.onNotificationBubbleChanged(entry.getKey(), true, flags); - } catch (RemoteException e) { - Log.e(TAG, e.getMessage()); - } - mShadeController.collapsePanel(true); - if (entry.getRow() != null) { - entry.getRow().updateBubbleButton(); - } - } - /** * Adds or updates a bubble associated with the provided notification entry. * * @param notif the notification associated with this bubble. */ - void updateBubble(NotificationEntry notif) { + @VisibleForTesting + public void updateBubble(BubbleEntry notif) { updateBubble(notif, false /* suppressFlyout */, true /* showInShade */); } @@ -1144,27 +693,32 @@ public class BubbleController implements Bubbles, ConfigurationController.Config return; } bubble.inflate((b) -> mBubbleData.overflowBubble(DISMISS_AGED, bubble), - mContext, mStackView, mBubbleIconFactory, true /* skipInflation */); + mContext, this, mStackView, mBubbleIconFactory, true /* skipInflation */); }); return null; }); } - void updateBubble(NotificationEntry notif, boolean suppressFlyout, boolean showInShade) { + /** + * Adds or updates a bubble associated with the provided notification entry. + * + * @param notif the notification associated with this bubble. + * @param suppressFlyout this bubble suppress flyout or not. + * @param showInShade this bubble show in shade or not. + */ + @VisibleForTesting + public void updateBubble(BubbleEntry notif, boolean suppressFlyout, boolean showInShade) { // If this is an interruptive notif, mark that it's interrupted - if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) { - notif.setInterruption(); - } + mSysuiProxy.setNotificationInterruption(notif.getKey()); if (!notif.getRanking().visuallyInterruptive() && (notif.getBubbleMetadata() != null && !notif.getBubbleMetadata().getAutoExpandBubble()) && mBubbleData.hasOverflowBubbleWithKey(notif.getKey())) { // Update the bubble but don't promote it out of overflow Bubble b = mBubbleData.getOverflowBubbleWithKey(notif.getKey()); - b.setEntry(notifToBubbleEntry(notif)); + b.setEntry(notif); } else { - Bubble bubble = mBubbleData.getOrCreateBubble( - notifToBubbleEntry(notif), null /* persistedBubble */); + Bubble bubble = mBubbleData.getOrCreateBubble(notif, null /* persistedBubble */); inflateAndAdd(bubble, suppressFlyout, showInShade); } } @@ -1174,68 +728,33 @@ public class BubbleController implements Bubbles, ConfigurationController.Config ensureStackViewCreated(); bubble.setInflateSynchronously(mInflateSynchronously); bubble.inflate(b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade), - mContext, mStackView, mBubbleIconFactory, false /* skipInflation */); - } - - @Override - public void onUserChangedBubble(@NonNull final NotificationEntry entry, boolean shouldBubble) { - NotificationChannel channel = entry.getChannel(); - final String appPkg = entry.getSbn().getPackageName(); - final int appUid = entry.getSbn().getUid(); - if (channel == null || appPkg == null) { - return; - } - - // Update the state in NotificationManagerService - try { - int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; - flags |= Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE; - mBarService.onNotificationBubbleChanged(entry.getKey(), shouldBubble, flags); - } catch (RemoteException e) { - } - - // Change the settings - channel = NotificationChannelHelper.createConversationChannelIfNeeded(mContext, - mINotificationManager, entry, channel); - channel.setAllowBubbles(shouldBubble); - try { - int currentPref = mINotificationManager.getBubblePreferenceForPackage(appPkg, appUid); - if (shouldBubble && currentPref == BUBBLE_PREFERENCE_NONE) { - mINotificationManager.setBubblesAllowed(appPkg, appUid, BUBBLE_PREFERENCE_SELECTED); - } - mINotificationManager.updateNotificationChannelForPackage(appPkg, appUid, channel); - } catch (RemoteException e) { - Log.e(TAG, e.getMessage()); - } - - if (shouldBubble) { - mShadeController.collapsePanel(true); - if (entry.getRow() != null) { - entry.getRow().updateBubbleButton(); - } - } + mContext, this, mStackView, mBubbleIconFactory, false /* skipInflation */); } + /** + * Removes the bubble with the given key. + * <p> + * Must be called from the main thread. + */ + @VisibleForTesting @MainThread - @Override public void removeBubble(String key, int reason) { if (mBubbleData.hasAnyBubbleWithKey(key)) { mBubbleData.dismissBubbleWithKey(key, reason); } } - private void onEntryAdded(NotificationEntry entry) { - if (mNotificationInterruptStateProvider.shouldBubbleUp(entry) - && entry.isBubble() - && canLaunchInActivityView(mContext, entry)) { + @Override + public void onEntryAdded(BubbleEntry entry) { + if (canLaunchInActivityView(mContext, entry)) { updateBubble(entry); } } - private void onEntryUpdated(NotificationEntry entry) { + @Override + public void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp) { // shouldBubbleUp checks canBubble & for bubble metadata - boolean shouldBubble = mNotificationInterruptStateProvider.shouldBubbleUp(entry) - && canLaunchInActivityView(mContext, entry); + boolean shouldBubble = shouldBubbleUp && canLaunchInActivityView(mContext, entry); if (!shouldBubble && mBubbleData.hasAnyBubbleWithKey(entry.getKey())) { // It was previously a bubble but no longer a bubble -- lets remove it removeBubble(entry.getKey(), DISMISS_NO_LONGER_BUBBLE); @@ -1244,9 +763,10 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } } - private void onEntryRemoved(NotificationEntry entry) { + @Override + public void onEntryRemoved(BubbleEntry entry) { if (isSummaryOfBubbles(entry)) { - final String groupKey = entry.getSbn().getGroupKey(); + final String groupKey = entry.getStatusBarNotification().getGroupKey(); mBubbleData.removeSuppressedSummary(groupKey); // Remove any associated bubble children with the summary @@ -1259,39 +779,30 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } } - /** - * Called when NotificationListener has received adjusted notification rank and reapplied - * filtering and sorting. This is used to dismiss or create bubbles based on changes in - * permissions on the notification channel or the global setting. - * - * @param rankingMap the updated ranking map from NotificationListenerService - */ - private void onRankingUpdated(RankingMap rankingMap) { + @Override + public void onRankingUpdated(RankingMap rankingMap) { if (mTmpRanking == null) { mTmpRanking = new NotificationListenerService.Ranking(); } String[] orderedKeys = rankingMap.getOrderedKeys(); for (int i = 0; i < orderedKeys.length; i++) { String key = orderedKeys[i]; - NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(key); + BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(key); rankingMap.getRanking(key, mTmpRanking); boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key); if (isActiveBubble && !mTmpRanking.canBubble()) { // If this entry is no longer allowed to bubble, dismiss with the BLOCKED reason. // This means that the app or channel's ability to bubble has been revoked. - mBubbleData.dismissBubbleWithKey( - key, BubbleController.DISMISS_BLOCKED); - } else if (isActiveBubble - && !mNotificationInterruptStateProvider.shouldBubbleUp(entry)) { + mBubbleData.dismissBubbleWithKey(key, DISMISS_BLOCKED); + } else if (isActiveBubble && !mSysuiProxy.shouldBubbleUp(key)) { // If this entry is allowed to bubble, but cannot currently bubble up, dismiss it. // This happens when DND is enabled and configured to hide bubbles. Dismissing with // the reason DISMISS_NO_BUBBLE_UP will retain the underlying notification, so that // the bubble will be re-created if shouldBubbleUp returns true. - mBubbleData.dismissBubbleWithKey( - key, BubbleController.DISMISS_NO_BUBBLE_UP); + mBubbleData.dismissBubbleWithKey(key, DISMISS_NO_BUBBLE_UP); } else if (entry != null && mTmpRanking.isBubble() && !isActiveBubble) { entry.setFlagBubble(true); - onEntryUpdated(entry); + onEntryUpdated(entry, true /* shouldBubbleUp */); } } } @@ -1306,23 +817,18 @@ public class BubbleController implements Bubbles, ConfigurationController.Config return bubbleChildren; } for (Bubble bubble : mBubbleData.getActiveBubbles()) { - final NotificationEntry entry = - mNotificationEntryManager.getPendingOrActiveNotif(bubble.getKey()); - if (entry != null && groupKey.equals(entry.getSbn().getGroupKey())) { + final BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(bubble.getKey()); + if (entry != null && groupKey.equals(entry.getStatusBarNotification().getGroupKey())) { bubbleChildren.add(bubble); } } return bubbleChildren; } - private void setIsBubble(@NonNull final NotificationEntry entry, final boolean isBubble, + private void setIsBubble(@NonNull final BubbleEntry entry, final boolean isBubble, final boolean autoExpand) { Objects.requireNonNull(entry); - if (isBubble) { - entry.getSbn().getNotification().flags |= FLAG_BUBBLE; - } else { - entry.getSbn().getNotification().flags &= ~FLAG_BUBBLE; - } + entry.setFlagBubble(isBubble); try { int flags = 0; if (autoExpand) { @@ -1338,8 +844,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config private void setIsBubble(@NonNull final Bubble b, final boolean isBubble) { Objects.requireNonNull(b); b.setIsBubble(isBubble); - final NotificationEntry entry = mNotificationEntryManager - .getPendingOrActiveNotif(b.getKey()); + final BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(b.getKey()); if (entry != null) { // Updating the entry to be a bubble will trigger our normal update flow setIsBubble(entry, isBubble, b.shouldAutoExpand()); @@ -1372,7 +877,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config // Collapsing? Do this first before remaining steps. if (update.expandedChanged && !update.expanded) { mStackView.setExpanded(false); - mNotificationShadeWindowController.setRequestTopUi(false, TAG); + mSysuiProxy.requestNotificationShadeTopUi(false, TAG); } // Do removals, if any. @@ -1396,8 +901,6 @@ public class BubbleController implements Bubbles, ConfigurationController.Config if (reason == DISMISS_NOTIF_CANCEL) { bubblesToBeRemovedFromRepository.add(bubble); } - final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( - bubble.getKey()); if (!mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) { if (!mBubbleData.hasOverflowBubbleWithKey(bubble.getKey()) && (!bubble.showInShade() @@ -1405,31 +908,21 @@ public class BubbleController implements Bubbles, ConfigurationController.Config || reason == DISMISS_GROUP_CANCELLED)) { // The bubble is now gone & the notification is hidden from the shade, so // time to actually remove it - for (NotifCallback cb : mCallbacks) { - if (entry != null) { - cb.removeNotification( - entry, - getDismissedByUserStats(entry, true), - REASON_CANCEL); - } - } + mSysuiProxy.notifyRemoveNotification(bubble.getKey(), REASON_CANCEL); } else { if (bubble.isBubble()) { setIsBubble(bubble, false /* isBubble */); } - if (entry != null && entry.getRow() != null) { - entry.getRow().updateBubbleButton(); - } + mSysuiProxy.updateNotificationBubbleButton(bubble.getKey()); } } + final BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(bubble.getKey()); if (entry != null) { - final String groupKey = entry.getSbn().getGroupKey(); + final String groupKey = entry.getStatusBarNotification().getGroupKey(); if (getBubblesInGroup(groupKey).isEmpty()) { // Time to potentially remove the summary - for (NotifCallback cb : mCallbacks) { - cb.maybeCancelSummary(entry); - } + mSysuiProxy.notifyMaybeCancelSummary(bubble.getKey()); } } } @@ -1454,11 +947,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config if (update.selectionChanged && mStackView != null) { mStackView.setSelectedBubble(update.selectedBubble); if (update.selectedBubble != null) { - final NotificationEntry entry = mNotificationEntryManager - .getPendingOrActiveNotif(update.selectedBubble.getKey()); - if (entry != null) { - mNotificationGroupManager.updateSuppression(entry); - } + mSysuiProxy.updateNotificationSuppression(update.selectedBubble.getKey()); } } @@ -1466,24 +955,20 @@ public class BubbleController implements Bubbles, ConfigurationController.Config if (update.expandedChanged && update.expanded) { if (mStackView != null) { mStackView.setExpanded(true); - mNotificationShadeWindowController.setRequestTopUi(true, TAG); + mSysuiProxy.requestNotificationShadeTopUi(true, TAG); } } - for (NotifCallback cb : mCallbacks) { - cb.invalidateNotifications("BubbleData.Listener.applyUpdate"); - } + mSysuiProxy.notifyInvalidateNotifications("BubbleData.Listener.applyUpdate"); updateStack(); } }; @Override - public boolean handleDismissalInterception(NotificationEntry entry) { - if (entry == null) { - return false; - } + public boolean handleDismissalInterception(BubbleEntry entry, + @Nullable List<BubbleEntry> children, IntConsumer removeCallback) { if (isSummaryOfBubbles(entry)) { - handleSummaryDismissalInterception(entry); + handleSummaryDismissalInterception(entry, children, removeCallback); } else { Bubble bubble = mBubbleData.getBubbleInStackWithKey(entry.getKey()); if (bubble == null || !entry.isBubble()) { @@ -1496,87 +981,50 @@ public class BubbleController implements Bubbles, ConfigurationController.Config bubble.setShowDot(false /* show */); } // Update the shade - for (NotifCallback cb : mCallbacks) { - cb.invalidateNotifications("BubbleController.handleDismissalInterception"); - } + mSysuiProxy.notifyInvalidateNotifications("BubbleController.handleDismissalInterception"); return true; } - private boolean isSummaryOfBubbles(NotificationEntry entry) { - if (entry == null) { - return false; - } - - String groupKey = entry.getSbn().getGroupKey(); + private boolean isSummaryOfBubbles(BubbleEntry entry) { + String groupKey = entry.getStatusBarNotification().getGroupKey(); ArrayList<Bubble> bubbleChildren = getBubblesInGroup(groupKey); boolean isSuppressedSummary = (mBubbleData.isSummarySuppressed(groupKey) && mBubbleData.getSummaryKey(groupKey).equals(entry.getKey())); - boolean isSummary = entry.getSbn().getNotification().isGroupSummary(); - return (isSuppressedSummary || isSummary) - && bubbleChildren != null - && !bubbleChildren.isEmpty(); + boolean isSummary = entry.getStatusBarNotification().getNotification().isGroupSummary(); + return (isSuppressedSummary || isSummary) && !bubbleChildren.isEmpty(); } - private void handleSummaryDismissalInterception(NotificationEntry summary) { - // current children in the row: - final List<NotificationEntry> children = summary.getAttachedNotifChildren(); + private void handleSummaryDismissalInterception( + BubbleEntry summary, @Nullable List<BubbleEntry> children, IntConsumer removeCallback) { if (children != null) { for (int i = 0; i < children.size(); i++) { - NotificationEntry child = children.get(i); + BubbleEntry child = children.get(i); if (mBubbleData.hasAnyBubbleWithKey(child.getKey())) { // Suppress the bubbled child // As far as group manager is concerned, once a child is no longer shown // in the shade, it is essentially removed. Bubble bubbleChild = mBubbleData.getAnyBubbleWithkey(child.getKey()); if (bubbleChild != null) { - final NotificationEntry entry = mNotificationEntryManager - .getPendingOrActiveNotif(bubbleChild.getKey()); - if (entry != null) { - mNotificationGroupManager.onEntryRemoved(entry); - } + mSysuiProxy.removeNotificationEntry(bubbleChild.getKey()); bubbleChild.setSuppressNotification(true); bubbleChild.setShowDot(false /* show */); } } else { // non-bubbled children can be removed - for (NotifCallback cb : mCallbacks) { - cb.removeNotification( - child, - getDismissedByUserStats(child, true), - REASON_GROUP_SUMMARY_CANCELED); - } + removeCallback.accept(i); } } } // And since all children are removed, remove the summary. - mNotificationGroupManager.onEntryRemoved(summary); + removeCallback.accept(-1); // TODO: (b/145659174) remove references to mSuppressedGroupKeys once fully migrated - mBubbleData.addSummaryToSuppress(summary.getSbn().getGroupKey(), + mBubbleData.addSummaryToSuppress(summary.getStatusBarNotification().getGroupKey(), summary.getKey()); } /** - * Gets the DismissedByUserStats used by {@link NotificationEntryManager}. - * Will not be necessary when using the new notification pipeline's {@link NotifCollection}. - * Instead, this is taken care of by {@link BubbleCoordinator}. - */ - private DismissedByUserStats getDismissedByUserStats( - NotificationEntry entry, - boolean isVisible) { - return new DismissedByUserStats( - DISMISSAL_BUBBLE, - DISMISS_SENTIMENT_NEUTRAL, - NotificationVisibility.obtain( - entry.getKey(), - entry.getRanking().getRank(), - mNotificationEntryManager.getActiveNotificationsCount(), - isVisible, - NotificationLogger.getNotificationLocation(entry))); - } - - /** * Updates the visibility of the bubbles based on current state. * Does not un-bubble, just hides or un-hides. * Updates stack description for TalkBack focus. @@ -1586,7 +1034,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config return; } - if (mStatusBarStateListener.getCurrentState() != SHADE) { + if (!mIsStatusBarShade) { // Bubbles don't appear over the locked shade. mStackView.setVisibility(INVISIBLE); } else if (hasBubbles()) { @@ -1610,20 +1058,21 @@ public class BubbleController implements Bubbles, ConfigurationController.Config final BubbleViewProvider expandedViewProvider = mStackView.getExpandedBubble(); if (expandedViewProvider != null && isStackExpanded() && !mStackView.isExpansionAnimating() - && !mNotificationShadeWindowController.getPanelExpanded()) { + && !mSysuiProxy.isNotificationShadeExpand()) { return expandedViewProvider.getTaskId(); } return INVALID_TASK_ID; } @VisibleForTesting - BubbleStackView getStackView() { + public BubbleStackView getStackView() { return mStackView; } /** * Description of current bubble state. */ + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("BubbleController state:"); mBubbleData.dump(fd, pw, args); @@ -1635,39 +1084,6 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } /** - * This task stack listener is responsible for responding to tasks moved to the front - * which are on the default (main) display. When this happens, expanded bubbles must be - * collapsed so the user may interact with the app which was just moved to the front. - * <p> - * This listener is registered with SystemUI's ActivityManagerWrapper which dispatches - * these calls via a main thread Handler. - */ - @MainThread - private class BubbleTaskStackListener extends TaskStackChangeListener { - - @Override - public void onTaskMovedToFront(RunningTaskInfo taskInfo) { - int expandedId = getExpandedTaskId(); - if (expandedId != INVALID_TASK_ID && expandedId != taskInfo.taskId) { - mBubbleData.setExpanded(false); - } - } - - @Override - public void onActivityRestartAttempt(RunningTaskInfo taskInfo, boolean homeTaskVisible, - boolean clearedTask, boolean wasVisible) { - for (Bubble b : mBubbleData.getBubbles()) { - if (taskInfo.taskId == b.getTaskId()) { - mBubbleData.setSelectedBubble(b); - mBubbleData.setExpanded(true); - return; - } - } - } - - } - - /** * Whether an intent is properly configured to display in an {@link android.app.ActivityView}. * * Keep checks in sync with NotificationManagerService#canLaunchInActivityView. Typically @@ -1676,7 +1092,7 @@ public class BubbleController implements Bubbles, ConfigurationController.Config * @param context the context to use. * @param entry the entry to bubble. */ - static boolean canLaunchInActivityView(Context context, NotificationEntry entry) { + static boolean canLaunchInActivityView(Context context, BubbleEntry entry) { PendingIntent intent = entry.getBubbleMetadata() != null ? entry.getBubbleMetadata().getIntent() : null; @@ -1688,8 +1104,8 @@ public class BubbleController implements Bubbles, ConfigurationController.Config Log.w(TAG, "Unable to create bubble -- no intent: " + entry.getKey()); return false; } - PackageManager packageManager = StatusBar.getPackageManagerForUser( - context, entry.getSbn().getUser().getIdentifier()); + PackageManager packageManager = getPackageManagerForUser( + context, entry.getStatusBarNotification().getUser().getIdentifier()); ActivityInfo info = intent.getIntent().resolveActivityInfo(packageManager, 0); if (info == null) { @@ -1707,6 +1123,24 @@ public class BubbleController implements Bubbles, ConfigurationController.Config return true; } + static PackageManager getPackageManagerForUser(Context context, int userId) { + Context contextForUser = context; + // UserHandle defines special userId as negative values, e.g. USER_ALL + if (userId >= 0) { + try { + // Create a context for the correct user so if a package isn't installed + // for user 0 we can still load information about the package. + contextForUser = + context.createPackageContextAsUser(context.getPackageName(), + Context.CONTEXT_RESTRICTED, + new UserHandle(userId)); + } catch (PackageManager.NameNotFoundException e) { + // Shouldn't fail to find the package name for system ui. + } + } + return contextForUser.getPackageManager(); + } + /** PinnedStackListener that dispatches IME visibility updates to the stack. */ //TODO(b/170442945): Better way to do this / insets listener? private class BubblesImeListener extends PinnedStackListenerForwarder.PinnedStackListener { @@ -1717,10 +1151,4 @@ public class BubbleController implements Bubbles, ConfigurationController.Config } } } - - static BubbleEntry notifToBubbleEntry(NotificationEntry e) { - return new BubbleEntry(e.getSbn(), e.getRanking(), e.isClearable(), - e.shouldSuppressNotificationDot(), e.shouldSuppressNotificationList(), - e.shouldSuppressPeek()); - } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java index b4626f27d370..8cacc8f2ef01 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java @@ -34,7 +34,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FrameworkStatsLog; import com.android.systemui.R; -import com.android.systemui.bubbles.BubbleController.DismissReason; +import com.android.systemui.bubbles.Bubbles.DismissReason; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -137,8 +137,8 @@ public class BubbleData { private Listener mListener; @Nullable - private BubbleController.NotificationSuppressionChangedListener mSuppressionListener; - private BubbleController.PendingIntentCanceledListener mCancelledListener; + private Bubbles.NotificationSuppressionChangedListener mSuppressionListener; + private Bubbles.PendingIntentCanceledListener mCancelledListener; /** * We track groups with summaries that aren't visibly displayed but still kept around because @@ -165,12 +165,12 @@ public class BubbleData { } public void setSuppressionChangedListener( - BubbleController.NotificationSuppressionChangedListener listener) { + Bubbles.NotificationSuppressionChangedListener listener) { mSuppressionListener = listener; } public void setPendingIntentCancelledListener( - BubbleController.PendingIntentCanceledListener listener) { + Bubbles.PendingIntentCanceledListener listener) { mCancelledListener = listener; } @@ -344,7 +344,8 @@ public class BubbleData { /** * Whether the summary for the provided group key is suppressed. */ - boolean isSummarySuppressed(String groupKey) { + @VisibleForTesting + public boolean isSummarySuppressed(String groupKey) { return mSuppressedGroupKeys.containsKey(groupKey); } @@ -415,7 +416,7 @@ public class BubbleData { // skip the selected bubble .filter((b) -> !b.equals(mSelectedBubble)) .findFirst() - .ifPresent((b) -> doRemove(b.getKey(), BubbleController.DISMISS_AGED)); + .ifPresent((b) -> doRemove(b.getKey(), Bubbles.DISMISS_AGED)); } } @@ -459,12 +460,12 @@ public class BubbleData { int indexToRemove = indexForKey(key); if (indexToRemove == -1) { if (hasOverflowBubbleWithKey(key) - && (reason == BubbleController.DISMISS_NOTIF_CANCEL - || reason == BubbleController.DISMISS_GROUP_CANCELLED - || reason == BubbleController.DISMISS_NO_LONGER_BUBBLE - || reason == BubbleController.DISMISS_BLOCKED - || reason == BubbleController.DISMISS_SHORTCUT_REMOVED - || reason == BubbleController.DISMISS_PACKAGE_REMOVED)) { + && (reason == Bubbles.DISMISS_NOTIF_CANCEL + || reason == Bubbles.DISMISS_GROUP_CANCELLED + || reason == Bubbles.DISMISS_NO_LONGER_BUBBLE + || reason == Bubbles.DISMISS_BLOCKED + || reason == Bubbles.DISMISS_SHORTCUT_REMOVED + || reason == Bubbles.DISMISS_PACKAGE_REMOVED)) { Bubble b = getOverflowBubbleWithKey(key); if (DEBUG_BUBBLE_DATA) { @@ -512,8 +513,8 @@ public class BubbleData { void overflowBubble(@DismissReason int reason, Bubble bubble) { if (bubble.getPendingIntentCanceled() - || !(reason == BubbleController.DISMISS_AGED - || reason == BubbleController.DISMISS_USER_GESTURE)) { + || !(reason == Bubbles.DISMISS_AGED + || reason == Bubbles.DISMISS_USER_GESTURE)) { return; } if (DEBUG_BUBBLE_DATA) { @@ -529,7 +530,7 @@ public class BubbleData { if (DEBUG_BUBBLE_DATA) { Log.d(TAG, "Overflow full. Remove: " + oldest); } - mStateChange.bubbleRemoved(oldest, BubbleController.DISMISS_OVERFLOW_MAX_REACHED); + mStateChange.bubbleRemoved(oldest, Bubbles.DISMISS_OVERFLOW_MAX_REACHED); mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED); mOverflowBubbles.remove(oldest); mStateChange.removedOverflowBubble = oldest; @@ -694,7 +695,7 @@ public class BubbleData { } private void maybeSendDeleteIntent(@DismissReason int reason, @NonNull final Bubble bubble) { - if (reason != BubbleController.DISMISS_USER_GESTURE) return; + if (reason != Bubbles.DISMISS_USER_GESTURE) return; PendingIntent deleteIntent = bubble.getDeleteIntent(); if (deleteIntent == null) return; try { @@ -726,7 +727,7 @@ public class BubbleData { * The set of bubbles in overflow. */ @VisibleForTesting(visibility = PRIVATE) - List<Bubble> getOverflowBubbles() { + public List<Bubble> getOverflowBubbles() { return Collections.unmodifiableList(mOverflowBubbles); } @@ -742,7 +743,7 @@ public class BubbleData { @VisibleForTesting(visibility = PRIVATE) @Nullable - Bubble getBubbleInStackWithKey(String key) { + public Bubble getBubbleInStackWithKey(String key) { for (int i = 0; i < mBubbles.size(); i++) { Bubble bubble = mBubbles.get(i); if (bubble.getKey().equals(key)) { @@ -764,7 +765,7 @@ public class BubbleData { } @VisibleForTesting(visibility = PRIVATE) - Bubble getOverflowBubbleWithKey(String key) { + public Bubble getOverflowBubbleWithKey(String key) { for (int i = 0; i < mOverflowBubbles.size(); i++) { Bubble bubble = mOverflowBubbles.get(i); if (bubble.getKey().equals(key)) { @@ -788,7 +789,7 @@ public class BubbleData { * This method should only be used in tests, not in production. */ @VisibleForTesting - void setMaxOverflowBubbles(int maxOverflowBubbles) { + public void setMaxOverflowBubbles(int maxOverflowBubbles) { mMaxOverflowBubbles = maxOverflowBubbles; } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java index d98fee399470..3937422750cc 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java @@ -33,10 +33,10 @@ public class BubbleDebugConfig { // to figure-out the origin of a log message while debugging the Bubbles a little painful. By // setting this constant to true, log messages from the Bubbles package will be tagged with // their class names instead fot the generic tag. - static final boolean TAG_WITH_CLASS_NAME = false; + public static final boolean TAG_WITH_CLASS_NAME = false; // Default log tag for the Bubbles package. - static final String TAG_BUBBLES = "Bubbles"; + public static final String TAG_BUBBLES = "Bubbles"; static final boolean DEBUG_BUBBLE_CONTROLLER = false; static final boolean DEBUG_BUBBLE_DATA = false; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleEntry.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleEntry.java index 6a1302518699..a0d3391f8347 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleEntry.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleEntry.java @@ -16,6 +16,9 @@ package com.android.systemui.bubbles; +import static android.app.Notification.FLAG_BUBBLE; + +import android.app.Notification; import android.app.Notification.BubbleMetadata; import android.app.NotificationManager.Policy; import android.service.notification.NotificationListenerService.Ranking; @@ -67,12 +70,45 @@ public class BubbleEntry { return mSbn.getKey(); } + /** @return the group key in the {@link StatusBarNotification}. */ + public String getGroupKey() { + return mSbn.getGroupKey(); + } + /** @return the {@link BubbleMetadata} in the {@link StatusBarNotification}. */ @Nullable public BubbleMetadata getBubbleMetadata() { return getStatusBarNotification().getNotification().getBubbleMetadata(); } + /** + * Updates the {@link Notification#FLAG_BUBBLE} flag on this notification to indicate + * whether it is a bubble or not. If this entry is set to not bubble, or does not have + * the required info to bubble, the flag cannot be set to true. + * + * @param shouldBubble whether this notification should be flagged as a bubble. + * @return true if the value changed. + */ + public boolean setFlagBubble(boolean shouldBubble) { + boolean wasBubble = isBubble(); + if (!shouldBubble) { + mSbn.getNotification().flags &= ~FLAG_BUBBLE; + } else if (getBubbleMetadata() != null && canBubble()) { + // wants to be bubble & can bubble, set flag + mSbn.getNotification().flags |= FLAG_BUBBLE; + } + return wasBubble != isBubble(); + } + + public boolean isBubble() { + return (mSbn.getNotification().flags & FLAG_BUBBLE) != 0; + } + + /** @see Ranking#canBubble() */ + public boolean canBubble() { + return mRanking.canBubble(); + } + /** @return true if this notification is clearable. */ public boolean isClearable() { return mIsClearable; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index bc060209132b..ae3c683cb165 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -54,7 +54,6 @@ import android.widget.LinearLayout; import androidx.annotation.Nullable; import com.android.internal.policy.ScreenDecorationsUtils; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.recents.TriangleShape; import com.android.systemui.statusbar.AlphaOptimizedButton; @@ -99,7 +98,7 @@ public class BubbleExpandedView extends LinearLayout { // TODO(b/170891664): Don't use a flag, set the BubbleOverflow object instead private boolean mIsOverflow; - private Bubbles mBubbles = Dependency.get(Bubbles.class); + private BubbleController mController; private BubbleStackView mStackView; private BubblePositioner mPositioner; @@ -156,8 +155,7 @@ public class BubbleExpandedView extends LinearLayout { // the bubble again so we'll just remove it. Log.w(TAG, "Exception while displaying bubble: " + getBubbleKey() + ", " + e.getMessage() + "; removing bubble"); - mBubbles.removeBubble(getBubbleKey(), - BubbleController.DISMISS_INVALID_INTENT); + mController.removeBubble(getBubbleKey(), Bubbles.DISMISS_INVALID_INTENT); } }); mInitialized = true; @@ -195,15 +193,15 @@ public class BubbleExpandedView extends LinearLayout { } if (mBubble != null) { // Must post because this is called from a binder thread. - post(() -> mBubbles.removeBubble(mBubble.getKey(), - BubbleController.DISMISS_TASK_FINISHED)); + post(() -> mController.removeBubble( + mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED)); } } @Override public void onBackPressedOnTaskRoot(int taskId) { if (mTaskId == taskId && mStackView.isExpanded()) { - mBubbles.collapseStack(); + mController.collapseStack(); } } }; @@ -250,10 +248,6 @@ public class BubbleExpandedView extends LinearLayout { R.dimen.bubble_manage_button_height); mSettingsIcon = findViewById(R.id.settings_button); - mPositioner = mBubbles.getPositioner(); - - mTaskView = new TaskView(mContext, mBubbles.getTaskOrganizer(), - new HandlerExecutor(getHandler())); // Set ActivityView's alpha value as zero, since there is no view content to be shown. setContentVisibility(false); @@ -264,7 +258,6 @@ public class BubbleExpandedView extends LinearLayout { } }); mExpandedViewContainer.setClipToOutline(true); - mExpandedViewContainer.addView(mTaskView); mExpandedViewContainer.setLayoutParams( new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); addView(mExpandedViewContainer); @@ -275,9 +268,7 @@ public class BubbleExpandedView extends LinearLayout { // ==> expanded view // ==> activity view // ==> manage button - bringChildToFront(mTaskView); bringChildToFront(mSettingsIcon); - mTaskView.setListener(mTaskViewListener); applyThemeAttrs(); @@ -310,6 +301,26 @@ public class BubbleExpandedView extends LinearLayout { setLayoutDirection(LAYOUT_DIRECTION_LOCALE); } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mTaskView.setExecutor(new HandlerExecutor(getHandler())); + } + /** + * Initialize {@link BubbleController} and {@link BubbleStackView} here, this method must need + * to be called after view inflate. + */ + void initialize(BubbleController controller, BubbleStackView stackView) { + mController = controller; + mStackView = stackView; + + mTaskView = new TaskView(mContext, mController.getTaskOrganizer()); + mExpandedViewContainer.addView(mTaskView); + bringChildToFront(mTaskView); + mTaskView.setListener(mTaskViewListener); + mPositioner = mController.getPositioner(); + } + void updateDimensions() { Resources res = getResources(); mMinHeight = res.getDimensionPixelSize(R.dimen.bubble_expanded_default_height); @@ -459,16 +470,12 @@ public class BubbleExpandedView extends LinearLayout { return mTaskId; } - void setStackView(BubbleStackView stackView) { - mStackView = stackView; - } - public void setOverflow(boolean overflow) { mIsOverflow = overflow; Intent target = new Intent(mContext, BubbleOverflowActivity.class); Bundle extras = new Bundle(); - extras.putBinder(EXTRA_BUBBLE_CONTROLLER, ObjectWrapper.wrap(mBubbles)); + extras.putBinder(EXTRA_BUBBLE_CONTROLLER, ObjectWrapper.wrap(mController)); target.putExtras(extras); mPendingIntent = PendingIntent.getActivity(mContext, 0 /* requestCode */, target, PendingIntent.FLAG_UPDATE_CURRENT); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLogger.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLogger.java index 48c809d1b0a7..a24f5c2b54c5 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLogger.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleLogger.java @@ -91,14 +91,14 @@ public class BubbleLogger { * @param b Bubble removed from overflow * @param r Reason that bubble was removed */ - public void logOverflowRemove(Bubble b, @BubbleController.DismissReason int r) { - if (r == BubbleController.DISMISS_NOTIF_CANCEL) { + public void logOverflowRemove(Bubble b, @Bubbles.DismissReason int r) { + if (r == Bubbles.DISMISS_NOTIF_CANCEL) { log(b, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_CANCEL); - } else if (r == BubbleController.DISMISS_GROUP_CANCELLED) { + } else if (r == Bubbles.DISMISS_GROUP_CANCELLED) { log(b, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_GROUP_CANCEL); - } else if (r == BubbleController.DISMISS_NO_LONGER_BUBBLE) { + } else if (r == Bubbles.DISMISS_NO_LONGER_BUBBLE) { log(b, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_NO_LONGER_BUBBLE); - } else if (r == BubbleController.DISMISS_BLOCKED) { + } else if (r == Bubbles.DISMISS_BLOCKED) { log(b, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_BLOCKED); } } @@ -107,10 +107,10 @@ public class BubbleLogger { * @param b Bubble added to overflow * @param r Reason that bubble was added to overflow */ - public void logOverflowAdd(Bubble b, @BubbleController.DismissReason int r) { - if (r == BubbleController.DISMISS_AGED) { + public void logOverflowAdd(Bubble b, @Bubbles.DismissReason int r) { + if (r == Bubbles.DISMISS_AGED) { log(b, Event.BUBBLE_OVERFLOW_ADD_AGED); - } else if (r == BubbleController.DISMISS_USER_GESTURE) { + } else if (r == Bubbles.DISMISS_USER_GESTURE) { log(b, Event.BUBBLE_OVERFLOW_ADD_USER_GESTURE); } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt index 102055de2bea..297144a86143 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.kt @@ -35,6 +35,7 @@ import com.android.systemui.R class BubbleOverflow( private val context: Context, + private val controller: BubbleController, private val stack: BubbleStackView ) : BubbleViewProvider { @@ -56,8 +57,8 @@ class BubbleOverflow( init { updateResources() with(expandedView) { + initialize(controller, stack) setOverflow(true) - setStackView(stack) applyThemeAttrs() } with(overflowBtn) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java index fc3f5b6cbf5e..bc841730833c 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java @@ -63,7 +63,7 @@ public class BubbleOverflowActivity extends Activity { private TextView mEmptyStateTitle; private TextView mEmptyStateSubtitle; private ImageView mEmptyStateImage; - private Bubbles mBubbles; + private BubbleController mController; private BubbleOverflowAdapter mAdapter; private RecyclerView mRecyclerView; private List<Bubble> mOverflowBubbles = new ArrayList<>(); @@ -111,7 +111,7 @@ public class BubbleOverflowActivity extends Activity { if (intent != null && intent.getExtras() != null) { IBinder binder = intent.getExtras().getBinder(EXTRA_BUBBLE_CONTROLLER); if (binder instanceof ObjectWrapper) { - mBubbles = ((ObjectWrapper<Bubbles>) binder).get(); + mController = ((ObjectWrapper<BubbleController>) binder).get(); } } else { Log.w(TAG, "Bubble overflow activity created without bubble controller!"); @@ -139,15 +139,15 @@ public class BubbleOverflowActivity extends Activity { final int viewHeight = recyclerViewHeight / rows; mAdapter = new BubbleOverflowAdapter(getApplicationContext(), mOverflowBubbles, - mBubbles::promoteBubbleFromOverflow, viewWidth, viewHeight); + mController::promoteBubbleFromOverflow, viewWidth, viewHeight); mRecyclerView.setAdapter(mAdapter); mOverflowBubbles.clear(); - mOverflowBubbles.addAll(mBubbles.getOverflowBubbles()); + mOverflowBubbles.addAll(mController.getOverflowBubbles()); mAdapter.notifyDataSetChanged(); updateEmptyStateVisibility(); - mBubbles.setOverflowListener(mDataListener); + mController.setOverflowListener(mDataListener); updateTheme(); } @@ -217,7 +217,7 @@ public class BubbleOverflowActivity extends Activity { if (DEBUG_OVERFLOW) { Log.d(TAG, BubbleDebugConfig.formatBubblesString( - mBubbles.getOverflowBubbles(), null)); + mController.getOverflowBubbles(), null)); } } }; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 0714c5eb4fa4..e89b2526456a 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -90,6 +90,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Consumer; +import java.util.stream.Collectors; /** * Renders bubbles in a stack and handles animating expanded and collapsed states. @@ -154,7 +155,7 @@ public class BubbleStackView extends FrameLayout * * {@hide} */ - interface SurfaceSynchronizer { + public interface SurfaceSynchronizer { /** * Wait until requested change on a {@link View} is reflected on the screen. * @@ -185,7 +186,7 @@ public class BubbleStackView extends FrameLayout }); } }; - + private final BubbleController mBubbleController; private final BubbleData mBubbleData; private final ValueAnimator mDesaturateAndDarkenAnimator; @@ -383,22 +384,6 @@ public class BubbleStackView extends FrameLayout private final SurfaceSynchronizer mSurfaceSynchronizer; /** - * Callback to run when the IME visibility changes - BubbleController uses this to update the - * Bubbles window focusability flags with the WindowManager. - */ - public final Consumer<Boolean> mOnImeVisibilityChanged; - - /** - * Callback to run when the bubble expand status changes. - */ - private final Consumer<Boolean> mOnBubbleExpandChanged; - - /** - * Callback to run to ask BubbleController to hide the current IME. - */ - private final Runnable mHideCurrentInputMethodCallback; - - /** * The currently magnetized object, which is being dragged and will be attracted to the magnetic * dismiss target. * @@ -732,16 +717,12 @@ public class BubbleStackView extends FrameLayout private BubblePositioner mPositioner; @SuppressLint("ClickableViewAccessibility") - public BubbleStackView(Context context, BubbleData data, - @Nullable SurfaceSynchronizer synchronizer, - FloatingContentCoordinator floatingContentCoordinator, - Runnable allBubblesAnimatedOutAction, - Consumer<Boolean> onImeVisibilityChanged, - Runnable hideCurrentInputMethodCallback, - Consumer<Boolean> onBubbleExpandChanged, - BubblePositioner positioner) { + public BubbleStackView(Context context, BubbleController bubbleController, + BubbleData data, @Nullable SurfaceSynchronizer synchronizer, + FloatingContentCoordinator floatingContentCoordinator) { super(context); + mBubbleController = bubbleController; mBubbleData = data; Resources res = getResources(); @@ -754,7 +735,7 @@ public class BubbleStackView extends FrameLayout mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset); - mPositioner = positioner; + mPositioner = mBubbleController.getPositioner(); mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding); int elevation = res.getDimensionPixelSize(R.dimen.bubble_elevation); @@ -766,7 +747,7 @@ public class BubbleStackView extends FrameLayout final Runnable onBubbleAnimatedOut = () -> { if (getBubbleCount() == 0) { - allBubblesAnimatedOutAction.run(); + mBubbleController.onAllBubblesAnimatedOut(); } }; @@ -838,7 +819,7 @@ public class BubbleStackView extends FrameLayout setFocusable(true); mBubbleContainer.bringToFront(); - mBubbleOverflow = new BubbleOverflow(getContext(), this); + mBubbleOverflow = new BubbleOverflow(getContext(), bubbleController, this); mBubbleContainer.addView(mBubbleOverflow.getIconView(), mBubbleContainer.getChildCount() /* index */, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, @@ -849,12 +830,9 @@ public class BubbleStackView extends FrameLayout showManageMenu(false); }); - mOnImeVisibilityChanged = onImeVisibilityChanged; - mHideCurrentInputMethodCallback = hideCurrentInputMethodCallback; - mOnBubbleExpandChanged = onBubbleExpandChanged; - setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> { - onImeVisibilityChanged.accept(insets.getInsets(WindowInsets.Type.ime()).bottom > 0); + mBubbleController.onImeVisibilityChanged( + insets.getInsets(WindowInsets.Type.ime()).bottom > 0); if (!mIsExpanded || mIsExpansionAnimating) { return view.onApplyWindowInsets(insets); } @@ -1298,7 +1276,7 @@ public class BubbleStackView extends FrameLayout // R constants are not final so we cannot use switch-case here. if (action == AccessibilityNodeInfo.ACTION_DISMISS) { - mBubbleData.dismissAll(BubbleController.DISMISS_ACCESSIBILITY_ACTION); + mBubbleData.dismissAll(Bubbles.DISMISS_ACCESSIBILITY_ACTION); announceForAccessibility( getResources().getString(R.string.accessibility_bubble_dismissed)); return true; @@ -1401,8 +1379,9 @@ public class BubbleStackView extends FrameLayout /** * The {@link Bubble} that is expanded, null if one does not exist. */ + @VisibleForTesting @Nullable - BubbleViewProvider getExpandedBubble() { + public BubbleViewProvider getExpandedBubble() { return mExpandedBubble; } @@ -1479,12 +1458,24 @@ public class BubbleStackView extends FrameLayout logBubbleEvent(bubble, FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__UPDATED); } + /** + * Update bubble order and pointer position. + */ public void updateBubbleOrder(List<Bubble> bubbles) { - for (int i = 0; i < bubbles.size(); i++) { - Bubble bubble = bubbles.get(i); - mBubbleContainer.reorderView(bubble.getIconView(), i); + final Runnable reorder = () -> { + for (int i = 0; i < bubbles.size(); i++) { + Bubble bubble = bubbles.get(i); + mBubbleContainer.reorderView(bubble.getIconView(), i); + } + }; + if (mIsExpanded) { + reorder.run(); + updateBubbleIcons(); + } else { + List<View> bubbleViews = bubbles.stream() + .map(b -> b.getIconView()).collect(Collectors.toList()); + mStackAnimationController.animateReorder(bubbleViews, reorder); } - updateBubbleIcons(); updatePointerPosition(); } @@ -1604,7 +1595,7 @@ public class BubbleStackView extends FrameLayout hideCurrentInputMethod(); - mOnBubbleExpandChanged.accept(shouldExpand); + mBubbleController.getSysuiProxy().onStackExpandChanged(shouldExpand); if (mIsExpanded) { animateCollapse(); @@ -1624,7 +1615,7 @@ public class BubbleStackView extends FrameLayout * not. */ void hideCurrentInputMethod() { - mHideCurrentInputMethodCallback.run(); + mBubbleController.hideCurrentInputMethod(); } private void beforeExpandedViewAnimation() { @@ -2122,14 +2113,13 @@ public class BubbleStackView extends FrameLayout final View draggedOutBubbleView = (View) mMagnetizedObject.getUnderlyingObject(); dismissBubbleIfExists(mBubbleData.getBubbleWithView(draggedOutBubbleView)); } else { - mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); } } private void dismissBubbleIfExists(@Nullable Bubble bubble) { if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) { - mBubbleData.dismissBubbleWithKey( - bubble.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(bubble.getKey(), Bubbles.DISMISS_USER_GESTURE); } } @@ -2595,17 +2585,11 @@ public class BubbleStackView extends FrameLayout bv.setZ((mMaxBubbles * mBubbleElevation) - i); if (mIsExpanded) { - bv.removeDotSuppressionFlag( - BadgedImageView.SuppressionFlag.BEHIND_STACK); - bv.animateDotBadgePositions(false /* onLeft */); + bv.showDotAndBadge(false /* onLeft */); } else if (i == 0) { - bv.removeDotSuppressionFlag( - BadgedImageView.SuppressionFlag.BEHIND_STACK); - bv.animateDotBadgePositions(!mStackOnLeftOrWillBe); + bv.showDotAndBadge(!mStackOnLeftOrWillBe); } else { - bv.addDotSuppressionFlag( - BadgedImageView.SuppressionFlag.BEHIND_STACK); - bv.hideBadge(); + bv.hideDotAndBadge(!mStackOnLeftOrWillBe); } } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java index 010a29e3560a..a3e6a1ecc387 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java @@ -66,6 +66,7 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask private Bubble mBubble; private WeakReference<Context> mContext; + private WeakReference<BubbleController> mController; private WeakReference<BubbleStackView> mStackView; private BubbleIconFactory mIconFactory; private boolean mSkipInflation; @@ -77,12 +78,14 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask */ BubbleViewInfoTask(Bubble b, Context context, + BubbleController controller, BubbleStackView stackView, BubbleIconFactory factory, boolean skipInflation, Callback c) { mBubble = b; mContext = new WeakReference<>(context); + mController = new WeakReference<>(controller); mStackView = new WeakReference<>(stackView); mIconFactory = factory; mSkipInflation = skipInflation; @@ -91,8 +94,8 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask @Override protected BubbleViewInfo doInBackground(Void... voids) { - return BubbleViewInfo.populate(mContext.get(), mStackView.get(), mIconFactory, mBubble, - mSkipInflation); + return BubbleViewInfo.populate(mContext.get(), mController.get(), mStackView.get(), + mIconFactory, mBubble, mSkipInflation); } @Override @@ -121,8 +124,9 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask Bubble.FlyoutMessage flyoutMessage; @Nullable - static BubbleViewInfo populate(Context c, BubbleStackView stackView, - BubbleIconFactory iconFactory, Bubble b, boolean skipInflation) { + static BubbleViewInfo populate(Context c, BubbleController controller, + BubbleStackView stackView, BubbleIconFactory iconFactory, Bubble b, + boolean skipInflation) { BubbleViewInfo info = new BubbleViewInfo(); // View inflation: only should do this once per bubble @@ -133,7 +137,7 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask info.expandedView = (BubbleExpandedView) inflater.inflate( R.layout.bubble_expanded_view, stackView, false /* attachToRoot */); - info.expandedView.setStackView(stackView); + info.expandedView.initialize(controller, stackView); } if (b.getShortcutInfo() != null) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java index 5cc24ce5a775..589017242311 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java @@ -26,7 +26,7 @@ import androidx.annotation.Nullable; /** * Interface to represent actual Bubbles and UI elements that act like bubbles, like BubbleOverflow. */ -interface BubbleViewProvider { +public interface BubbleViewProvider { @Nullable BubbleExpandedView getExpandedView(); void setContentVisibility(boolean visible); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubbles.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubbles.java index 4882abc51ed6..415edb1b647c 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubbles.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubbles.java @@ -16,62 +16,93 @@ package com.android.systemui.bubbles; -import android.annotation.NonNull; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.LOCAL_VARIABLE; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.SOURCE; -import androidx.annotation.MainThread; +import android.content.res.Configuration; +import android.service.notification.NotificationListenerService.RankingMap; +import android.util.ArraySet; +import android.view.View; -import com.android.systemui.statusbar.ScrimView; -import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.phone.ScrimController; -import com.android.wm.shell.ShellTaskOrganizer; +import androidx.annotation.IntDef; +import androidx.annotation.Nullable; +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; import java.util.List; +import java.util.function.IntConsumer; /** * Interface to engage bubbles feature. */ public interface Bubbles { + @Retention(SOURCE) + @IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED, + DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE, + DISMISS_USER_CHANGED, DISMISS_GROUP_CANCELLED, DISMISS_INVALID_INTENT, + DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED, + DISMISS_NO_BUBBLE_UP}) + @Target({FIELD, LOCAL_VARIABLE, PARAMETER}) + @interface DismissReason {} + + int DISMISS_USER_GESTURE = 1; + int DISMISS_AGED = 2; + int DISMISS_TASK_FINISHED = 3; + int DISMISS_BLOCKED = 4; + int DISMISS_NOTIF_CANCEL = 5; + int DISMISS_ACCESSIBILITY_ACTION = 6; + int DISMISS_NO_LONGER_BUBBLE = 7; + int DISMISS_USER_CHANGED = 8; + int DISMISS_GROUP_CANCELLED = 9; + int DISMISS_INVALID_INTENT = 10; + int DISMISS_OVERFLOW_MAX_REACHED = 11; + int DISMISS_SHORTCUT_REMOVED = 12; + int DISMISS_PACKAGE_REMOVED = 13; + int DISMISS_NO_BUBBLE_UP = 14; + /** * @return {@code true} if there is a bubble associated with the provided key and if its * notification is hidden from the shade or there is a group summary associated with the * provided key that is hidden from the shade because it has been dismissed but still has child * bubbles active. */ - boolean isBubbleNotificationSuppressedFromShade(NotificationEntry entry); + boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey); /** * @return {@code true} if the current notification entry same as selected bubble * notification entry and the stack is currently expanded. */ - boolean isBubbleExpanded(NotificationEntry entry); + boolean isBubbleExpanded(String key); /** @return {@code true} if stack of bubbles is expanded or not. */ boolean isStackExpanded(); + /** @return {@code true} if the summary for the provided group key is suppressed. */ + boolean isSummarySuppressed(String groupKey); + /** - * @return the {@link ScrimView} drawn behind the bubble stack. This is managed by - * {@link ScrimController} since we want the scrim's appearance and behavior to be identical to - * that of the notification shade scrim. + * Removes a group key indicating that summary for this group should no longer be suppressed. */ - ScrimView getScrimForBubble(); - - /** @return Bubbles for updating overflow. */ - List<Bubble> getOverflowBubbles(); + void removeSuppressedSummary(String groupKey); /** Tell the stack of bubbles to collapse. */ void collapseStack(); + /** Tell the controller need update its UI to fit theme. */ + void updateForThemeChanges(); + /** * Request the stack expand if needed, then select the specified Bubble as current. * If no bubble exists for this entry, one is created. * * @param entry the notification for the bubble to be selected */ - void expandStackAndSelectBubble(NotificationEntry entry); - - /** Promote the provided bubbles when overflow view. */ - void promoteBubbleFromOverflow(Bubble bubble); + void expandStackAndSelectBubble(BubbleEntry entry); /** * We intercept notification entries (including group summaries) dismissed by the user when @@ -81,26 +112,65 @@ public interface Bubbles { * {@link Bubble#setSuppressNotification}. For the case of suppressed summaries, we also add * {@link BubbleData#addSummaryToSuppress}. * + * @param entry the notification of the BubbleEntry should be removed. + * @param children the list of child notification of the BubbleEntry from 1st param entry, + * this will be null if entry does have no children. + * @param removeCallback the remove callback for SystemUI side to remove notification, the int + * number should be list position of children list and use -1 for + * removing the parent notification. + * * @return true if we want to intercept the dismissal of the entry, else false. */ - boolean handleDismissalInterception(NotificationEntry entry); + boolean handleDismissalInterception(BubbleEntry entry, @Nullable List<BubbleEntry> children, + IntConsumer removeCallback); /** - * Removes the bubble with the given key. - * <p> - * Must be called from the main thread. + * Retrieves the notif entry key of the summary associated with the provided group key. + * + * @param groupKey the group to look up + * @return the key for the notification that is the summary of this group. */ - @MainThread - void removeBubble(String key, int reason); + String getSummaryKey(String groupKey); + + /** Set the proxy to commnuicate with SysUi side components. */ + void setSysuiProxy(SysuiProxy proxy); + + /** Set the scrim view for bubbles. */ + void setBubbleScrim(View view); + + /** Set a listener to be notified of bubble expand events. */ + void setExpandListener(BubbleExpandListener listener); + /** + * Called when new notification entry added. + * + * @param entry the {@link BubbleEntry} by the notification. + */ + void onEntryAdded(BubbleEntry entry); + + /** + * Called when new notification entry updated. + * + * @param entry the {@link BubbleEntry} by the notification. + * @param shouldBubbleUp {@code true} if this notification should bubble up. + */ + void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp); + + /** + * Called when new notification entry removed. + * + * @param entry the {@link BubbleEntry} by the notification. + */ + void onEntryRemoved(BubbleEntry entry); /** - * When a notification is marked Priority, expand the stack if needed, - * then (maybe create and) select the given bubble. + * Called when NotificationListener has received adjusted notification rank and reapplied + * filtering and sorting. This is used to dismiss or create bubbles based on changes in + * permissions on the notification channel or the global setting. * - * @param entry the notification for the bubble to show + * @param rankingMap the updated ranking map from NotificationListenerService */ - void onUserChangedImportance(NotificationEntry entry); + void onRankingUpdated(RankingMap rankingMap); /** * Called when the status bar has become visible or invisible (either permanently or @@ -108,30 +178,85 @@ public interface Bubbles { */ void onStatusBarVisibilityChanged(boolean visible); + /** Called when system zen mode state changed. */ + void onZenStateChanged(); + /** - * Called when a user has indicated that an active notification should be shown as a bubble. - * <p> - * This method will collapse the shade, create the bubble without a flyout or dot, and suppress - * the notification from appearing in the shade. + * Called when statusBar state changed. * - * @param entry the notification to change bubble state for. - * @param shouldBubble whether the notification should show as a bubble or not. + * @param isShade {@code true} is state is SHADE. */ - void onUserChangedBubble(@NonNull NotificationEntry entry, boolean shouldBubble); + void onStatusBarStateChanged(boolean isShade); + /** + * Called when the current user changed. + * + * @param newUserId the new user's id. + */ + void onUserChanged(int newUserId); - /** See {@link BubbleController.NotifCallback}. */ - void addNotifCallback(BubbleController.NotifCallback callback); + /** + * Called when config changed. + * + * @param newConfig the new config. + */ + void onConfigChanged(Configuration newConfig); - /** Set a listener to be notified of bubble expand events. */ - void setExpandListener(BubbleController.BubbleExpandListener listener); + /** Description of current bubble state. */ + void dump(FileDescriptor fd, PrintWriter pw, String[] args); + + /** Listener to find out about stack expansion / collapse events. */ + interface BubbleExpandListener { + /** + * Called when the expansion state of the bubble stack changes. + * + * @param isExpanding whether it's expanding or collapsing + * @param key the notification key associated with bubble being expanded + */ + void onBubbleExpandChanged(boolean isExpanding, String key); + } + + /** Listener to be notified when a bubbles' notification suppression state changes.*/ + interface NotificationSuppressionChangedListener { + /** Called when the notification suppression state of a bubble changes. */ + void onBubbleNotificationSuppressionChange(Bubble bubble); + } + + /** Listener to be notified when a pending intent has been canceled for a bubble. */ + interface PendingIntentCanceledListener { + /** Called when the pending intent for a bubble has been canceled. */ + void onPendingIntentCanceled(Bubble bubble); + } + + /** Callback to tell SysUi components execute some methods. */ + interface SysuiProxy { + @Nullable + BubbleEntry getPendingOrActiveEntry(String key); + + List<BubbleEntry> getShouldRestoredEntries(ArraySet<String> savedBubbleKeys); + + boolean isNotificationShadeExpand(); + + boolean shouldBubbleUp(String key); + + void setNotificationInterruption(String key); + + void requestNotificationShadeTopUi(boolean requestTopUi, String componentTag); + + void notifyRemoveNotification(String key, int reason); + + void notifyInvalidateNotifications(String reason); + + void notifyMaybeCancelSummary(String key); + + void removeNotificationEntry(String key); + + void updateNotificationBubbleButton(String key); - /** Set a listener to be notified of when overflow view update. */ - void setOverflowListener(BubbleData.Listener listener); + void updateNotificationSuppression(String key); - /** The task listener for events in bubble tasks. **/ - ShellTaskOrganizer getTaskOrganizer(); + void onStackExpandChanged(boolean shouldExpand); - /** Contains information to help position things on the screen. */ - BubblePositioner getPositioner(); + void onUnbubbleConversation(String key); + } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/TaskView.java b/packages/SystemUI/src/com/android/systemui/bubbles/TaskView.java index 85616d1513f5..0a2cfbfffd9e 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/TaskView.java @@ -30,7 +30,6 @@ import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.graphics.Rect; import android.os.Binder; -import android.os.Handler; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceView; @@ -82,21 +81,25 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, private boolean mSurfaceCreated; private boolean mIsInitialized; private Listener mListener; - private final Executor mExecutor; + private Executor mExecutor; private final Rect mTmpRect = new Rect(); private final Rect mTmpRootRect = new Rect(); - public TaskView(Context context, ShellTaskOrganizer organizer, Executor executor) { + public TaskView(Context context, ShellTaskOrganizer organizer) { super(context, null, 0, 0, true /* disableBackgroundLayer */); - mExecutor = executor; mTaskOrganizer = organizer; setUseAlpha(); getHolder().addCallback(this); mGuard.open("release"); } + // TODO: Use TaskOrganizer executor when part of wmshell proper + public void setExecutor(Executor executor) { + mExecutor = executor; + } + /** * Only one listener may be set on the view, throws an exception otherwise. */ @@ -225,6 +228,7 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { + if (mExecutor == null) return; mExecutor.execute(() -> { mTaskInfo = taskInfo; mTaskToken = taskInfo.token; @@ -253,6 +257,7 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, @Override public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { + if (mExecutor == null) return; mExecutor.execute(() -> { if (mTaskToken == null || !mTaskToken.equals(taskInfo.token)) return; @@ -268,6 +273,7 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, @Override public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { + if (mExecutor == null) return; mExecutor.execute(() -> { mTaskInfo.taskDescription = taskInfo.taskDescription; setResizeBackgroundColor(taskInfo.taskDescription.getBackgroundColor()); @@ -276,6 +282,7 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, @Override public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) { + if (mExecutor == null) return; mExecutor.execute(() -> { if (mTaskToken == null || !mTaskToken.equals(taskInfo.token)) return; if (mListener != null) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java index 31e1ca839e5d..c410b8267dd4 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java @@ -34,6 +34,7 @@ import androidx.dynamicanimation.animation.SpringAnimation; import androidx.dynamicanimation.animation.SpringForce; import com.android.systemui.R; +import com.android.systemui.bubbles.BadgedImageView; import com.android.systemui.bubbles.BubblePositioner; import com.android.systemui.bubbles.BubbleStackView; import com.android.wm.shell.animation.PhysicsAnimator; @@ -45,6 +46,7 @@ import com.google.android.collect.Sets; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.HashMap; +import java.util.List; import java.util.Set; import java.util.function.IntSupplier; @@ -63,6 +65,10 @@ public class StackAnimationController extends private static final float ANIMATE_IN_STIFFNESS = 1000f; private static final int ANIMATE_IN_START_DELAY = 25; + /** Values to use for animating updated bubble to top of stack. */ + private static final float BUBBLE_SWAP_SCALE = 0.8f; + private static final long BUBBLE_SWAP_DURATION = 300L; + /** * Values to use for the default {@link SpringForce} provided to the physics animation layout. */ @@ -180,6 +186,12 @@ public class StackAnimationController extends /** Horizontal offset of bubbles in the stack. */ private float mStackOffset; + /** Offset between stack y and animation y for bubble swap. */ + private float mSwapAnimationOffset; + /** Max number of bubbles to show in the expanded bubble row. */ + private int mMaxBubbles; + /** Default bubble elevation. */ + private int mElevation; /** Diameter of the bubble icon. */ private int mBubbleBitmapSize; /** Width of the bubble (icon and padding). */ @@ -770,6 +782,50 @@ public class StackAnimationController extends } } + public void animateReorder(List<View> bubbleViews, Runnable after) { + for (int newIndex = 0; newIndex < bubbleViews.size(); newIndex++) { + View view = bubbleViews.get(newIndex); + final int oldIndex= mLayout.indexOfChild(view); + animateSwap(view, oldIndex, newIndex, after); + } + } + + private void animateSwap(View view, int oldIndex, int newIndex, Runnable finishReorder) { + final float newY = getStackPosition().y + newIndex * mSwapAnimationOffset; + final float swapY = newIndex == 0 + ? newY - mSwapAnimationOffset // Above top of stack + : newY + mSwapAnimationOffset; // Below where bubble will be + view.animate() + .scaleX(BUBBLE_SWAP_SCALE) + .scaleY(BUBBLE_SWAP_SCALE) + .translationY(swapY) + .setDuration(BUBBLE_SWAP_DURATION) + .withEndAction(() -> finishSwapAnimation(view, oldIndex, newIndex, finishReorder)); + } + + private void finishSwapAnimation(View view, int oldIndex, int newIndex, + Runnable finishReorder) { + + // At this point, swapping bubbles have the least overlap. + // Update z-index and badge visibility here for least jarring transition. + view.setZ((mMaxBubbles * mElevation) - newIndex); + BadgedImageView bv = (BadgedImageView) view; + if (oldIndex == 0 && newIndex > 0) { + bv.hideDotAndBadge(!isStackOnLeftSide()); + } else if (oldIndex > 0 && newIndex == 0) { + bv.showDotAndBadge(!isStackOnLeftSide()); + } + + // Animate bubble back into stack, at new index and original size. + final float newY = getStackPosition().y + newIndex * mStackOffset; + view.animate() + .scaleX(1f) + .scaleY(1f) + .translationY(newY) + .setDuration(BUBBLE_SWAP_DURATION) + .withEndAction(() -> finishReorder.run()); + } + @Override void onChildReordered(View child, int oldIndex, int newIndex) { if (isStackPositionSet()) { @@ -781,6 +837,9 @@ public class StackAnimationController extends void onActiveControllerForLayout(PhysicsAnimationLayout layout) { Resources res = layout.getResources(); mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset); + mSwapAnimationOffset = res.getDimensionPixelSize(R.dimen.bubble_swap_animation_offset); + mMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered); + mElevation = res.getDimensionPixelSize(R.dimen.bubble_elevation); mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size); mBubbleBitmapSize = res.getDimensionPixelSize(R.dimen.bubble_bitmap_size); mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java index 6b5f237ac76f..5a7e033607f8 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java @@ -22,6 +22,8 @@ import android.content.pm.LauncherApps; import android.os.Handler; import android.view.WindowManager; +import androidx.annotation.Nullable; + import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.bubbles.BubbleController; @@ -41,10 +43,13 @@ import com.android.systemui.statusbar.notification.interruption.NotificationInte import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.wmshell.BubblesManager; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.FloatingContentCoordinator; +import java.util.Optional; + import dagger.Module; import dagger.Provides; @@ -56,23 +61,8 @@ public interface BubbleModule { */ @SysUISingleton @Provides - static Bubbles newBubbleController( - Context context, - NotificationShadeWindowController notificationShadeWindowController, - StatusBarStateController statusBarStateController, - ShadeController shadeController, - ConfigurationController configurationController, - NotificationInterruptStateProvider interruptionStateProvider, - ZenModeController zenModeController, - NotificationLockscreenUserManager notifUserManager, - NotificationGroupManagerLegacy groupManager, - NotificationEntryManager entryManager, - NotifPipeline notifPipeline, - FeatureFlags featureFlags, - DumpManager dumpManager, + static Bubbles newBubbleController(Context context, FloatingContentCoordinator floatingContentCoordinator, - SysUiState sysUiState, - INotificationManager notifManager, IStatusBarService statusBarService, WindowManager windowManager, WindowManagerShellWrapper windowManagerShellWrapper, @@ -80,30 +70,29 @@ public interface BubbleModule { UiEventLogger uiEventLogger, @Main Handler mainHandler, ShellTaskOrganizer organizer) { - return BubbleController.create( - context, - notificationShadeWindowController, - statusBarStateController, - shadeController, - null /* synchronizer */, - configurationController, - interruptionStateProvider, - zenModeController, - notifUserManager, - groupManager, - entryManager, - notifPipeline, - featureFlags, - dumpManager, - floatingContentCoordinator, - sysUiState, - notifManager, - statusBarService, - windowManager, - windowManagerShellWrapper, - launcherApps, - uiEventLogger, - mainHandler, - organizer); + return BubbleController.create(context, null /* synchronizer */, floatingContentCoordinator, + statusBarService, windowManager, windowManagerShellWrapper, launcherApps, + uiEventLogger, mainHandler, organizer); + } + + /** Provides Optional of BubbleManager */ + @SysUISingleton + @Provides + static Optional<BubblesManager> provideBubblesManager(Context context, + Optional<Bubbles> bubblesOptional, + NotificationShadeWindowController notificationShadeWindowController, + StatusBarStateController statusBarStateController, ShadeController shadeController, + ConfigurationController configurationController, + @Nullable IStatusBarService statusBarService, INotificationManager notificationManager, + NotificationInterruptStateProvider interruptionStateProvider, + ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager, + NotificationGroupManagerLegacy groupManager, NotificationEntryManager entryManager, + NotifPipeline notifPipeline, SysUiState sysUiState, FeatureFlags featureFlags, + DumpManager dumpManager) { + return Optional.ofNullable(BubblesManager.create(context, bubblesOptional, + notificationShadeWindowController, statusBarStateController, shadeController, + configurationController, statusBarService, notificationManager, + interruptionStateProvider, zenModeController, notifUserManager, + groupManager, entryManager, notifPipeline, sysUiState, featureFlags, dumpManager)); } } diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index e3ee2a10821b..fff185b99a1e 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -120,6 +120,18 @@ public class LogModule { return buffer; } + /** Provides a logging buffer for all logs related to privacy indicators in SystemUI. */ + @Provides + @SysUISingleton + @PrivacyLog + public static LogBuffer providePrivacyLogBuffer( + LogcatEchoTracker bufferFilter, + DumpManager dumpManager) { + LogBuffer buffer = new LogBuffer(("PrivacyLog"), 100, 10, bufferFilter); + buffer.attach(dumpManager); + return buffer; + } + /** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */ @Provides @SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/PrivacyLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/PrivacyLog.java new file mode 100644 index 000000000000..e96e532f94bf --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/PrivacyLog.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.dagger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.android.systemui.log.LogBuffer; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Qualifier; + +/** A {@link LogBuffer} for privacy indicator-related messages. */ +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface PrivacyLog { +} diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt index 3da1363f2a56..7359e79b26f5 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt @@ -19,20 +19,31 @@ import com.android.systemui.R typealias Privacy = PrivacyType -enum class PrivacyType(val nameId: Int, val iconId: Int) { +enum class PrivacyType(val nameId: Int, val iconId: Int, val logName: String) { // This is uses the icons used by the corresponding permission groups in the AndroidManifest - TYPE_CAMERA(R.string.privacy_type_camera, - com.android.internal.R.drawable.perm_group_camera), - TYPE_MICROPHONE(R.string.privacy_type_microphone, - com.android.internal.R.drawable.perm_group_microphone), - TYPE_LOCATION(R.string.privacy_type_location, - com.android.internal.R.drawable.perm_group_location); + TYPE_CAMERA( + R.string.privacy_type_camera, + com.android.internal.R.drawable.perm_group_camera, + "camera" + ), + TYPE_MICROPHONE( + R.string.privacy_type_microphone, + com.android.internal.R.drawable.perm_group_microphone, + "microphone" + ), + TYPE_LOCATION( + R.string.privacy_type_location, + com.android.internal.R.drawable.perm_group_location, + "location" + ); fun getName(context: Context) = context.resources.getString(nameId) fun getIcon(context: Context) = context.resources.getDrawable(iconId, context.theme) } -data class PrivacyItem(val privacyType: PrivacyType, val application: PrivacyApplication) +data class PrivacyItem(val privacyType: PrivacyType, val application: PrivacyApplication) { + fun toLog(): String = "(${privacyType.logName}, ${application.packageName}(${application.uid}))" +} data class PrivacyApplication(val packageName: String, val uid: Int) diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt index dc5ba693a658..87ffbd465109 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -32,6 +32,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager +import com.android.systemui.privacy.logging.PrivacyLogger import com.android.systemui.settings.UserTracker import com.android.systemui.util.DeviceConfigProxy import com.android.systemui.util.concurrency.DelayableExecutor @@ -48,6 +49,7 @@ class PrivacyItemController @Inject constructor( @Background private val bgExecutor: Executor, private val deviceConfigProxy: DeviceConfigProxy, private val userTracker: UserTracker, + private val logger: PrivacyLogger, dumpManager: DumpManager ) : Dumpable { @@ -158,6 +160,7 @@ class PrivacyItemController @Inject constructor( } val userId = UserHandle.getUserId(uid) if (userId in currentUserIds) { + logger.logUpdatedItemFromAppOps(code, uid, packageName, active) update(false) } } @@ -194,6 +197,7 @@ class PrivacyItemController @Inject constructor( bgExecutor.execute { if (updateUsers) { currentUserIds = userTracker.userProfiles.map { it.id } + logger.logCurrentProfilesChanged(currentUserIds) } updateListAndNotifyChanges.run() } @@ -260,6 +264,8 @@ class PrivacyItemController @Inject constructor( } val list = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) } .mapNotNull { toPrivacyItem(it) }.distinct() + logger.logUpdatedPrivacyItemsList( + list.joinToString(separator = ", ", transform = PrivacyItem::toLog)) privacyList = list } diff --git a/packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt b/packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt new file mode 100644 index 000000000000..c88676e713b3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.privacy.logging + +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogLevel +import com.android.systemui.log.LogMessage +import com.android.systemui.log.dagger.PrivacyLog +import javax.inject.Inject + +private const val TAG = "PrivacyLog" + +class PrivacyLogger @Inject constructor( + @PrivacyLog private val buffer: LogBuffer +) { + + fun logUpdatedItemFromAppOps(code: Int, uid: Int, packageName: String, active: Boolean) { + log(LogLevel.INFO, { + int1 = code + int2 = uid + str1 = packageName + bool1 = active + }, { + "App Op: $int1 for $str1($int2), active=$bool1" + }) + } + + fun logUpdatedPrivacyItemsList(listAsString: String) { + log(LogLevel.INFO, { + str1 = listAsString + }, { + "Updated list: $str1" + }) + } + + fun logCurrentProfilesChanged(profiles: List<Int>) { + log(LogLevel.INFO, { + str1 = profiles.toString() + }, { + "Profiles changed: $str1" + }) + } + + fun logChipVisible(visible: Boolean) { + log(LogLevel.INFO, { + bool1 = visible + }, { + "Chip visible: $bool1" + }) + } + + fun logStatusBarIconsVisible( + showCamera: Boolean, + showMichrophone: Boolean, + showLocation: Boolean + ) { + log(LogLevel.INFO, { + bool1 = showCamera + bool2 = showMichrophone + bool3 = showLocation + }, { + "Status bar icons visible: camera=$bool1, microphone=$bool2, location=$bool3" + }) + } + + private inline fun log( + logLevel: LogLevel, + initializer: LogMessage.() -> Unit, + noinline printer: LogMessage.() -> String + ) { + buffer.log(TAG, logLevel, initializer, printer) + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt index 81076475c5ce..6ac1e7079531 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt @@ -99,7 +99,7 @@ class DoubleLineTileLayout( } } - override fun getNumVisibleTiles() = tilesToShow + override fun getNumVisibleTiles() = Math.min(mRecords.size, tilesToShow) override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 1b17a2a277f2..76f244652cd9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -480,7 +480,6 @@ public class QSPanel extends LinearLayout implements Tunable, BrightnessMirrorLi } } mTileLayout = newLayout; - newLayout.setListening(mListening); if (needsDynamicRowsAndColumns()) { newLayout.setMinRows(horizontal ? 2 : 1); // Let's use 3 columns to match the current layout @@ -498,6 +497,14 @@ public class QSPanel extends LinearLayout implements Tunable, BrightnessMirrorLi return false; } + /** + * Sets the listening state of the current layout to the state of the view. Used after + * switching layouts. + */ + public void reSetLayoutListening() { + mTileLayout.setListening(mListening); + } + private void updateHorizontalLinearLayoutMargins() { if (mHorizontalLinearLayout != null && !displayMediaMarginsOnMedia()) { LayoutParams lp = (LayoutParams) mHorizontalLinearLayout.getLayoutParams(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java index fe92827806c6..68a6cdcbd289 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java @@ -214,6 +214,7 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr boolean switchTileLayout(boolean force) { if (mView.switchTileLayout(force, mRecords)) { setTiles(); + mView.reSetLayoutListening(); return true; } return false; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java index c90182b15da6..270fcbffbd71 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java @@ -16,11 +16,13 @@ package com.android.systemui.qs; import android.app.AlertDialog; +import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyEventLogger; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.UserInfo; +import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -39,6 +41,8 @@ import android.view.Window; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.VisibleForTesting; + import com.android.internal.util.FrameworkStatsLog; import com.android.systemui.Dependency; import com.android.systemui.FontSizeUtils; @@ -156,15 +160,16 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen mSecurityController.getWorkProfileOrganizationName(); final boolean isProfileOwnerOfOrganizationOwnedDevice = mSecurityController.isProfileOwnerOfOrganizationOwnedDevice(); + final boolean isParentalControlsEnabled = mSecurityController.isParentalControlsEnabled(); // Update visibility of footer mIsVisible = (isDeviceManaged && !isDemoDevice) || hasCACerts || hasCACertsInWorkProfile || vpnName != null || vpnNameWorkProfile != null - || isProfileOwnerOfOrganizationOwnedDevice; + || isProfileOwnerOfOrganizationOwnedDevice || isParentalControlsEnabled; // Update the string mFooterTextContent = getFooterText(isDeviceManaged, hasWorkProfile, hasCACerts, hasCACertsInWorkProfile, isNetworkLoggingEnabled, vpnName, vpnNameWorkProfile, organizationName, workProfileOrganizationName, - isProfileOwnerOfOrganizationOwnedDevice); + isProfileOwnerOfOrganizationOwnedDevice, isParentalControlsEnabled); // Update the icon int footerIconId = R.drawable.ic_info_outline; if (vpnName != null || vpnNameWorkProfile != null) { @@ -185,7 +190,10 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled, String vpnName, String vpnNameWorkProfile, CharSequence organizationName, CharSequence workProfileOrganizationName, - boolean isProfileOwnerOfOrganizationOwnedDevice) { + boolean isProfileOwnerOfOrganizationOwnedDevice, boolean isParentalControlsEnabled) { + if (isParentalControlsEnabled) { + return mContext.getString(R.string.quick_settings_disclosure_parental_controls); + } if (isDeviceManaged || DEBUG_FORCE_VISIBLE) { if (hasCACerts || hasCACertsInWorkProfile || isNetworkLoggingEnabled) { if (organizationName == null) { @@ -268,6 +276,27 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen } private void createDialog() { + mDialog = new SystemUIDialog(mContext); + mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this); + mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getNegativeButton(), this); + + mDialog.setView(createDialogView()); + + mDialog.show(); + mDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + } + + @VisibleForTesting + View createDialogView() { + if (mSecurityController.isParentalControlsEnabled()) { + return createParentalControlsDialogView(); + } + return createOrganizationDialogView(); + } + + private View createOrganizationDialogView() { final boolean isDeviceManaged = mSecurityController.isDeviceManaged(); boolean isProfileOwnerOfOrganizationOwnedDevice = mSecurityController.isProfileOwnerOfOrganizationOwnedDevice(); @@ -282,13 +311,10 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen final String vpnName = mSecurityController.getPrimaryVpnName(); final String vpnNameWorkProfile = mSecurityController.getWorkProfileVpnName(); - mDialog = new SystemUIDialog(mContext); - mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + View dialogView = LayoutInflater.from( new ContextThemeWrapper(mContext, R.style.Theme_SystemUI_Dialog)) .inflate(R.layout.quick_settings_footer_dialog, null, false); - mDialog.setView(dialogView); - mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this); // device management section CharSequence managementMessage = getManagementMessage(isDeviceManaged, @@ -353,9 +379,26 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen vpnMessage != null, dialogView); - mDialog.show(); - mDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); + return dialogView; + } + + private View createParentalControlsDialogView() { + View dialogView = LayoutInflater.from( + new ContextThemeWrapper(mContext, R.style.Theme_SystemUI_Dialog)) + .inflate(R.layout.quick_settings_footer_dialog_parental_controls, null, false); + + DeviceAdminInfo info = mSecurityController.getDeviceAdminInfo(); + Drawable icon = mSecurityController.getIcon(info); + if (icon != null) { + ImageView imageView = (ImageView) dialogView.findViewById(R.id.parental_controls_icon); + imageView.setImageDrawable(icon); + } + + TextView parentalControlsTitle = + (TextView) dialogView.findViewById(R.id.parental_controls_title); + parentalControlsTitle.setText(mSecurityController.getLabel(info)); + + return dialogView; } protected void configSubtitleVisibility(boolean showDeviceManagement, boolean showCaCerts, @@ -394,6 +437,13 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen return mContext.getString(R.string.ok); } + private String getNegativeButton() { + if (mSecurityController.isParentalControlsEnabled()) { + return mContext.getString(R.string.monitoring_button_view_controls); + } + return null; + } + protected CharSequence getManagementMessage(boolean isDeviceManaged, CharSequence organizationName, boolean isProfileOwnerOfOrganizationOwnedDevice, CharSequence workProfileOrganizationName) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java index 84a5b6f0538d..ed0900d07b56 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java @@ -336,7 +336,7 @@ public class QuickQSPanel extends QSPanel { @Override public int getNumVisibleTiles() { - return mColumns; + return Math.min(mRecords.size(), mColumns); } @Override @@ -353,6 +353,7 @@ public class QuickQSPanel extends QSPanel { boolean startedListening = !mListening && listening; super.setListening(listening); if (startedListening) { + // getNumVisibleTiles() <= mRecords.size() for (int i = 0; i < getNumVisibleTiles(); i++) { QSTile tile = mRecords.get(i).tile; mUiEventLogger.logWithInstanceId(QSEvent.QQS_TILE_VISIBLE, 0, diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java index 44f847c34e2b..32904a21cd3c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java @@ -43,6 +43,7 @@ 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.privacy.logging.PrivacyLogger; import com.android.systemui.qs.carrier.QSCarrierGroupController; import com.android.systemui.qs.dagger.QSScope; import com.android.systemui.settings.UserTracker; @@ -90,6 +91,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader private final StatusIconContainer mIconContainer; private final StatusBarIconController.TintedIconManager mIconManager; private final DemoMode mDemoModeReceiver; + private final PrivacyLogger mPrivacyLogger; private boolean mListening; private AlarmClockInfo mNextAlarm; @@ -213,7 +215,8 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader QSTileHost qsTileHost, StatusBarIconController statusBarIconController, CommandQueue commandQueue, DemoModeController demoModeController, UserTracker userTracker, QuickQSPanelController quickQSPanelController, - QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder) { + QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder, + PrivacyLogger privacyLogger) { super(view); mZenModeController = zenModeController; mNextAlarmController = nextAlarmController; @@ -228,6 +231,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader mUserTracker = userTracker; mLifecycle = new LifecycleRegistry(mLifecycleOwner); mHeaderQsPanelController = quickQSPanelController; + mPrivacyLogger = privacyLogger; mQSCarrierGroupController = qsCarrierGroupControllerBuilder .setQSCarrierGroup(mView.findViewById(R.id.carrier_group)) @@ -323,6 +327,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader private void setChipVisibility(boolean chipVisible) { if (chipVisible && getChipEnabled()) { mPrivacyChip.setVisibility(View.VISIBLE); + mPrivacyLogger.logChipVisible(true); // 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) { @@ -330,6 +335,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_VIEW); } } else { + mPrivacyLogger.logChipVisible(false); mPrivacyChip.setVisibility(View.GONE); } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java index c0061ad97293..b2ebf3f700b9 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java @@ -281,8 +281,10 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // cancel current pending intent (if any) since clipData isn't used for matching - PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, 0, - sharingChooserIntent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); + PendingIntent pendingIntent = PendingIntent.getActivityAsUser( + context, 0, sharingChooserIntent, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, + null, UserHandle.CURRENT); // Create a share action for the notification PendingIntent shareAction = PendingIntent.getBroadcastAsUser(context, requestCode, @@ -294,7 +296,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { mSmartActionsEnabled) .setAction(Intent.ACTION_SEND) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), - PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM); + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, + UserHandle.SYSTEM); Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder( Icon.createWithResource(r, R.drawable.ic_screenshot_share), @@ -323,7 +326,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, 0, - editIntent, 0, null, UserHandle.CURRENT); + editIntent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT); // Make sure pending intents for the system user are still unique across users // by setting the (otherwise unused) request code to the current user id. @@ -338,7 +341,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { mSmartActionsEnabled) .setAction(Intent.ACTION_EDIT) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), - PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM); + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, + UserHandle.SYSTEM); Notification.Action.Builder editActionBuilder = new Notification.Action.Builder( Icon.createWithResource(r, R.drawable.ic_screenshot_edit), r.getString(com.android.internal.R.string.screenshot_edit), editAction); @@ -360,7 +364,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { .putExtra(ScreenshotController.EXTRA_SMART_ACTIONS_ENABLED, mSmartActionsEnabled) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); + PendingIntent.FLAG_CANCEL_CURRENT + | PendingIntent.FLAG_ONE_SHOT + | PendingIntent.FLAG_IMMUTABLE); Notification.Action.Builder deleteActionBuilder = new Notification.Action.Builder( Icon.createWithResource(r, R.drawable.ic_screenshot_delete), r.getString(com.android.internal.R.string.delete), deleteAction); @@ -401,7 +407,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { PendingIntent broadcastIntent = PendingIntent.getBroadcast(context, mRandom.nextInt(), intent, - PendingIntent.FLAG_CANCEL_CURRENT); + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); broadcastActions.add(new Notification.Action.Builder(action.getIcon(), action.title, broadcastIntent).setContextual(true).addExtras(extras).build()); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 5d8f70c4e460..260f55799e0b 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -38,6 +38,7 @@ import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.media.MediaActionSound; import android.net.Uri; +import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -108,7 +109,7 @@ public class ScreenshotController { abstract void onActionsReady(ScreenshotController.SavedImageData imageData); } - private static final String TAG = "GlobalScreenshotController"; + private static final String TAG = "ScreenshotController"; // These strings are used for communicating the action invoked to // ScreenshotNotificationSmartActionsProvider. @@ -143,6 +144,7 @@ public class ScreenshotController { private final AccessibilityManager mAccessibilityManager; private final MediaActionSound mCameraSound; + private final Binder mWindowToken; private ScreenshotView mScreenshotView; private Bitmap mScreenBitmap; private SaveImageInBackgroundTask mSaveInBgTask; @@ -178,13 +180,9 @@ public class ScreenshotController { mNotificationsController = screenshotNotificationsController; mUiEventLogger = uiEventLogger; - // Create a visual (Window) context - // After this, our windowToken is available from mContext.getActivityToken() final DisplayManager dm = requireNonNull(context.getSystemService(DisplayManager.class)); mDisplay = dm.getDisplay(DEFAULT_DISPLAY); - Context displayContext = context.createDisplayContext(mDisplay); - mContext = new WindowContext(displayContext, WindowManager.LayoutParams.TYPE_SCREENSHOT, - null); + mContext = context.createDisplayContext(mDisplay); mWindowManager = mContext.getSystemService(WindowManager.class); mAccessibilityManager = AccessibilityManager.getInstance(mContext); @@ -194,6 +192,7 @@ public class ScreenshotController { mInDarkMode = config.isNightModeActive(); mDirectionLTR = config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; mOrientationPortrait = config.orientation == ORIENTATION_PORTRAIT; + mWindowToken = new Binder("ScreenshotController"); // Setup the window that we are going to use mWindowLayoutParams = new WindowManager.LayoutParams( @@ -210,6 +209,7 @@ public class ScreenshotController { mWindowLayoutParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; mWindowLayoutParams.setFitInsetsTypes(0 /* types */); + mWindowLayoutParams.token = mWindowToken; mDisplayMetrics = new DisplayMetrics(); mDisplay.getRealMetrics(mDisplayMetrics); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java index 03fe2920405f..29f6e8b0db00 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java @@ -49,7 +49,6 @@ import android.util.Log; import android.util.MathUtils; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.view.WindowInsets; @@ -73,7 +72,7 @@ import java.util.function.Consumer; public class ScreenshotView extends FrameLayout implements ViewTreeObserver.OnComputeInternalInsetsListener { - private static final String TAG = "GlobalScreenshotView"; + private static final String TAG = "ScreenshotView"; private static final long SCREENSHOT_FLASH_IN_DURATION_MS = 133; private static final long SCREENSHOT_FLASH_OUT_DURATION_MS = 217; @@ -105,7 +104,6 @@ public class ScreenshotView extends FrameLayout implements private boolean mDirectionLTR; private ScreenshotSelectorView mScreenshotSelectorView; - private ImageView mScreenshotAnimatedView; private ImageView mScreenshotPreview; private ImageView mScreenshotFlash; private ImageView mActionsContainerBackground; @@ -116,7 +114,7 @@ public class ScreenshotView extends FrameLayout implements private ScreenshotActionChip mShareChip; private ScreenshotActionChip mEditChip; - private ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>(); + private final ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>(); private PendingInteraction mPendingInteraction; private enum PendingInteraction { @@ -183,8 +181,6 @@ public class ScreenshotView extends FrameLayout implements @Override // View protected void onFinishInflate() { - mScreenshotAnimatedView = requireNonNull( - findViewById(R.id.global_screenshot_animated_view)); mScreenshotPreview = requireNonNull(findViewById(R.id.global_screenshot_preview)); mActionsContainerBackground = requireNonNull(findViewById( R.id.global_screenshot_actions_container_background)); @@ -198,14 +194,6 @@ public class ScreenshotView extends FrameLayout implements mShareChip = requireNonNull(mActionsContainer.findViewById(R.id.screenshot_share_chip)); mEditChip = requireNonNull(mActionsContainer.findViewById(R.id.screenshot_edit_chip)); - mScreenshotAnimatedView.setClipToOutline(true); - mScreenshotAnimatedView.setOutlineProvider(new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()), - ROUNDED_CORNER_RADIUS * view.getWidth()); - } - }); mScreenshotPreview.setClipToOutline(true); mScreenshotPreview.setOutlineProvider(new ViewOutlineProvider() { @Override @@ -218,8 +206,6 @@ public class ScreenshotView extends FrameLayout implements setFocusable(true); mScreenshotSelectorView.setFocusable(true); mScreenshotSelectorView.setFocusableInTouchMode(true); - mScreenshotAnimatedView.setPivotX(0); - mScreenshotAnimatedView.setPivotY(0); mActionsContainer.setScrollX(0); mNavMode = getResources().getInteger( @@ -253,13 +239,6 @@ public class ScreenshotView extends FrameLayout implements } void prepareForAnimation(Bitmap bitmap, Rect screenRect, Insets screenInsets) { - mScreenshotAnimatedView.setImageDrawable( - createScreenDrawable(mResources, bitmap, screenInsets)); - setAnimatedViewSize(screenRect.width(), screenRect.height()); - - // will show when the animation starts - mScreenshotAnimatedView.setVisibility(View.GONE); - mScreenshotPreview.setImageDrawable(createScreenDrawable(mResources, bitmap, screenInsets)); // make static preview invisible (from gone) so we can query its location on screen mScreenshotPreview.setVisibility(View.INVISIBLE); @@ -275,10 +254,10 @@ public class ScreenshotView extends FrameLayout implements float cornerScale = mCornerSizeX / (mOrientationPortrait ? bounds.width() : bounds.height()); - final float currentScale = 1f; + final float currentScale = 1 / cornerScale; - mScreenshotAnimatedView.setScaleX(currentScale); - mScreenshotAnimatedView.setScaleY(currentScale); + mScreenshotPreview.setScaleX(currentScale); + mScreenshotPreview.setScaleY(currentScale); mDismissButton.setAlpha(0); mDismissButton.setVisibility(View.VISIBLE); @@ -312,36 +291,33 @@ public class ScreenshotView extends FrameLayout implements float t = animation.getAnimatedFraction(); if (t < scalePct) { float scale = MathUtils.lerp( - currentScale, cornerScale, mFastOutSlowIn.getInterpolation(t / scalePct)); - mScreenshotAnimatedView.setScaleX(scale); - mScreenshotAnimatedView.setScaleY(scale); + currentScale, 1, mFastOutSlowIn.getInterpolation(t / scalePct)); + mScreenshotPreview.setScaleX(scale); + mScreenshotPreview.setScaleY(scale); } else { - mScreenshotAnimatedView.setScaleX(cornerScale); - mScreenshotAnimatedView.setScaleY(cornerScale); + mScreenshotPreview.setScaleX(1); + mScreenshotPreview.setScaleY(1); } - float currentScaleX = mScreenshotAnimatedView.getScaleX(); - float currentScaleY = mScreenshotAnimatedView.getScaleY(); - if (t < xPositionPct) { float xCenter = MathUtils.lerp(startPos.x, finalPos.x, mFastOutSlowIn.getInterpolation(t / xPositionPct)); - mScreenshotAnimatedView.setX(xCenter - bounds.width() * currentScaleX / 2f); + mScreenshotPreview.setX(xCenter - mScreenshotPreview.getWidth() / 2f); } else { - mScreenshotAnimatedView.setX(finalPos.x - bounds.width() * currentScaleX / 2f); + mScreenshotPreview.setX(finalPos.x - mScreenshotPreview.getWidth() / 2f); } float yCenter = MathUtils.lerp( startPos.y, finalPos.y, mFastOutSlowIn.getInterpolation(t)); - mScreenshotAnimatedView.setY(yCenter - bounds.height() * currentScaleY / 2f); + mScreenshotPreview.setY(yCenter - mScreenshotPreview.getHeight() / 2f); if (t >= dismissPct) { mDismissButton.setAlpha((t - dismissPct) / (1 - dismissPct)); - float currentX = mScreenshotAnimatedView.getX(); - float currentY = mScreenshotAnimatedView.getY(); + float currentX = mScreenshotPreview.getX(); + float currentY = mScreenshotPreview.getY(); mDismissButton.setY(currentY - mDismissButton.getHeight() / 2f); if (mDirectionLTR) { - mDismissButton.setX(currentX - + bounds.width() * currentScaleX - mDismissButton.getWidth() / 2f); + mDismissButton.setX(currentX + mScreenshotPreview.getWidth() + - mDismissButton.getWidth() / 2f); } else { mDismissButton.setX(currentX - mDismissButton.getWidth() / 2f); } @@ -352,7 +328,7 @@ public class ScreenshotView extends FrameLayout implements @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); - mScreenshotAnimatedView.setVisibility(View.VISIBLE); + mScreenshotPreview.setVisibility(View.VISIBLE); } }); @@ -380,13 +356,11 @@ public class ScreenshotView extends FrameLayout implements mDismissButton.setX(finalDismissX); mDismissButton.setY( finalPos.y - dismissOffset - bounds.height() * cornerScale / 2f); - mScreenshotAnimatedView.setScaleX(1); - mScreenshotAnimatedView.setScaleY(1); - mScreenshotAnimatedView.setX(finalPos.x - bounds.width() * cornerScale / 2f); - mScreenshotAnimatedView.setY(finalPos.y - bounds.height() * cornerScale / 2f); - mScreenshotAnimatedView.setVisibility(View.GONE); - mScreenshotPreview.setVisibility(View.VISIBLE); - forceLayout(); + mScreenshotPreview.setScaleX(1); + mScreenshotPreview.setScaleY(1); + mScreenshotPreview.setX(finalPos.x - bounds.width() * cornerScale / 2f); + mScreenshotPreview.setY(finalPos.y - bounds.height() * cornerScale / 2f); + requestLayout(); createScreenshotActionsShadeAnimation().start(); } }); @@ -540,8 +514,6 @@ public class ScreenshotView extends FrameLayout implements void reset() { // Clear any references to the bitmap mScreenshotPreview.setImageDrawable(null); - mScreenshotAnimatedView.setImageDrawable(null); - mScreenshotAnimatedView.setVisibility(View.GONE); mActionsContainerBackground.setVisibility(View.GONE); mActionsContainer.setVisibility(View.GONE); mBackgroundProtection.setAlpha(0f); @@ -568,13 +540,6 @@ public class ScreenshotView extends FrameLayout implements mScreenshotSelectorView.stop(); } - private void setAnimatedViewSize(int width, int height) { - ViewGroup.LayoutParams layoutParams = mScreenshotAnimatedView.getLayoutParams(); - layoutParams.width = width; - layoutParams.height = height; - mScreenshotAnimatedView.setLayoutParams(layoutParams); - } - /** * Create a drawable using the size of the bitmap and insets as the fractional inset parameters. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index dcee9fa9e648..5b3763e66307 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -284,7 +284,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController< default void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, - @BiometricAuthenticator.Modality int biometricModality, + int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, String opPackageName, long operationId) { } default void onBiometricAuthenticated() { } @@ -829,17 +829,18 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController< @Override public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, - @BiometricAuthenticator.Modality int biometricModality, boolean requireConfirmation, + int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, String opPackageName, long operationId) { synchronized (mLock) { SomeArgs args = SomeArgs.obtain(); args.arg1 = promptInfo; args.arg2 = receiver; - args.argi1 = biometricModality; - args.arg3 = requireConfirmation; - args.argi2 = userId; - args.arg4 = opPackageName; - args.arg5 = operationId; + args.arg3 = sensorIds; // + args.arg4 = credentialAllowed; // + args.arg5 = requireConfirmation; + args.argi1 = userId; + args.arg6 = opPackageName; + args.arg7 = operationId; mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args) .sendToTarget(); } @@ -1264,11 +1265,12 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController< mCallbacks.get(i).showAuthenticationDialog( (PromptInfo) someArgs.arg1, (IBiometricSysuiReceiver) someArgs.arg2, - someArgs.argi1 /* biometricModality */, - (boolean) someArgs.arg3 /* requireConfirmation */, - someArgs.argi2 /* userId */, - (String) someArgs.arg4 /* opPackageName */, - (long) someArgs.arg5 /* operationId */); + (int[]) someArgs.arg3 /* sensorIds */, + (boolean) someArgs.arg4 /* credentialAllowed */, + (boolean) someArgs.arg5 /* requireConfirmation */, + someArgs.argi1 /* userId */, + (String) someArgs.arg6 /* opPackageName */, + (long) someArgs.arg7 /* operationId */); } someArgs.recycle(); break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java index 597658276d49..25c8e7feb9b2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java @@ -170,7 +170,7 @@ public class NotificationHeaderUtil { private void sanitizeChild(View child) { if (child != null) { ViewGroup header = child.findViewById( - com.android.internal.R.id.notification_header); + com.android.internal.R.id.notification_top_line); sanitizeHeader(header); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index 53179ba4be90..a92b9e4818b4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -159,7 +159,8 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle for (int i = 0; i < N; i++) { NotificationEntry ent = activeNotifications.get(i); final boolean isBubbleNotificationSuppressedFromShade = mBubblesOptional.isPresent() - && mBubblesOptional.get().isBubbleNotificationSuppressedFromShade(ent); + && mBubblesOptional.get().isBubbleNotificationSuppressedFromShade( + ent.getKey(), ent.getSbn().getGroupKey()); if (ent.isRowDismissed() || ent.isRowRemoved() || isBubbleNotificationSuppressedFromShade || mFgsSectionController.hasEntry(ent)) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt index ddfa18e65ee0..44b9bd26aa38 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt @@ -46,7 +46,7 @@ class ConversationNotificationProcessor @Inject constructor( Notification.MessagingStyle.CONVERSATION_TYPE_IMPORTANT else Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL - entry.ranking.shortcutInfo?.let { shortcutInfo -> + entry.ranking.conversationShortcutInfo?.let { shortcutInfo -> messagingStyle.shortcutIcon = launcherApps.getShortcutIcon(shortcutInfo) shortcutInfo.label?.let { label -> messagingStyle.conversationTitle = label diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java index c301002ef8d0..65e333f14df6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java @@ -47,7 +47,7 @@ public class NotificationChannelHelper { final String pkg = entry.getSbn().getPackageName(); final int appUid = entry.getSbn().getUid(); if (TextUtils.isEmpty(conversationId) || TextUtils.isEmpty(pkg) - || entry.getRanking().getShortcutInfo() == null) { + || entry.getRanking().getConversationShortcutInfo() == null) { return channel; } @@ -68,8 +68,8 @@ public class NotificationChannelHelper { } private static CharSequence getName(NotificationEntry entry) { - if (entry.getRanking().getShortcutInfo().getLabel() != null) { - return entry.getRanking().getShortcutInfo().getLabel().toString(); + if (entry.getRanking().getConversationShortcutInfo().getLabel() != null) { + return entry.getRanking().getConversationShortcutInfo().getLabel().toString(); } Bundle extras = entry.getSbn().getNotification().extras; CharSequence nameString = extras.getCharSequence(Notification.EXTRA_CONVERSATION_TITLE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java index 0455b0f18afc..83a569bd6573 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java @@ -25,6 +25,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor; +import com.android.systemui.wmshell.BubblesManager; import java.util.HashSet; import java.util.Optional; @@ -56,6 +57,7 @@ import javax.inject.Inject; public class BubbleCoordinator implements Coordinator { private static final String TAG = "BubbleCoordinator"; + private final Optional<BubblesManager> mBubblesManagerOptional; private final Optional<Bubbles> mBubblesOptional; private final NotifCollection mNotifCollection; private final Set<String> mInterceptedDismissalEntries = new HashSet<>(); @@ -64,8 +66,10 @@ public class BubbleCoordinator implements Coordinator { @Inject public BubbleCoordinator( + Optional<BubblesManager> bubblesManagerOptional, Optional<Bubbles> bubblesOptional, NotifCollection notifCollection) { + mBubblesManagerOptional = bubblesManagerOptional; mBubblesOptional = bubblesOptional; mNotifCollection = notifCollection; } @@ -75,8 +79,8 @@ public class BubbleCoordinator implements Coordinator { mNotifPipeline = pipeline; mNotifPipeline.addNotificationDismissInterceptor(mDismissInterceptor); mNotifPipeline.addFinalizeFilter(mNotifFilter); - if (mBubblesOptional.isPresent()) { - mBubblesOptional.get().addNotifCallback(mNotifCallback); + if (mBubblesManagerOptional.isPresent()) { + mBubblesManagerOptional.get().addNotifCallback(mNotifCallback); } } @@ -85,7 +89,8 @@ public class BubbleCoordinator implements Coordinator { @Override public boolean shouldFilterOut(NotificationEntry entry, long now) { return mBubblesOptional.isPresent() - && mBubblesOptional.get().isBubbleNotificationSuppressedFromShade(entry); + && mBubblesOptional.get().isBubbleNotificationSuppressedFromShade( + entry.getKey(), entry.getSbn().getGroupKey()); } }; @@ -102,9 +107,8 @@ public class BubbleCoordinator implements Coordinator { @Override public boolean shouldInterceptDismissal(NotificationEntry entry) { - // for experimental bubbles - if (mBubblesOptional.isPresent() - && mBubblesOptional.get().handleDismissalInterception(entry)) { + if (mBubblesManagerOptional.isPresent() + && mBubblesManagerOptional.get().handleDismissalInterception(entry)) { mInterceptedDismissalEntries.add(entry.getKey()); return true; } else { @@ -119,8 +123,7 @@ public class BubbleCoordinator implements Coordinator { } }; - private final BubbleController.NotifCallback mNotifCallback = - new BubbleController.NotifCallback() { + private final BubblesManager.NotifCallback mNotifCallback = new BubblesManager.NotifCallback() { @Override public void removeNotification( NotificationEntry entry, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java index 490989dbb39e..36adfac21bc3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java @@ -64,7 +64,7 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, new ArraySet<>(); private final ArraySet<OnGroupChangeListener> mGroupChangeListeners = new ArraySet<>(); private final Lazy<PeopleNotificationIdentifier> mPeopleNotificationIdentifier; - private final Optional<Lazy<Bubbles>> mBubblesOptional; + private final Optional<Bubbles> mBubblesOptional; private int mBarState = -1; private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>(); private HeadsUpManager mHeadsUpManager; @@ -74,7 +74,7 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, public NotificationGroupManagerLegacy( StatusBarStateController statusBarStateController, Lazy<PeopleNotificationIdentifier> peopleNotificationIdentifier, - Optional<Lazy<Bubbles>> bubblesOptional) { + Optional<Bubbles> bubblesOptional) { statusBarStateController.addCallback(this); mPeopleNotificationIdentifier = peopleNotificationIdentifier; mBubblesOptional = bubblesOptional; @@ -242,8 +242,9 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, int childCount = 0; boolean hasBubbles = false; for (NotificationEntry entry : group.children.values()) { - if (mBubblesOptional.isPresent() && !mBubblesOptional.get().get() - .isBubbleNotificationSuppressedFromShade(entry)) { + if (mBubblesOptional.isPresent() && !mBubblesOptional.get() + .isBubbleNotificationSuppressedFromShade( + entry.getKey(), entry.getSbn().getGroupKey())) { childCount++; } else { hasBubbles = true; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index 4fff99b482d8..ff55cd60ab3b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -26,7 +26,6 @@ import android.view.accessibility.AccessibilityManager; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.R; -import com.android.systemui.bubbles.Bubbles; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; @@ -73,6 +72,7 @@ import com.android.systemui.statusbar.notification.row.PriorityOnboardingDialogC import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.leak.LeakDetector; +import com.android.systemui.wmshell.BubblesManager; import java.util.Optional; import java.util.concurrent.Executor; @@ -133,7 +133,7 @@ public interface NotificationsModule { UserContextProvider contextTracker, Provider<PriorityOnboardingDialogController.Builder> builderProvider, AssistantFeedbackController assistantFeedbackController, - Optional<Bubbles> bubblesOptional, + Optional<BubblesManager> bubblesManagerOptional, UiEventLogger uiEventLogger, OnUserInteractionCallback onUserInteractionCallback) { return new NotificationGutsManager( @@ -150,7 +150,7 @@ public interface NotificationsModule { contextTracker, builderProvider, assistantFeedbackController, - bubblesOptional, + bubblesManagerOptional, uiEventLogger, onUserInteractionCallback); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt index 13f7a53f5e54..ba45f9a687ed 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt @@ -255,7 +255,7 @@ class IconManager @Inject constructor( private fun createPeopleAvatar(entry: NotificationEntry): Icon? { var ic: Icon? = null - val shortcut = entry.ranking.shortcutInfo + val shortcut = entry.ranking.conversationShortcutInfo if (shortcut != null) { ic = launcherApps.getShortcutIcon(shortcut) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt index 99b2fcc9d610..cd9ba4e690e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt @@ -220,7 +220,7 @@ class PeopleHubDataSourceImpl @Inject constructor( } val clickRunnable = Runnable { notificationListener.unsnoozeNotification(key) } val extras = sbn.notification.extras - val name = ranking.shortcutInfo?.label + val name = ranking.conversationShortcutInfo?.label ?: extras.getCharSequence(Notification.EXTRA_CONVERSATION_TITLE) ?: extras.getCharSequence(Notification.EXTRA_TITLE) ?: return null @@ -238,9 +238,9 @@ class PeopleHubDataSourceImpl @Inject constructor( iconFactory: ConversationIconFactory, sbn: StatusBarNotification ): Drawable? = - shortcutInfo?.let { shortcutInfo -> + conversationShortcutInfo?.let { conversationShortcutInfo -> iconFactory.getConversationDrawable( - shortcutInfo, + conversationShortcutInfo, sbn.packageName, sbn.uid, channel.isImportantConversation diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt index 0d92616767f3..691f1f452da8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt @@ -103,7 +103,7 @@ class PeopleNotificationIdentifierImpl @Inject constructor( private val Ranking.personTypeInfo get() = when { !isConversation -> TYPE_NON_PERSON - shortcutInfo == null -> TYPE_PERSON + conversationShortcutInfo == null -> TYPE_PERSON channel?.isImportantConversation == true -> TYPE_IMPORTANT_PERSON else -> TYPE_FULL_PERSON } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 5ee66fabe55a..280c525f41cf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -72,7 +72,6 @@ import com.android.internal.widget.CachingIconView; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.bubbles.Bubbles; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; @@ -102,12 +101,14 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAndActions; +import com.android.systemui.wmshell.BubblesManager; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.function.BooleanSupplier; import java.util.function.Consumer; @@ -147,6 +148,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private LayoutListener mLayoutListener; private RowContentBindStage mRowContentBindStage; private PeopleNotificationIdentifier mPeopleNotificationIdentifier; + private Optional<BubblesManager> mBubblesManagerOptional; private int mIconTransformContentShift; private int mMaxHeadsUpHeightBeforeN; private int mMaxHeadsUpHeightBeforeP; @@ -1078,13 +1080,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView /** The click listener for the bubble button. */ public View.OnClickListener getBubbleClickListener() { - return new View.OnClickListener() { - @Override - public void onClick(View v) { - Dependency.get(Bubbles.class) - .onUserChangedBubble(mEntry, !mEntry.isBubble() /* createBubble */); - mHeadsUpManager.removeNotification(mEntry.getKey(), true /* releaseImmediately */); + return v -> { + if (mBubblesManagerOptional.isPresent()) { + mBubblesManagerOptional.get() + .onUserChangedBubble(mEntry, !mEntry.isBubble() /* createBubble */); } + mHeadsUpManager.removeNotification(mEntry.getKey(), true /* releaseImmediately */); }; } @@ -1553,7 +1554,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView FalsingManager falsingManager, StatusBarStateController statusBarStateController, PeopleNotificationIdentifier peopleNotificationIdentifier, - OnUserInteractionCallback onUserInteractionCallback) { + OnUserInteractionCallback onUserInteractionCallback, + Optional<BubblesManager> bubblesManagerOptional) { mEntry = entry; mAppName = appName; if (mMenuRow == null) { @@ -1581,6 +1583,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView l.setPeopleNotificationIdentifier(mPeopleNotificationIdentifier); } mOnUserInteractionCallback = onUserInteractionCallback; + mBubblesManagerOptional = bubblesManagerOptional; cacheIsSystemNotification(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index c995e324ecfe..05b1dba36a7b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -43,8 +43,10 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.time.SystemClock; +import com.android.systemui.wmshell.BubblesManager; import java.util.List; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Named; @@ -79,6 +81,7 @@ public class ExpandableNotificationRowController implements NodeController { private final FalsingManager mFalsingManager; private final boolean mAllowLongPress; private final PeopleNotificationIdentifier mPeopleNotificationIdentifier; + private final Optional<BubblesManager> mBubblesManagerOptional; @Inject public ExpandableNotificationRowController( @@ -102,7 +105,8 @@ public class ExpandableNotificationRowController implements NodeController { @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress, OnUserInteractionCallback onUserInteractionCallback, FalsingManager falsingManager, - PeopleNotificationIdentifier peopleNotificationIdentifier) { + PeopleNotificationIdentifier peopleNotificationIdentifier, + Optional<BubblesManager> bubblesManagerOptional) { mView = view; mListContainer = listContainer; mActivatableNotificationViewController = activatableNotificationViewController; @@ -125,6 +129,7 @@ public class ExpandableNotificationRowController implements NodeController { mAllowLongPress = allowLongPress; mFalsingManager = falsingManager; mPeopleNotificationIdentifier = peopleNotificationIdentifier; + mBubblesManagerOptional = bubblesManagerOptional; } /** @@ -148,8 +153,8 @@ public class ExpandableNotificationRowController implements NodeController { mFalsingManager, mStatusBarStateController, mPeopleNotificationIdentifier, - mOnUserInteractionCallback - + mOnUserInteractionCallback, + mBubblesManagerOptional ); mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); if (mAllowLongPress) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java index 07a4a188bc48..e43130f1698b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java @@ -67,12 +67,12 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.notification.ConversationIconFactory; import com.android.systemui.Prefs; import com.android.systemui.R; -import com.android.systemui.bubbles.Bubbles; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.notification.NotificationChannelHelper; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; +import com.android.systemui.wmshell.BubblesManager; import java.lang.annotation.Retention; import java.util.Optional; @@ -94,7 +94,7 @@ public class NotificationConversationInfo extends LinearLayout implements private OnUserInteractionCallback mOnUserInteractionCallback; private Handler mMainHandler; private Handler mBgHandler; - private Optional<Bubbles> mBubblesOptional; + private Optional<BubblesManager> mBubblesManagerOptional; private String mPackageName; private String mAppName; private int mAppUid; @@ -223,7 +223,7 @@ public class NotificationConversationInfo extends LinearLayout implements @Main Handler mainHandler, @Background Handler bgHandler, OnConversationSettingsClickListener onConversationSettingsClickListener, - Optional<Bubbles> bubblesOptional) { + Optional<BubblesManager> bubblesManagerOptional) { mSelectedAction = -1; mINotificationManager = iNotificationManager; mOnUserInteractionCallback = onUserInteractionCallback; @@ -242,12 +242,12 @@ public class NotificationConversationInfo extends LinearLayout implements mIconFactory = conversationIconFactory; mUserContext = userContext; mBubbleMetadata = bubbleMetadata; - mBubblesOptional = bubblesOptional; + mBubblesManagerOptional = bubblesManagerOptional; mBuilderProvider = builderProvider; mMainHandler = mainHandler; mBgHandler = bgHandler; mShortcutManager = shortcutManager; - mShortcutInfo = entry.getRanking().getShortcutInfo(); + mShortcutInfo = entry.getRanking().getConversationShortcutInfo(); if (mShortcutInfo == null) { throw new IllegalArgumentException("Does not have required information"); } @@ -641,9 +641,9 @@ public class NotificationConversationInfo extends LinearLayout implements mINotificationManager.setBubblesAllowed(mAppPkg, mAppUid, BUBBLE_PREFERENCE_SELECTED); } - if (mBubblesOptional.isPresent()) { + if (mBubblesManagerOptional.isPresent()) { post(() -> { - mBubblesOptional.get().onUserChangedImportance(mEntry); + mBubblesManagerOptional.get().onUserChangedImportance(mEntry); }); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 373f20e6ba96..d2cfb2908e9c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -47,7 +47,6 @@ import com.android.settingslib.notification.ConversationIconFactory; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.R; -import com.android.systemui.bubbles.Bubbles; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; @@ -67,6 +66,7 @@ import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSav import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.wmshell.BubblesManager; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -117,7 +117,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx private final Lazy<StatusBar> mStatusBarLazy; private final Handler mMainHandler; private final Handler mBgHandler; - private final Optional<Bubbles> mBubblesOptional; + private final Optional<BubblesManager> mBubblesManagerOptional; private Runnable mOpenRunnable; private final INotificationManager mNotificationManager; private final LauncherApps mLauncherApps; @@ -142,7 +142,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx UserContextProvider contextTracker, Provider<PriorityOnboardingDialogController.Builder> builderProvider, AssistantFeedbackController assistantFeedbackController, - Optional<Bubbles> bubblesOptional, + Optional<BubblesManager> bubblesManagerOptional, UiEventLogger uiEventLogger, OnUserInteractionCallback onUserInteractionCallback) { mContext = context; @@ -158,7 +158,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mBuilderProvider = builderProvider; mChannelEditorDialogController = channelEditorDialogController; mAssistantFeedbackController = assistantFeedbackController; - mBubblesOptional = bubblesOptional; + mBubblesManagerOptional = bubblesManagerOptional; mUiEventLogger = uiEventLogger; mOnUserInteractionCallback = onUserInteractionCallback; } @@ -491,7 +491,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mMainHandler, mBgHandler, onConversationSettingsListener, - mBubblesOptional); + mBubblesManagerOptional); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index e065b47ef5b1..f2ae3da73f5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -306,7 +306,8 @@ public class NotificationIconAreaController implements || !entry.isPulseSuppressed())) { return false; } - if (mBubblesOptional.isPresent() && mBubblesOptional.get().isBubbleExpanded(entry)) { + if (mBubblesOptional.isPresent() + && mBubblesOptional.get().isBubbleExpanded(entry.getKey())) { return false; } return true; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 6ed092f33d95..d53724159244 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -50,6 +50,7 @@ import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.privacy.PrivacyItem; import com.android.systemui.privacy.PrivacyItemController; import com.android.systemui.privacy.PrivacyType; +import com.android.systemui.privacy.logging.PrivacyLogger; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.screenrecord.RecordingController; @@ -145,6 +146,7 @@ public class PhoneStatusBarPolicy private final SensorPrivacyController mSensorPrivacyController; private final RecordingController mRecordingController; private final RingerModeTracker mRingerModeTracker; + private final PrivacyLogger mPrivacyLogger; private boolean mZenVisible; private boolean mVolumeVisible; @@ -172,7 +174,8 @@ public class PhoneStatusBarPolicy @Nullable TelecomManager telecomManager, @DisplayId int displayId, @Main SharedPreferences sharedPreferences, DateFormatUtil dateFormatUtil, RingerModeTracker ringerModeTracker, - PrivacyItemController privacyItemController) { + PrivacyItemController privacyItemController, + PrivacyLogger privacyLogger) { mIconController = iconController; mCommandQueue = commandQueue; mBroadcastDispatcher = broadcastDispatcher; @@ -197,6 +200,7 @@ public class PhoneStatusBarPolicy mUiBgExecutor = uiBgExecutor; mTelecomManager = telecomManager; mRingerModeTracker = ringerModeTracker; + mPrivacyLogger = privacyLogger; mSlotCast = resources.getString(com.android.internal.R.string.status_bar_cast); mSlotHotspot = resources.getString(com.android.internal.R.string.status_bar_hotspot); @@ -675,6 +679,7 @@ public class PhoneStatusBarPolicy || mPrivacyItemController.getLocationAvailable()) { mIconController.setIconVisibility(mSlotLocation, showLocation); } + mPrivacyLogger.logStatusBarIconsVisible(showCamera, showMicrophone, showLocation); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 9bd98f2e8c24..a8d41046a1eb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -144,7 +144,6 @@ import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; -import com.android.systemui.bubbles.BubbleController; import com.android.systemui.bubbles.Bubbles; import com.android.systemui.charging.WirelessChargingAnimation; import com.android.systemui.classifier.FalsingLog; @@ -229,6 +228,7 @@ import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.statusbar.policy.UserInfoControllerImpl; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.volume.VolumeComponent; +import com.android.systemui.wmshell.BubblesManager; import com.android.wm.shell.splitscreen.SplitScreen; import java.io.FileDescriptor; @@ -648,8 +648,9 @@ public class StatusBar extends SystemUI implements DemoMode, protected StatusBarNotificationPresenter mPresenter; private NotificationActivityStarter mNotificationActivityStarter; private Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy; + private final Optional<BubblesManager> mBubblesManagerOptional; private final Optional<Bubbles> mBubblesOptional; - private final BubbleController.BubbleExpandListener mBubbleExpandListener; + private final Bubbles.BubbleExpandListener mBubbleExpandListener; private ActivityIntentHelper mActivityIntentHelper; private NotificationStackScrollLayoutController mStackScrollerController; @@ -697,6 +698,7 @@ public class StatusBar extends SystemUI implements DemoMode, WakefulnessLifecycle wakefulnessLifecycle, SysuiStatusBarStateController statusBarStateController, VibratorHelper vibratorHelper, + Optional<BubblesManager> bubblesManagerOptional, Optional<Bubbles> bubblesOptional, VisualStabilityManager visualStabilityManager, DeviceProvisionedController deviceProvisionedController, @@ -776,6 +778,7 @@ public class StatusBar extends SystemUI implements DemoMode, mWakefulnessLifecycle = wakefulnessLifecycle; mStatusBarStateController = statusBarStateController; mVibratorHelper = vibratorHelper; + mBubblesManagerOptional = bubblesManagerOptional; mBubblesOptional = bubblesOptional; mVisualStabilityManager = visualStabilityManager; mDeviceProvisionedController = deviceProvisionedController; @@ -1141,8 +1144,8 @@ public class StatusBar extends SystemUI implements DemoMode, ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind); ScrimView scrimInFront = mNotificationShadeWindowView.findViewById(R.id.scrim_in_front); - ScrimView scrimForBubble = mBubblesOptional.isPresent() - ? mBubblesOptional.get().getScrimForBubble() : null; + ScrimView scrimForBubble = mBubblesManagerOptional.isPresent() + ? mBubblesManagerOptional.get().getScrimForBubble() : null; mScrimController.setScrimVisibleListener(scrimsVisible -> { mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index 256ee2081f41..acca953629c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -48,7 +48,6 @@ import com.android.internal.widget.LockPatternUtils; import com.android.systemui.ActivityIntentHelper; import com.android.systemui.EventLogTags; import com.android.systemui.assist.AssistManager; -import com.android.systemui.bubbles.Bubbles; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; @@ -76,6 +75,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback; import com.android.systemui.statusbar.policy.HeadsUpUtil; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.wmshell.BubblesManager; import java.util.Optional; import java.util.concurrent.Executor; @@ -104,7 +104,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final KeyguardManager mKeyguardManager; private final IDreamManager mDreamManager; - private final Optional<Bubbles> mBubblesOptional; + private final Optional<BubblesManager> mBubblesManagerOptional; private final Lazy<AssistManager> mAssistManagerLazy; private final NotificationRemoteInputManager mRemoteInputManager; private final GroupMembershipManager mGroupMembershipManager; @@ -142,7 +142,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit StatusBarKeyguardViewManager statusBarKeyguardViewManager, KeyguardManager keyguardManager, IDreamManager dreamManager, - Optional<Bubbles> bubblesOptional, + Optional<BubblesManager> bubblesManagerOptional, Lazy<AssistManager> assistManagerLazy, NotificationRemoteInputManager remoteInputManager, GroupMembershipManager groupMembershipManager, @@ -176,7 +176,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mKeyguardManager = keyguardManager; mDreamManager = dreamManager; - mBubblesOptional = bubblesOptional; + mBubblesManagerOptional = bubblesManagerOptional; mAssistManagerLazy = assistManagerLazy; mRemoteInputManager = remoteInputManager; mGroupMembershipManager = groupMembershipManager; @@ -360,15 +360,11 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit collapseOnMainThread(); } - final int count = getVisibleNotificationsCount(); - final int rank = entry.getRanking().getRank(); NotificationVisibility.NotificationLocation location = NotificationLogger.getNotificationLocation(entry); - final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey, - rank, count, true, location); + final NotificationVisibility nv = NotificationVisibility.obtain(entry.getKey(), + entry.getRanking().getRank(), getVisibleNotificationsCount(), true, location); - // NMS will officially remove notification if the notification has FLAG_AUTO_CANCEL: - mClickNotifier.onNotificationClick(notificationKey, nv); // TODO (b/162832756): delete these notification removals when migrating to the new // pipeline; this is taken care of in {@link NotifCollection#tryRemoveNotification} @@ -378,23 +374,40 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit if (shouldAutoCancel(entry.getSbn()) || mRemoteInputManager.isNotificationKeptForRemoteInputHistory( notificationKey)) { - // manually call notification removal in order to cancel any lifetime extenders - removeNotification(row.getEntry()); + // Immediately remove notification from visually showing. + // We have to post the removal to the UI thread for synchronization. + mMainThreadHandler.post(() -> { + final Runnable removeNotification = () -> { + mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK); + mClickNotifier.onNotificationClick(entry.getKey(), nv); + }; + if (mPresenter.isCollapsing()) { + // To avoid lags we're only performing the remove + // after the shade is collapsed + mShadeController.addPostCollapseAction(removeNotification); + } else { + removeNotification.run(); + } + }); } + } else { + // inform NMS that the notification was clicked + mClickNotifier.onNotificationClick(notificationKey, nv); } mIsCollapsingToShowActivityOverLockscreen = false; } private void expandBubbleStackOnMainThread(NotificationEntry entry) { - if (!mBubblesOptional.isPresent()) { + if (!mBubblesManagerOptional.isPresent()) { return; } if (Looper.getMainLooper().isCurrentThread()) { - mBubblesOptional.get().expandStackAndSelectBubble(entry); + mBubblesManagerOptional.get().expandStackAndSelectBubble(entry); } else { - mMainThreadHandler.post(() -> mBubblesOptional.get().expandStackAndSelectBubble(entry)); + mMainThreadHandler.post( + () -> mBubblesManagerOptional.get().expandStackAndSelectBubble(entry)); } } @@ -565,21 +578,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit return entry.shouldSuppressFullScreenIntent(); } - private void removeNotification(NotificationEntry entry) { - // We have to post it to the UI thread for synchronization - mMainThreadHandler.post(() -> { - if (mPresenter.isCollapsing()) { - // To avoid lags we're only performing the remove - // after the shade was collapsed - mShadeController.addPostCollapseAction( - () -> mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK) - ); - } else { - mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK); - } - }); - } - // --------------------- NotificationEntryManager/NotifPipeline methods ------------------------ private int getVisibleNotificationsCount() { @@ -609,7 +607,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final KeyguardManager mKeyguardManager; private final IDreamManager mDreamManager; - private final Optional<Bubbles> mBubblesOptional; + private final Optional<BubblesManager> mBubblesManagerOptional; private final Lazy<AssistManager> mAssistManagerLazy; private final NotificationRemoteInputManager mRemoteInputManager; private final GroupMembershipManager mGroupMembershipManager; @@ -646,7 +644,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit StatusBarKeyguardViewManager statusBarKeyguardViewManager, KeyguardManager keyguardManager, IDreamManager dreamManager, - Optional<Bubbles> bubblesOptional, + Optional<BubblesManager> bubblesManager, Lazy<AssistManager> assistManagerLazy, NotificationRemoteInputManager remoteInputManager, GroupMembershipManager groupMembershipManager, @@ -676,7 +674,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mKeyguardManager = keyguardManager; mDreamManager = dreamManager; - mBubblesOptional = bubblesOptional; + mBubblesManagerOptional = bubblesManager; mAssistManagerLazy = assistManagerLazy; mRemoteInputManager = remoteInputManager; mGroupMembershipManager = groupMembershipManager; @@ -732,7 +730,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mStatusBarKeyguardViewManager, mKeyguardManager, mDreamManager, - mBubblesOptional, + mBubblesManagerOptional, mAssistManagerLazy, mRemoteInputManager, mGroupMembershipManager, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java index 6d4099b656cb..b69da859b3c8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java @@ -97,6 +97,7 @@ import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; import com.android.systemui.statusbar.policy.UserInfoControllerImpl; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.volume.VolumeComponent; +import com.android.systemui.wmshell.BubblesManager; import com.android.wm.shell.splitscreen.SplitScreen; import java.util.Optional; @@ -155,6 +156,7 @@ public interface StatusBarPhoneModule { WakefulnessLifecycle wakefulnessLifecycle, SysuiStatusBarStateController statusBarStateController, VibratorHelper vibratorHelper, + Optional<BubblesManager> bubblesManagerOptional, Optional<Bubbles> bubblesOptional, VisualStabilityManager visualStabilityManager, DeviceProvisionedController deviceProvisionedController, @@ -233,6 +235,7 @@ public interface StatusBarPhoneModule { wakefulnessLifecycle, statusBarStateController, vibratorHelper, + bubblesManagerOptional, bubblesOptional, visualStabilityManager, deviceProvisionedController, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index c84589a9e142..4552026ced4b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -73,9 +73,7 @@ import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewW import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.LightBarController; -import java.util.Collections; import java.util.HashMap; -import java.util.Set; import java.util.function.Consumer; /** @@ -315,7 +313,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mRemoteInputs = remoteInputs; mRemoteInput = remoteInput; mEditText.setHint(mRemoteInput.getLabel()); - mEditText.mSupportedMimeTypes = remoteInput.getAllowedDataTypes(); + mEditText.mSupportedMimeTypes = (remoteInput.getAllowedDataTypes() == null) ? null + : remoteInput.getAllowedDataTypes().toArray(new String[0]); mEntry.editedSuggestionInfo = editedSuggestionInfo; if (editedSuggestionInfo != null) { @@ -574,7 +573,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene boolean mShowImeOnInputConnection; private LightBarController mLightBarController; UserHandle mUser; - private Set<String> mSupportedMimeTypes; + private String[] mSupportedMimeTypes; public RemoteEditText(Context context, AttributeSet attrs) { super(context, attrs); @@ -585,35 +584,31 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override protected void onFinishInflate() { super.onFinishInflate(); - setOnReceiveContentCallback(new OnReceiveContentCallback<View>() { - @Override - public boolean onReceiveContent(@NonNull View view, @NonNull Payload payload) { - ClipData clip = payload.getClip(); - if (clip.getItemCount() == 0) { - return false; - } - Uri contentUri = clip.getItemAt(0).getUri(); - ClipDescription description = clip.getDescription(); - String mimeType = null; - if (description.getMimeTypeCount() > 0) { - mimeType = description.getMimeType(0); - } - if (mimeType != null) { - Intent dataIntent = mRemoteInputView - .prepareRemoteInputFromData(mimeType, contentUri); - mRemoteInputView.sendRemoteInput(dataIntent); - } - return true; - } - - @NonNull - @Override - public Set<String> getSupportedMimeTypes(@NonNull View view) { - return mSupportedMimeTypes != null - ? mSupportedMimeTypes - : Collections.emptySet(); - } - }); + if (mSupportedMimeTypes != null && mSupportedMimeTypes.length > 0) { + setOnReceiveContentCallback(mSupportedMimeTypes, + new OnReceiveContentCallback<View>() { + @Override + public boolean onReceiveContent(@NonNull View view, + @NonNull Payload payload) { + ClipData clip = payload.getClip(); + if (clip.getItemCount() == 0) { + return false; + } + Uri contentUri = clip.getItemAt(0).getUri(); + ClipDescription description = clip.getDescription(); + String mimeType = null; + if (description.getMimeTypeCount() > 0) { + mimeType = description.getMimeType(0); + } + if (mimeType != null) { + Intent dataIntent = mRemoteInputView + .prepareRemoteInputFromData(mimeType, contentUri); + mRemoteInputView.sendRemoteInput(dataIntent); + } + return true; + } + }); + } } private void defocusIfNeeded(boolean animate) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java index 79d264ca4577..e8331a176134 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java @@ -15,6 +15,9 @@ */ package com.android.systemui.statusbar.policy; +import android.app.admin.DeviceAdminInfo; +import android.graphics.drawable.Drawable; + import com.android.systemui.Dumpable; import com.android.systemui.statusbar.policy.SecurityController.SecurityControllerCallback; @@ -40,6 +43,15 @@ public interface SecurityController extends CallbackController<SecurityControlle boolean hasCACertInCurrentUser(); boolean hasCACertInWorkProfile(); void onUserSwitched(int newUserId); + /** Whether or not parental controls is enabled */ + boolean isParentalControlsEnabled(); + /** DeviceAdminInfo for active admin */ + DeviceAdminInfo getDeviceAdminInfo(); + /** Icon for admin */ + Drawable getIcon(DeviceAdminInfo info); + /** Label for admin */ + CharSequence getLabel(DeviceAdminInfo info); + public interface SecurityControllerCallback { void onStateChanged(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java index 7e54e8d1c1c3..1d778419cbaf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java @@ -16,15 +16,19 @@ package com.android.systemui.statusbar.policy; import android.app.ActivityManager; +import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; +import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.IConnectivityManager; @@ -53,7 +57,10 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.settings.CurrentUserTracker; +import org.xmlpull.v1.XmlPullParserException; + import java.io.FileDescriptor; +import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.concurrent.Executor; @@ -306,6 +313,50 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi fireCallbacks(); } + @Override + public boolean isParentalControlsEnabled() { + return getProfileOwnerOrDeviceOwnerSupervisionComponent() != null; + } + + @Override + public DeviceAdminInfo getDeviceAdminInfo() { + return getDeviceAdminInfo(getProfileOwnerOrDeviceOwnerComponent()); + } + + @Override + public Drawable getIcon(DeviceAdminInfo info) { + return (info == null) ? null : info.loadIcon(mPackageManager); + } + + @Override + public CharSequence getLabel(DeviceAdminInfo info) { + return (info == null) ? null : info.loadLabel(mPackageManager); + } + + private ComponentName getProfileOwnerOrDeviceOwnerSupervisionComponent() { + UserHandle currentUser = new UserHandle(mCurrentUserId); + return mDevicePolicyManager + .getProfileOwnerOrDeviceOwnerSupervisionComponent(currentUser); + } + + // Returns the ComponentName of the current DO/PO. Right now it only checks the supervision + // component but can be changed to check for other DO/POs. This change would make getIcon() + // and getLabel() work for all admins. + private ComponentName getProfileOwnerOrDeviceOwnerComponent() { + return getProfileOwnerOrDeviceOwnerSupervisionComponent(); + } + + private DeviceAdminInfo getDeviceAdminInfo(ComponentName componentName) { + try { + ResolveInfo resolveInfo = new ResolveInfo(); + resolveInfo.activityInfo = mPackageManager.getReceiverInfo(componentName, + PackageManager.GET_META_DATA); + return new DeviceAdminInfo(mContext, resolveInfo); + } catch (NameNotFoundException | XmlPullParserException | IOException e) { + return null; + } + } + private void refreshCACerts(int userId) { mBgExecutor.execute(() -> { Pair<Integer, Boolean> idWithCert = null; diff --git a/packages/SystemUI/src/com/android/systemui/toast/ToastUI.java b/packages/SystemUI/src/com/android/systemui/toast/ToastUI.java index 1c682e3bb7dc..409d1361223c 100644 --- a/packages/SystemUI/src/com/android/systemui/toast/ToastUI.java +++ b/packages/SystemUI/src/com/android/systemui/toast/ToastUI.java @@ -129,6 +129,8 @@ public class ToastUI extends SystemUI implements CommandQueue.Callbacks { mCallback = callback; mPresenter = new ToastPresenter(context, mIAccessibilityManager, mNotificationManager, packageName); + // Set as trusted overlay so touches can pass through toasts + mPresenter.getLayoutParams().setTrustedOverlay(); mToastLogger.logOnShowToast(uid, packageName, text.toString(), token.toString()); mPresenter.show(mToast.getView(), token, windowToken, duration, mToast.getGravity(), mToast.getXOffset(), mToast.getYOffset(), mToast.getHorizontalMargin(), diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java new file mode 100644 index 000000000000..ad596c27ba97 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java @@ -0,0 +1,725 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.wmshell; + +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; +import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; +import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL; +import static android.service.notification.NotificationListenerService.REASON_CANCEL; +import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL; +import static android.service.notification.NotificationListenerService.REASON_CLICK; +import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; +import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE; +import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; + +import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; +import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.systemui.statusbar.StatusBarState.SHADE; +import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON; + +import android.app.INotificationManager; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.content.res.Configuration; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.service.notification.NotificationListenerService.RankingMap; +import android.service.notification.ZenModeConfig; +import android.util.ArraySet; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.NotificationVisibility; +import com.android.systemui.Dumpable; +import com.android.systemui.bubbles.BubbleEntry; +import com.android.systemui.bubbles.Bubbles; +import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dump.DumpManager; +import com.android.systemui.model.SysUiState; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shared.system.QuickStepContract; +import com.android.systemui.statusbar.FeatureFlags; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationShadeWindowController; +import com.android.systemui.statusbar.ScrimView; +import com.android.systemui.statusbar.notification.NotificationChannelHelper; +import com.android.systemui.statusbar.notification.NotificationEntryListener; +import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.collection.NotifCollection; +import com.android.systemui.statusbar.notification.collection.NotifPipeline; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.coordinator.BubbleCoordinator; +import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; +import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; +import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; +import com.android.systemui.statusbar.notification.logging.NotificationLogger; +import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.ZenModeController; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.IntConsumer; + +/** + * The SysUi side bubbles manager which communicate with other SysUi components. + */ +@SysUISingleton +public class BubblesManager implements Dumpable { + + private static final String TAG = TAG_WITH_CLASS_NAME ? "BubblesManager" : TAG_BUBBLES; + + private final Context mContext; + private final Bubbles mBubbles; + private final NotificationShadeWindowController mNotificationShadeWindowController; + private final ShadeController mShadeController; + private final IStatusBarService mBarService; + private final INotificationManager mNotificationManager; + private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; + private final NotificationGroupManagerLegacy mNotificationGroupManager; + private final NotificationEntryManager mNotificationEntryManager; + private final NotifPipeline mNotifPipeline; + + private final ScrimView mBubbleScrim; + private final Bubbles.SysuiProxy mSysuiProxy; + // TODO (b/145659174): allow for multiple callbacks to support the "shadow" new notif pipeline + private final List<NotifCallback> mCallbacks = new ArrayList<>(); + + /** + * Creates {@link BubblesManager}, returns {@code null} if Optional {@link Bubbles} not present + * which means bubbles feature not support. + */ + @Nullable + public static BubblesManager create(Context context, + Optional<Bubbles> bubblesOptional, + NotificationShadeWindowController notificationShadeWindowController, + StatusBarStateController statusBarStateController, + ShadeController shadeController, + ConfigurationController configurationController, + @Nullable IStatusBarService statusBarService, + INotificationManager notificationManager, + NotificationInterruptStateProvider interruptionStateProvider, + ZenModeController zenModeController, + NotificationLockscreenUserManager notifUserManager, + NotificationGroupManagerLegacy groupManager, + NotificationEntryManager entryManager, + NotifPipeline notifPipeline, + SysUiState sysUiState, + FeatureFlags featureFlags, + DumpManager dumpManager) { + if (bubblesOptional.isPresent()) { + return new BubblesManager(context, bubblesOptional.get(), + notificationShadeWindowController, statusBarStateController, shadeController, + configurationController, statusBarService, notificationManager, + interruptionStateProvider, zenModeController, notifUserManager, + groupManager, entryManager, notifPipeline, sysUiState, featureFlags, + dumpManager); + } else { + return null; + } + } + + @VisibleForTesting + BubblesManager(Context context, + Bubbles bubbles, + NotificationShadeWindowController notificationShadeWindowController, + StatusBarStateController statusBarStateController, + ShadeController shadeController, + ConfigurationController configurationController, + @Nullable IStatusBarService statusBarService, + INotificationManager notificationManager, + NotificationInterruptStateProvider interruptionStateProvider, + ZenModeController zenModeController, + NotificationLockscreenUserManager notifUserManager, + NotificationGroupManagerLegacy groupManager, + NotificationEntryManager entryManager, + NotifPipeline notifPipeline, + SysUiState sysUiState, + FeatureFlags featureFlags, + DumpManager dumpManager) { + mContext = context; + mBubbles = bubbles; + mNotificationShadeWindowController = notificationShadeWindowController; + mShadeController = shadeController; + mNotificationManager = notificationManager; + mNotificationInterruptStateProvider = interruptionStateProvider; + mNotificationGroupManager = groupManager; + mNotificationEntryManager = entryManager; + mNotifPipeline = notifPipeline; + + mBarService = statusBarService == null + ? IStatusBarService.Stub.asInterface( + ServiceManager.getService(Context.STATUS_BAR_SERVICE)) + : statusBarService; + + mBubbleScrim = new ScrimView(mContext); + mBubbleScrim.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + mBubbles.setBubbleScrim(mBubbleScrim); + + if (featureFlags.isNewNotifPipelineRenderingEnabled()) { + setupNotifPipeline(); + } else { + setupNEM(); + } + + dumpManager.registerDumpable(TAG, this); + + statusBarStateController.addCallback(new StatusBarStateController.StateListener() { + @Override + public void onStateChanged(int newState) { + boolean isShade = newState == SHADE; + bubbles.onStatusBarStateChanged(isShade); + } + }); + + configurationController.addCallback(new ConfigurationController.ConfigurationListener() { + @Override + public void onConfigChanged(Configuration newConfig) { + mBubbles.onConfigChanged(newConfig); + } + + @Override + public void onUiModeChanged() { + mBubbles.updateForThemeChanges(); + } + + @Override + public void onThemeChanged() { + mBubbles.updateForThemeChanges(); + } + }); + + zenModeController.addCallback(new ZenModeController.Callback() { + @Override + public void onZenChanged(int zen) { + mBubbles.onZenStateChanged(); + } + + @Override + public void onConfigChanged(ZenModeConfig config) { + mBubbles.onZenStateChanged(); + } + }); + + notifUserManager.addUserChangedListener( + new NotificationLockscreenUserManager.UserChangedListener() { + @Override + public void onUserChanged(int userId) { + mBubbles.onUserChanged(userId); + } + }); + + mSysuiProxy = new Bubbles.SysuiProxy() { + @Override + @Nullable + public BubbleEntry getPendingOrActiveEntry(String key) { + NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(key); + return entry == null ? null : notifToBubbleEntry(entry); + } + + @Override + public List<BubbleEntry> getShouldRestoredEntries(ArraySet<String> savedBubbleKeys) { + List<BubbleEntry> result = new ArrayList<>(); + List<NotificationEntry> activeEntries = + mNotificationEntryManager.getActiveNotificationsForCurrentUser(); + for (int i = 0; i < activeEntries.size(); i++) { + NotificationEntry entry = activeEntries.get(i); + if (savedBubbleKeys.contains(entry.getKey()) + && mNotificationInterruptStateProvider.shouldBubbleUp(entry) + && entry.isBubble()) { + result.add(notifToBubbleEntry(entry)); + } + } + return result; + } + + @Override + public boolean isNotificationShadeExpand() { + return mNotificationShadeWindowController.getPanelExpanded(); + } + + @Override + public boolean shouldBubbleUp(String key) { + final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( + key); + if (entry != null) { + return mNotificationInterruptStateProvider.shouldBubbleUp(entry); + } + return false; + } + + @Override + public void setNotificationInterruption(String key) { + final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( + key); + if (entry != null && entry.getImportance() >= NotificationManager.IMPORTANCE_HIGH) { + entry.setInterruption(); + } + } + + @Override + public void requestNotificationShadeTopUi(boolean requestTopUi, String componentTag) { + mNotificationShadeWindowController.setRequestTopUi(requestTopUi, componentTag); + } + + @Override + public void notifyRemoveNotification(String key, int reason) { + final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( + key); + if (entry != null) { + for (NotifCallback cb : mCallbacks) { + cb.removeNotification(entry, getDismissedByUserStats(entry, true), reason); + } + } + } + + @Override + public void notifyInvalidateNotifications(String reason) { + for (NotifCallback cb : mCallbacks) { + cb.invalidateNotifications(reason); + } + } + + @Override + public void notifyMaybeCancelSummary(String key) { + final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( + key); + if (entry != null) { + for (NotifCallback cb : mCallbacks) { + cb.maybeCancelSummary(entry); + } + } + } + + @Override + public void removeNotificationEntry(String key) { + final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( + key); + if (entry != null) { + mNotificationGroupManager.onEntryRemoved(entry); + } + } + + @Override + public void updateNotificationBubbleButton(String key) { + final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( + key); + if (entry != null && entry.getRow() != null) { + entry.getRow().updateBubbleButton(); + } + } + + @Override + public void updateNotificationSuppression(String key) { + final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( + key); + if (entry != null) { + mNotificationGroupManager.updateSuppression(entry); + } + } + + @Override + public void onStackExpandChanged(boolean shouldExpand) { + sysUiState + .setFlag(QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED, shouldExpand) + .commitUpdate(mContext.getDisplayId()); + } + + @Override + public void onUnbubbleConversation(String key) { + final NotificationEntry entry = + mNotificationEntryManager.getPendingOrActiveNotif(key); + if (entry != null) { + onUserChangedBubble(entry, false /* shouldBubble */); + } + } + }; + mBubbles.setSysuiProxy(mSysuiProxy); + } + + private void setupNEM() { + mNotificationEntryManager.addNotificationEntryListener( + new NotificationEntryListener() { + @Override + public void onPendingEntryAdded(NotificationEntry entry) { + BubblesManager.this.onEntryAdded(entry); + } + + @Override + public void onPreEntryUpdated(NotificationEntry entry) { + BubblesManager.this.onEntryUpdated(entry); + } + + @Override + public void onEntryRemoved(NotificationEntry entry, + @Nullable NotificationVisibility visibility, + boolean removedByUser, int reason) { + BubblesManager.this.onEntryRemoved(entry); + } + + @Override + public void onNotificationRankingUpdated(RankingMap rankingMap) { + BubblesManager.this.onRankingUpdate(rankingMap); + } + }); + + // The new pipeline takes care of this as a NotifDismissInterceptor BubbleCoordinator + mNotificationEntryManager.addNotificationRemoveInterceptor( + (key, entry, dismissReason) -> { + final boolean isClearAll = dismissReason == REASON_CANCEL_ALL; + final boolean isUserDismiss = dismissReason == REASON_CANCEL + || dismissReason == REASON_CLICK; + final boolean isAppCancel = dismissReason == REASON_APP_CANCEL + || dismissReason == REASON_APP_CANCEL_ALL; + final boolean isSummaryCancel = + dismissReason == REASON_GROUP_SUMMARY_CANCELED; + + // Need to check for !appCancel here because the notification may have + // previously been dismissed & entry.isRowDismissed would still be true + boolean userRemovedNotif = + (entry != null && entry.isRowDismissed() && !isAppCancel) + || isClearAll || isUserDismiss || isSummaryCancel; + + if (userRemovedNotif) { + return handleDismissalInterception(entry); + } + return false; + }); + + mNotificationGroupManager.registerGroupChangeListener( + new NotificationGroupManagerLegacy.OnGroupChangeListener() { + @Override + public void onGroupSuppressionChanged( + NotificationGroupManagerLegacy.NotificationGroup group, + boolean suppressed) { + // More notifications could be added causing summary to no longer + // be suppressed -- in this case need to remove the key. + final String groupKey = group.summary != null + ? group.summary.getSbn().getGroupKey() + : null; + if (!suppressed && groupKey != null + && mBubbles.isSummarySuppressed(groupKey)) { + mBubbles.removeSuppressedSummary(groupKey); + } + } + }); + + addNotifCallback(new NotifCallback() { + @Override + public void removeNotification(NotificationEntry entry, + DismissedByUserStats dismissedByUserStats, int reason) { + mNotificationEntryManager.performRemoveNotification(entry.getSbn(), + dismissedByUserStats, reason); + } + + @Override + public void invalidateNotifications(String reason) { + mNotificationEntryManager.updateNotifications(reason); + } + + @Override + public void maybeCancelSummary(NotificationEntry entry) { + // Check if removed bubble has an associated suppressed group summary that needs + // to be removed now. + final String groupKey = entry.getSbn().getGroupKey(); + if (mBubbles.isSummarySuppressed(groupKey)) { + mBubbles.removeSuppressedSummary(groupKey); + + final NotificationEntry summary = + mNotificationEntryManager.getActiveNotificationUnfiltered( + mBubbles.getSummaryKey(groupKey)); + if (summary != null) { + mNotificationEntryManager.performRemoveNotification( + summary.getSbn(), + getDismissedByUserStats(summary, false), + UNDEFINED_DISMISS_REASON); + } + } + + // Check if we still need to remove the summary from NoManGroup because the summary + // may not be in the mBubbleData.mSuppressedGroupKeys list and removed above. + // For example: + // 1. Bubbled notifications (group) is posted to shade and are visible bubbles + // 2. User expands bubbles so now their respective notifications in the shade are + // hidden, including the group summary + // 3. User removes all bubbles + // 4. We expect all the removed bubbles AND the summary (note: the summary was + // never added to the suppressedSummary list in BubbleData, so we add this check) + NotificationEntry summary = mNotificationGroupManager.getLogicalGroupSummary(entry); + if (summary != null) { + ArrayList<NotificationEntry> summaryChildren = + mNotificationGroupManager.getLogicalChildren(summary.getSbn()); + boolean isSummaryThisNotif = summary.getKey().equals(entry.getKey()); + if (!isSummaryThisNotif && (summaryChildren == null + || summaryChildren.isEmpty())) { + mNotificationEntryManager.performRemoveNotification( + summary.getSbn(), + getDismissedByUserStats(summary, false), + UNDEFINED_DISMISS_REASON); + } + } + } + }); + } + + private void setupNotifPipeline() { + mNotifPipeline.addCollectionListener(new NotifCollectionListener() { + @Override + public void onEntryAdded(NotificationEntry entry) { + BubblesManager.this.onEntryAdded(entry); + } + + @Override + public void onEntryUpdated(NotificationEntry entry) { + BubblesManager.this.onEntryUpdated(entry); + } + + @Override + public void onEntryRemoved(NotificationEntry entry, + @NotifCollection.CancellationReason int reason) { + BubblesManager.this.onEntryRemoved(entry); + } + + @Override + public void onRankingUpdate(RankingMap rankingMap) { + BubblesManager.this.onRankingUpdate(rankingMap); + } + }); + } + + void onEntryAdded(NotificationEntry entry) { + if (mNotificationInterruptStateProvider.shouldBubbleUp(entry) + && entry.isBubble()) { + mBubbles.onEntryAdded(notifToBubbleEntry(entry)); + } + } + + void onEntryUpdated(NotificationEntry entry) { + mBubbles.onEntryUpdated(notifToBubbleEntry(entry), + mNotificationInterruptStateProvider.shouldBubbleUp(entry)); + } + + void onEntryRemoved(NotificationEntry entry) { + mBubbles.onEntryRemoved(notifToBubbleEntry(entry)); + } + + void onRankingUpdate(RankingMap rankingMap) { + mBubbles.onRankingUpdated(rankingMap); + } + + /** + * Gets the DismissedByUserStats used by {@link NotificationEntryManager}. + * Will not be necessary when using the new notification pipeline's {@link NotifCollection}. + * Instead, this is taken care of by {@link BubbleCoordinator}. + */ + private DismissedByUserStats getDismissedByUserStats( + NotificationEntry entry, + boolean isVisible) { + return new DismissedByUserStats( + DISMISSAL_BUBBLE, + DISMISS_SENTIMENT_NEUTRAL, + NotificationVisibility.obtain( + entry.getKey(), + entry.getRanking().getRank(), + mNotificationEntryManager.getActiveNotificationsCount(), + isVisible, + NotificationLogger.getNotificationLocation(entry))); + } + + /** + * Returns the scrim drawn behind the bubble stack. This is managed by {@link ScrimController} + * since we want the scrim's appearance and behavior to be identical to that of the notification + * shade scrim. + */ + public ScrimView getScrimForBubble() { + return mBubbleScrim; + } + + /** + * We intercept notification entries (including group summaries) dismissed by the user when + * there is an active bubble associated with it. We do this so that developers can still + * cancel it (and hence the bubbles associated with it). + * + * @return true if we want to intercept the dismissal of the entry, else false. + * @see Bubbles#handleDismissalInterception(BubbleEntry, List, IntConsumer) + */ + public boolean handleDismissalInterception(NotificationEntry entry) { + if (entry == null) { + return false; + } + + List<NotificationEntry> children = entry.getAttachedNotifChildren(); + List<BubbleEntry> bubbleChildren = null; + if (children != null) { + bubbleChildren = new ArrayList<>(); + for (int i = 0; i < children.size(); i++) { + bubbleChildren.add(notifToBubbleEntry(children.get(i))); + } + } + + return mBubbles.handleDismissalInterception(notifToBubbleEntry(entry), bubbleChildren, + // TODO : b/171847985 should re-work on notification side to make this more clear. + (int i) -> { + if (i >= 0) { + for (NotifCallback cb : mCallbacks) { + cb.removeNotification(children.get(i), + getDismissedByUserStats(children.get(i), true), + REASON_GROUP_SUMMARY_CANCELED); + } + } else { + mNotificationGroupManager.onEntryRemoved(entry); + } + }); + } + + /** + * Request the stack expand if needed, then select the specified Bubble as current. + * If no bubble exists for this entry, one is created. + * + * @param entry the notification for the bubble to be selected + */ + public void expandStackAndSelectBubble(NotificationEntry entry) { + mBubbles.expandStackAndSelectBubble(notifToBubbleEntry(entry)); + } + + /** See {@link NotifCallback}. */ + public void addNotifCallback(NotifCallback callback) { + mCallbacks.add(callback); + } + + /** + * When a notification is marked Priority, expand the stack if needed, + * then (maybe create and) select the given bubble. + * + * @param entry the notification for the bubble to show + */ + public void onUserChangedImportance(NotificationEntry entry) { + try { + int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; + flags |= Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE; + mBarService.onNotificationBubbleChanged(entry.getKey(), true, flags); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + mShadeController.collapsePanel(true); + if (entry.getRow() != null) { + entry.getRow().updateBubbleButton(); + } + } + + /** + * Called when a user has indicated that an active notification should be shown as a bubble. + * <p> + * This method will collapse the shade, create the bubble without a flyout or dot, and suppress + * the notification from appearing in the shade. + * + * @param entry the notification to change bubble state for. + * @param shouldBubble whether the notification should show as a bubble or not. + */ + public void onUserChangedBubble(@NonNull final NotificationEntry entry, boolean shouldBubble) { + NotificationChannel channel = entry.getChannel(); + final String appPkg = entry.getSbn().getPackageName(); + final int appUid = entry.getSbn().getUid(); + if (channel == null || appPkg == null) { + return; + } + + // Update the state in NotificationManagerService + try { + int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; + flags |= Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE; + mBarService.onNotificationBubbleChanged(entry.getKey(), shouldBubble, flags); + } catch (RemoteException e) { + } + + // Change the settings + channel = NotificationChannelHelper.createConversationChannelIfNeeded(mContext, + mNotificationManager, entry, channel); + channel.setAllowBubbles(shouldBubble); + try { + int currentPref = mNotificationManager.getBubblePreferenceForPackage(appPkg, appUid); + if (shouldBubble && currentPref == BUBBLE_PREFERENCE_NONE) { + mNotificationManager.setBubblesAllowed(appPkg, appUid, BUBBLE_PREFERENCE_SELECTED); + } + mNotificationManager.updateNotificationChannelForPackage(appPkg, appUid, channel); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + + if (shouldBubble) { + mShadeController.collapsePanel(true); + if (entry.getRow() != null) { + entry.getRow().updateBubbleButton(); + } + } + } + + @Override + public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { + mBubbles.dump(fd, pw, args); + } + + static BubbleEntry notifToBubbleEntry(NotificationEntry e) { + return new BubbleEntry(e.getSbn(), e.getRanking(), e.isClearable(), + e.shouldSuppressNotificationDot(), e.shouldSuppressNotificationList(), + e.shouldSuppressPeek()); + } + + /** + * Callback for when the BubbleController wants to interact with the notification pipeline to: + * - Remove a previously bubbled notification + * - Update the notification shade since bubbled notification should/shouldn't be showing + */ + public interface NotifCallback { + /** + * Called when a bubbled notification that was hidden from the shade is now being removed + * This can happen when an app cancels a bubbled notification or when the user dismisses a + * bubble. + */ + void removeNotification(@NonNull NotificationEntry entry, + @NonNull DismissedByUserStats stats, int reason); + + /** + * Called when a bubbled notification has changed whether it should be + * filtered from the shade. + */ + void invalidateNotifications(@NonNull String reason); + + /** + * Called on a bubbled entry that has been removed when there are no longer + * bubbled entries in its group. + * + * Checks whether its group has any other (non-bubbled) children. If it doesn't, + * removes all remnants of the group's summary from the notification pipeline. + * TODO: (b/145659174) Only old pipeline needs this - delete post-migration. + */ + void maybeCancelSummary(@NonNull NotificationEntry entry); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java index 6bedd392ef3a..b7efa7c4c5ac 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java @@ -17,8 +17,6 @@ package com.android.systemui.wmshell; import android.content.Context; -import android.os.Handler; -import android.view.LayoutInflater; import com.android.systemui.dagger.WMSingleton; import com.android.wm.shell.ShellTaskOrganizer; @@ -27,6 +25,7 @@ import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipBoundsHandler; import com.android.wm.shell.pip.PipBoundsState; +import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipSurfaceTransactionHelper; import com.android.wm.shell.pip.PipTaskOrganizer; import com.android.wm.shell.pip.PipUiEventLogger; @@ -53,6 +52,8 @@ public abstract class TvPipModule { PipBoundsState pipBoundsState, PipBoundsHandler pipBoundsHandler, PipTaskOrganizer pipTaskOrganizer, + PipMediaController pipMediaController, + PipNotification pipNotification, WindowManagerShellWrapper windowManagerShellWrapper) { return Optional.of( new PipController( @@ -60,16 +61,16 @@ public abstract class TvPipModule { pipBoundsState, pipBoundsHandler, pipTaskOrganizer, + pipMediaController, + pipNotification, windowManagerShellWrapper)); } @WMSingleton @Provides static PipControlsViewController providePipControlsViewController( - PipControlsView pipControlsView, PipController pipController, - LayoutInflater layoutInflater, Handler handler) { - return new PipControlsViewController(pipControlsView, pipController, layoutInflater, - handler); + PipControlsView pipControlsView, PipController pipController) { + return new PipControlsViewController(pipControlsView, pipController); } @WMSingleton @@ -81,8 +82,8 @@ public abstract class TvPipModule { @WMSingleton @Provides static PipNotification providePipNotification(Context context, - PipController pipController) { - return new PipNotification(context, pipController); + PipMediaController pipMediaController) { + return new PipNotification(context, pipMediaController); } @WMSingleton diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index 4330659dde02..f896891c5039 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -71,7 +71,7 @@ import com.android.wm.shell.onehanded.OneHandedEvents; import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback; import com.android.wm.shell.onehanded.OneHandedTransitionCallback; import com.android.wm.shell.pip.Pip; -import com.android.wm.shell.pip.phone.PipUtils; +import com.android.wm.shell.pip.PipUtils; import com.android.wm.shell.protolog.ShellProtoLogImpl; import com.android.wm.shell.splitscreen.SplitScreen; @@ -211,8 +211,7 @@ public final class WMShell extends SystemUI @Override public void onActivityUnpinned() { final Pair<ComponentName, Integer> topPipActivityInfo = - PipUtils.getTopPipActivity( - mContext, ActivityManager.getService()); + PipUtils.getTopPipActivity(mContext); final ComponentName topActivity = topPipActivityInfo.first; pip.onActivityUnpinned(topActivity); mInputConsumerController.unregisterInputConsumer(); diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index ead2fc1cd9dc..91ae08e07677 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -34,6 +34,7 @@ import com.android.wm.shell.common.AnimationThread; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.HandlerExecutor; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; @@ -41,10 +42,10 @@ import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.pip.Pip; +import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipSurfaceTransactionHelper; import com.android.wm.shell.pip.PipUiEventLogger; import com.android.wm.shell.pip.phone.PipAppOpsListener; -import com.android.wm.shell.pip.phone.PipMediaController; import com.android.wm.shell.pip.phone.PipTouchHandler; import com.android.wm.shell.splitscreen.SplitScreen; @@ -102,8 +103,9 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides - static DragAndDropController provideDragAndDropController(DisplayController displayController) { - return new DragAndDropController(displayController); + static DragAndDropController provideDragAndDropController(Context context, + DisplayController displayController) { + return new DragAndDropController(context, displayController); } @WMSingleton @@ -122,9 +124,8 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides - static PipMediaController providePipMediaController(Context context, - IActivityManager activityManager) { - return new PipMediaController(context, activityManager); + static PipMediaController providePipMediaController(Context context) { + return new PipMediaController(context); } @WMSingleton @@ -157,9 +158,9 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides static ShellTaskOrganizer provideShellTaskOrganizer(SyncTransactionQueue syncQueue, - @Main Handler handler, TransactionPool transactionPool) { + ShellExecutor mainExecutor, TransactionPool transactionPool) { return new ShellTaskOrganizer(syncQueue, transactionPool, - new HandlerExecutor(handler), AnimationThread.instance().getExecutor()); + mainExecutor, AnimationThread.instance().getExecutor()); } @BindsOptionalOf @@ -174,4 +175,11 @@ public abstract class WMShellBaseModule { DisplayController displayController) { return Optional.ofNullable(OneHandedController.create(context, displayController)); } + + @WMSingleton + @Provides + static ShellExecutor provideMainShellExecutor(@Main Handler handler) { + return new HandlerExecutor(handler); + } + } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java index a6fe72850716..b6fbd589ae2c 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java @@ -27,18 +27,19 @@ import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.FloatingContentCoordinator; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipBoundsHandler; import com.android.wm.shell.pip.PipBoundsState; +import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipSurfaceTransactionHelper; import com.android.wm.shell.pip.PipTaskOrganizer; import com.android.wm.shell.pip.PipUiEventLogger; import com.android.wm.shell.pip.phone.PipAppOpsListener; import com.android.wm.shell.pip.phone.PipController; -import com.android.wm.shell.pip.phone.PipMediaController; import com.android.wm.shell.pip.phone.PipMenuActivityController; import com.android.wm.shell.pip.phone.PipTouchHandler; import com.android.wm.shell.splitscreen.SplitScreen; @@ -82,11 +83,12 @@ public class WMShellModule { PipAppOpsListener pipAppOpsListener, PipBoundsHandler pipBoundsHandler, PipBoundsState pipBoundsState, PipMediaController pipMediaController, PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, - PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper) { + PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper, + ShellExecutor mainExecutor) { return Optional.ofNullable(PipController.create(context, displayController, pipAppOpsListener, pipBoundsHandler, pipBoundsState, pipMediaController, pipMenuActivityController, pipTaskOrganizer, pipTouchHandler, - windowManagerShellWrapper)); + windowManagerShellWrapper, mainExecutor)); } @WMSingleton diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml index d541c8fbdff1..e5847b08a4c5 100644 --- a/packages/SystemUI/tests/AndroidManifest.xml +++ b/packages/SystemUI/tests/AndroidManifest.xml @@ -46,7 +46,7 @@ <uses-permission android:name="android.permission.DEVICE_POWER" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.STATUS_BAR" /> - <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> <uses-permission android:name="android.permission.REAL_GET_TASKS" /> <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" /> <uses-permission android:name="android.permission.NETWORK_SETTINGS" /> diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java index 3da1f297dfe9..c923515fc8cc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java @@ -43,6 +43,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.pm.ActivityInfo; +import android.os.UserHandle; import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.view.MotionEvent; @@ -186,8 +187,8 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { // Perform dragging final View.OnTouchListener listener = mTouchListenerCaptor.getValue(); final int offset = ViewConfiguration.get(mContext).getScaledTouchSlop(); - final int previousMode = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0); + final int previousMode = Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0, UserHandle.USER_CURRENT); listener.onTouch(mSpyImageView, MotionEvent.obtain( 0, 0, ACTION_DOWN, 100, 100, 0)); verify(mViewPropertyAnimator).cancel(); @@ -334,8 +335,8 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { verify(mSpyImageView).setImageResource( getIconResId(expectedMode)); verify(mWindowManager).removeView(mSpyImageView); - final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0); + final int actualMode = Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0, UserHandle.USER_CURRENT); assertEquals(expectedMode, actualMode); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java index b60fa4f7ea67..777db952591e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java @@ -32,10 +32,15 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.annotation.Nullable; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.PromptInfo; +import android.hardware.biometrics.SensorProperties; +import android.hardware.face.FaceSensorPropertiesInternal; +import android.hardware.fingerprint.FingerprintSensorProperties; +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.IBinder; import android.os.UserManager; import android.test.suitebuilder.annotation.SmallTest; @@ -58,6 +63,9 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.ArrayList; +import java.util.List; + @RunWith(AndroidTestingRunner.class) @RunWithLooper @SmallTest @@ -222,18 +230,28 @@ public class AuthContainerViewTest extends SysuiTestCase { AuthContainerView.Config config = new AuthContainerView.Config(); config.mContext = mContext; config.mCallback = mCallback; - config.mModalityMask |= BiometricAuthenticator.TYPE_FINGERPRINT; + config.mSensorIds = new int[] {0}; + config.mCredentialAllowed = false; PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(authenticators); config.mPromptInfo = promptInfo; - mAuthContainer = new TestableAuthContainer(config); + final List<FingerprintSensorPropertiesInternal> fpProps = new ArrayList<>(); + fpProps.add(new FingerprintSensorPropertiesInternal(0, + SensorProperties.STRENGTH_STRONG, + 5 /* maxEnrollmentsPerUser */, + FingerprintSensorProperties.TYPE_REAR, + false /* resetLockoutRequiresHardwareAuthToken */)); + mAuthContainer = new TestableAuthContainer(config, fpProps, null /* faceProps */); } private class TestableAuthContainer extends AuthContainerView { - TestableAuthContainer(AuthContainerView.Config config) { - super(config, new MockInjector()); + TestableAuthContainer(AuthContainerView.Config config, + @Nullable List<FingerprintSensorPropertiesInternal> fpProps, + @Nullable List<FaceSensorPropertiesInternal> faceProps) { + + super(config, new MockInjector(), fpProps, faceProps); } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java index e0420ca38f45..0186d7394ecb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -97,6 +97,8 @@ public class AuthControllerTest extends SysuiTestCase { @Mock private FingerprintManager mFingerprintManager; @Mock + private FaceManager mFaceManager; + @Mock private UdfpsController mUdfpsController; private TestableAuthController mAuthController; @@ -132,7 +134,7 @@ public class AuthControllerTest extends SysuiTestCase { when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props); mAuthController = new TestableAuthController(context, mCommandQueue, - mStatusBarStateController, mActivityTaskManager, mFingerprintManager, + mStatusBarStateController, mActivityTaskManager, mFingerprintManager, mFaceManager, () -> mUdfpsController); mAuthController.start(); @@ -142,7 +144,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testSendsReasonUserCanceled_whenDismissedByUserCancel() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED, null /* credentialAttestation */); verify(mReceiver).onDialogDismissed( @@ -152,7 +154,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testSendsReasonNegative_whenDismissedByButtonNegative() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE, null /* credentialAttestation */); verify(mReceiver).onDialogDismissed( @@ -162,7 +164,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testSendsReasonConfirmed_whenDismissedByButtonPositive() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE, null /* credentialAttestation */); verify(mReceiver).onDialogDismissed( @@ -172,7 +174,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testSendsReasonConfirmNotRequired_whenDismissedByAuthenticated() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED, null /* credentialAttestation */); verify(mReceiver).onDialogDismissed( @@ -182,7 +184,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testSendsReasonError_whenDismissedByError() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_ERROR, null /* credentialAttestation */); verify(mReceiver).onDialogDismissed( @@ -192,7 +194,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testSendsReasonServerRequested_whenDismissedByServer() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BY_SYSTEM_SERVER, null /* credentialAttestation */); verify(mReceiver).onDialogDismissed( @@ -203,7 +205,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testSendsReasonCredentialConfirmed_whenDeviceCredentialAuthenticated() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); final byte[] credentialAttestation = generateRandomHAT(); @@ -217,22 +219,21 @@ public class AuthControllerTest extends SysuiTestCase { // Statusbar tests @Test - public void testShowInvoked_whenSystemRequested() - throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + public void testShowInvoked_whenSystemRequested() { + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); verify(mDialog1).show(any(), any()); } @Test public void testOnAuthenticationSucceededInvoked_whenSystemRequested() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onBiometricAuthenticated(); verify(mDialog1).onAuthenticationSucceeded(); } @Test public void testOnAuthenticationFailedInvoked_whenBiometricRejected() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onBiometricError(BiometricAuthenticator.TYPE_NONE, BiometricConstants.BIOMETRIC_PAUSED_REJECTED, 0 /* vendorCode */); @@ -245,7 +246,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testOnAuthenticationFailedInvoked_whenBiometricTimedOut() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); final int error = BiometricConstants.BIOMETRIC_ERROR_TIMEOUT; final int vendorCode = 0; mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode); @@ -258,7 +259,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testOnHelpInvoked_whenSystemRequested() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); final String helpMessage = "help"; mAuthController.onBiometricHelp(helpMessage); @@ -269,8 +270,8 @@ public class AuthControllerTest extends SysuiTestCase { } @Test - public void testOnErrorInvoked_whenSystemRequested() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + public void testOnErrorInvoked_whenSystemRequested() { + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); final int error = 1; final int vendorCode = 0; mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode); @@ -283,7 +284,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testErrorLockout_whenCredentialAllowed_AnimatesToCredentialUI() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT; final int vendorCode = 0; @@ -296,7 +297,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testErrorLockoutPermanent_whenCredentialAllowed_AnimatesToCredentialUI() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT; final int vendorCode = 0; @@ -309,7 +310,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testErrorLockout_whenCredentialNotAllowed_sendsOnError() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT; final int vendorCode = 0; @@ -322,7 +323,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testErrorLockoutPermanent_whenCredentialNotAllowed_sendsOnError() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT; final int vendorCode = 0; @@ -335,7 +336,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testHideAuthenticationDialog_invokesDismissFromSystemServer() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.hideAuthenticationDialog(); verify(mDialog1).dismissFromSystemServer(); @@ -355,7 +356,7 @@ public class AuthControllerTest extends SysuiTestCase { // 1) Credential is confirmed // 2) Client cancels authentication - showDialog(Authenticators.DEVICE_CREDENTIAL, BiometricPrompt.TYPE_NONE); + showDialog(new int[0] /* sensorIds */, true /* credentialAllowed */); verify(mDialog1).show(any(), any()); final byte[] credentialAttestation = generateRandomHAT(); @@ -371,10 +372,10 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testShowNewDialog_beforeOldDialogDismissed_SkipsAnimations() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); verify(mDialog1).show(any(), any()); - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); // First dialog should be dismissed without animation verify(mDialog1).dismissWithoutCallback(eq(false) /* animate */); @@ -385,7 +386,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testConfigurationPersists_whenOnConfigurationChanged() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); verify(mDialog1).show(any(), any()); // Return that the UI is in "showing" state @@ -415,8 +416,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testConfigurationPersists_whenBiometricFallbackToCredential() { - showDialog(Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK, - BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, true /* credentialAllowed */); verify(mDialog1).show(any(), any()); // Pretend that the UI is now showing device credential UI. @@ -440,7 +440,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testClientNotified_whenTaskStackChangesDuringAuthentication() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); List<ActivityManager.RunningTaskInfo> tasks = new ArrayList<>(); ActivityManager.RunningTaskInfo taskInfo = mock(ActivityManager.RunningTaskInfo.class); @@ -462,7 +462,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testDoesNotCrash_whenTryAgainPressedAfterDismissal() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED, null /* credentialAttestation */); mAuthController.onTryAgainPressed(); @@ -470,7 +470,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testDoesNotCrash_whenDeviceCredentialPressedAfterDismissal() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED, null /* credentialAttestation */); mAuthController.onDeviceCredentialPressed(); @@ -478,7 +478,7 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testActionCloseSystemDialogs_dismissesDialogIfShowing() throws Exception { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); mAuthController.mBroadcastReceiver.onReceive(mContext, intent); waitForIdleSync(); @@ -500,14 +500,14 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testOnBiometricAuthenticated_OnCancelAodInterrupt() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FINGERPRINT); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onBiometricAuthenticated(); verify(mUdfpsController).onCancelAodInterrupt(); } @Test public void testOnBiometricError_OnCancelAodInterrupt() { - showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FINGERPRINT); + showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onBiometricError(0, 0, 0); verify(mUdfpsController).onCancelAodInterrupt(); } @@ -538,17 +538,18 @@ public class AuthControllerTest extends SysuiTestCase { // Helpers - private void showDialog(int authenticators, int biometricModality) { - mAuthController.showAuthenticationDialog(createTestPromptInfo(authenticators), + private void showDialog(int[] sensorIds, boolean credentialAllowed) { + mAuthController.showAuthenticationDialog(createTestPromptInfo(), mReceiver /* receiver */, - biometricModality, + sensorIds, + credentialAllowed, true /* requireConfirmation */, 0 /* userId */, "testPackage", 0 /* operationId */); } - private PromptInfo createTestPromptInfo(int authenticators) { + private PromptInfo createTestPromptInfo() { PromptInfo promptInfo = new PromptInfo(); promptInfo.setTitle("Title"); @@ -560,8 +561,6 @@ public class AuthControllerTest extends SysuiTestCase { // by user settings, and should be tested in BiometricService. promptInfo.setConfirmationRequested(true); - promptInfo.setAuthenticators(authenticators); - return promptInfo; } @@ -580,15 +579,16 @@ public class AuthControllerTest extends SysuiTestCase { StatusBarStateController statusBarStateController, IActivityTaskManager activityTaskManager, FingerprintManager fingerprintManager, + FaceManager faceManager, Provider<UdfpsController> udfpsControllerFactory) { super(context, commandQueue, statusBarStateController, activityTaskManager, - fingerprintManager, udfpsControllerFactory); + fingerprintManager, faceManager, udfpsControllerFactory); } @Override protected AuthDialog buildDialog(PromptInfo promptInfo, - boolean requireConfirmation, int userId, int type, String opPackageName, - boolean skipIntro, long operationId) { + boolean requireConfirmation, int userId, int[] sensorIds, boolean credentialAllowed, + String opPackageName, boolean skipIntro, long operationId) { mLastBiometricPromptInfo = promptInfo; diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index e24f4ca3581d..a95396cccd66 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -132,7 +132,7 @@ public class UdfpsControllerTest extends SysuiTestCase { verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); - assertEquals(TEST_UDFPS_SENSOR_ID, mUdfpsController.mUdfpsSensorId); + assertEquals(TEST_UDFPS_SENSOR_ID, mUdfpsController.mSensorProps.sensorId); } private void setUpResources() { @@ -222,8 +222,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); event.recycle(); // THEN the event is passed to the FingerprintManager - verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mUdfpsSensorId), eq(0), eq(0), - eq(0f), eq(0f)); + verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mSensorProps.sensorId), eq(0), + eq(0), eq(0f), eq(0f)); // AND the scrim and dot is shown verify(mUdfpsView).showScrimAndDot(); } @@ -236,8 +236,8 @@ public class UdfpsControllerTest extends SysuiTestCase { // WHEN fingerprint is requested because of AOD interrupt mUdfpsController.onAodInterrupt(0, 0); // THEN the event is passed to the FingerprintManager - verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mUdfpsSensorId), eq(0), eq(0), - anyFloat(), anyFloat()); + verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mSensorProps.sensorId), eq(0), + eq(0), anyFloat(), anyFloat()); // AND the scrim and dot is shown verify(mUdfpsView).showScrimAndDot(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java index 0c872db45194..31c08ae471ae 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java @@ -102,10 +102,10 @@ public class BubbleDataTest extends SysuiTestCase { private ArgumentCaptor<BubbleData.Update> mUpdateCaptor; @Mock - private BubbleController.NotificationSuppressionChangedListener mSuppressionListener; + private Bubbles.NotificationSuppressionChangedListener mSuppressionListener; @Mock - private BubbleController.PendingIntentCanceledListener mPendingIntentCanceledListener; + private Bubbles.PendingIntentCanceledListener mPendingIntentCanceledListener; @Before public void setUp() throws Exception { @@ -171,12 +171,11 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); // Test - mBubbleData.dismissBubbleWithKey( - mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_USER_GESTURE); // Verify verifyUpdateReceived(); - assertBubbleRemoved(mBubbleA1, BubbleController.DISMISS_USER_GESTURE); + assertBubbleRemoved(mBubbleA1, Bubbles.DISMISS_USER_GESTURE); } @Test @@ -269,7 +268,7 @@ public class BubbleDataTest extends SysuiTestCase { sendUpdatedEntryAtTime(mEntryC1, 6000); verifyUpdateReceived(); - assertBubbleRemoved(mBubbleA1, BubbleController.DISMISS_AGED); + assertBubbleRemoved(mBubbleA1, Bubbles.DISMISS_AGED); assertOverflowChangedTo(ImmutableList.of(mBubbleA1)); Bubble bubbleA1 = mBubbleData.getOrCreateBubble(mEntryA1, null /* persistedBubble */); @@ -277,7 +276,7 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.notificationEntryUpdated(bubbleA1, false /* suppressFlyout*/, true /* showInShade */); verifyUpdateReceived(); - assertBubbleRemoved(mBubbleA2, BubbleController.DISMISS_AGED); + assertBubbleRemoved(mBubbleA2, Bubbles.DISMISS_AGED); assertOverflowChangedTo(ImmutableList.of(mBubbleA2)); } @@ -294,14 +293,12 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); mBubbleData.setMaxOverflowBubbles(1); - mBubbleData.dismissBubbleWithKey( - mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_USER_GESTURE); verifyUpdateReceived(); assertOverflowChangedTo(ImmutableList.of(mBubbleA1)); // Overflow max of 1 is reached; A1 is oldest, so it gets removed - mBubbleData.dismissBubbleWithKey( - mEntryA2.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryA2.getKey(), Bubbles.DISMISS_USER_GESTURE); verifyUpdateReceived(); assertOverflowChangedTo(ImmutableList.of(mBubbleA2)); } @@ -322,14 +319,12 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); // Test - mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), - BubbleController.DISMISS_NOTIF_CANCEL); + mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); verifyUpdateReceived(); assertOverflowChangedTo(ImmutableList.of(mBubbleA2)); // Test - mBubbleData.dismissBubbleWithKey(mEntryA2.getKey(), - BubbleController.DISMISS_GROUP_CANCELLED); + mBubbleData.dismissBubbleWithKey(mEntryA2.getKey(), Bubbles.DISMISS_GROUP_CANCELLED); verifyUpdateReceived(); assertOverflowChangedTo(ImmutableList.of()); } @@ -409,8 +404,7 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); // Test - mBubbleData.dismissBubbleWithKey( - mEntryA2.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryA2.getKey(), Bubbles.DISMISS_USER_GESTURE); verifyUpdateReceived(); // TODO: this should fail if things work as I expect them to? assertOrderChangedTo(mBubbleB2, mBubbleB1, mBubbleA1); @@ -430,8 +424,7 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); // Test - mBubbleData.dismissBubbleWithKey( - mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_USER_GESTURE); verifyUpdateReceived(); assertOrderNotChanged(); } @@ -450,8 +443,7 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); // Test - mBubbleData.dismissBubbleWithKey( - mEntryA2.getKey(), BubbleController.DISMISS_NOTIF_CANCEL); + mBubbleData.dismissBubbleWithKey(mEntryA2.getKey(), Bubbles.DISMISS_NOTIF_CANCEL); verifyUpdateReceived(); assertSelectionChangedTo(mBubbleB2); } @@ -545,8 +537,7 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); // Test - mBubbleData.dismissBubbleWithKey( - mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_USER_GESTURE); // Verify the selection was cleared. verifyUpdateReceived(); @@ -646,8 +637,7 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); // Test - mBubbleData.dismissBubbleWithKey( - mEntryB2.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryB2.getKey(), Bubbles.DISMISS_USER_GESTURE); verifyUpdateReceived(); assertOrderChangedTo(mBubbleA2, mBubbleB1, mBubbleA1); } @@ -671,13 +661,11 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); // Test - mBubbleData.dismissBubbleWithKey( - mEntryA2.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryA2.getKey(), Bubbles.DISMISS_USER_GESTURE); verifyUpdateReceived(); assertSelectionChangedTo(mBubbleB1); - mBubbleData.dismissBubbleWithKey( - mEntryB1.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryB1.getKey(), Bubbles.DISMISS_USER_GESTURE); verifyUpdateReceived(); assertSelectionChangedTo(mBubbleA1); } @@ -791,8 +779,7 @@ public class BubbleDataTest extends SysuiTestCase { mBubbleData.setListener(mListener); // Test - mBubbleData.dismissBubbleWithKey( - mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_USER_GESTURE); verifyUpdateReceived(); assertExpandedChangedTo(false); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java index 29ead593c51a..690a1ad42861 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java @@ -60,7 +60,7 @@ public class BubbleTest extends SysuiTestCase { private Bubble mBubble; @Mock - private BubbleController.NotificationSuppressionChangedListener mSuppressionListener; + private Bubbles.NotificationSuppressionChangedListener mSuppressionListener; @Before public void setUp() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TaskViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TaskViewTest.java index b13c6fc0cad4..5c148598f10a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TaskViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TaskViewTest.java @@ -36,7 +36,6 @@ import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.PendingIntent; import android.content.Context; -import android.os.Handler; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.SurfaceControl; @@ -101,7 +100,8 @@ public class TaskViewTest extends SysuiTestCase { return null; }).when(mExecutor).execute(any()); - mTaskView = new TaskView(mContext, mOrganizer, mExecutor); + mTaskView = new TaskView(mContext, mOrganizer); + mTaskView.setExecutor(mExecutor); mTaskView.setListener(mViewListener); } @@ -114,7 +114,8 @@ public class TaskViewTest extends SysuiTestCase { @Test public void testSetPendingListener_throwsException() { - TaskView taskView = new TaskView(mContext, mOrganizer, mExecutor); + TaskView taskView = new TaskView(mContext, mOrganizer); + mTaskView.setExecutor(mExecutor); taskView.setListener(mViewListener); try { taskView.setListener(mViewListener); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java deleted file mode 100644 index aaeee16dc1fd..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java +++ /dev/null @@ -1,85 +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.systemui.bubbles; - -import android.app.INotificationManager; -import android.content.Context; -import android.content.pm.LauncherApps; -import android.os.Handler; -import android.view.WindowManager; - -import com.android.internal.statusbar.IStatusBarService; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.model.SysUiState; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.FeatureFlags; -import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.NotificationShadeWindowController; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.collection.NotifPipeline; -import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; -import com.android.systemui.statusbar.phone.ShadeController; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.wm.shell.ShellTaskOrganizer; -import com.android.wm.shell.WindowManagerShellWrapper; -import com.android.wm.shell.common.FloatingContentCoordinator; - -/** - * Testable BubbleController subclass that immediately synchronizes surfaces. - */ -public class TestableBubbleController extends BubbleController { - - // Let's assume surfaces can be synchronized immediately. - TestableBubbleController(Context context, - NotificationShadeWindowController notificationShadeWindowController, - StatusBarStateController statusBarStateController, - ShadeController shadeController, - BubbleData data, - ConfigurationController configurationController, - NotificationInterruptStateProvider interruptionStateProvider, - ZenModeController zenModeController, - NotificationLockscreenUserManager lockscreenUserManager, - NotificationGroupManagerLegacy groupManager, - NotificationEntryManager entryManager, - NotifPipeline notifPipeline, - FeatureFlags featureFlags, - DumpManager dumpManager, - FloatingContentCoordinator floatingContentCoordinator, - BubbleDataRepository dataRepository, - SysUiState sysUiState, - INotificationManager notificationManager, - IStatusBarService statusBarService, - WindowManager windowManager, - WindowManagerShellWrapper windowManagerShellWrapper, - LauncherApps launcherApps, - BubbleLogger bubbleLogger, - Handler mainHandler, - ShellTaskOrganizer shellTaskOrganizer, - BubblePositioner positioner) { - super(context, - notificationShadeWindowController, statusBarStateController, shadeController, - data, Runnable::run, configurationController, interruptionStateProvider, - zenModeController, lockscreenUserManager, groupManager, entryManager, - notifPipeline, featureFlags, dumpManager, floatingContentCoordinator, - dataRepository, sysUiState, notificationManager, statusBarService, - windowManager, windowManagerShellWrapper, launcherApps, bubbleLogger, - mainHandler, shellTaskOrganizer, positioner); - setInflateSynchronously(true); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt index cd94f8444c45..c401fab1e1bc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt @@ -23,6 +23,7 @@ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.appops.AppOpsController import com.android.systemui.dump.DumpManager +import com.android.systemui.privacy.logging.PrivacyLogger import com.android.systemui.settings.UserTracker import com.android.systemui.util.DeviceConfigProxy import com.android.systemui.util.DeviceConfigProxyFake @@ -65,6 +66,8 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { private lateinit var dumpManager: DumpManager @Mock private lateinit var userTracker: UserTracker + @Mock + private lateinit var logger: PrivacyLogger private lateinit var privacyItemController: PrivacyItemController private lateinit var executor: FakeExecutor @@ -77,8 +80,8 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { executor, deviceConfigProxy, userTracker, - dumpManager - ) + logger, + dumpManager) } @Before diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt index 16a11050f9bb..3e834986e383 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt @@ -29,10 +29,12 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.appops.AppOpItem import com.android.systemui.appops.AppOpsController import com.android.systemui.dump.DumpManager +import com.android.systemui.privacy.logging.PrivacyLogger import com.android.systemui.settings.UserTracker import com.android.systemui.util.DeviceConfigProxy import com.android.systemui.util.DeviceConfigProxyFake import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.time.FakeSystemClock import org.hamcrest.Matchers.hasItem import org.hamcrest.Matchers.not @@ -86,6 +88,8 @@ class PrivacyItemControllerTest : SysuiTestCase() { private lateinit var userTracker: UserTracker @Mock private lateinit var dumpManager: DumpManager + @Mock + private lateinit var logger: PrivacyLogger @Captor private lateinit var argCaptor: ArgumentCaptor<List<PrivacyItem>> @Captor @@ -102,8 +106,8 @@ class PrivacyItemControllerTest : SysuiTestCase() { executor, deviceConfigProxy, userTracker, - dumpManager - ) + logger, + dumpManager) } @Before @@ -300,6 +304,45 @@ class PrivacyItemControllerTest : SysuiTestCase() { verify(callback, never()).onPrivacyItemsChanged(any()) } + @Test + fun testLogActiveChanged() { + privacyItemController.addCallback(callback) + executor.runAllReady() + + verify(appOpsController).addCallback(any(), capture(argCaptorCallback)) + argCaptorCallback.value.onActiveStateChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true) + + verify(logger).logUpdatedItemFromAppOps( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true) + } + + @Test + fun testLogListUpdated() { + doReturn(listOf( + AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, 0)) + ).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + + privacyItemController.addCallback(callback) + executor.runAllReady() + + verify(appOpsController).addCallback(any(), capture(argCaptorCallback)) + argCaptorCallback.value.onActiveStateChanged( + AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true) + executor.runAllReady() + + val expected = PrivacyItem( + PrivacyType.TYPE_LOCATION, + PrivacyApplication(TEST_PACKAGE_NAME, TEST_UID) + ) + + val captor = argumentCaptor<String>() + verify(logger, atLeastOnce()).logUpdatedPrivacyItemsList(capture(captor)) + // Let's look at the last log + val values = captor.allValues + assertTrue(values[values.size - 1].contains(expected.toLog())) + } + private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value) private fun changeAll(value: Boolean?) = changeProperty(ALL_INDICATORS, value) diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java index fd1866b9ebc3..c82aee48ab91 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java @@ -17,6 +17,7 @@ package com.android.systemui.qs; import static junit.framework.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -66,6 +67,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { private final String DEVICE_OWNER_PACKAGE = "TestDPC"; private final String VPN_PACKAGE = "TestVPN"; private final String VPN_PACKAGE_2 = "TestVPN 2"; + private static final String PARENTAL_CONTROLS_LABEL = "Parental Control App"; private ViewGroup mRootView; private TextView mFooterText; @@ -525,6 +527,27 @@ public class QSSecurityFooterTest extends SysuiTestCase { verify(mockHost, never()).collapsePanels(); } + @Test + public void testParentalControls() { + when(mSecurityController.isParentalControlsEnabled()).thenReturn(true); + mFooter.refreshState(); + + TestableLooper.get(this).processAllMessages(); + + assertEquals(mContext.getString(R.string.quick_settings_disclosure_parental_controls), + mFooterText.getText()); + } + + @Test + public void testParentalControlsDialog() { + when(mSecurityController.isParentalControlsEnabled()).thenReturn(true); + when(mSecurityController.getLabel(any())).thenReturn(PARENTAL_CONTROLS_LABEL); + + View view = mFooter.createDialogView(); + TextView textView = (TextView) view.findViewById(R.id.parental_controls_title); + assertEquals(PARENTAL_CONTROLS_LABEL, textView.getText()); + } + private CharSequence addLink(CharSequence description) { final SpannableStringBuilder message = new SpannableStringBuilder(); message.append(description); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt index 226995198843..26b5d26387b4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt @@ -27,6 +27,7 @@ import com.android.systemui.demomode.DemoModeController import com.android.systemui.plugins.ActivityStarter import com.android.systemui.privacy.OngoingPrivacyChip import com.android.systemui.privacy.PrivacyItemController +import com.android.systemui.privacy.logging.PrivacyLogger import com.android.systemui.qs.carrier.QSCarrierGroup import com.android.systemui.qs.carrier.QSCarrierGroupController import com.android.systemui.settings.UserTracker @@ -86,6 +87,8 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() { @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController @Mock + private lateinit var privacyLogger: PrivacyLogger + @Mock private lateinit var iconContainer: StatusIconContainer @Mock private lateinit var qsCarrierGroup: QSCarrierGroup @@ -123,7 +126,8 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() { demoModeController, userTracker, quickQSPanelController, - qsCarrierGroupControllerBuilder + qsCarrierGroupControllerBuilder, + privacyLogger ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java index 8617a8326283..d2d57087485c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import android.content.ComponentName; import android.graphics.Rect; +import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.PromptInfo; import android.os.Bundle; import android.view.WindowInsetsController.Appearance; @@ -409,13 +410,20 @@ public class CommandQueueTest extends SysuiTestCase { @Test public void testShowAuthenticationDialog() { PromptInfo promptInfo = new PromptInfo(); - String packageName = "test"; + final IBiometricSysuiReceiver receiver = mock(IBiometricSysuiReceiver.class); + final int[] sensorIds = {1, 2}; + final boolean credentialAllowed = true; + final boolean requireConfirmation = true; + final int userId = 10; + final String packageName = "test"; final long operationId = 1; - mCommandQueue.showAuthenticationDialog(promptInfo, null /* receiver */, 1, true, 3, - packageName, operationId); + + mCommandQueue.showAuthenticationDialog(promptInfo, receiver, sensorIds, + credentialAllowed, requireConfirmation , userId, packageName, operationId); waitForIdleSync(); - verify(mCallbacks).showAuthenticationDialog(eq(promptInfo), eq(null), eq(1), eq(true), - eq(3), eq(packageName), eq(operationId)); + verify(mCallbacks).showAuthenticationDialog(eq(promptInfo), eq(receiver), eq(sensorIds), + eq(credentialAllowed), eq(requireConfirmation), eq(userId), eq(packageName), + eq(operationId)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java index aeb625c98283..152c51e1f9f4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java @@ -83,7 +83,7 @@ public class RankingBuilder { mCanBubble = ranking.canBubble(); mIsVisuallyInterruptive = ranking.visuallyInterruptive(); mIsConversation = ranking.isConversation(); - mShortcutInfo = ranking.getShortcutInfo(); + mShortcutInfo = ranking.getConversationShortcutInfo(); mRankingAdjustment = ranking.getRankingAdjustment(); mIsBubble = ranking.isBubble(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java index d835123e4cad..cd46dda772e3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java @@ -116,7 +116,7 @@ public class NotificationFilterTest extends SysuiTestCase { new NotificationGroupManagerLegacy( mock(StatusBarStateController.class), () -> mock(PeopleNotificationIdentifier.class), - Optional.of(() -> mock(Bubbles.class)))); + Optional.of(mock(Bubbles.class)))); mDependency.injectMockDependency(ShadeController.class); mDependency.injectMockDependency(NotificationLockscreenUserManager.class); mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java index 61edcf9c200c..4698b8e50efb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java @@ -76,12 +76,12 @@ import com.android.settingslib.notification.ConversationIconFactory; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; -import com.android.systemui.bubbles.Bubbles; import com.android.systemui.bubbles.BubblesTestActivity; import com.android.systemui.statusbar.SbnBuilder; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.wmshell.BubblesManager; import org.junit.Before; import org.junit.Rule; @@ -137,7 +137,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { @Mock private OnUserInteractionCallback mOnUserInteractionCallback; @Mock - private Bubbles mBubbles; + private BubblesManager mBubblesManager; @Mock private LauncherApps mLauncherApps; @Mock @@ -255,7 +255,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); final ImageView view = mNotificationInfo.findViewById(R.id.conversation_icon); assertEquals(mIconDrawable, view.getDrawable()); } @@ -279,7 +279,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); final TextView textView = mNotificationInfo.findViewById(R.id.pkg_name); assertTrue(textView.getText().toString().contains("App Name")); assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility()); @@ -330,7 +330,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); final TextView textView = mNotificationInfo.findViewById(R.id.group_name); assertTrue(textView.getText().toString().contains(group.getName())); assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility()); @@ -355,7 +355,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); final TextView textView = mNotificationInfo.findViewById(R.id.group_name); assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility()); assertEquals(GONE, textView.getVisibility()); @@ -379,7 +379,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name); assertEquals(GONE, nameView.getVisibility()); } @@ -414,7 +414,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name); assertEquals(VISIBLE, nameView.getVisibility()); assertTrue(nameView.getText().toString().contains("Proxied")); @@ -442,7 +442,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); final View settingsButton = mNotificationInfo.findViewById(R.id.info); settingsButton.performClick(); @@ -468,7 +468,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); final View settingsButton = mNotificationInfo.findViewById(R.id.info); assertTrue(settingsButton.getVisibility() != View.VISIBLE); } @@ -495,7 +495,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, false, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); final View settingsButton = mNotificationInfo.findViewById(R.id.info); assertTrue(settingsButton.getVisibility() != View.VISIBLE); } @@ -520,7 +520,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); View view = mNotificationInfo.findViewById(R.id.silence); assertThat(view.isSelected()).isTrue(); } @@ -548,7 +548,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); View view = mNotificationInfo.findViewById(R.id.default_behavior); assertThat(view.isSelected()).isTrue(); assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo( @@ -579,7 +579,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); View view = mNotificationInfo.findViewById(R.id.default_behavior); assertThat(view.isSelected()).isTrue(); assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo( @@ -609,7 +609,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); View fave = mNotificationInfo.findViewById(R.id.priority); fave.performClick(); @@ -653,7 +653,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); mNotificationInfo.findViewById(R.id.default_behavior).performClick(); mTestableLooper.processAllMessages(); @@ -696,7 +696,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); View silence = mNotificationInfo.findViewById(R.id.silence); @@ -740,7 +740,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); View fave = mNotificationInfo.findViewById(R.id.priority); fave.performClick(); @@ -777,7 +777,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); View fave = mNotificationInfo.findViewById(R.id.priority); fave.performClick(); @@ -813,7 +813,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); View fave = mNotificationInfo.findViewById(R.id.priority); fave.performClick(); @@ -851,7 +851,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); mNotificationInfo.findViewById(R.id.default_behavior).performClick(); mNotificationInfo.findViewById(R.id.done).performClick(); @@ -887,7 +887,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); mNotificationInfo.findViewById(R.id.default_behavior).performClick(); mNotificationInfo.findViewById(R.id.done).performClick(); @@ -923,7 +923,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); mNotificationInfo.findViewById(R.id.default_behavior).performClick(); mNotificationInfo.findViewById(R.id.done).performClick(); @@ -958,7 +958,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); View silence = mNotificationInfo.findViewById(R.id.silence); silence.performClick(); @@ -992,7 +992,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); verify(mMockINotificationManager, times(1)).createConversationNotificationChannelForPackage( anyString(), anyInt(), any(), eq(CONVERSATION_ID)); @@ -1017,7 +1017,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { mBuilderProvider, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); verify(mMockINotificationManager, never()).createConversationNotificationChannelForPackage( anyString(), anyInt(), any(), eq(CONVERSATION_ID)); @@ -1052,7 +1052,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { () -> b, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); // WHEN user clicks "priority" mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE); @@ -1092,7 +1092,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { () -> b, true, mTestHandler, - mTestHandler, null, Optional.of(mBubbles)); + mTestHandler, null, Optional.of(mBubblesManager)); // WHEN user clicks "priority" mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java index 8a5afe6ce667..dbaf5c467c45 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java @@ -84,6 +84,7 @@ import com.android.systemui.statusbar.policy.InflatedSmartReplies; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.leak.LeakDetector; import com.android.systemui.util.time.FakeSystemClock; +import com.android.systemui.wmshell.BubblesManager; import org.junit.After; import org.junit.Before; @@ -96,6 +97,7 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.stubbing.Answer; +import java.util.Optional; import java.util.concurrent.CountDownLatch; /** @@ -243,7 +245,8 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { true, null, mFalsingManager, - mPeopleNotificationIdentifier + mPeopleNotificationIdentifier, + Optional.of(mock(BubblesManager.class)) )); when(mNotificationRowComponentBuilder.activatableNotificationView(any())) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java index bbc1df21237f..3000b8b449c3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java @@ -67,7 +67,6 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.systemui.SysuiTestCase; -import com.android.systemui.bubbles.Bubbles; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -81,6 +80,7 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager.O import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.wmshell.BubblesManager; import org.junit.Before; import org.junit.Ignore; @@ -131,7 +131,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { @Mock private ChannelEditorDialogController mChannelEditorDialogController; @Mock private PeopleNotificationIdentifier mPeopleNotificationIdentifier; @Mock private UserContextProvider mContextTracker; - @Mock private Bubbles mBubbles; + @Mock private BubblesManager mBubblesManager; @Mock(answer = Answers.RETURNS_SELF) private PriorityOnboardingDialogController.Builder mBuilder; private Provider<PriorityOnboardingDialogController.Builder> mProvider = () -> mBuilder; @@ -156,7 +156,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { () -> mStatusBar, mHandler, mHandler, mAccessibilityManager, mHighPriorityProvider, mINotificationManager, mLauncherApps, mShortcutManager, mChannelEditorDialogController, mContextTracker, mProvider, - mAssistantFeedbackController, Optional.of(mBubbles), + mAssistantFeedbackController, Optional.of(mBubblesManager), new UiEventLoggerFake(), mOnUserInteractionCallback); mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer, mCheckSaveListener, mOnSettingsClickListener); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index 847e0a474a6a..48375e02f64f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -70,6 +70,7 @@ import com.android.systemui.statusbar.phone.ConfigurationControllerImpl; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.InflatedSmartReplies; +import com.android.systemui.wmshell.BubblesManager; import org.mockito.ArgumentCaptor; @@ -121,7 +122,7 @@ public class NotificationTestHelper { mGroupMembershipManager = new NotificationGroupManagerLegacy( mStatusBarStateController, () -> mock(PeopleNotificationIdentifier.class), - Optional.of(() -> mock(Bubbles.class))); + Optional.of((mock(Bubbles.class)))); mGroupExpansionManager = mGroupMembershipManager; mHeadsUpManager = new HeadsUpManagerPhone(mContext, mStatusBarStateController, mock(KeyguardBypassController.class), mock(NotificationGroupManagerLegacy.class), @@ -430,7 +431,8 @@ public class NotificationTestHelper { mock(FalsingManager.class), mStatusBarStateController, mPeopleNotificationIdentifier, - mock(OnUserInteractionCallback.class)); + mock(OnUserInteractionCallback.class), + Optional.of(mock(BubblesManager.class))); row.setAboveShelfChangedListener(aboveShelf -> { }); mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java index 7d84f86cc7b3..b0086ef1d4fb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java @@ -92,7 +92,7 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase { mGroupManager = new NotificationGroupManagerLegacy( mock(StatusBarStateController.class), () -> mock(PeopleNotificationIdentifier.class), - Optional.of(() -> mock(Bubbles.class))); + Optional.of(mock(Bubbles.class))); mDependency.injectTestDependency(NotificationGroupManagerLegacy.class, mGroupManager); mGroupManager.setHeadsUpManager(mHeadsUpManager); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java index 29e445a13e24..f81672ab6a37 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerLegacyTest.java @@ -70,7 +70,7 @@ public class NotificationGroupManagerLegacyTest extends SysuiTestCase { mGroupManager = new NotificationGroupManagerLegacy( mock(StatusBarStateController.class), () -> mock(PeopleNotificationIdentifier.class), - Optional.of(() -> mock(Bubbles.class))); + Optional.of(mock(Bubbles.class))); mGroupManager.setHeadsUpManager(mHeadsUpManager); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java index f7489b1c164a..1f31fcd2a2bf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java @@ -53,7 +53,6 @@ import com.android.internal.widget.LockPatternUtils; import com.android.systemui.ActivityIntentHelper; import com.android.systemui.SysuiTestCase; import com.android.systemui.assist.AssistManager; -import com.android.systemui.bubbles.Bubbles; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; @@ -77,6 +76,7 @@ import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; +import com.android.systemui.wmshell.BubblesManager; import org.junit.Before; import org.junit.Test; @@ -116,7 +116,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { @Mock private Handler mHandler; @Mock - private Bubbles mBubbles; + private BubblesManager mBubblesManager; @Mock private ShadeControllerImpl mShadeController; @Mock @@ -193,7 +193,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mStatusBarKeyguardViewManager, mock(KeyguardManager.class), mock(IDreamManager.class), - Optional.of(mBubbles), + Optional.of(mBubblesManager), () -> mAssistManager, mRemoteInputManager, mock(NotificationGroupManagerLegacy.class), @@ -280,7 +280,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow); // Then - verify(mBubbles).expandStackAndSelectBubble(eq(mBubbleNotificationRow.getEntry())); + verify(mBubblesManager).expandStackAndSelectBubble(eq(mBubbleNotificationRow.getEntry())); // This is called regardless, and simply short circuits when there is nothing to do. verify(mShadeController, atLeastOnce()).collapsePanel(); @@ -312,7 +312,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow); // Then - verify(mBubbles).expandStackAndSelectBubble(mBubbleNotificationRow.getEntry()); + verify(mBubblesManager).expandStackAndSelectBubble(eq(mBubbleNotificationRow.getEntry())); verify(mShadeController, atLeastOnce()).collapsePanel(); @@ -342,7 +342,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow); // Then - verify(mBubbles).expandStackAndSelectBubble(mBubbleNotificationRow.getEntry()); + verify(mBubblesManager).expandStackAndSelectBubble(mBubbleNotificationRow.getEntry()); verify(mShadeController, atLeastOnce()).collapsePanel(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index d6a7acbcbd78..9f096dada6f2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -145,6 +145,7 @@ import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; import com.android.systemui.volume.VolumeComponent; +import com.android.systemui.wmshell.BubblesManager; import com.android.wm.shell.splitscreen.SplitScreen; import org.junit.Before; @@ -223,6 +224,7 @@ public class StatusBarTest extends SysuiTestCase { @Mock private UserSwitcherController mUserSwitcherController; @Mock private NetworkController mNetworkController; @Mock private VibratorHelper mVibratorHelper; + @Mock private BubblesManager mBubblesManager; @Mock private Bubbles mBubbles; @Mock private NotificationShadeWindowController mNotificationShadeWindowController; @Mock private NotificationIconAreaController mNotificationIconAreaController; @@ -377,6 +379,7 @@ public class StatusBarTest extends SysuiTestCase { wakefulnessLifecycle, mStatusBarStateController, mVibratorHelper, + Optional.of(mBubblesManager), Optional.of(mBubbles), mVisualStabilityManager, mDeviceProvisionedController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java index e8911a2f5d4e..c0722a459929 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java @@ -14,6 +14,8 @@ package com.android.systemui.utils.leaks; +import android.app.admin.DeviceAdminInfo; +import android.graphics.drawable.Drawable; import android.testing.LeakCheck; import com.android.systemui.statusbar.policy.SecurityController; @@ -109,4 +111,24 @@ public class FakeSecurityController extends BaseLeakChecker<SecurityControllerCa public void onUserSwitched(int newUserId) { } + + @Override + public boolean isParentalControlsEnabled() { + return false; + } + + @Override + public DeviceAdminInfo getDeviceAdminInfo() { + return null; + } + + @Override + public Drawable getIcon(DeviceAdminInfo info) { + return null; + } + + @Override + public CharSequence getLabel(DeviceAdminInfo info) { + return null; + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index d9e9a8b26f0f..88d04011e738 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.bubbles; +package com.android.systemui.wmshell; import static android.app.Notification.FLAG_BUBBLE; import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; @@ -64,6 +64,14 @@ import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.SysuiTestCase; +import com.android.systemui.bubbles.Bubble; +import com.android.systemui.bubbles.BubbleData; +import com.android.systemui.bubbles.BubbleDataRepository; +import com.android.systemui.bubbles.BubbleEntry; +import com.android.systemui.bubbles.BubbleLogger; +import com.android.systemui.bubbles.BubblePositioner; +import com.android.systemui.bubbles.BubbleStackView; +import com.android.systemui.bubbles.Bubbles; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardViewMediator; @@ -112,12 +120,12 @@ import java.util.List; /** * Tests the NotificationEntryManager setup with BubbleController. * The {@link NotifPipeline} setup with BubbleController is tested in - * {@link NewNotifPipelineBubbleControllerTest}. + * {@link NewNotifPipelineBubblesTest}. */ @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper(setAsMainLooper = true) -public class BubbleControllerTest extends SysuiTestCase { +public class BubblesTest extends SysuiTestCase { @Mock private NotificationEntryManager mNotificationEntryManager; @Mock @@ -157,6 +165,7 @@ public class BubbleControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor; + private BubblesManager mBubblesManager; private TestableBubbleController mBubbleController; private NotificationShadeWindowControllerImpl mNotificationShadeWindowController; private NotificationEntryListener mEntryListener; @@ -167,9 +176,12 @@ public class BubbleControllerTest extends SysuiTestCase { private ExpandableNotificationRow mRow2; private ExpandableNotificationRow mRow3; private ExpandableNotificationRow mNonBubbleNotifRow; + private BubbleEntry mBubbleEntry; + private BubbleEntry mBubbleEntry2; + private BubbleEntry mBubbleEntry3; @Mock - private BubbleController.BubbleExpandListener mBubbleExpandListener; + private Bubbles.BubbleExpandListener mBubbleExpandListener; @Mock private PendingIntent mDeleteIntent; @Mock @@ -226,6 +238,9 @@ public class BubbleControllerTest extends SysuiTestCase { mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent); mRow3 = mNotificationTestHelper.createBubble(mDeleteIntent); mNonBubbleNotifRow = mNotificationTestHelper.createRow(); + mBubbleEntry = BubblesManager.notifToBubbleEntry(mRow.getEntry()); + mBubbleEntry2 = BubblesManager.notifToBubbleEntry(mRow2.getEntry()); + mBubbleEntry3 = BubblesManager.notifToBubbleEntry(mRow3.getEntry()); // Return non-null notification data from the NEM when(mNotificationEntryManager @@ -258,26 +273,13 @@ public class BubbleControllerTest extends SysuiTestCase { mock(HeadsUpManager.class), mock(Handler.class) ); + when(mFeatureFlagsOldPipeline.isNewNotifPipelineRenderingEnabled()).thenReturn(false); mBubbleController = new TestableBubbleController( mContext, - mNotificationShadeWindowController, - mStatusBarStateController, - mShadeController, mBubbleData, - mConfigurationController, - interruptionStateProvider, - mZenModeController, - mLockscreenUserManager, - mNotificationGroupManager, - mNotificationEntryManager, - mNotifPipeline, - mFeatureFlagsOldPipeline, - mDumpManager, mFloatingContentCoordinator, mDataRepository, - mSysUiState, - mock(INotificationManager.class), mStatusBarService, mWindowManager, mWindowManagerShellWrapper, @@ -288,6 +290,25 @@ public class BubbleControllerTest extends SysuiTestCase { mPositioner); mBubbleController.setExpandListener(mBubbleExpandListener); + mBubblesManager = new BubblesManager( + mContext, + mBubbleController, + mNotificationShadeWindowController, + mStatusBarStateController, + mShadeController, + mConfigurationController, + mStatusBarService, + mock(INotificationManager.class), + interruptionStateProvider, + mZenModeController, + mLockscreenUserManager, + mNotificationGroupManager, + mNotificationEntryManager, + mNotifPipeline, + mSysUiState, + mFeatureFlagsOldPipeline, + mDumpManager); + // Get a reference to the BubbleController's entry listener verify(mNotificationEntryManager, atLeastOnce()) .addNotificationEntryListener(mEntryListenerCaptor.capture()); @@ -300,7 +321,7 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testAddBubble() { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertFalse(mSysUiStateBubblesExpanded); @@ -309,20 +330,20 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testHasBubbles() { assertFalse(mBubbleController.hasBubbles()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertFalse(mSysUiStateBubblesExpanded); } @Test public void testRemoveBubble() { - mBubbleController.updateBubble(mRow.getEntry()); - assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey())); + mBubbleController.updateBubble(mBubbleEntry); + assertNotNull(mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey())); assertTrue(mBubbleController.hasBubbles()); verify(mNotificationEntryManager).updateNotifications(any()); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey())); verify(mNotificationEntryManager, times(2)).updateNotifications(anyString()); @@ -331,14 +352,14 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testPromoteBubble_autoExpand() throws Exception { - mBubbleController.updateBubble(mRow2.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry2); + mBubbleController.updateBubble(mBubbleEntry); when(mNotificationEntryManager.getPendingOrActiveNotif(mRow.getEntry().getKey())) .thenReturn(mRow.getEntry()); when(mNotificationEntryManager.getPendingOrActiveNotif(mRow2.getEntry().getKey())) .thenReturn(mRow2.getEntry()); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); Bubble b = mBubbleData.getOverflowBubbleWithKey(mRow.getEntry().getKey()); assertThat(mBubbleData.getOverflowBubbles()).isEqualTo(ImmutableList.of(b)); @@ -361,18 +382,18 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testCancelOverflowBubble() { - mBubbleController.updateBubble(mRow2.getEntry()); - mBubbleController.updateBubble(mRow.getEntry(), /* suppressFlyout */ + mBubbleController.updateBubble(mBubbleEntry2); + mBubbleController.updateBubble(mBubbleEntry, /* suppressFlyout */ false, /* showInShade */ true); when(mNotificationEntryManager.getPendingOrActiveNotif(mRow.getEntry().getKey())) .thenReturn(mRow.getEntry()); when(mNotificationEntryManager.getPendingOrActiveNotif(mRow2.getEntry().getKey())) .thenReturn(mRow2.getEntry()); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL); + mRow.getEntry().getKey(), Bubbles.DISMISS_NOTIF_CANCEL); verify(mNotificationEntryManager, times(1)).performRemoveNotification( eq(mRow.getEntry().getSbn()), any(), anyInt()); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); @@ -381,11 +402,11 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testUserChange_doesNotRemoveNotif() { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_CHANGED); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_CHANGED); verify(mNotificationEntryManager, never()).performRemoveNotification( eq(mRow.getEntry().getSbn()), any(), anyInt()); assertFalse(mBubbleController.hasBubbles()); @@ -395,15 +416,15 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testDismissStack() { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); verify(mNotificationEntryManager, times(1)).updateNotifications(any()); assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey())); - mBubbleController.updateBubble(mRow2.getEntry()); + mBubbleController.updateBubble(mBubbleEntry2); verify(mNotificationEntryManager, times(2)).updateNotifications(any()); assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey())); assertTrue(mBubbleController.hasBubbles()); - mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); verify(mNotificationEntryManager, times(3)).updateNotifications(any()); assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey())); assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey())); @@ -417,12 +438,12 @@ public class BubbleControllerTest extends SysuiTestCase { // Mark it as a bubble and add it explicitly mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // We should have bubbles & their notifs should not be suppressed assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Expand the stack BubbleStackView stackView = mBubbleController.getStackView(); @@ -434,7 +455,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Make sure the notif is suppressed assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Collapse mBubbleController.collapseStack(); @@ -450,15 +471,15 @@ public class BubbleControllerTest extends SysuiTestCase { // Mark it as a bubble and add it explicitly mEntryListener.onPendingEntryAdded(mRow.getEntry()); mEntryListener.onPendingEntryAdded(mRow2.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); - mBubbleController.updateBubble(mRow2.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); + mBubbleController.updateBubble(mBubbleEntry2); // We should have bubbles & their notifs should not be suppressed assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow2.getEntry())); + mBubbleEntry2.getKey(), mBubbleEntry2.getGroupKey())); // Expand BubbleStackView stackView = mBubbleController.getStackView(); @@ -472,7 +493,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Last added is the one that is expanded assertEquals(mRow2.getEntry().getKey(), mBubbleData.getSelectedBubble().getKey()); assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow2.getEntry())); + mBubbleEntry2.getKey(), mBubbleEntry2.getGroupKey())); // Switch which bubble is expanded mBubbleData.setSelectedBubble(mBubbleData.getBubbleInStackWithKey( @@ -481,7 +502,7 @@ public class BubbleControllerTest extends SysuiTestCase { assertEquals(mRow.getEntry().getKey(), mBubbleData.getBubbleInStackWithKey( stackView.getExpandedBubble().getKey()).getKey()); assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // collapse for previous bubble verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged( @@ -501,12 +522,12 @@ public class BubbleControllerTest extends SysuiTestCase { public void testExpansionRemovesShowInShadeAndDot() { // Mark it as a bubble and add it explicitly mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // We should have bubbles & their notifs should not be suppressed assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mTestableLooper.processAllMessages(); assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); @@ -520,7 +541,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Notif is suppressed after expansion assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Notif shouldn't show dot after expansion assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); } @@ -529,12 +550,12 @@ public class BubbleControllerTest extends SysuiTestCase { public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() { // Mark it as a bubble and add it explicitly mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // We should have bubbles & their notifs should not be suppressed assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mTestableLooper.processAllMessages(); assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); @@ -548,7 +569,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Notif is suppressed after expansion assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Notif shouldn't show dot after expansion assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); @@ -558,7 +579,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Nothing should have changed // Notif is suppressed after expansion assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Notif shouldn't show dot after expansion assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); } @@ -568,8 +589,8 @@ public class BubbleControllerTest extends SysuiTestCase { // Mark it as a bubble and add it explicitly mEntryListener.onPendingEntryAdded(mRow.getEntry()); mEntryListener.onPendingEntryAdded(mRow2.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); - mBubbleController.updateBubble(mRow2.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); + mBubbleController.updateBubble(mBubbleEntry2); // Expand BubbleStackView stackView = mBubbleController.getStackView(); @@ -584,13 +605,13 @@ public class BubbleControllerTest extends SysuiTestCase { assertEquals(mRow2.getEntry().getKey(), mBubbleData.getBubbleInStackWithKey( stackView.getExpandedBubble().getKey()).getKey()); assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow2.getEntry())); + mBubbleEntry2.getKey(), mBubbleEntry2.getGroupKey())); // Dismiss currently expanded mBubbleController.removeBubble( mBubbleData.getBubbleInStackWithKey( stackView.getExpandedBubble().getKey()).getKey(), - BubbleController.DISMISS_USER_GESTURE); + Bubbles.DISMISS_USER_GESTURE); verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().getKey()); // Make sure first bubble is selected @@ -602,7 +623,7 @@ public class BubbleControllerTest extends SysuiTestCase { mBubbleController.removeBubble( mBubbleData.getBubbleInStackWithKey( stackView.getExpandedBubble().getKey()).getKey(), - BubbleController.DISMISS_USER_GESTURE); + Bubbles.DISMISS_USER_GESTURE); // Make sure state changes and collapse happens verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey()); @@ -619,7 +640,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Add the auto expand bubble mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Expansion shouldn't change verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */, @@ -636,7 +657,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Add the auto expand bubble mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Expansion should change verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */, @@ -653,11 +674,11 @@ public class BubbleControllerTest extends SysuiTestCase { // Add the suppress notif bubble mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Notif should be suppressed because we were foreground assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Dot + flyout is hidden because notif is suppressed assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout()); @@ -667,22 +688,22 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testSuppressNotif_onUpdateNotif() { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Should not be suppressed assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Should show dot assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); // Update to suppress notif setMetadataFlags(mRow.getEntry(), Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Notif should be suppressed assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Dot + flyout is hidden because notif is suppressed assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout()); @@ -695,13 +716,13 @@ public class BubbleControllerTest extends SysuiTestCase { final String key = mRow.getEntry().getKey(); mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Simulate notification cancellation. mRemoveInterceptor.onNotificationRemoveRequested( mRow.getEntry().getKey(), mRow.getEntry(), REASON_APP_CANCEL); - mBubbleController.expandStackAndSelectBubble(mRow.getEntry()); + mBubbleController.expandStackAndSelectBubble(mBubbleEntry); assertTrue(mSysUiStateBubblesExpanded); } @@ -710,7 +731,7 @@ public class BubbleControllerTest extends SysuiTestCase { public void testMarkNewNotificationAsShowInShade() { mEntryListener.onPendingEntryAdded(mRow.getEntry()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mTestableLooper.processAllMessages(); assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); @@ -726,31 +747,31 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mRow.getEntry()); - mBubbleController.removeBubble(mRow.getEntry().getKey(), BubbleController.DISMISS_AGED); + mBubbleController.updateBubble(mBubbleEntry); + mBubbleController.removeBubble(mRow.getEntry().getKey(), Bubbles.DISMISS_AGED); verify(mDeleteIntent, never()).send(); } @Test public void testDeleteIntent_removeBubble_user() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); verify(mDeleteIntent, times(1)).send(); } @Test public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mRow.getEntry()); - mBubbleController.updateBubble(mRow2.getEntry()); - mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); + mBubbleController.updateBubble(mBubbleEntry); + mBubbleController.updateBubble(mBubbleEntry2); + mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); verify(mDeleteIntent, times(2)).send(); } @Test public void testRemoveBubble_noLongerBubbleAfterUpdate() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); mRow.getEntry().getSbn().getNotification().flags &= ~FLAG_BUBBLE; @@ -766,7 +787,7 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testRemoveBubble_succeeds_appCancel() { mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); @@ -780,7 +801,7 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testRemoveBubble_entryListenerRemove() { mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); @@ -792,11 +813,11 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void removeBubble_clearAllIntercepted() { mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested( mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL_ALL); @@ -805,17 +826,17 @@ public class BubbleControllerTest extends SysuiTestCase { assertTrue(intercepted); // Should update show in shade state assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); } @Test public void removeBubble_userDismissNotifIntercepted() { mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested( mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL); @@ -824,21 +845,21 @@ public class BubbleControllerTest extends SysuiTestCase { assertTrue(intercepted); // Should update show in shade state assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); } @Test public void removeNotif_inOverflow_intercepted() { // Get bubble with notif in shade. mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Dismiss the bubble into overflow. mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); assertFalse(mBubbleController.hasBubbles()); boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested( @@ -852,14 +873,14 @@ public class BubbleControllerTest extends SysuiTestCase { public void removeNotif_notInOverflow_notIntercepted() { // Get bubble with notif in shade. mEntryListener.onPendingEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_NO_LONGER_BUBBLE); + mRow.getEntry().getKey(), Bubbles.DISMISS_NO_LONGER_BUBBLE); assertFalse(mBubbleController.hasBubbles()); boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested( @@ -872,11 +893,11 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testOverflowBubble_maxReached_notInShade_bubbleRemoved() { mBubbleController.updateBubble( - mRow.getEntry(), /* suppressFlyout */ false, /* showInShade */ false); + mBubbleEntry, /* suppressFlyout */ false, /* showInShade */ false); mBubbleController.updateBubble( - mRow2.getEntry(), /* suppressFlyout */ false, /* showInShade */ false); + mBubbleEntry2, /* suppressFlyout */ false, /* showInShade */ false); mBubbleController.updateBubble( - mRow3.getEntry(), /* suppressFlyout */ false, /* showInShade */ false); + mBubbleEntry3, /* suppressFlyout */ false, /* showInShade */ false); when(mNotificationEntryManager.getPendingOrActiveNotif(mRow.getEntry().getKey())) .thenReturn(mRow.getEntry()); when(mNotificationEntryManager.getPendingOrActiveNotif(mRow2.getEntry().getKey())) @@ -887,12 +908,12 @@ public class BubbleControllerTest extends SysuiTestCase { mBubbleData.setMaxOverflowBubbles(1); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); assertEquals(mBubbleData.getBubbles().size(), 2); assertEquals(mBubbleData.getOverflowBubbles().size(), 1); mBubbleController.removeBubble( - mRow2.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow2.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); // Overflow max of 1 is reached; mRow is oldest, so it gets removed verify(mNotificationEntryManager, times(1)).performRemoveNotification( eq(mRow.getEntry().getSbn()), any(), eq(REASON_CANCEL)); @@ -902,22 +923,22 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testNotifyShadeSuppressionChange_notificationDismiss() { - BubbleController.NotificationSuppressionChangedListener listener = - mock(BubbleController.NotificationSuppressionChangedListener.class); + Bubbles.NotificationSuppressionChangedListener listener = + mock(Bubbles.NotificationSuppressionChangedListener.class); mBubbleData.setSuppressionChangedListener(listener); mEntryListener.onPendingEntryAdded(mRow.getEntry()); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mRemoveInterceptor.onNotificationRemoveRequested( mRow.getEntry().getKey(), mRow.getEntry(), REASON_CANCEL); // Should update show in shade state assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Should notify delegate that shade state changed verify(listener).onBubbleNotificationSuppressionChange( @@ -926,21 +947,21 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void testNotifyShadeSuppressionChange_bubbleExpanded() { - BubbleController.NotificationSuppressionChangedListener listener = - mock(BubbleController.NotificationSuppressionChangedListener.class); + Bubbles.NotificationSuppressionChangedListener listener = + mock(Bubbles.NotificationSuppressionChangedListener.class); mBubbleData.setSuppressionChangedListener(listener); mEntryListener.onPendingEntryAdded(mRow.getEntry()); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mBubbleData.setExpanded(true); // Once a bubble is expanded the notif is suppressed assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Should notify delegate that shade state changed verify(listener).onBubbleNotificationSuppressionChange( @@ -959,11 +980,11 @@ public class BubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); // WHEN the summary is dismissed - mBubbleController.handleDismissalInterception(groupSummary.getEntry()); + mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); // THEN the summary and bubbled child are suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - groupedBubble.getEntry())); + groupedBubble.getEntry().getKey(), groupSummary.getEntry().getSbn().getGroupKey())); assertTrue(mBubbleData.isSummarySuppressed(groupSummary.getEntry().getSbn().getGroupKey())); } @@ -979,7 +1000,7 @@ public class BubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); // GIVEN the summary is dismissed - mBubbleController.handleDismissalInterception(groupSummary.getEntry()); + mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); // WHEN the summary is cancelled by the app mEntryListener.onEntryRemoved(groupSummary.getEntry(), null, false, REASON_APP_CANCEL); @@ -1002,7 +1023,7 @@ public class BubbleControllerTest extends SysuiTestCase { groupSummary.addChildNotification(groupedBubble); // WHEN the summary is dismissed - mBubbleController.handleDismissalInterception(groupSummary.getEntry()); + mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); // THEN only the NON-bubble children are dismissed List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren(); @@ -1017,7 +1038,8 @@ public class BubbleControllerTest extends SysuiTestCase { // THEN the bubble child is suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - groupedBubble.getEntry())); + groupedBubble.getEntry().getKey(), + groupedBubble.getEntry().getSbn().getGroupKey())); // THEN the summary is removed from GroupManager verify(mNotificationGroupManager, times(1)).onEntryRemoved(groupSummary.getEntry()); @@ -1031,18 +1053,18 @@ public class BubbleControllerTest extends SysuiTestCase { @Test public void test_notVisuallyInterruptive_updateOverflowBubble_notAdded() { // Setup - mBubbleController.updateBubble(mRow.getEntry()); - mBubbleController.updateBubble(mRow2.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); + mBubbleController.updateBubble(mBubbleEntry2); assertTrue(mBubbleController.hasBubbles()); // Overflow it mBubbleData.dismissBubbleWithKey(mRow.getEntry().getKey(), - BubbleController.DISMISS_USER_GESTURE); + Bubbles.DISMISS_USER_GESTURE); assertThat(mBubbleData.hasBubbleInStackWithKey(mRow.getEntry().getKey())).isFalse(); assertThat(mBubbleData.hasOverflowBubbleWithKey(mRow.getEntry().getKey())).isTrue(); // Test - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertThat(mBubbleData.hasBubbleInStackWithKey(mRow.getEntry().getKey())).isFalse(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java index b9394ff3f26a..99c8ca417778 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.bubbles; +package com.android.systemui.wmshell; import static android.app.Notification.FLAG_BUBBLE; import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; @@ -46,7 +46,6 @@ import android.content.res.Configuration; import android.graphics.Insets; import android.graphics.Rect; import android.hardware.display.AmbientDisplayConfiguration; -import android.hardware.face.FaceManager; import android.os.Handler; import android.os.PowerManager; import android.service.dreams.IDreamManager; @@ -60,8 +59,14 @@ import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.statusbar.IStatusBarService; -import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; +import com.android.systemui.bubbles.BubbleData; +import com.android.systemui.bubbles.BubbleDataRepository; +import com.android.systemui.bubbles.BubbleEntry; +import com.android.systemui.bubbles.BubbleLogger; +import com.android.systemui.bubbles.BubblePositioner; +import com.android.systemui.bubbles.BubbleStackView; +import com.android.systemui.bubbles.Bubbles; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardViewMediator; @@ -69,9 +74,7 @@ import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.RankingBuilder; -import com.android.systemui.statusbar.SuperStatusBarViewFactory; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationFilter; @@ -81,10 +84,8 @@ import com.android.systemui.statusbar.notification.collection.legacy.Notificatio import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationTestHelper; -import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.phone.LockscreenLockIconController; import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl; import com.android.systemui.statusbar.phone.NotificationShadeWindowView; import com.android.systemui.statusbar.phone.ShadeController; @@ -92,7 +93,6 @@ import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.systemui.util.InjectionInflationController; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.FloatingContentCoordinator; @@ -111,18 +111,18 @@ import java.util.List; /** * Tests the NotifPipeline setup with BubbleController. * The NotificationEntryManager setup with BubbleController is tested in - * {@link BubbleControllerTest}. + * {@link BubblesTest}. */ @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper(setAsMainLooper = true) -public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { +public class NewNotifPipelineBubblesTest extends SysuiTestCase { @Mock private NotificationEntryManager mNotificationEntryManager; @Mock private NotificationGroupManagerLegacy mNotificationGroupManager; @Mock - private BubbleController.NotifCallback mNotifCallback; + private BubblesManager.NotifCallback mNotifCallback; @Mock private WindowManager mWindowManager; @Mock @@ -136,8 +136,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Mock private ZenModeConfig mZenModeConfig; @Mock - private FaceManager mFaceManager; - @Mock private NotificationLockscreenUserManager mLockscreenUserManager; @Mock private SysuiStatusBarStateController mStatusBarStateController; @@ -156,6 +154,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor<NotifCollectionListener> mNotifListenerCaptor; + private BubblesManager mBubblesManager; private TestableBubbleController mBubbleController; private NotificationShadeWindowControllerImpl mNotificationShadeWindowController; private NotifCollectionListener mEntryListener; @@ -163,8 +162,10 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { private ExpandableNotificationRow mRow; private ExpandableNotificationRow mRow2; private ExpandableNotificationRow mNonBubbleNotifRow; + private BubbleEntry mBubbleEntry; + private BubbleEntry mBubbleEntry2; @Mock - private BubbleController.BubbleExpandListener mBubbleExpandListener; + private Bubbles.BubbleExpandListener mBubbleExpandListener; @Mock private PendingIntent mDeleteIntent; @Mock @@ -174,16 +175,12 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Mock private ShadeController mShadeController; @Mock - private NotificationShelfComponent mNotificationShelfComponent; - @Mock private NotifPipeline mNotifPipeline; @Mock private FeatureFlags mFeatureFlagsNewPipeline; @Mock private DumpManager mDumpManager; @Mock - private LockscreenLockIconController mLockIconController; - @Mock private IStatusBarService mStatusBarService; @Mock private LauncherApps mLauncherApps; @@ -197,7 +194,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { private BubbleData mBubbleData; private TestableLooper mTestableLooper; - private SuperStatusBarViewFactory mSuperStatusBarViewFactory; @Before public void setUp() throws Exception { @@ -205,26 +201,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { mTestableLooper = TestableLooper.get(this); - mContext.addMockSystemService(FaceManager.class, mFaceManager); when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors); - mSuperStatusBarViewFactory = new SuperStatusBarViewFactory(mContext, - new InjectionInflationController(SystemUIFactory.getInstance().getSysUIComponent() - .createViewInstanceCreatorFactory()), - new NotificationShelfComponent.Builder() { - @Override - public NotificationShelfComponent.Builder notificationShelf( - NotificationShelf view) { - return this; - } - - @Override - public NotificationShelfComponent build() { - return mNotificationShelfComponent; - } - }, - mLockIconController); - mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext, mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController, @@ -240,6 +218,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { mRow = mNotificationTestHelper.createBubble(mDeleteIntent); mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent); mNonBubbleNotifRow = mNotificationTestHelper.createRow(); + mBubbleEntry = BubblesManager.notifToBubbleEntry(mRow.getEntry()); + mBubbleEntry2 = BubblesManager.notifToBubbleEntry(mRow2.getEntry()); mZenModeConfig.suppressedVisualEffects = 0; when(mZenModeController.getConfig()).thenReturn(mZenModeConfig); @@ -265,23 +245,9 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { when(mFeatureFlagsNewPipeline.isNewNotifPipelineRenderingEnabled()).thenReturn(true); mBubbleController = new TestableBubbleController( mContext, - mNotificationShadeWindowController, - mStatusBarStateController, - mShadeController, mBubbleData, - mConfigurationController, - interruptionStateProvider, - mZenModeController, - mLockscreenUserManager, - mNotificationGroupManager, - mNotificationEntryManager, - mNotifPipeline, - mFeatureFlagsNewPipeline, - mDumpManager, mFloatingContentCoordinator, mDataRepository, - mSysUiState, - mock(INotificationManager.class), mStatusBarService, mWindowManager, mWindowManagerShellWrapper, @@ -290,9 +256,28 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { mock(Handler.class), mock(ShellTaskOrganizer.class), mPositioner); - mBubbleController.addNotifCallback(mNotifCallback); mBubbleController.setExpandListener(mBubbleExpandListener); + mBubblesManager = new BubblesManager( + mContext, + mBubbleController, + mNotificationShadeWindowController, + mStatusBarStateController, + mShadeController, + mConfigurationController, + mStatusBarService, + mock(INotificationManager.class), + interruptionStateProvider, + mZenModeController, + mLockscreenUserManager, + mNotificationGroupManager, + mNotificationEntryManager, + mNotifPipeline, + mSysUiState, + mFeatureFlagsNewPipeline, + mDumpManager); + mBubblesManager.addNotifCallback(mNotifCallback); + // Get a reference to the BubbleController's entry listener verify(mNotifPipeline, atLeastOnce()) .addCollectionListener(mNotifListenerCaptor.capture()); @@ -301,26 +286,26 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void testAddBubble() { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); } @Test public void testHasBubbles() { assertFalse(mBubbleController.hasBubbles()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); } @Test public void testRemoveBubble() { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey())); assertTrue(mBubbleController.hasBubbles()); verify(mNotifCallback, times(1)).invalidateNotifications(anyString()); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey())); verify(mNotifCallback, times(2)).invalidateNotifications(anyString()); } @@ -328,17 +313,18 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void testRemoveBubble_withDismissedNotif_inOverflow() { mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); - assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry())); + assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Make it look like dismissed notif mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).setSuppressNotification(true); // Now remove the bubble mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); assertTrue(mBubbleData.hasOverflowBubbleWithKey(mRow.getEntry().getKey())); // We don't remove the notification since the bubble is still in overflow. @@ -349,19 +335,20 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void testRemoveBubble_withDismissedNotif_notInOverflow() { mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); when(mNotificationEntryManager.getPendingOrActiveNotif(mRow.getEntry().getKey())) .thenReturn(mRow.getEntry()); assertTrue(mBubbleController.hasBubbles()); - assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry())); + assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Make it look like dismissed notif mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).setSuppressNotification(true); // Now remove the bubble mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL); + mRow.getEntry().getKey(), Bubbles.DISMISS_NOTIF_CANCEL); assertFalse(mBubbleData.hasOverflowBubbleWithKey(mRow.getEntry().getKey())); // Since the notif is dismissed and not in overflow, once the bubble is removed, @@ -373,15 +360,15 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void testDismissStack() { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); verify(mNotifCallback, times(1)).invalidateNotifications(anyString()); assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey())); - mBubbleController.updateBubble(mRow2.getEntry()); + mBubbleController.updateBubble(mBubbleEntry2); verify(mNotifCallback, times(2)).invalidateNotifications(anyString()); assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey())); assertTrue(mBubbleController.hasBubbles()); - mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); verify(mNotifCallback, times(3)).invalidateNotifications(anyString()); assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey())); assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey())); @@ -393,12 +380,12 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Mark it as a bubble and add it explicitly mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // We should have bubbles & their notifs should not be suppressed assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Expand the stack BubbleStackView stackView = mBubbleController.getStackView(); @@ -407,7 +394,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); // Make sure the notif is suppressed - assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry())); + assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Collapse mBubbleController.collapseStack(); @@ -421,15 +409,15 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Mark it as a bubble and add it explicitly mEntryListener.onEntryAdded(mRow.getEntry()); mEntryListener.onEntryAdded(mRow2.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); - mBubbleController.updateBubble(mRow2.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); + mBubbleController.updateBubble(mBubbleEntry2); // We should have bubbles & their notifs should not be suppressed assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow2.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Expand BubbleStackView stackView = mBubbleController.getStackView(); @@ -440,15 +428,17 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Last added is the one that is expanded assertEquals(mRow2.getEntry().getKey(), mBubbleData.getSelectedBubble().getKey()); - assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry())); + assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( + mBubbleEntry2.getKey(), mBubbleEntry2.getGroupKey())); // Switch which bubble is expanded - mBubbleData.setSelectedBubble(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey())); + mBubbleData.setSelectedBubble(mBubbleData.getBubbleInStackWithKey( + mRow.getEntry().getKey())); mBubbleData.setExpanded(true); assertEquals(mRow.getEntry().getKey(), mBubbleData.getBubbleInStackWithKey( stackView.getExpandedBubble().getKey()).getKey()); assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // collapse for previous bubble verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged( @@ -467,11 +457,12 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { public void testExpansionRemovesShowInShadeAndDot() { // Mark it as a bubble and add it explicitly mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // We should have bubbles & their notifs should not be suppressed assertTrue(mBubbleController.hasBubbles()); - assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry())); + assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mTestableLooper.processAllMessages(); assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); @@ -483,7 +474,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Notif is suppressed after expansion assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Notif shouldn't show dot after expansion assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); } @@ -492,12 +483,12 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() { // Mark it as a bubble and add it explicitly mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // We should have bubbles & their notifs should not be suppressed assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mTestableLooper.processAllMessages(); assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); @@ -509,7 +500,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Notif is suppressed after expansion assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Notif shouldn't show dot after expansion assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); @@ -519,7 +510,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Nothing should have changed // Notif is suppressed after expansion assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Notif shouldn't show dot after expansion assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); } @@ -529,8 +520,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Mark it as a bubble and add it explicitly mEntryListener.onEntryAdded(mRow.getEntry()); mEntryListener.onEntryAdded(mRow2.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); - mBubbleController.updateBubble(mRow2.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); + mBubbleController.updateBubble(mBubbleEntry2); // Expand BubbleStackView stackView = mBubbleController.getStackView(); @@ -543,13 +534,13 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertEquals(mRow2.getEntry().getKey(), mBubbleData.getBubbleInStackWithKey( stackView.getExpandedBubble().getKey()).getKey()); assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow2.getEntry())); + mBubbleEntry2.getKey(), mBubbleEntry2.getGroupKey())); // Dismiss currently expanded mBubbleController.removeBubble( mBubbleData.getBubbleInStackWithKey( stackView.getExpandedBubble().getKey()).getKey(), - BubbleController.DISMISS_USER_GESTURE); + Bubbles.DISMISS_USER_GESTURE); verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().getKey()); // Make sure first bubble is selected @@ -561,7 +552,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { mBubbleController.removeBubble( mBubbleData.getBubbleInStackWithKey( stackView.getExpandedBubble().getKey()).getKey(), - BubbleController.DISMISS_USER_GESTURE); + Bubbles.DISMISS_USER_GESTURE); // Make sure state changes and collapse happens verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey()); @@ -576,7 +567,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Add the auto expand bubble mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Expansion shouldn't change verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */, @@ -591,7 +582,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Add the auto expand bubble mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Expansion should change verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */, @@ -606,11 +597,11 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Add the suppress notif bubble mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Notif should be suppressed because we were foreground assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Dot + flyout is hidden because notif is suppressed assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout()); @@ -618,22 +609,22 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void testSuppressNotif_onUpdateNotif() { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Should not be suppressed assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Should show dot assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); // Update to suppress notif setMetadataFlags(mRow.getEntry(), Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); // Notif should be suppressed assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Dot + flyout is hidden because notif is suppressed assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout()); @@ -643,7 +634,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { public void testMarkNewNotificationAsShowInShade() { mEntryListener.onEntryAdded(mRow.getEntry()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mTestableLooper.processAllMessages(); assertTrue(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot()); @@ -659,31 +650,31 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mRow.getEntry()); - mBubbleController.removeBubble(mRow.getEntry().getKey(), BubbleController.DISMISS_AGED); + mBubbleController.updateBubble(mBubbleEntry); + mBubbleController.removeBubble(mRow.getEntry().getKey(), Bubbles.DISMISS_AGED); verify(mDeleteIntent, never()).send(); } @Test public void testDeleteIntent_removeBubble_user() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); verify(mDeleteIntent, times(1)).send(); } @Test public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mRow.getEntry()); - mBubbleController.updateBubble(mRow2.getEntry()); - mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); + mBubbleController.updateBubble(mBubbleEntry); + mBubbleController.updateBubble(mBubbleEntry2); + mBubbleData.dismissAll(Bubbles.DISMISS_USER_GESTURE); verify(mDeleteIntent, times(2)).send(); } @Test public void testRemoveBubble_noLongerBubbleAfterUpdate() throws PendingIntent.CanceledException { - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); mRow.getEntry().getSbn().getNotification().flags &= ~FLAG_BUBBLE; @@ -699,7 +690,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void testRemoveBubble_entryListenerRemove() { mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); @@ -711,36 +702,36 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void removeBubble_intercepted() { mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); - boolean intercepted = mBubbleController.handleDismissalInterception(mRow.getEntry()); + boolean intercepted = mBubblesManager.handleDismissalInterception(mRow.getEntry()); // Intercept! assertTrue(intercepted); // Should update show in shade state - assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry())); + assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); } @Test public void removeBubble_dismissIntoOverflow_intercepted() { mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Dismiss the bubble - mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE); + mBubbleController.removeBubble(mRow.getEntry().getKey(), Bubbles.DISMISS_USER_GESTURE); assertFalse(mBubbleController.hasBubbles()); // Dismiss the notification - boolean intercepted = mBubbleController.handleDismissalInterception(mRow.getEntry()); + boolean intercepted = mBubblesManager.handleDismissalInterception(mRow.getEntry()); // Intercept dismissal since bubble is going into overflow assertTrue(intercepted); @@ -749,19 +740,18 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void removeBubble_notIntercepted() { mEntryListener.onEntryAdded(mRow.getEntry()); - mBubbleController.updateBubble(mRow.getEntry()); + mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Dismiss the bubble - mBubbleController.removeBubble( - mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL); + mBubbleController.removeBubble(mRow.getEntry().getKey(), Bubbles.DISMISS_NOTIF_CANCEL); assertFalse(mBubbleController.hasBubbles()); // Dismiss the notification - boolean intercepted = mBubbleController.handleDismissalInterception(mRow.getEntry()); + boolean intercepted = mBubblesManager.handleDismissalInterception(mRow.getEntry()); // Not a bubble anymore so we don't intercept dismissal. assertFalse(intercepted); @@ -769,21 +759,21 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void testNotifyShadeSuppressionChange_notificationDismiss() { - BubbleController.NotificationSuppressionChangedListener listener = - mock(BubbleController.NotificationSuppressionChangedListener.class); + Bubbles.NotificationSuppressionChangedListener listener = + mock(Bubbles.NotificationSuppressionChangedListener.class); mBubbleData.setSuppressionChangedListener(listener); mEntryListener.onEntryAdded(mRow.getEntry()); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); - mBubbleController.handleDismissalInterception(mRow.getEntry()); + mBubblesManager.handleDismissalInterception(mRow.getEntry()); // Should update show in shade state assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Should notify delegate that shade state changed verify(listener).onBubbleNotificationSuppressionChange( @@ -792,21 +782,21 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { @Test public void testNotifyShadeSuppressionChange_bubbleExpanded() { - BubbleController.NotificationSuppressionChangedListener listener = - mock(BubbleController.NotificationSuppressionChangedListener.class); + Bubbles.NotificationSuppressionChangedListener listener = + mock(Bubbles.NotificationSuppressionChangedListener.class); mBubbleData.setSuppressionChangedListener(listener); mEntryListener.onEntryAdded(mRow.getEntry()); assertTrue(mBubbleController.hasBubbles()); assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); mBubbleData.setExpanded(true); // Once a bubble is expanded the notif is suppressed assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - mRow.getEntry())); + mBubbleEntry.getKey(), mBubbleEntry.getGroupKey())); // Should notify delegate that shade state changed verify(listener).onBubbleNotificationSuppressionChange( @@ -825,11 +815,12 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); // WHEN the summary is dismissed - mBubbleController.handleDismissalInterception(groupSummary.getEntry()); + mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); // THEN the summary and bubbled child are suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - groupedBubble.getEntry())); + groupedBubble.getEntry().getKey(), + groupedBubble.getEntry().getSbn().getGroupKey())); assertTrue(mBubbleData.isSummarySuppressed(groupSummary.getEntry().getSbn().getGroupKey())); } @@ -845,7 +836,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); // GIVEN the summary is dismissed - mBubbleController.handleDismissalInterception(groupSummary.getEntry()); + mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); // WHEN the summary is cancelled by the app mEntryListener.onEntryRemoved(groupSummary.getEntry(), 0); @@ -868,7 +859,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { groupSummary.addChildNotification(groupedBubble); // WHEN the summary is dismissed - mBubbleController.handleDismissalInterception(groupSummary.getEntry()); + mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); // THEN only the NON-bubble children are dismissed List<ExpandableNotificationRow> childrenRows = groupSummary.getAttachedChildren(); @@ -882,11 +873,13 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // THEN the bubble child still exists as a bubble and is suppressed from the shade assertTrue(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - groupedBubble.getEntry())); + groupedBubble.getEntry().getKey(), + groupedBubble.getEntry().getSbn().getGroupKey())); // THEN the summary is also suppressed from the shade assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade( - groupSummary.getEntry())); + groupSummary.getEntry().getKey(), + groupSummary.getEntry().getSbn().getGroupKey())); } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java new file mode 100644 index 000000000000..2273bc48ce8b --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.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.systemui.wmshell; + +import android.content.Context; +import android.content.pm.LauncherApps; +import android.os.Handler; +import android.view.WindowManager; + +import com.android.internal.statusbar.IStatusBarService; +import com.android.systemui.bubbles.BubbleController; +import com.android.systemui.bubbles.BubbleData; +import com.android.systemui.bubbles.BubbleDataRepository; +import com.android.systemui.bubbles.BubbleLogger; +import com.android.systemui.bubbles.BubblePositioner; +import com.android.wm.shell.ShellTaskOrganizer; +import com.android.wm.shell.WindowManagerShellWrapper; +import com.android.wm.shell.common.FloatingContentCoordinator; + +/** + * Testable BubbleController subclass that immediately synchronizes surfaces. + */ +public class TestableBubbleController extends BubbleController { + + // Let's assume surfaces can be synchronized immediately. + TestableBubbleController(Context context, + BubbleData data, + FloatingContentCoordinator floatingContentCoordinator, + BubbleDataRepository dataRepository, + IStatusBarService statusBarService, + WindowManager windowManager, + WindowManagerShellWrapper windowManagerShellWrapper, + LauncherApps launcherApps, + BubbleLogger bubbleLogger, + Handler mainHandler, + ShellTaskOrganizer shellTaskOrganizer, + BubblePositioner positioner) { + super(context, data, Runnable::run, floatingContentCoordinator, dataRepository, + statusBarService, windowManager, windowManagerShellWrapper, launcherApps, + bubbleLogger, mainHandler, shellTaskOrganizer, positioner); + setInflateSynchronously(true); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptStateProviderImpl.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java index 17dc76b38a56..7847c57dbc32 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptStateProviderImpl.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.bubbles; +package com.android.systemui.wmshell; import android.content.ContentResolver; import android.hardware.display.AmbientDisplayConfiguration; diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp index 613d28b20b8e..5526c657b874 100644 --- a/packages/Tethering/Android.bp +++ b/packages/Tethering/Android.bp @@ -37,7 +37,6 @@ java_defaults { libs: [ "framework-statsd.stubs.module_lib", "framework-tethering.impl", - "framework-telephony-stubs", "framework-wifi", "unsupportedappusage", ], diff --git a/packages/Tethering/OWNERS b/packages/Tethering/OWNERS index 5b42d490411e..a6c21fc16bec 100644 --- a/packages/Tethering/OWNERS +++ b/packages/Tethering/OWNERS @@ -1,2 +1,2 @@ -include platform/packages/modules/NetworkStack/:/OWNERS -markchien@google.com +set noparent # while performing migration - b/167962976 +baligh@google.com diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp index bf643cdcecc5..ddb6880753b4 100644 --- a/packages/Tethering/common/TetheringLib/Android.bp +++ b/packages/Tethering/common/TetheringLib/Android.bp @@ -16,7 +16,10 @@ java_sdk_library { name: "framework-tethering", defaults: ["framework-module-defaults"], - impl_library_visibility: ["//frameworks/base/packages/Tethering:__subpackages__"], + impl_library_visibility: [ + "//frameworks/base/packages/Tethering:__subpackages__", + "//packages/modules/Connectivity/Tethering:__subpackages__", + ], srcs: [":framework-tethering-srcs"], diff --git a/packages/Tethering/tests/Android.bp b/packages/Tethering/tests/Android.bp index cb0a20bdf0e8..731144cee0fb 100644 --- a/packages/Tethering/tests/Android.bp +++ b/packages/Tethering/tests/Android.bp @@ -19,5 +19,6 @@ filegroup { srcs: ["jarjar-rules.txt"], visibility: [ "//frameworks/base/packages/Tethering/tests:__subpackages__", + "//packages/modules/Connectivity/Tethering/tests:__subpackages__", ] } diff --git a/packages/Tethering/tests/unit/Android.bp b/packages/Tethering/tests/unit/Android.bp index ef556cf92392..956e2e832589 100644 --- a/packages/Tethering/tests/unit/Android.bp +++ b/packages/Tethering/tests/unit/Android.bp @@ -59,7 +59,6 @@ java_defaults { "ext", "framework-minus-apex", "framework-res", - "framework-telephony-stubs", "framework-tethering.impl", "framework-wifi.stubs.module_lib", ], @@ -78,6 +77,7 @@ android_library { defaults: ["TetheringTestsDefaults"], visibility: [ "//frameworks/base/packages/Tethering/tests/integration", + "//packages/modules/Connectivity/Tethering/tests/integration", ] } diff --git a/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-bn/strings.xml b/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-bn/strings.xml deleted file mode 100644 index 3e9c962f8946..000000000000 --- a/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-bn/strings.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ 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. - --> - -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay" msgid="7305489596221077240">"পাঞ্চ হোল কাট-আউট"</string> -</resources> diff --git a/rs/java/android/renderscript/Font.java b/rs/java/android/renderscript/Font.java index df9d8019f28d..e47ec4b31700 100644 --- a/rs/java/android/renderscript/Font.java +++ b/rs/java/android/renderscript/Font.java @@ -19,6 +19,7 @@ package android.renderscript; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; import android.content.res.Resources; +import android.os.Build; import android.os.Environment; import java.io.File; @@ -237,7 +238,7 @@ public class Font extends BaseObj { * * Returns default font if no match could be found. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) static public Font create(RenderScript rs, Resources res, String familyName, Style fontStyle, float pointSize) { String fileName = getFontFileName(familyName, fontStyle); String fontPath = Environment.getRootDirectory().getAbsolutePath(); diff --git a/rs/java/android/renderscript/Mesh.java b/rs/java/android/renderscript/Mesh.java index 826225a70d86..1a4d1fd5afbb 100644 --- a/rs/java/android/renderscript/Mesh.java +++ b/rs/java/android/renderscript/Mesh.java @@ -17,6 +17,7 @@ package android.renderscript; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.util.Vector; @@ -606,7 +607,7 @@ public class Mesh extends BaseObj { * channels are present in the mesh * **/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) { mRS = rs; mVtxCount = 0; @@ -663,7 +664,7 @@ public class Mesh extends BaseObj { * @return this * **/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public TriangleMeshBuilder addVertex(float x, float y) { if (mVtxSize != 2) { throw new IllegalStateException("add mistmatch with declared components."); @@ -769,7 +770,7 @@ public class Mesh extends BaseObj { * * @return this **/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public TriangleMeshBuilder addTriangle(int idx1, int idx2, int idx3) { if((idx1 >= mMaxIndex) || (idx1 < 0) || (idx2 >= mMaxIndex) || (idx2 < 0) || @@ -802,7 +803,7 @@ public class Mesh extends BaseObj { * accessible memory * **/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Mesh create(boolean uploadToBufferObject) { Element.Builder b = new Element.Builder(mRS); b.add(Element.createVector(mRS, diff --git a/rs/java/android/renderscript/ProgramStore.java b/rs/java/android/renderscript/ProgramStore.java index 7e61347ee218..1952b8860033 100644 --- a/rs/java/android/renderscript/ProgramStore.java +++ b/rs/java/android/renderscript/ProgramStore.java @@ -17,6 +17,7 @@ package android.renderscript; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** @@ -308,7 +309,7 @@ public class ProgramStore extends BaseObj { * * @param rs Context to which the program will belong. **/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static ProgramStore BLEND_ALPHA_DEPTH_NONE(RenderScript rs) { if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH == null) { ProgramStore.Builder builder = new ProgramStore.Builder(rs); diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java index 92b8608f4f6c..bd26d44bed6f 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java @@ -25,6 +25,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.AppGlobals; +import android.content.ClipData; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -296,11 +297,29 @@ final class RemoteAugmentedAutofillService dataset.getId(), clientState); try { final ArrayList<AutofillId> fieldIds = dataset.getFieldIds(); - final int size = fieldIds.size(); - final boolean hideHighlight = size == 1 - && fieldIds.get(0).equals(focusedId); - client.autofill(sessionId, fieldIds, dataset.getFieldValues(), - hideHighlight); + final ClipData content = dataset.getFieldContent(); + if (content != null) { + final AutofillId fieldId = fieldIds.get(0); + if (sDebug) { + Slog.d(TAG, "Calling client autofillContent(): " + + "id=" + fieldId + ", content=" + content); + } + client.autofillContent(sessionId, fieldId, content); + } else { + final int size = fieldIds.size(); + final boolean hideHighlight = size == 1 + && fieldIds.get(0).equals(focusedId); + if (sDebug) { + Slog.d(TAG, "Calling client autofill(): " + + "ids=" + fieldIds + + ", values=" + dataset.getFieldValues()); + } + client.autofill( + sessionId, + fieldIds, + dataset.getFieldValues(), + hideHighlight); + } inlineSuggestionsCallback.apply( InlineFillUi.emptyUi(focusedId)); } catch (RemoteException e) { diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index f596b072d713..0302b2251f10 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -47,6 +47,7 @@ import android.app.IAssistDataReceiver; import android.app.assist.AssistStructure; import android.app.assist.AssistStructure.AutofillOverlay; import android.app.assist.AssistStructure.ViewNode; +import android.content.ClipData; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -1493,11 +1494,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState Slog.d(TAG, "Auth result for augmented autofill: sessionId=" + id + ", authId=" + authId + ", dataset=" + dataset); } - if (dataset == null - || dataset.getFieldIds().size() != 1 - || dataset.getFieldIds().get(0) == null - || dataset.getFieldValues().size() != 1 - || dataset.getFieldValues().get(0) == null) { + final AutofillId fieldId = (dataset != null && dataset.getFieldIds().size() == 1) + ? dataset.getFieldIds().get(0) : null; + final AutofillValue value = (dataset != null && dataset.getFieldValues().size() == 1) + ? dataset.getFieldValues().get(0) : null; + final ClipData content = (dataset != null) ? dataset.getFieldContent() : null; + if (fieldId == null || (value == null && content == null)) { if (sDebug) { Slog.d(TAG, "Rejecting empty/invalid auth result"); } @@ -1505,10 +1507,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState removeSelfLocked(); return; } - final List<AutofillId> fieldIds = dataset.getFieldIds(); - final List<AutofillValue> autofillValues = dataset.getFieldValues(); - final AutofillId fieldId = fieldIds.get(0); - final AutofillValue value = autofillValues.get(0); // Update state to ensure that after filling the field here we don't end up firing another // autofill request that will end up showing the same suggestions to the user again. When @@ -1524,13 +1522,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // Fill the value into the field. if (sDebug) { - Slog.d(TAG, "Filling after auth: fieldId=" + fieldId + ", value=" + value); + Slog.d(TAG, "Filling after auth: fieldId=" + fieldId + ", value=" + value + + ", content=" + content); } try { - mClient.autofill(id, fieldIds, autofillValues, true); + if (content != null) { + mClient.autofillContent(id, fieldId, content); + } else { + mClient.autofill(id, dataset.getFieldIds(), dataset.getFieldValues(), true); + } } catch (RemoteException e) { Slog.w(TAG, "Error filling after auth: fieldId=" + fieldId + ", value=" + value - + ", error=" + e); + + ", content=" + content, e); } // Clear the suggestions since the user already accepted one of them. diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 032820dc97f8..e32324941aef 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -309,6 +309,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind mFindDeviceCallback = callback; mRequest = request; mCallingPackage = callingPackage; + request.setCallingPackage(callingPackage); callback.asBinder().linkToDeath(CompanionDeviceManagerService.this /* recipient */, 0); final long callingIdentity = Binder.clearCallingIdentity(); diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index 4c8925bd4828..70cf04522c45 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -1122,4 +1122,8 @@ public abstract class PackageManagerInternal { public abstract IncrementalStatesInfo getIncrementalStatesInfo(String packageName, int filterCallingUid, int userId); + /** + * Notifies that a package has crashed or ANR'd. + */ + public abstract void notifyPackageCrashOrAnr(String packageName); } diff --git a/services/core/java/android/content/pm/TestUtilityService.java b/services/core/java/android/content/pm/TestUtilityService.java new file mode 100644 index 000000000000..426352b250f8 --- /dev/null +++ b/services/core/java/android/content/pm/TestUtilityService.java @@ -0,0 +1,30 @@ +/* + * 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.IBinder; + +/** + * Utility methods for testing and debugging. + */ +public interface TestUtilityService { + /** + * Verifies validity of the token passed as a parameter to holdLock(). Throws an exception if + * the token is invalid. + */ + void verifyHoldLockToken(IBinder token); +} diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 85d77f246bbb..21ad6de045bb 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2431,9 +2431,9 @@ public class ConnectivityService extends IConnectivityManager.Stub try { if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu); - mNMS.setMtu(iface, mtu); - } catch (Exception e) { - Slog.e(TAG, "exception in setMtu()" + e); + mNetd.interfaceSetMtu(iface, mtu); + } catch (RemoteException | ServiceSpecificException e) { + Slog.e(TAG, "exception in interfaceSetMtu()" + e); } } @@ -6078,7 +6078,7 @@ public class ConnectivityService extends IConnectivityManager.Stub for (final String iface : interfaceDiff.added) { try { if (DBG) log("Adding iface " + iface + " to network " + netId); - mNMS.addInterfaceToNetwork(iface, netId); + mNetd.networkAddInterface(netId, iface); wakeupModifyInterface(iface, caps, true); bs.noteNetworkInterfaceType(iface, legacyType); } catch (Exception e) { @@ -6090,7 +6090,7 @@ public class ConnectivityService extends IConnectivityManager.Stub try { if (DBG) log("Removing iface " + iface + " from network " + netId); wakeupModifyInterface(iface, caps, false); - mNMS.removeInterfaceFromNetwork(iface, netId); + mNetd.networkRemoveInterface(netId, iface); } catch (Exception e) { loge("Exception removing interface: " + e); } @@ -6256,9 +6256,9 @@ public class ConnectivityService extends IConnectivityManager.Stub final int newPermission = getNetworkPermission(newNc); if (oldPermission != newPermission && nai.created && !nai.isVPN()) { try { - mNMS.setNetworkPermission(nai.network.netId, newPermission); - } catch (RemoteException e) { - loge("Exception in setNetworkPermission: " + e); + mNetd.networkSetPermissionForNetwork(nai.network.netId, newPermission); + } catch (RemoteException | ServiceSpecificException e) { + loge("Exception in networkSetPermissionForNetwork: " + e); } } } @@ -6700,11 +6700,11 @@ public class ConnectivityService extends IConnectivityManager.Stub try { if (null != newNetwork) { - mNMS.setDefaultNetId(newNetwork.network.netId); + mNetd.networkSetDefault(newNetwork.network.netId); } else { - mNMS.clearDefaultNetId(); + mNetd.networkClearDefault(); } - } catch (Exception e) { + } catch (RemoteException | ServiceSpecificException e) { loge("Exception setting default network :" + e); } diff --git a/services/core/java/com/android/server/Dumpable.java b/services/core/java/com/android/server/Dumpable.java new file mode 100644 index 000000000000..d2bd66f59b62 --- /dev/null +++ b/services/core/java/com/android/server/Dumpable.java @@ -0,0 +1,40 @@ +/* + * 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; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.util.IndentingPrintWriter; + +/** + * Interface used to dump {@link SystemServer} state that is not associated with any service. + */ +public interface Dumpable { + + /** + * Dumps the state. + */ + void dump(@NonNull IndentingPrintWriter pw, @Nullable String[] args); + + /** + * Gets the name of the dumpable. + * + * <p>If not overridden, will return the simple class name. + */ + default String getDumpableName() { + return Dumpable.this.getClass().getSimpleName(); + } +} diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index 20f68da1592e..d4e912b65e17 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -75,9 +75,9 @@ public class GestureLauncherService extends SystemService { @VisibleForTesting static final long POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS = 500; /** - * Number of taps required to launch panic ui. + * Number of taps required to launch emergency gesture ui. */ - private static final int PANIC_POWER_TAP_COUNT_THRESHOLD = 5; + private static final int EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD = 5; /** * Number of taps required to launch camera shortcut. @@ -138,9 +138,9 @@ public class GestureLauncherService extends SystemService { private boolean mCameraDoubleTapPowerEnabled; /** - * Whether panic button gesture is currently enabled + * Whether emergency gesture is currently enabled */ - private boolean mPanicButtonGestureEnabled; + private boolean mEmergencyGestureEnabled; private long mLastPowerDown; private int mPowerButtonConsecutiveTaps; @@ -178,7 +178,7 @@ public class GestureLauncherService extends SystemService { "GestureLauncherService"); updateCameraRegistered(); updateCameraDoubleTapPowerEnabled(); - updatePanicButtonGestureEnabled(); + updateEmergencyGestureEnabled(); mUserId = ActivityManager.getCurrentUser(); mContext.registerReceiver(mUserReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED)); @@ -197,7 +197,7 @@ public class GestureLauncherService extends SystemService { Settings.Secure.getUriFor(Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED), false, mSettingObserver, mUserId); mContext.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.PANIC_GESTURE_ENABLED), + Settings.Secure.getUriFor(Settings.Secure.EMERGENCY_GESTURE_ENABLED), false, mSettingObserver, mUserId); } @@ -225,10 +225,10 @@ public class GestureLauncherService extends SystemService { } @VisibleForTesting - void updatePanicButtonGestureEnabled() { - boolean enabled = isPanicButtonGestureEnabled(mContext, mUserId); + void updateEmergencyGestureEnabled() { + boolean enabled = isEmergencyGestureEnabled(mContext, mUserId); synchronized (this) { - mPanicButtonGestureEnabled = enabled; + mEmergencyGestureEnabled = enabled; } } @@ -357,11 +357,11 @@ public class GestureLauncherService extends SystemService { } /** - * Whether to enable panic button gesture. + * Whether to enable emergency gesture. */ - public static boolean isPanicButtonGestureEnabled(Context context, int userId) { + public static boolean isEmergencyGestureEnabled(Context context, int userId) { return Settings.Secure.getIntForUser(context.getContentResolver(), - Settings.Secure.PANIC_GESTURE_ENABLED, 0, userId) != 0; + Settings.Secure.EMERGENCY_GESTURE_ENABLED, 0, userId) != 0; } /** @@ -409,7 +409,7 @@ public class GestureLauncherService extends SystemService { return false; } boolean launchCamera = false; - boolean launchPanic = false; + boolean launchEmergencyGesture = false; boolean intercept = false; long powerTapInterval; synchronized (this) { @@ -428,15 +428,15 @@ public class GestureLauncherService extends SystemService { mPowerButtonConsecutiveTaps++; mPowerButtonSlowConsecutiveTaps++; } - // Check if we need to launch camera or panic flows - if (mPanicButtonGestureEnabled) { + // Check if we need to launch camera or emergency gesture flows + if (mEmergencyGestureEnabled) { // Commit to intercepting the powerkey event after the second "quick" tap to avoid - // lockscreen changes between launching camera and the panic flow. + // lockscreen changes between launching camera and the emergency gesture flow. if (mPowerButtonConsecutiveTaps > 1) { intercept = interactive; } - if (mPowerButtonConsecutiveTaps == PANIC_POWER_TAP_COUNT_THRESHOLD) { - launchPanic = true; + if (mPowerButtonConsecutiveTaps == EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD) { + launchEmergencyGesture = true; } } if (mCameraDoubleTapPowerEnabled @@ -461,18 +461,18 @@ public class GestureLauncherService extends SystemService { mMetricsLogger.action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) powerTapInterval); } - } else if (launchPanic) { - Slog.i(TAG, "Panic gesture detected, launching panic."); - launchPanic = handlePanicButtonGesture(); + } else if (launchEmergencyGesture) { + Slog.i(TAG, "Emergency gesture detected, launching."); + launchEmergencyGesture = handleEmergencyGesture(); // TODO(b/160006048): Add logging } mMetricsLogger.histogram("power_consecutive_short_tap_count", mPowerButtonSlowConsecutiveTaps); mMetricsLogger.histogram("power_double_tap_interval", (int) powerTapInterval); - outLaunched.value = launchCamera || launchPanic; - // Intercept power key event if the press is part of a gesture (camera, panic) and the user - // has completed setup. + outLaunched.value = launchCamera || launchEmergencyGesture; + // Intercept power key event if the press is part of a gesture (camera, eGesture) and the + // user has completed setup. return intercept && isUserSetupComplete(); } @@ -512,27 +512,25 @@ public class GestureLauncherService extends SystemService { } /** - * @return true if panic ui was launched, false otherwise. + * @return true if emergency gesture UI was launched, false otherwise. */ @VisibleForTesting - boolean handlePanicButtonGesture() { - // TODO(b/160006048): This is the wrong way to launch panic ui. Rewrite this to go - // through SysUI + boolean handleEmergencyGesture() { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, - "GestureLauncher:handlePanicButtonGesture"); + "GestureLauncher:handleEmergencyGesture"); try { boolean userSetupComplete = isUserSetupComplete(); if (!userSetupComplete) { if (DBG) { Slog.d(TAG, String.format( - "userSetupComplete = %s, ignoring panic gesture.", + "userSetupComplete = %s, ignoring emergency gesture.", userSetupComplete)); } return false; } if (DBG) { Slog.d(TAG, String.format( - "userSetupComplete = %s, performing panic gesture.", + "userSetupComplete = %s, performing emergency gesture.", userSetupComplete)); } StatusBarManagerInternal service = LocalServices.getService( @@ -558,7 +556,7 @@ public class GestureLauncherService extends SystemService { registerContentObservers(); updateCameraRegistered(); updateCameraDoubleTapPowerEnabled(); - updatePanicButtonGestureEnabled(); + updateEmergencyGestureEnabled(); } } }; @@ -568,7 +566,7 @@ public class GestureLauncherService extends SystemService { if (userId == mUserId) { updateCameraRegistered(); updateCameraDoubleTapPowerEnabled(); - updatePanicButtonGestureEnabled(); + updateEmergencyGestureEnabled(); } } }; diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index ea14fadff433..1c99465dfebf 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -945,17 +945,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } @Override - public void setMtu(String iface, int mtu) { - NetworkStack.checkNetworkStackPermission(mContext); - - try { - mNetdService.interfaceSetMtu(iface, mtu); - } catch (RemoteException | ServiceSpecificException e) { - throw new IllegalStateException(e); - } - } - - @Override public void shutdown() { // TODO: remove from aidl if nobody calls externally mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG); @@ -1985,16 +1974,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { pw.println("]"); } - @Override - public void addInterfaceToNetwork(String iface, int netId) { - modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface); - } - - @Override - public void removeInterfaceFromNetwork(String iface, int netId) { - modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, netId, iface); - } - private void modifyInterfaceInNetwork(boolean add, int netId, String iface) { NetworkStack.checkNetworkStackPermission(mContext); try { @@ -2030,39 +2009,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } @Override - public void setDefaultNetId(int netId) { - NetworkStack.checkNetworkStackPermission(mContext); - - try { - mNetdService.networkSetDefault(netId); - } catch (RemoteException | ServiceSpecificException e) { - throw new IllegalStateException(e); - } - } - - @Override - public void clearDefaultNetId() { - NetworkStack.checkNetworkStackPermission(mContext); - - try { - mNetdService.networkClearDefault(); - } catch (RemoteException | ServiceSpecificException e) { - throw new IllegalStateException(e); - } - } - - @Override - public void setNetworkPermission(int netId, int permission) { - NetworkStack.checkNetworkStackPermission(mContext); - - try { - mNetdService.networkSetPermissionForNetwork(netId, permission); - } catch (RemoteException | ServiceSpecificException e) { - throw new IllegalStateException(e); - } - } - - @Override public void allowProtect(int uid) { NetworkStack.checkNetworkStackPermission(mContext); diff --git a/services/core/java/com/android/server/SystemServerInitThreadPool.java b/services/core/java/com/android/server/SystemServerInitThreadPool.java index c0611374679b..c23f1cab0614 100644 --- a/services/core/java/com/android/server/SystemServerInitThreadPool.java +++ b/services/core/java/com/android/server/SystemServerInitThreadPool.java @@ -19,6 +19,7 @@ package com.android.server; import android.annotation.NonNull; import android.os.Build; import android.os.Process; +import android.util.IndentingPrintWriter; import android.util.Slog; import com.android.internal.annotations.GuardedBy; @@ -44,7 +45,7 @@ import java.util.concurrent.TimeUnit; * * @hide */ -public class SystemServerInitThreadPool { +public final class SystemServerInitThreadPool implements Dumpable { private static final String TAG = SystemServerInitThreadPool.class.getSimpleName(); private static final int SHUTDOWN_TIMEOUT_MILLIS = 20000; private static final boolean IS_DEBUGGABLE = Build.IS_DEBUGGABLE; @@ -53,6 +54,7 @@ public class SystemServerInitThreadPool { @GuardedBy("LOCK") private static SystemServerInitThreadPool sInstance; + private final int mSize; // used by dump() only private final ExecutorService mService; @GuardedBy("mPendingTasks") @@ -62,9 +64,9 @@ public class SystemServerInitThreadPool { private boolean mShutDown; private SystemServerInitThreadPool() { - final int size = Runtime.getRuntime().availableProcessors(); - Slog.i(TAG, "Creating instance with " + size + " threads"); - mService = ConcurrentUtils.newFixedThreadPool(size, + mSize = Runtime.getRuntime().availableProcessors(); + Slog.i(TAG, "Creating instance with " + mSize + " threads"); + mService = ConcurrentUtils.newFixedThreadPool(mSize, "system-server-init-thread", Process.THREAD_PRIORITY_FOREGROUND); } @@ -123,11 +125,13 @@ public class SystemServerInitThreadPool { * * @throws IllegalStateException if it has been started already without being shut down yet. */ - static void start() { + static SystemServerInitThreadPool start() { + SystemServerInitThreadPool instance; synchronized (LOCK) { Preconditions.checkState(sInstance == null, TAG + " already started"); - sInstance = new SystemServerInitThreadPool(); + instance = sInstance = new SystemServerInitThreadPool(); } + return instance; } /** @@ -190,4 +194,22 @@ public class SystemServerInitThreadPool { ActivityManagerService.dumpStackTraces(pids, null, null, Watchdog.getInterestingNativePids(), null); } + + @Override + public void dump(IndentingPrintWriter pw, String[] args) { + synchronized (LOCK) { + pw.printf("has instance: %b\n", (sInstance != null)); + } + pw.printf("number of threads: %d\n", mSize); + pw.printf("service: %s\n", mService); + synchronized (mPendingTasks) { + pw.printf("is shutdown: %b\n", mShutDown); + final int pendingTasks = mPendingTasks.size(); + if (pendingTasks == 0) { + pw.println("no pending tasks"); + } else { + pw.printf("%d pending tasks: %s\n", pendingTasks, mPendingTasks); + } + } + } } diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java index 84d01ec3598d..6c81de6af402 100644 --- a/services/core/java/com/android/server/SystemService.java +++ b/services/core/java/com/android/server/SystemService.java @@ -200,21 +200,21 @@ public abstract class SystemService { /** * @hide */ - public void dump(@NonNull StringBuilder builder) { - builder.append(getUserIdentifier()); + public void dump(@NonNull PrintWriter pw) { + pw.print(getUserIdentifier()); if (!isFull() && !isManagedProfile()) return; - builder.append('('); + pw.print('('); boolean addComma = false; if (isFull()) { - builder.append("full"); + pw.print("full"); } if (isManagedProfile()) { - if (addComma) builder.append(','); - builder.append("mp"); + if (addComma) pw.print(','); + pw.print("mp"); } - builder.append(')'); + pw.print(')'); } } diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java index ff2661b19b48..71a18218110e 100644 --- a/services/core/java/com/android/server/SystemServiceManager.java +++ b/services/core/java/com/android/server/SystemServiceManager.java @@ -27,6 +27,7 @@ import android.os.Trace; import android.os.UserManagerInternal; import android.util.ArrayMap; import android.util.EventLog; +import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.SparseArray; @@ -49,7 +50,7 @@ import java.util.ArrayList; * * {@hide} */ -public final class SystemServiceManager { +public final class SystemServiceManager implements Dumpable { private static final String TAG = SystemServiceManager.class.getSimpleName(); private static final boolean DEBUG = false; private static final int SERVICE_CALL_WARN_TIME_MS = 50; @@ -489,31 +490,39 @@ public final class SystemServiceManager { return sSystemDir; } - /** - * Outputs the state of this manager to the System log. - */ - public void dump() { - StringBuilder builder = new StringBuilder(); - builder.append("Current phase: ").append(mCurrentPhase).append('\n'); - builder.append("Services:\n"); - final int startedLen = mServices.size(); - for (int i = 0; i < startedLen; i++) { - final SystemService service = mServices.get(i); - builder.append("\t") - .append(service.getClass().getSimpleName()) - .append("\n"); - } + @Override + public void dump(IndentingPrintWriter pw, String[] args) { + pw.printf("Current phase: %d\n", mCurrentPhase); synchronized (mTargetUsers) { - builder.append("Current user: ").append(mCurrentUser).append('\n'); - builder.append("Target users: "); + if (mCurrentUser != null) { + pw.print("Current user: "); mCurrentUser.dump(pw); pw.println(); + } else { + pw.println("Current user not set!"); + } + final int targetUsersSize = mTargetUsers.size(); - for (int i = 0; i < targetUsersSize; i++) { - mTargetUsers.valueAt(i).dump(builder); - if (i != targetUsersSize - 1) builder.append(','); + if (targetUsersSize > 0) { + pw.printf("%d target users: ", targetUsersSize); + for (int i = 0; i < targetUsersSize; i++) { + mTargetUsers.valueAt(i).dump(pw); + if (i != targetUsersSize - 1) pw.print(", "); + } + pw.println(); + } else { + pw.println("No target users"); } - builder.append('\n'); } - - Slog.e(TAG, builder.toString()); + final int startedLen = mServices.size(); + if (startedLen > 0) { + pw.printf("%d started services:\n", startedLen); + pw.increaseIndent(); + for (int i = 0; i < startedLen; i++) { + final SystemService service = mServices.get(i); + pw.println(service.getClass().getCanonicalName()); + } + pw.decreaseIndent(); + } else { + pw.println("No started services"); + } } } diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index afddd650c46c..74fba0441be8 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -1794,25 +1794,20 @@ public class VibratorService extends IVibratorService.Stub mWakeLock.setWorkSource(mTmpWorkSource); } - private long delayLocked(long duration) { + private void delayLocked(long wakeUpTime) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "delayLocked"); try { - long durationRemaining = duration; - if (duration > 0) { - final long bedtime = duration + SystemClock.uptimeMillis(); - do { - try { - this.wait(durationRemaining); - } - catch (InterruptedException e) { } - if (mForceStop) { - break; - } - durationRemaining = bedtime - SystemClock.uptimeMillis(); - } while (durationRemaining > 0); - return duration - durationRemaining; + long durationRemaining = wakeUpTime - SystemClock.uptimeMillis(); + while (durationRemaining > 0) { + try { + this.wait(durationRemaining); + } catch (InterruptedException e) { + } + if (mForceStop) { + break; + } + durationRemaining = wakeUpTime - SystemClock.uptimeMillis(); } - return 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } @@ -1846,7 +1841,8 @@ public class VibratorService extends IVibratorService.Stub final int repeat = mWaveform.getRepeatIndex(); int index = 0; - long onDuration = 0; + long nextStepStartTime = SystemClock.uptimeMillis(); + long nextVibratorStopTime = 0; while (!mForceStop) { if (index < len) { final int amplitude = amplitudes[index]; @@ -1855,27 +1851,33 @@ public class VibratorService extends IVibratorService.Stub continue; } if (amplitude != 0) { - if (onDuration <= 0) { + long now = SystemClock.uptimeMillis(); + if (nextVibratorStopTime <= now) { // Telling the vibrator to start multiple times usually causes // effects to feel "choppy" because the motor resets at every on // command. Instead we figure out how long our next "on" period // is going to be, tell the motor to stay on for the full // duration, and then wake up to change the amplitude at the // appropriate intervals. - onDuration = getTotalOnDuration(timings, amplitudes, index - 1, - repeat); + long onDuration = getTotalOnDuration( + timings, amplitudes, index - 1, repeat); mVibration.effect = VibrationEffect.createOneShot( onDuration, amplitude); doVibratorOn(mVibration); + nextVibratorStopTime = now + onDuration; } else { + // Vibrator is already ON, so just change its amplitude. doVibratorSetAmplitude(amplitude); } } - long waitTime = delayLocked(duration); - if (amplitude != 0) { - onDuration -= waitTime; - } + // We wait until the time this waveform step was supposed to end, + // calculated from the time it was supposed to start. All start times + // are calculated from the waveform original start time by adding the + // input durations. Any scheduling or processing delay should not affect + // this step's perceived total duration. They will be amortized here. + nextStepStartTime += duration; + delayLocked(nextStepStartTime); } else if (repeat < 0) { break; } else { diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 6e5c0412985c..4a338b37e41f 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -1970,7 +1970,7 @@ public final class ActiveServices { } if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { - mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, + mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS, "BIND_TREAT_LIKE_ACTIVITY"); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 32d95f594ce9..112814c69d9b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -208,6 +208,7 @@ import android.content.pm.ProviderInfoList; import android.content.pm.ResolveInfo; import android.content.pm.SELinuxUtil; import android.content.pm.ServiceInfo; +import android.content.pm.TestUtilityService; import android.content.pm.UserInfo; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; @@ -339,6 +340,7 @@ import com.android.server.SystemServiceManager; import com.android.server.ThreadPriorityBooster; import com.android.server.UserspaceRebootLogger; import com.android.server.Watchdog; +import com.android.server.am.LowMemDetector.MemFactor; import com.android.server.appop.AppOpsService; import com.android.server.compat.PlatformCompat; import com.android.server.contentcapture.ContentCaptureManagerInternal; @@ -1311,6 +1313,7 @@ public class ActivityManagerService extends IActivityManager.Stub PackageManagerInternal mPackageManagerInt; PermissionManagerServiceInternal mPermissionManagerInt; + private TestUtilityService mTestUtilityService; /** * Whether to force background check on all apps (for battery saver) or not. @@ -5784,6 +5787,14 @@ public class ActivityManagerService extends IActivityManager.Stub return mPermissionManagerInt; } + private TestUtilityService getTestUtilityServiceLocked() { + if (mTestUtilityService == null) { + mTestUtilityService = + LocalServices.getService(TestUtilityService.class); + } + return mTestUtilityService; + } + @Override public void appNotResponding(final String reason) { final int callingPid = Binder.getCallingPid(); @@ -7595,6 +7606,10 @@ public class ActivityManagerService extends IActivityManager.Stub eventType, r, processName, null, null, null, null, null, null, crashInfo); mAppErrors.crashApplication(r, crashInfo); + // Notify package manager service to possibly update package state + if (r != null && r.info != null && r.info.packageName != null) { + mPackageManagerInt.notifyPackageCrashOrAnr(r.info.packageName); + } } public void handleApplicationStrictModeViolation( @@ -8210,13 +8225,25 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public int getMemoryTrimLevel() { + public @MemFactor int getMemoryTrimLevel() { enforceNotIsolatedCaller("getMyMemoryState"); synchronized (this) { return mAppProfiler.getLastMemoryLevelLocked(); } } + void setMemFactorOverride(@MemFactor int level) { + synchronized (this) { + if (level == mAppProfiler.getLastMemoryLevelLocked()) { + return; + } + + mAppProfiler.setMemFactorOverrideLocked(level); + // Kick off an oom adj update since we forced a mem factor update. + updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE); + } + } + @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, @@ -17339,11 +17366,12 @@ public class ActivityManagerService extends IActivityManager.Stub /** * Holds the AM lock for the specified amount of milliseconds. * Intended for use by the tests that need to imitate lock contention. - * Requires permission identity of the shell UID. + * The token should be obtained by + * {@link android.content.pm.PackageManager#getHoldLockToken()}. */ @Override - public void holdLock(int durationMs) { - enforceCallingPermission(Manifest.permission.INJECT_EVENTS, "holdLock"); + public void holdLock(IBinder token, int durationMs) { + getTestUtilityServiceLocked().verifyHoldLockToken(token); synchronized (this) { SystemClock.sleep(durationMs); diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 31e7106979f1..e3c071fe10e2 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -25,6 +25,12 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.INVALID_DISPLAY; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL; +import static com.android.server.am.LowMemDetector.ADJ_MEM_FACTOR_NOTHING; + import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ActivityTaskManager; @@ -92,6 +98,7 @@ import android.view.Display; import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.util.HexDump; import com.android.internal.util.MemInfoReader; +import com.android.server.am.LowMemDetector.MemFactor; import com.android.server.compat.PlatformCompat; import java.io.BufferedReader; @@ -309,6 +316,8 @@ final class ActivityManagerShellCommand extends ShellCommand { return runCompat(pw); case "refresh-settings-cache": return runRefreshSettingsCache(); + case "memory-factor": + return runMemoryFactor(pw); default: return handleDefaultCommands(cmd); } @@ -3014,6 +3023,81 @@ final class ActivityManagerShellCommand extends ShellCommand { return -1; } + private int runSetMemoryFactor(PrintWriter pw) throws RemoteException { + final String levelArg = getNextArgRequired(); + @MemFactor int level = ADJ_MEM_FACTOR_NOTHING; + switch (levelArg) { + case "NORMAL": + level = ADJ_MEM_FACTOR_NORMAL; + break; + case "MODERATE": + level = ADJ_MEM_FACTOR_MODERATE; + break; + case "LOW": + level = ADJ_MEM_FACTOR_LOW; + break; + case "CRITICAL": + level = ADJ_MEM_FACTOR_CRITICAL; + break; + default: + try { + level = Integer.parseInt(levelArg); + } catch (NumberFormatException e) { + } + if (level < ADJ_MEM_FACTOR_NORMAL || level > ADJ_MEM_FACTOR_CRITICAL) { + getErrPrintWriter().println("Error: Unknown level option: " + levelArg); + return -1; + } + } + mInternal.setMemFactorOverride(level); + return 0; + } + + private int runShowMemoryFactor(PrintWriter pw) throws RemoteException { + final @MemFactor int level = mInternal.getMemoryTrimLevel(); + switch (level) { + case ADJ_MEM_FACTOR_NOTHING: + pw.println("<UNKNOWN>"); + break; + case ADJ_MEM_FACTOR_NORMAL: + pw.println("NORMAL"); + break; + case ADJ_MEM_FACTOR_MODERATE: + pw.println("MODERATE"); + break; + case ADJ_MEM_FACTOR_LOW: + pw.println("LOW"); + break; + case ADJ_MEM_FACTOR_CRITICAL: + pw.println("CRITICAL"); + break; + } + pw.flush(); + return 0; + } + + private int runResetMemoryFactor(PrintWriter pw) throws RemoteException { + mInternal.setMemFactorOverride(ADJ_MEM_FACTOR_NOTHING); + return 0; + } + + private int runMemoryFactor(PrintWriter pw) throws RemoteException { + mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, + "runMemoryFactor()"); + + final String op = getNextArgRequired(); + switch (op) { + case "set": + return runSetMemoryFactor(pw); + case "show": + return runShowMemoryFactor(pw); + case "reset": + return runResetMemoryFactor(pw); + default: + getErrPrintWriter().println("Error: unknown command '" + op + "'"); + return -1; + } + } private Resources getResources(PrintWriter pw) throws RemoteException { // system resources does not contain all the device configuration, construct it manually. @@ -3334,6 +3418,13 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" Removes all existing overrides for all changes for "); pw.println(" <PACKAGE_NAME> (back to default behaviour)."); pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect)."); + pw.println(" memory-factor [command] [...]: sub-commands for overriding memory pressure factor"); + pw.println(" set <NORMAL|MODERATE|LOW|CRITICAL>"); + pw.println(" Overrides memory pressure factor. May also supply a raw int level"); + pw.println(" show"); + pw.println(" Shows the existing memory pressure factor"); + pw.println(" reset"); + pw.println(" Removes existing override for memory pressure factor"); pw.println(); Intent.printIntentArgsHelp(pw, ""); } diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java index 31ffb35f24b3..5e59a35fc4ee 100644 --- a/services/core/java/com/android/server/am/AppProfiler.java +++ b/services/core/java/com/android/server/am/AppProfiler.java @@ -20,11 +20,16 @@ import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; import static android.os.Process.FIRST_APPLICATION_UID; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.am.LowMemDetector.ADJ_MEM_FACTOR_NOTHING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; import android.annotation.BroadcastBehavior; @@ -72,6 +77,7 @@ import com.android.internal.os.ProcessCpuTracker; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.MemInfoReader; +import com.android.server.am.LowMemDetector.MemFactor; import com.android.server.am.ProcessList.ProcStateMemTracker; import com.android.server.utils.PriorityDump; @@ -202,7 +208,10 @@ public class AppProfiler { * processes are going away for other reasons. */ @GuardedBy("mService") - private int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; + private @MemFactor int mLastMemoryLevel = ADJ_MEM_FACTOR_NORMAL; + + @GuardedBy("mService") + private @MemFactor int mMemFactorOverride = ADJ_MEM_FACTOR_NOTHING; /** * The last total number of process we have, to determine if changes actually look @@ -851,7 +860,7 @@ public class AppProfiler { @GuardedBy("mService") boolean isLastMemoryLevelNormal() { - return mLastMemoryLevel <= ProcessStats.ADJ_MEM_FACTOR_NORMAL; + return mLastMemoryLevel <= ADJ_MEM_FACTOR_NORMAL; } @GuardedBy("mService") @@ -868,6 +877,11 @@ public class AppProfiler { } @GuardedBy("mService") + void setMemFactorOverrideLocked(@MemFactor int factor) { + mMemFactorOverride = factor; + } + + @GuardedBy("mService") boolean updateLowMemStateLocked(int numCached, int numEmpty, int numTrimming) { final int numOfLru = mService.mProcessList.getLruSizeLocked(); final long now = SystemClock.uptimeMillis(); @@ -885,28 +899,32 @@ public class AppProfiler { && numEmpty <= mService.mConstants.CUR_TRIM_EMPTY_PROCESSES) { final int numCachedAndEmpty = numCached + numEmpty; if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { - memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; + memFactor = ADJ_MEM_FACTOR_CRITICAL; } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { - memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; + memFactor = ADJ_MEM_FACTOR_LOW; } else { - memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; + memFactor = ADJ_MEM_FACTOR_MODERATE; } } else { - memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; + memFactor = ADJ_MEM_FACTOR_NORMAL; } } // We always allow the memory level to go up (better). We only allow it to go // down if we are in a state where that is allowed, *and* the total number of processes // has gone down since last time. if (DEBUG_OOM_ADJ) { - Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor + Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor + " override=" + mMemFactorOverride + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mService.mProcessList.getLruSizeLocked() + " last=" + mLastNumProcesses); } + boolean override; + if (override = (mMemFactorOverride != ADJ_MEM_FACTOR_NOTHING)) { + memFactor = mMemFactorOverride; + } if (memFactor > mLastMemoryLevel) { - if (!mAllowLowerMemLevel - || mService.mProcessList.getLruSizeLocked() >= mLastNumProcesses) { + if (!override && (!mAllowLowerMemLevel + || mService.mProcessList.getLruSizeLocked() >= mLastNumProcesses)) { memFactor = mLastMemoryLevel; if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!"); } @@ -924,17 +942,17 @@ public class AppProfiler { mService.mAtmInternal == null || !mService.mAtmInternal.isSleeping(), now); trackerMemFactor = mService.mProcessStats.getMemFactorLocked(); } - if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { + if (memFactor != ADJ_MEM_FACTOR_NORMAL) { if (mLowRamStartTime == 0) { mLowRamStartTime = now; } int step = 0; int fgTrimLevel; switch (memFactor) { - case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: + case ADJ_MEM_FACTOR_CRITICAL: fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; break; - case ProcessStats.ADJ_MEM_FACTOR_LOW: + case ADJ_MEM_FACTOR_LOW: fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; break; default: @@ -947,7 +965,7 @@ public class AppProfiler { if (mService.mAtmInternal.getPreviousProcess() != null) minFactor++; if (factor < minFactor) factor = minFactor; int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; - for (int i = numOfLru - 1; i >= 0; i--) { + for (int i = 0; i < numOfLru; i++) { ProcessRecord app = mService.mProcessList.mLruProcesses.get(i); if (allChanged || app.procStateChanged) { mService.setProcessTrackerStateLocked(app, trackerMemFactor, now); @@ -1032,7 +1050,7 @@ public class AppProfiler { mLowRamTimeSinceLastIdle += now - mLowRamStartTime; mLowRamStartTime = 0; } - for (int i = numOfLru - 1; i >= 0; i--) { + for (int i = 0; i < numOfLru; i++) { ProcessRecord app = mService.mProcessList.mLruProcesses.get(i); if (allChanged || app.procStateChanged) { mService.setProcessTrackerStateLocked(app, trackerMemFactor, now); @@ -1622,16 +1640,16 @@ public class AppProfiler { @GuardedBy("mService") void dumpLastMemoryLevelLocked(PrintWriter pw) { switch (mLastMemoryLevel) { - case ProcessStats.ADJ_MEM_FACTOR_NORMAL: + case ADJ_MEM_FACTOR_NORMAL: pw.println("normal)"); break; - case ProcessStats.ADJ_MEM_FACTOR_MODERATE: + case ADJ_MEM_FACTOR_MODERATE: pw.println("moderate)"); break; - case ProcessStats.ADJ_MEM_FACTOR_LOW: + case ADJ_MEM_FACTOR_LOW: pw.println("low)"); break; - case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: + case ADJ_MEM_FACTOR_CRITICAL: pw.println("critical)"); break; default: diff --git a/services/core/java/com/android/server/am/LowMemDetector.java b/services/core/java/com/android/server/am/LowMemDetector.java index e82a207cdd59..8f791331f0cf 100644 --- a/services/core/java/com/android/server/am/LowMemDetector.java +++ b/services/core/java/com/android/server/am/LowMemDetector.java @@ -16,8 +16,19 @@ package com.android.server.am; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL; +import static com.android.internal.app.procstats.ProcessStats.ADJ_NOTHING; + +import android.annotation.IntDef; + import com.android.internal.annotations.GuardedBy; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Detects low memory using PSI. * @@ -32,13 +43,20 @@ public final class LowMemDetector { private final Object mPressureStateLock = new Object(); @GuardedBy("mPressureStateLock") - private int mPressureState = MEM_PRESSURE_NONE; + private int mPressureState = ADJ_MEM_FACTOR_NORMAL; + + public static final int ADJ_MEM_FACTOR_NOTHING = ADJ_NOTHING; /* getPressureState return values */ - public static final int MEM_PRESSURE_NONE = 0; - public static final int MEM_PRESSURE_LOW = 1; - public static final int MEM_PRESSURE_MEDIUM = 2; - public static final int MEM_PRESSURE_HIGH = 3; + @IntDef(prefix = { "ADJ_MEM_FACTOR_" }, value = { + ADJ_MEM_FACTOR_NOTHING, + ADJ_MEM_FACTOR_NORMAL, + ADJ_MEM_FACTOR_MODERATE, + ADJ_MEM_FACTOR_LOW, + ADJ_MEM_FACTOR_CRITICAL, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface MemFactor{} LowMemDetector(ActivityManagerService am) { mAm = am; @@ -62,7 +80,7 @@ public final class LowMemDetector { * there should be conversion performed here to translate pressure state * into memFactor. */ - public int getMemFactor() { + public @MemFactor int getMemFactor() { synchronized (mPressureStateLock) { return mPressureState; } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 53c6758585cf..ccdd6a746239 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -1764,6 +1764,12 @@ class ProcessRecord implements WindowProcessListener { makeAppNotRespondingLocked(activityShortComponentName, annotation != null ? "ANR " + annotation : "ANR", info.toString()); + // Notify package manager service to possibly update package state + if (aInfo != null && aInfo.packageName != null) { + mService.getPackageManagerInternalLocked().notifyPackageCrashOrAnr( + aInfo.packageName); + } + // mUiHandler can be null if the AMS is constructed with injector only. This will only // happen in tests. if (mService.mUiHandler != null) { diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java index 15dc95673790..3c18cd4ed231 100644 --- a/services/core/java/com/android/server/biometrics/AuthSession.java +++ b/services/core/java/com/android/server/biometrics/AuthSession.java @@ -44,6 +44,8 @@ import com.android.internal.util.FrameworkStatsLog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; import java.util.Random; /** @@ -241,7 +243,8 @@ public final class AuthSession implements IBinder.DeathRecipient { mStatusBarService.showAuthenticationDialog( mPromptInfo, mSysuiReceiver, - 0 /* biometricModality */, + new int[0] /* sensorIds */, + true /* credentialAllowed */, false /* requireConfirmation */, mUserId, mOpPackageName, @@ -271,11 +274,16 @@ public final class AuthSession implements IBinder.DeathRecipient { try { // If any sensor requires confirmation, request it to be shown. final boolean requireConfirmation = isConfirmationRequiredByAnyEligibleSensor(); - final @BiometricAuthenticator.Modality int modality = - getEligibleModalities(); + + final int[] sensorIds = new int[mPreAuthInfo.eligibleSensors.size()]; + for (int i = 0; i < mPreAuthInfo.eligibleSensors.size(); i++) { + sensorIds[i] = mPreAuthInfo.eligibleSensors.get(i).id; + } + mStatusBarService.showAuthenticationDialog(mPromptInfo, mSysuiReceiver, - modality, + sensorIds, + mPreAuthInfo.shouldShowCredential(), requireConfirmation, mUserId, mOpPackageName, @@ -369,7 +377,8 @@ public final class AuthSession implements IBinder.DeathRecipient { mStatusBarService.showAuthenticationDialog( mPromptInfo, mSysuiReceiver, - 0 /* biometricModality */, + new int[0] /* sensorIds */, + true /* credentialAllowed */, false /* requireConfirmation */, mUserId, mOpPackageName, diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java index 08a617134221..6905b3da9bc4 100644 --- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java +++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java @@ -32,7 +32,6 @@ import android.os.RemoteException; import android.util.Pair; import android.util.Slog; -import com.android.internal.annotations.VisibleForTesting; import com.android.server.biometrics.sensors.LockoutTracker; import java.lang.annotation.Retention; @@ -356,6 +355,13 @@ class PreAuthInfo { } /** + * @return true if SystemUI should show the credential UI. + */ + boolean shouldShowCredential() { + return credentialRequested && credentialAvailable; + } + + /** * @return bitmask representing the modalities that are running or could be running for the * current session. */ diff --git a/services/core/java/com/android/server/biometrics/TEST_MAPPING b/services/core/java/com/android/server/biometrics/TEST_MAPPING new file mode 100644 index 000000000000..36acc3c7344d --- /dev/null +++ b/services/core/java/com/android/server/biometrics/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "CtsBiometricsTestCases" + } + ] +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java index 5dcadee20e13..9ac12ed11ded 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java @@ -52,11 +52,10 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.provider.Settings; -import android.util.ArrayMap; -import android.util.ArraySet; import android.util.EventLog; import android.util.Pair; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import android.view.Surface; import com.android.internal.R; @@ -92,55 +91,6 @@ public class FingerprintService extends SystemService { private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher; private final LockPatternUtils mLockPatternUtils; @NonNull private List<ServiceProvider> mServiceProviders; - @NonNull private final ArrayMap<Integer, TestSession> mTestSessions; - - private final class TestSession extends ITestSession.Stub { - private final int mSensorId; - - TestSession(int sensorId) { - mSensorId = sensorId; - } - - @Override - public void enableTestHal(boolean enableTestHal) { - Utils.checkPermission(getContext(), TEST_BIOMETRIC); - } - - @Override - public void startEnroll(int userId) { - Utils.checkPermission(getContext(), TEST_BIOMETRIC); - } - - @Override - public void finishEnroll(int userId) { - Utils.checkPermission(getContext(), TEST_BIOMETRIC); - } - - @Override - public void acceptAuthentication(int userId) { - Utils.checkPermission(getContext(), TEST_BIOMETRIC); - } - - @Override - public void rejectAuthentication(int userId) { - Utils.checkPermission(getContext(), TEST_BIOMETRIC); - } - - @Override - public void notifyAcquired(int userId, int acquireInfo) { - Utils.checkPermission(getContext(), TEST_BIOMETRIC); - } - - @Override - public void notifyError(int userId, int errorCode) { - Utils.checkPermission(getContext(), TEST_BIOMETRIC); - } - - @Override - public void cleanupInternalState(int userId) { - Utils.checkPermission(getContext(), TEST_BIOMETRIC); - } - } /** * Receives the incoming binder calls from FingerprintManager. @@ -150,20 +100,22 @@ public class FingerprintService extends SystemService { public ITestSession createTestSession(int sensorId, String opPackageName) { Utils.checkPermission(getContext(), TEST_BIOMETRIC); - final TestSession session; - synchronized (mTestSessions) { - if (!mTestSessions.containsKey(sensorId)) { - mTestSessions.put(sensorId, new TestSession(sensorId)); + for (ServiceProvider provider : mServiceProviders) { + if (provider.containsSensor(sensorId)) { + return provider.createTestSession(sensorId, opPackageName); } - session = mTestSessions.get(sensorId); } - return session; + + return null; } @Override // Binder call public List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal( String opPackageName) { - Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); + if (getContext().checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL) + != PackageManager.PERMISSION_GRANTED) { + Utils.checkPermission(getContext(), TEST_BIOMETRIC); + } final List<FingerprintSensorPropertiesInternal> properties = FingerprintService.this.getSensorProperties(); @@ -424,12 +376,28 @@ public class FingerprintService extends SystemService { final long ident = Binder.clearCallingIdentity(); try { - for (ServiceProvider provider : mServiceProviders) { - for (FingerprintSensorPropertiesInternal props : - provider.getSensorProperties()) { - if (args.length > 0 && "--proto".equals(args[0])) { - provider.dumpProto(props.sensorId, fd); - } else { + if (args.length > 1 && "--proto".equals(args[0]) && "--state".equals(args[1])) { + final ProtoOutputStream proto = new ProtoOutputStream(fd); + for (ServiceProvider provider : mServiceProviders) { + for (FingerprintSensorPropertiesInternal props + : provider.getSensorProperties()) { + provider.dumpProtoState(props.sensorId, proto); + } + } + proto.flush(); + } else if (args.length > 0 && "--proto".equals(args[0])) { + for (ServiceProvider provider : mServiceProviders) { + for (FingerprintSensorPropertiesInternal props + : provider.getSensorProperties()) { + provider.dumpProtoMetrics(props.sensorId, fd); + } + } + } else { + for (ServiceProvider provider : mServiceProviders) { + for (FingerprintSensorPropertiesInternal props + : provider.getSensorProperties()) { + pw.println("Dumping for sensorId: " + props.sensorId + + ", provider: " + provider.getClass().getSimpleName()); provider.dumpInternal(props.sensorId, pw); } } @@ -622,7 +590,6 @@ public class FingerprintService extends SystemService { mLockoutResetDispatcher = new LockoutResetDispatcher(context); mLockPatternUtils = new LockPatternUtils(context); mServiceProviders = new ArrayList<>(); - mTestSessions = new ArrayMap<>(); initializeAidlHals(); } @@ -648,7 +615,7 @@ public class FingerprintService extends SystemService { try { final SensorProps[] props = fp.getSensorProps(); final FingerprintProvider provider = - new FingerprintProvider(getContext(), props, fqName, + new FingerprintProvider(getContext(), props, instance, mLockoutResetDispatcher, mGestureAvailabilityDispatcher); mServiceProviders.add(provider); } catch (RemoteException e) { diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java index c2315fdd4ccc..1ed66a247bd0 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java @@ -19,11 +19,13 @@ package com.android.server.biometrics.sensors.fingerprint; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.fingerprint.Fingerprint; +import android.hardware.biometrics.ITestSession; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.IBinder; +import android.util.proto.ProtoOutputStream; import android.view.Surface; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; @@ -110,7 +112,11 @@ public interface ServiceProvider { void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller); - void dumpProto(int sensorId, @NonNull FileDescriptor fd); + void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto); + + void dumpProtoMetrics(int sensorId, @NonNull FileDescriptor fd); void dumpInternal(int sensorId, @NonNull PrintWriter pw); + + @NonNull ITestSession createTestSession(int sensorId, @NonNull String opPackageName); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java new file mode 100644 index 000000000000..6bb40e6630bf --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java @@ -0,0 +1,186 @@ +/* + * 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.biometrics.sensors.fingerprint.aidl; + +import static android.Manifest.permission.TEST_BIOMETRIC; + +import android.annotation.NonNull; +import android.content.Context; +import android.hardware.biometrics.ITestSession; +import android.hardware.fingerprint.Fingerprint; +import android.hardware.fingerprint.IFingerprintServiceReceiver; +import android.os.Binder; +import android.util.Slog; + +import com.android.server.biometrics.HardwareAuthTokenUtils; +import com.android.server.biometrics.Utils; +import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; + +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +/** + * A test session implementation for {@link FingerprintProvider}. See + * {@link android.hardware.biometrics.BiometricTestSession}. + */ +class BiometricTestSessionImpl extends ITestSession.Stub { + + private static final String TAG = "BiometricTestSessionImpl"; + + @NonNull private final Context mContext; + private final int mSensorId; + @NonNull private final FingerprintProvider mProvider; + @NonNull private final Sensor mSensor; + @NonNull private final Set<Integer> mEnrollmentIds; + @NonNull private final Random mRandom; + + /** + * Internal receiver currently only used for enroll. Results do not need to be forwarded to the + * test, since enrollment is a platform-only API. The authentication path is tested through + * the public FingerprintManager APIs and does not use this receiver. + */ + private final IFingerprintServiceReceiver mReceiver = new IFingerprintServiceReceiver.Stub() { + @Override + public void onEnrollResult(Fingerprint fp, int remaining) { + + } + + @Override + public void onAcquired(int acquiredInfo, int vendorCode) { + + } + + @Override + public void onAuthenticationSucceeded(Fingerprint fp, int userId, + boolean isStrongBiometric) { + + } + + @Override + public void onFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric) { + + } + + @Override + public void onAuthenticationFailed() { + + } + + @Override + public void onError(int error, int vendorCode) { + + } + + @Override + public void onRemoved(Fingerprint fp, int remaining) { + + } + + @Override + public void onChallengeGenerated(int sensorId, long challenge) { + + } + }; + + BiometricTestSessionImpl(@NonNull Context context, int sensorId, + @NonNull FingerprintProvider provider, @NonNull Sensor sensor) { + mContext = context; + mSensorId = sensorId; + mProvider = provider; + mSensor = sensor; + mEnrollmentIds = new HashSet<>(); + mRandom = new Random(); + } + + @Override + public void setTestHalEnabled(boolean enabled) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mProvider.setTestHalEnabled(enabled); + mSensor.setTestHalEnabled(enabled); + } + + @Override + public void startEnroll(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mProvider.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver, + mContext.getOpPackageName(), null /* surface */); + } + + @Override + public void finishEnroll(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + int nextRandomId = mRandom.nextInt(); + while (mEnrollmentIds.contains(nextRandomId)) { + nextRandomId = mRandom.nextInt(); + } + + mEnrollmentIds.add(nextRandomId); + mSensor.getSessionForUser(userId).mHalSessionCallback + .onEnrollmentProgress(nextRandomId, 0 /* remaining */); + } + + @Override + public void acceptAuthentication(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + // Fake authentication with any of the existing fingers + List<Fingerprint> fingerprints = FingerprintUtils.getInstance() + .getBiometricsForUser(mContext, userId); + if (fingerprints.isEmpty()) { + Slog.w(TAG, "No fingerprints, returning"); + return; + } + final int fid = fingerprints.get(0).getBiometricId(); + mSensor.getSessionForUser(userId).mHalSessionCallback.onAuthenticationSucceeded(fid, + HardwareAuthTokenUtils.toHardwareAuthToken(new byte[69])); + } + + @Override + public void rejectAuthentication(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mSensor.getSessionForUser(userId).mHalSessionCallback.onAuthenticationFailed(); + } + + @Override + public void notifyAcquired(int userId, int acquireInfo) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mSensor.getSessionForUser(userId).mHalSessionCallback + .onAcquired((byte) acquireInfo, 0 /* vendorCode */); + } + + @Override + public void notifyError(int userId, int errorCode) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mSensor.getSessionForUser(userId).mHalSessionCallback.onError((byte) errorCode, + 0 /* vendorCode */); + } + + @Override + public void cleanupInternalState(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mProvider.scheduleInternalCleanup(mSensorId, userId); + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java index fec3cff6d52f..2ad1fa306781 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java @@ -47,6 +47,11 @@ class FingerprintGetAuthenticatorIdClient extends ClientMonitor<ISession> { // Nothing to do here } + public void start(@NonNull Callback callback) { + super.start(callback); + startHalOperation(); + } + @Override protected void startHalOperation() { try { diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index d713f981b451..4d07f583fdf5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -24,6 +24,7 @@ import android.app.IActivityTaskManager; import android.app.TaskStackListener; import android.content.Context; import android.content.pm.UserInfo; +import android.hardware.biometrics.ITestSession; import android.hardware.biometrics.fingerprint.IFingerprint; import android.hardware.biometrics.fingerprint.SensorProps; import android.hardware.fingerprint.Fingerprint; @@ -38,6 +39,7 @@ import android.os.ServiceManager; import android.os.UserManager; import android.util.Slog; import android.util.SparseArray; +import android.util.proto.ProtoOutputStream; import android.view.Surface; import com.android.server.biometrics.Utils; @@ -62,6 +64,8 @@ import java.util.List; @SuppressWarnings("deprecation") public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvider { + private boolean mTestHalEnabled; + @NonNull private final Context mContext; @NonNull private final String mHalInstanceName; @NonNull private final SparseArray<Sensor> mSensors; // Map of sensors that this HAL supports @@ -132,7 +136,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi prop.commonProps.maxEnrollmentsPerUser, prop.sensorType, true /* resetLockoutRequiresHardwareAuthToken */); - final Sensor sensor = new Sensor(getTag() + "/" + sensorId, mContext, mHandler, + final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler, internalProp, gestureAvailabilityDispatcher); mSensors.put(sensorId, sensor); @@ -146,6 +150,13 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi @Nullable private synchronized IFingerprint getHalInstance() { + if (mTestHalEnabled) { + // Enabling the test HAL for a single sensor in a multi-sensor HAL currently enables + // the test HAL for all sensors under that HAL. This can be updated in the future if + // necessary. + return new TestHal(); + } + if (mDaemon != null) { return mDaemon; } @@ -153,7 +164,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi Slog.d(getTag(), "Daemon was null, reconnecting"); mDaemon = IFingerprint.Stub.asInterface( - ServiceManager.waitForDeclaredService(mHalInstanceName)); + ServiceManager.waitForDeclaredService(IFingerprint.DESCRIPTOR + + "/" + mHalInstanceName)); if (mDaemon == null) { Slog.e(getTag(), "Unable to get daemon"); return null; @@ -561,7 +573,14 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi } @Override - public void dumpProto(int sensorId, @NonNull FileDescriptor fd) { + public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) { + if (mSensors.contains(sensorId)) { + mSensors.get(sensorId).dumpProtoState(sensorId, proto); + } + } + + @Override + public void dumpProtoMetrics(int sensorId, @NonNull FileDescriptor fd) { } @@ -570,6 +589,12 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi } + @NonNull + @Override + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { + return mSensors.get(sensorId).createTestSession(); + } + @Override public void binderDied() { Slog.e(getTag(), "HAL died"); @@ -582,4 +607,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi } }); } + + void setTestHalEnabled(boolean enabled) { + mTestHalEnabled = enabled; + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java index d4ce896d42ec..51c30b68e0c5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java @@ -19,7 +19,9 @@ package com.android.server.biometrics.sensors.fingerprint.aidl; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.content.pm.UserInfo; import android.hardware.biometrics.BiometricsProtoEnums; +import android.hardware.biometrics.ITestSession; import android.hardware.biometrics.fingerprint.Error; import android.hardware.biometrics.fingerprint.IFingerprint; import android.hardware.biometrics.fingerprint.ISession; @@ -31,11 +33,16 @@ import android.hardware.keymaster.HardwareAuthToken; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.os.UserManager; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import com.android.internal.util.FrameworkStatsLog; import com.android.server.biometrics.HardwareAuthTokenUtils; import com.android.server.biometrics.Utils; +import com.android.server.biometrics.fingerprint.FingerprintServiceStateProto; +import com.android.server.biometrics.fingerprint.SensorStateProto; +import com.android.server.biometrics.fingerprint.UserStateProto; import com.android.server.biometrics.sensors.AcquisitionClient; import com.android.server.biometrics.sensors.AuthenticationConsumer; import com.android.server.biometrics.sensors.BiometricScheduler; @@ -48,9 +55,7 @@ import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -59,7 +64,11 @@ import java.util.Map; */ @SuppressWarnings("deprecation") class Sensor implements IBinder.DeathRecipient { + + private boolean mTestHalEnabled; + @NonNull private final String mTag; + @NonNull private final FingerprintProvider mProvider; @NonNull private final Context mContext; @NonNull private final Handler mHandler; @NonNull private final FingerprintSensorPropertiesInternal mSensorProperties; @@ -91,320 +100,377 @@ class Sensor implements IBinder.DeathRecipient { }); } - private static class Session { + static class Session { @NonNull private final String mTag; @NonNull private final ISession mSession; private final int mUserId; - private final ISessionCallback mSessionCallback; + @NonNull final HalSessionCallback mHalSessionCallback; Session(@NonNull String tag, @NonNull ISession session, int userId, - @NonNull ISessionCallback sessionCallback) { + @NonNull HalSessionCallback halSessionCallback) { mTag = tag; mSession = session; mUserId = userId; - mSessionCallback = sessionCallback; + mHalSessionCallback = halSessionCallback; Slog.d(mTag, "New session created for user: " + userId); } } - Sensor(@NonNull String tag, @NonNull Context context, @NonNull Handler handler, - @NonNull FingerprintSensorPropertiesInternal sensorProperties, - @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) { - mTag = tag; - mContext = context; - mHandler = handler; - mSensorProperties = sensorProperties; - mScheduler = new BiometricScheduler(tag, gestureAvailabilityDispatcher); - mLockoutCache = new LockoutCache(); - mAuthenticatorIds = new HashMap<>(); - mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null; - } - - @NonNull ClientMonitor.LazyDaemon<ISession> getLazySession() { - return mLazySession; - } - - @NonNull FingerprintSensorPropertiesInternal getSensorProperties() { - return mSensorProperties; - } - - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - boolean hasSessionForUser(int userId) { - return mCurrentSession != null && mCurrentSession.mUserId == userId; - } - - void createNewSession(@NonNull IFingerprint daemon, int sensorId, int userId) - throws RemoteException { - final ISessionCallback callback = new ISessionCallback.Stub() { - @Override - public void onStateChanged(int cookie, byte state) { - // TODO(b/162973174) - } - - @Override - public void onChallengeGenerated(long challenge) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof FingerprintGenerateChallengeClient)) { - Slog.e(mTag, "onChallengeGenerated for wrong client: " - + Utils.getClientName(client)); - return; - } - - final FingerprintGenerateChallengeClient generateChallengeClient = - (FingerprintGenerateChallengeClient) client; - generateChallengeClient.onChallengeGenerated(sensorId, userId, challenge); - }); - } + static class HalSessionCallback extends ISessionCallback.Stub { - @Override - public void onChallengeRevoked(long challenge) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof FingerprintRevokeChallengeClient)) { - Slog.e(mTag, "onChallengeRevoked for wrong client: " - + Utils.getClientName(client)); - return; - } + /** + * Interface to sends results to the HalSessionCallback's owner. + */ + public interface Callback { + /** + * Invoked when the HAL sends ERROR_HW_UNAVAILABLE. + */ + void onHardwareUnavailable(); + } - final FingerprintRevokeChallengeClient revokeChallengeClient = - (FingerprintRevokeChallengeClient) client; - revokeChallengeClient.onChallengeRevoked(sensorId, userId, challenge); - }); - } + @NonNull private final Context mContext; + @NonNull private final Handler mHandler; + @NonNull private final String mTag; + @NonNull private final BiometricScheduler mScheduler; + private final int mSensorId; + private final int mUserId; + @NonNull private final Callback mCallback; - @Override - public void onAcquired(byte info, int vendorCode) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof AcquisitionClient)) { - Slog.e(mTag, "onAcquired for non-acquisition client: " - + Utils.getClientName(client)); - return; - } + HalSessionCallback(@NonNull Context context, @NonNull Handler handler, @NonNull String tag, + @NonNull BiometricScheduler scheduler, int sensorId, int userId, + @NonNull Callback callback) { + mContext = context; + mHandler = handler; + mTag = tag; + mScheduler = scheduler; + mSensorId = sensorId; + mUserId = userId; + mCallback = callback; + } - final AcquisitionClient<?> acquisitionClient = (AcquisitionClient<?>) client; - acquisitionClient.onAcquired(info, vendorCode); - }); - } + @Override + public void onStateChanged(int cookie, byte state) { + // TODO(b/162973174) + } - @Override - public void onError(byte error, int vendorCode) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - Slog.d(mTag, "onError" - + ", client: " + Utils.getClientName(client) - + ", error: " + error - + ", vendorCode: " + vendorCode); - if (!(client instanceof Interruptable)) { - Slog.e(mTag, "onError for non-error consumer: " - + Utils.getClientName(client)); - return; - } + @Override + public void onChallengeGenerated(long challenge) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof FingerprintGenerateChallengeClient)) { + Slog.e(mTag, "onChallengeGenerated for wrong client: " + + Utils.getClientName(client)); + return; + } + + final FingerprintGenerateChallengeClient generateChallengeClient = + (FingerprintGenerateChallengeClient) client; + generateChallengeClient.onChallengeGenerated(mSensorId, mUserId, challenge); + }); + } - final Interruptable interruptable = (Interruptable) client; - interruptable.onError(error, vendorCode); + @Override + public void onChallengeRevoked(long challenge) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof FingerprintRevokeChallengeClient)) { + Slog.e(mTag, "onChallengeRevoked for wrong client: " + + Utils.getClientName(client)); + return; + } + + final FingerprintRevokeChallengeClient revokeChallengeClient = + (FingerprintRevokeChallengeClient) client; + revokeChallengeClient.onChallengeRevoked(mSensorId, mUserId, challenge); + }); + } - if (error == Error.HW_UNAVAILABLE) { - Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE"); - mCurrentSession = null; - } - }); - } + @Override + public void onAcquired(byte info, int vendorCode) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof AcquisitionClient)) { + Slog.e(mTag, "onAcquired for non-acquisition client: " + + Utils.getClientName(client)); + return; + } + + final AcquisitionClient<?> acquisitionClient = (AcquisitionClient<?>) client; + acquisitionClient.onAcquired(info, vendorCode); + }); + } - @Override - public void onEnrollmentProgress(int enrollmentId, int remaining) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof FingerprintEnrollClient)) { - Slog.e(mTag, "onEnrollmentProgress for non-enroll client: " - + Utils.getClientName(client)); - return; - } + @Override + public void onError(byte error, int vendorCode) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + Slog.d(mTag, "onError" + + ", client: " + Utils.getClientName(client) + + ", error: " + error + + ", vendorCode: " + vendorCode); + if (!(client instanceof Interruptable)) { + Slog.e(mTag, "onError for non-error consumer: " + + Utils.getClientName(client)); + return; + } - final int currentUserId = client.getTargetUserId(); - final CharSequence name = FingerprintUtils.getInstance(sensorId) - .getUniqueName(mContext, currentUserId); - final Fingerprint fingerprint = new Fingerprint(name, enrollmentId, sensorId); + final Interruptable interruptable = (Interruptable) client; + interruptable.onError(error, vendorCode); - final FingerprintEnrollClient enrollClient = (FingerprintEnrollClient) client; - enrollClient.onEnrollResult(fingerprint, remaining); - }); - } + if (error == Error.HW_UNAVAILABLE) { + mCallback.onHardwareUnavailable(); + } + }); + } - @Override - public void onAuthenticationSucceeded(int enrollmentId, HardwareAuthToken hat) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof AuthenticationConsumer)) { - Slog.e(mTag, "onAuthenticationSucceeded for non-authentication consumer: " - + Utils.getClientName(client)); - return; - } + @Override + public void onEnrollmentProgress(int enrollmentId, int remaining) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof FingerprintEnrollClient)) { + Slog.e(mTag, "onEnrollmentProgress for non-enroll client: " + + Utils.getClientName(client)); + return; + } + + final int currentUserId = client.getTargetUserId(); + final CharSequence name = FingerprintUtils.getInstance(mSensorId) + .getUniqueName(mContext, currentUserId); + final Fingerprint fingerprint = new Fingerprint(name, enrollmentId, mSensorId); + + final FingerprintEnrollClient enrollClient = (FingerprintEnrollClient) client; + enrollClient.onEnrollResult(fingerprint, remaining); + }); + } - final AuthenticationConsumer authenticationConsumer = - (AuthenticationConsumer) client; - final Fingerprint fp = new Fingerprint("", enrollmentId, sensorId); - final byte[] byteArray = HardwareAuthTokenUtils.toByteArray(hat); - final ArrayList<Byte> byteList = new ArrayList<>(); - for (byte b : byteArray) { - byteList.add(b); - } + @Override + public void onAuthenticationSucceeded(int enrollmentId, HardwareAuthToken hat) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof AuthenticationConsumer)) { + Slog.e(mTag, "onAuthenticationSucceeded for non-authentication consumer: " + + Utils.getClientName(client)); + return; + } + + final AuthenticationConsumer authenticationConsumer = + (AuthenticationConsumer) client; + final Fingerprint fp = new Fingerprint("", enrollmentId, mSensorId); + final byte[] byteArray = HardwareAuthTokenUtils.toByteArray(hat); + final ArrayList<Byte> byteList = new ArrayList<>(); + for (byte b : byteArray) { + byteList.add(b); + } + + authenticationConsumer.onAuthenticated(fp, true /* authenticated */, byteList); + }); + } - authenticationConsumer.onAuthenticated(fp, true /* authenticated */, byteList); - }); - } + @Override + public void onAuthenticationFailed() { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof AuthenticationConsumer)) { + Slog.e(mTag, "onAuthenticationFailed for non-authentication consumer: " + + Utils.getClientName(client)); + return; + } + + final AuthenticationConsumer authenticationConsumer = + (AuthenticationConsumer) client; + final Fingerprint fp = new Fingerprint("", 0 /* enrollmentId */, mSensorId); + authenticationConsumer + .onAuthenticated(fp, false /* authenticated */, null /* hat */); + }); + } - @Override - public void onAuthenticationFailed() { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof AuthenticationConsumer)) { - Slog.e(mTag, "onAuthenticationFailed for non-authentication consumer: " - + Utils.getClientName(client)); - return; - } + @Override + public void onLockoutTimed(long durationMillis) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof LockoutConsumer)) { + Slog.e(mTag, "onLockoutTimed for non-lockout consumer: " + + Utils.getClientName(client)); + return; + } + + final LockoutConsumer lockoutConsumer = (LockoutConsumer) client; + lockoutConsumer.onLockoutTimed(durationMillis); + }); + } - final AuthenticationConsumer authenticationConsumer = - (AuthenticationConsumer) client; - final Fingerprint fp = new Fingerprint("", 0 /* enrollmentId */, sensorId); - authenticationConsumer - .onAuthenticated(fp, false /* authenticated */, null /* hat */); - }); - } + @Override + public void onLockoutPermanent() { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof LockoutConsumer)) { + Slog.e(mTag, "onLockoutPermanent for non-lockout consumer: " + + Utils.getClientName(client)); + return; + } + + final LockoutConsumer lockoutConsumer = (LockoutConsumer) client; + lockoutConsumer.onLockoutPermanent(); + }); + } - @Override - public void onLockoutTimed(long durationMillis) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof LockoutConsumer)) { - Slog.e(mTag, "onLockoutTimed for non-lockout consumer: " - + Utils.getClientName(client)); - return; - } + @Override + public void onLockoutCleared() { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof FingerprintResetLockoutClient)) { + Slog.e(mTag, "onLockoutCleared for non-resetLockout client: " + + Utils.getClientName(client)); + return; + } + + final FingerprintResetLockoutClient resetLockoutClient = + (FingerprintResetLockoutClient) client; + resetLockoutClient.onLockoutCleared(); + }); + } - final LockoutConsumer lockoutConsumer = (LockoutConsumer) client; - lockoutConsumer.onLockoutTimed(durationMillis); - }); - } + @Override + public void onInteractionDetected() { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof FingerprintDetectClient)) { + Slog.e(mTag, "onInteractionDetected for non-detect client: " + + Utils.getClientName(client)); + return; + } + + final FingerprintDetectClient fingerprintDetectClient = + (FingerprintDetectClient) client; + fingerprintDetectClient.onInteractionDetected(); + }); + } - @Override - public void onLockoutPermanent() { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof LockoutConsumer)) { - Slog.e(mTag, "onLockoutPermanent for non-lockout consumer: " - + Utils.getClientName(client)); - return; + @Override + public void onEnrollmentsEnumerated(int[] enrollmentIds) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof EnumerateConsumer)) { + Slog.e(mTag, "onEnrollmentsEnumerated for non-enumerate consumer: " + + Utils.getClientName(client)); + return; + } + + final EnumerateConsumer enumerateConsumer = + (EnumerateConsumer) client; + if (enrollmentIds.length > 0) { + for (int i = 0; i < enrollmentIds.length; i++) { + final Fingerprint fp = new Fingerprint("", enrollmentIds[i], mSensorId); + enumerateConsumer.onEnumerationResult(fp, enrollmentIds.length - i - 1); } + } else { + enumerateConsumer.onEnumerationResult(null /* identifier */, 0); + } + }); + } - final LockoutConsumer lockoutConsumer = (LockoutConsumer) client; - lockoutConsumer.onLockoutPermanent(); - }); - } - - @Override - public void onLockoutCleared() { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof FingerprintResetLockoutClient)) { - Slog.e(mTag, "onLockoutCleared for non-resetLockout client: " - + Utils.getClientName(client)); - return; + @Override + public void onEnrollmentsRemoved(int[] enrollmentIds) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof RemovalConsumer)) { + Slog.e(mTag, "onRemoved for non-removal consumer: " + + Utils.getClientName(client)); + return; + } + + final RemovalConsumer removalConsumer = (RemovalConsumer) client; + if (enrollmentIds.length > 0) { + for (int i = 0; i < enrollmentIds.length; i++) { + final Fingerprint fp = new Fingerprint("", enrollmentIds[i], mSensorId); + removalConsumer.onRemoved(fp, enrollmentIds.length - i - 1); } + } else { + removalConsumer.onRemoved(null, 0); + } + }); + } - final FingerprintResetLockoutClient resetLockoutClient = - (FingerprintResetLockoutClient) client; - resetLockoutClient.onLockoutCleared(); - }); - } + @Override + public void onAuthenticatorIdRetrieved(long authenticatorId) { + mHandler.post(() -> { + final ClientMonitor<?> client = mScheduler.getCurrentClient(); + if (!(client instanceof FingerprintGetAuthenticatorIdClient)) { + Slog.e(mTag, "onAuthenticatorIdRetrieved for wrong consumer: " + + Utils.getClientName(client)); + return; + } + + final FingerprintGetAuthenticatorIdClient getAuthenticatorIdClient = + (FingerprintGetAuthenticatorIdClient) client; + getAuthenticatorIdClient.onAuthenticatorIdRetrieved(authenticatorId); + }); + } - @Override - public void onInteractionDetected() { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof FingerprintDetectClient)) { - Slog.e(mTag, "onInteractionDetected for non-detect client: " - + Utils.getClientName(client)); - return; - } + @Override + public void onAuthenticatorIdInvalidated() { + // TODO(159667191) + } + } - final FingerprintDetectClient fingerprintDetectClient = - (FingerprintDetectClient) client; - fingerprintDetectClient.onInteractionDetected(); - }); + Sensor(@NonNull String tag, @NonNull FingerprintProvider provider, @NonNull Context context, + @NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties, + @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) { + mTag = tag; + mProvider = provider; + mContext = context; + mHandler = handler; + mSensorProperties = sensorProperties; + mScheduler = new BiometricScheduler(tag, gestureAvailabilityDispatcher); + mLockoutCache = new LockoutCache(); + mAuthenticatorIds = new HashMap<>(); + mLazySession = () -> { + if (mTestHalEnabled) { + return new TestSession(mCurrentSession.mHalSessionCallback); + } else { + return mCurrentSession != null ? mCurrentSession.mSession : null; } + }; + } - @Override - public void onEnrollmentsEnumerated(int[] enrollmentIds) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof EnumerateConsumer)) { - Slog.e(mTag, "onEnrollmentsEnumerated for non-enumerate consumer: " - + Utils.getClientName(client)); - return; - } + @NonNull ClientMonitor.LazyDaemon<ISession> getLazySession() { + return mLazySession; + } - final EnumerateConsumer enumerateConsumer = - (EnumerateConsumer) client; - if (enrollmentIds.length > 0) { - for (int i = 0; i < enrollmentIds.length; i++) { - final Fingerprint fp = new Fingerprint("", enrollmentIds[i], sensorId); - enumerateConsumer.onEnumerationResult(fp, enrollmentIds.length - i - 1); - } - } else { - enumerateConsumer.onEnumerationResult(null /* identifier */, 0); - } - }); - } + @NonNull FingerprintSensorPropertiesInternal getSensorProperties() { + return mSensorProperties; + } - @Override - public void onEnrollmentsRemoved(int[] enrollmentIds) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof RemovalConsumer)) { - Slog.e(mTag, "onRemoved for non-removal consumer: " - + Utils.getClientName(client)); - return; - } + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + boolean hasSessionForUser(int userId) { + return mCurrentSession != null && mCurrentSession.mUserId == userId; + } - final RemovalConsumer removalConsumer = (RemovalConsumer) client; - if (enrollmentIds.length > 0) { - for (int i = 0; i < enrollmentIds.length; i++) { - final Fingerprint fp = new Fingerprint("", enrollmentIds[i], sensorId); - removalConsumer.onRemoved(fp, enrollmentIds.length - i - 1); - } - } else { - removalConsumer.onRemoved(null, 0); - } - }); - } + @Nullable Session getSessionForUser(int userId) { + if (mCurrentSession != null && mCurrentSession.mUserId == userId) { + return mCurrentSession; + } else { + return null; + } + } - @Override - public void onAuthenticatorIdRetrieved(long authenticatorId) { - mHandler.post(() -> { - final ClientMonitor<?> client = mScheduler.getCurrentClient(); - if (!(client instanceof FingerprintGetAuthenticatorIdClient)) { - Slog.e(mTag, "onAuthenticatorIdRetrieved for wrong consumer: " - + Utils.getClientName(client)); - return; - } + @NonNull ITestSession createTestSession() { + return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, mProvider, this); + } - final FingerprintGetAuthenticatorIdClient getAuthenticatorIdClient = - (FingerprintGetAuthenticatorIdClient) client; - getAuthenticatorIdClient.onAuthenticatorIdRetrieved(authenticatorId); - }); - } + void createNewSession(@NonNull IFingerprint daemon, int sensorId, int userId) + throws RemoteException { - @Override - public void onAuthenticatorIdInvalidated() { - // TODO(159667191) - } + final HalSessionCallback.Callback callback = () -> { + Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE"); + mCurrentSession = null; }; + final HalSessionCallback resultController = new HalSessionCallback(mContext, mHandler, + mTag, mScheduler, sensorId, userId, callback); - final ISession newSession = daemon.createSession(sensorId, userId, callback); + final ISession newSession = daemon.createSession(sensorId, userId, resultController); newSession.asBinder().linkToDeath(this, 0 /* flags */); - mCurrentSession = new Session(mTag, newSession, userId, callback); + mCurrentSession = new Session(mTag, newSession, userId, resultController); } @NonNull BiometricScheduler getScheduler() { @@ -418,4 +484,27 @@ class Sensor implements IBinder.DeathRecipient { @NonNull Map<Integer, Long> getAuthenticatorIds() { return mAuthenticatorIds; } + + void setTestHalEnabled(boolean enabled) { + mTestHalEnabled = enabled; + } + + void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) { + final long sensorToken = proto.start(FingerprintServiceStateProto.SENSOR_STATES); + + proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId); + proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null); + + for (UserInfo user : UserManager.get(mContext).getUsers()) { + final int userId = user.getUserHandle().getIdentifier(); + + final long userToken = proto.start(SensorStateProto.USER_STATES); + proto.write(UserStateProto.USER_ID, userId); + proto.write(UserStateProto.NUM_ENROLLED, FingerprintUtils.getInstance() + .getBiometricsForUser(mContext, userId).size()); + proto.end(userToken); + } + + proto.end(sensorToken); + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java new file mode 100644 index 000000000000..8c9a269486bb --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java @@ -0,0 +1,111 @@ +/* + * 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.biometrics.sensors.fingerprint.aidl; + +import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.fingerprint.IFingerprint; +import android.hardware.biometrics.fingerprint.ISession; +import android.hardware.biometrics.fingerprint.ISessionCallback; +import android.hardware.biometrics.fingerprint.SensorProps; +import android.hardware.keymaster.HardwareAuthToken; +import android.os.Binder; +import android.os.IBinder; + +/** + * Test HAL that provides only provides no-ops. + */ +public class TestHal extends IFingerprint.Stub { + @Override + public SensorProps[] getSensorProps() { + return new SensorProps[0]; + } + + @Override + public ISession createSession(int sensorId, int userId, ISessionCallback cb) { + return new ISession() { + @Override + public void generateChallenge(int cookie, int timeoutSec) { + + } + + @Override + public void revokeChallenge(int cookie, long challenge) { + + } + + @Override + public ICancellationSignal enroll(int cookie, HardwareAuthToken hat) { + return null; + } + + @Override + public ICancellationSignal authenticate(int cookie, long operationId) { + return null; + } + + @Override + public ICancellationSignal detectInteraction(int cookie) { + return null; + } + + @Override + public void enumerateEnrollments(int cookie) { + + } + + @Override + public void removeEnrollments(int cookie, int[] enrollmentIds) { + + } + + @Override + public void getAuthenticatorId(int cookie) { + + } + + @Override + public void invalidateAuthenticatorId(int cookie, HardwareAuthToken hat) { + + } + + @Override + public void resetLockout(int cookie, HardwareAuthToken hat) { + + } + + @Override + public void onPointerDown(int pointerId, int x, int y, float minor, float major) { + + } + + @Override + public void onPointerUp(int pointerId) { + + } + + @Override + public void onUiReady() { + + } + + @Override + public IBinder asBinder() { + return new Binder(); + } + }; + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java new file mode 100644 index 000000000000..d5afd0c68ad9 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java @@ -0,0 +1,106 @@ +/* + * 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.biometrics.sensors.fingerprint.aidl; + +import android.annotation.NonNull; +import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.fingerprint.ISession; +import android.hardware.keymaster.HardwareAuthToken; +import android.util.Slog; + +/** + * Test HAL that provides only provides mostly no-ops. + */ +class TestSession extends ISession.Stub { + + private static final String TAG = "TestSession"; + + @NonNull private final Sensor.HalSessionCallback mHalSessionCallback; + + TestSession(@NonNull Sensor.HalSessionCallback halSessionCallback) { + mHalSessionCallback = halSessionCallback; + } + + @Override + public void generateChallenge(int cookie, int timeoutSec) { + + } + + @Override + public void revokeChallenge(int cookie, long challenge) { + + } + + @Override + public ICancellationSignal enroll(int cookie, HardwareAuthToken hat) { + Slog.d(TAG, "enroll"); + return null; + } + + @Override + public ICancellationSignal authenticate(int cookie, long operationId) { + Slog.d(TAG, "authenticate"); + return null; + } + + @Override + public ICancellationSignal detectInteraction(int cookie) { + return null; + } + + @Override + public void enumerateEnrollments(int cookie) { + Slog.d(TAG, "enumerate"); + } + + @Override + public void removeEnrollments(int cookie, int[] enrollmentIds) { + Slog.d(TAG, "remove"); + } + + @Override + public void getAuthenticatorId(int cookie) { + Slog.d(TAG, "getAuthenticatorId"); + // Immediately return a value so the framework can continue with subsequent requests. + mHalSessionCallback.onAuthenticatorIdRetrieved(0); + } + + @Override + public void invalidateAuthenticatorId(int cookie, HardwareAuthToken hat) { + + } + + @Override + public void resetLockout(int cookie, HardwareAuthToken hat) { + + } + + @Override + public void onPointerDown(int pointerId, int x, int y, float minor, float major) { + + } + + @Override + public void onPointerUp(int pointerId) { + + } + + @Override + public void onUiReady() { + + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java new file mode 100644 index 000000000000..e0ea99077d51 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java @@ -0,0 +1,185 @@ +/* + * 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.biometrics.sensors.fingerprint.hidl; + +import static android.Manifest.permission.TEST_BIOMETRIC; + +import android.annotation.NonNull; +import android.content.Context; +import android.hardware.biometrics.ITestSession; +import android.hardware.fingerprint.Fingerprint; +import android.hardware.fingerprint.IFingerprintServiceReceiver; +import android.os.Binder; +import android.util.Slog; + +import com.android.server.biometrics.Utils; +import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +/** + * A test session implementation for the {@link Fingerprint21} provider. See + * {@link android.hardware.biometrics.BiometricTestSession}. + */ +public class BiometricTestSessionImpl extends ITestSession.Stub { + + private static final String TAG = "BiometricTestSessionImpl"; + + @NonNull private final Context mContext; + private final int mSensorId; + @NonNull private final Fingerprint21 mFingerprint21; + @NonNull private final Fingerprint21.HalResultController mHalResultController; + @NonNull private final Set<Integer> mEnrollmentIds; + @NonNull private final Random mRandom; + + /** + * Internal receiver currently only used for enroll. Results do not need to be forwarded to the + * test, since enrollment is a platform-only API. The authentication path is tested through + * the public FingerprintManager APIs and does not use this receiver. + */ + private final IFingerprintServiceReceiver mReceiver = new IFingerprintServiceReceiver.Stub() { + @Override + public void onEnrollResult(Fingerprint fp, int remaining) { + + } + + @Override + public void onAcquired(int acquiredInfo, int vendorCode) { + + } + + @Override + public void onAuthenticationSucceeded(Fingerprint fp, int userId, + boolean isStrongBiometric) { + + } + + @Override + public void onFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric) { + + } + + @Override + public void onAuthenticationFailed() { + + } + + @Override + public void onError(int error, int vendorCode) { + + } + + @Override + public void onRemoved(Fingerprint fp, int remaining) { + + } + + @Override + public void onChallengeGenerated(int sensorId, long challenge) { + + } + }; + + BiometricTestSessionImpl(@NonNull Context context, int sensorId, + @NonNull Fingerprint21 fingerprint21, + @NonNull Fingerprint21.HalResultController halResultController) { + mContext = context; + mSensorId = sensorId; + mFingerprint21 = fingerprint21; + mHalResultController = halResultController; + mEnrollmentIds = new HashSet<>(); + mRandom = new Random(); + } + + @Override + public void setTestHalEnabled(boolean enabled) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mFingerprint21.setTestHalEnabled(enabled); + } + + @Override + public void startEnroll(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mFingerprint21.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver, + mContext.getOpPackageName(), null /* surface */); + } + + @Override + public void finishEnroll(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + int nextRandomId = mRandom.nextInt(); + while (mEnrollmentIds.contains(nextRandomId)) { + nextRandomId = mRandom.nextInt(); + } + + mEnrollmentIds.add(nextRandomId); + mHalResultController.onEnrollResult(0 /* deviceId */, + nextRandomId /* fingerId */, userId, 0); + } + + @Override + public void acceptAuthentication(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + // Fake authentication with any of the existing fingers + List<Fingerprint> fingerprints = FingerprintUtils.getInstance() + .getBiometricsForUser(mContext, userId); + if (fingerprints.isEmpty()) { + Slog.w(TAG, "No fingerprints, returning"); + return; + } + final int fid = fingerprints.get(0).getBiometricId(); + final ArrayList<Byte> hat = new ArrayList<>(Collections.nCopies(69, (byte) 0)); + mHalResultController.onAuthenticated(0 /* deviceId */, fid, userId, hat); + } + + @Override + public void rejectAuthentication(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mHalResultController.onAuthenticated(0 /* deviceId */, 0 /* fingerId */, userId, null); + } + + @Override + public void notifyAcquired(int userId, int acquireInfo) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mHalResultController.onAcquired(0 /* deviceId */, acquireInfo, 0 /* vendorCode */); + } + + @Override + public void notifyError(int userId, int errorCode) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mHalResultController.onError(0 /* deviceId */, errorCode, 0 /* vendorCode */); + } + + @Override + public void cleanupInternalState(int userId) { + Utils.checkPermission(mContext, TEST_BIOMETRIC); + + mFingerprint21.scheduleInternalCleanup(mSensorId, userId); + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java index ab4427c5235c..241c911ce9ab 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java @@ -29,6 +29,7 @@ import android.content.pm.UserInfo; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricsProtoEnums; +import android.hardware.biometrics.ITestSession; import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback; import android.hardware.fingerprint.Fingerprint; @@ -51,8 +52,11 @@ import com.android.internal.R; import com.android.internal.util.FrameworkStatsLog; import com.android.server.biometrics.Utils; import com.android.server.biometrics.fingerprint.FingerprintServiceDumpProto; +import com.android.server.biometrics.fingerprint.FingerprintServiceStateProto; import com.android.server.biometrics.fingerprint.FingerprintUserStatsProto; import com.android.server.biometrics.fingerprint.PerformanceStatsProto; +import com.android.server.biometrics.fingerprint.SensorStateProto; +import com.android.server.biometrics.fingerprint.UserStateProto; import com.android.server.biometrics.sensors.AcquisitionClient; import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.AuthenticationConsumer; @@ -91,6 +95,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider private static final String TAG = "Fingerprint21"; private static final int ENROLL_TIMEOUT_SEC = 60; + private boolean mTestHalEnabled; + final Context mContext; private final IActivityTaskManager mActivityTaskManager; @NonNull private final FingerprintSensorPropertiesInternal mSensorProperties; @@ -391,6 +397,10 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider } private synchronized IBiometricsFingerprint getDaemon() { + if (mTestHalEnabled) { + return new TestHal(); + } + if (mDaemon != null) { return mDaemon; } @@ -693,7 +703,27 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider } @Override - public void dumpProto(int sensorId, FileDescriptor fd) { + public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) { + final long sensorToken = proto.start(FingerprintServiceStateProto.SENSOR_STATES); + + proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId); + proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null); + + for (UserInfo user : UserManager.get(mContext).getUsers()) { + final int userId = user.getUserHandle().getIdentifier(); + + final long userToken = proto.start(SensorStateProto.USER_STATES); + proto.write(UserStateProto.USER_ID, userId); + proto.write(UserStateProto.NUM_ENROLLED, FingerprintUtils.getInstance() + .getBiometricsForUser(mContext, userId).size()); + proto.end(userToken); + } + + proto.end(sensorToken); + } + + @Override + public void dumpProtoMetrics(int sensorId, FileDescriptor fd) { PerformanceTracker tracker = PerformanceTracker.getInstanceForSensorId(mSensorProperties.sensorId); @@ -771,4 +801,15 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount()); mScheduler.dump(pw); } + + void setTestHalEnabled(boolean enabled) { + mTestHalEnabled = enabled; + } + + @NonNull + @Override + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { + return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, this, + mHalResultController); + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/TestHal.java new file mode 100644 index 000000000000..86c0875af48c --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/TestHal.java @@ -0,0 +1,91 @@ +/* + * 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.biometrics.sensors.fingerprint.hidl; + +import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback; +import android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint; +import android.os.RemoteException; + +/** + * Test HAL that provides only provides no-ops. + */ +public class TestHal extends IBiometricsFingerprint.Stub { + @Override + public boolean isUdfps(int sensorId) { + return false; + } + + @Override + public void onFingerDown(int x, int y, float minor, float major) { + + } + + @Override + public void onFingerUp() { + + } + + @Override + public long setNotify(IBiometricsFingerprintClientCallback clientCallback) { + return 0; + } + + @Override + public long preEnroll() { + return 0; + } + + @Override + public int enroll(byte[] hat, int gid, int timeoutSec) { + return 0; + } + + @Override + public int postEnroll() { + return 0; + } + + @Override + public long getAuthenticatorId() { + return 0; + } + + @Override + public int cancel() { + return 0; + } + + @Override + public int enumerate() { + return 0; + } + + @Override + public int remove(int gid, int fid) { + return 0; + } + + @Override + public int setActiveGroup(int gid, String storePath) { + return 0; + } + + @Override + public int authenticate(long operationId, int gid) { + return 0; + } +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java index a0eafb4fc93f..b7e188c73eab 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java @@ -392,6 +392,7 @@ class RadioModule { } catch (RemoteException ex) { Slog.e(TAG, "Failed closing announcement listener", ex); } + hwCloseHandle.value = null; } }; } diff --git a/services/core/java/com/android/server/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java index 15f43a0481bd..fbd089c1f0ee 100644 --- a/services/core/java/com/android/server/connectivity/DataConnectionStats.java +++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java @@ -52,7 +52,6 @@ public class DataConnectionStats extends BroadcastReceiver { private SignalStrength mSignalStrength; private ServiceState mServiceState; private int mDataState = TelephonyManager.DATA_DISCONNECTED; - private int mNrState = NetworkRegistrationInfo.NR_STATE_NONE; public DataConnectionStats(Context context, Handler listenerHandler) { mContext = context; @@ -100,7 +99,7 @@ public class DataConnectionStats extends BroadcastReceiver { : regInfo.getAccessNetworkTechnology(); // If the device is in NSA NR connection the networkType will report as LTE. // For cell dwell rate metrics, this should report NR instead. - if (mNrState == NetworkRegistrationInfo.NR_STATE_CONNECTED) { + if (regInfo != null && regInfo.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED) { networkType = TelephonyManager.NETWORK_TYPE_NR; } if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible", @@ -172,7 +171,6 @@ public class DataConnectionStats extends BroadcastReceiver { @Override public void onServiceStateChanged(ServiceState state) { mServiceState = state; - mNrState = state.getNrState(); notePhoneDataConnectionState(); } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 4c2b1e34fa78..aebcdf19ecf4 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -201,6 +201,7 @@ public class Vpn { private final Context mContext; @VisibleForTesting final Dependencies mDeps; private final NetworkInfo mNetworkInfo; + private int mLegacyState; @VisibleForTesting protected String mPackage; private int mOwnerUID; private boolean mIsPackageTargetingAtLeastQ; @@ -415,6 +416,7 @@ public class Vpn { Log.wtf(TAG, "Problem registering observer", e); } + mLegacyState = LegacyVpnInfo.STATE_DISCONNECTED; mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_VPN, 0 /* subtype */, NETWORKTYPE, "" /* subtypeName */); mNetworkCapabilities = new NetworkCapabilities(); @@ -440,6 +442,7 @@ public class Vpn { @VisibleForTesting protected void updateState(DetailedState detailedState, String reason) { if (LOGD) Log.d(TAG, "setting state=" + detailedState + ", reason=" + reason); + mLegacyState = LegacyVpnInfo.stateFromNetworkInfo(detailedState); mNetworkInfo.setDetailedState(detailedState, reason, null); if (mNetworkAgent != null) { mNetworkAgent.sendNetworkInfo(mNetworkInfo); @@ -1243,6 +1246,7 @@ public class Vpn { // behaves the same as when it uses the default network. mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); + mLegacyState = LegacyVpnInfo.STATE_CONNECTING; mNetworkInfo.setDetailedState(DetailedState.CONNECTING, null, null); NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig(); @@ -2265,7 +2269,7 @@ public class Vpn { final LegacyVpnInfo info = new LegacyVpnInfo(); info.key = mConfig.user; - info.state = LegacyVpnInfo.stateFromNetworkInfo(mNetworkInfo); + info.state = mLegacyState; if (mNetworkInfo.isConnected()) { info.intent = mStatusIntent; } diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index c686ba4c4b5c..6a4ca8da00d1 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -210,7 +210,7 @@ public class SyncManager { private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock"; - private static final boolean USE_WTF_FOR_ACCOUNT_ERROR = false; + private static final boolean USE_WTF_FOR_ACCOUNT_ERROR = true; private static final int SYNC_OP_STATE_VALID = 0; // "1" used to include errors 3, 4 and 5 but now it's split up. @@ -231,7 +231,7 @@ public class SyncManager { private static final AccountAndUser[] INITIAL_ACCOUNTS_ARRAY = new AccountAndUser[0]; - // TODO: add better locking around mRunningAccounts + private final Object mAccountsLock = new Object(); private volatile AccountAndUser[] mRunningAccounts = INITIAL_ACCOUNTS_ARRAY; volatile private PowerManager.WakeLock mSyncManagerWakeLock; @@ -933,19 +933,21 @@ public class SyncManager { } AccountAndUser[] accounts = null; - if (requestedAccount != null) { - if (userId != UserHandle.USER_ALL) { - accounts = new AccountAndUser[]{new AccountAndUser(requestedAccount, userId)}; - } else { - for (AccountAndUser runningAccount : mRunningAccounts) { - if (requestedAccount.equals(runningAccount.account)) { - accounts = ArrayUtils.appendElement(AccountAndUser.class, - accounts, runningAccount); + synchronized (mAccountsLock) { + if (requestedAccount != null) { + if (userId != UserHandle.USER_ALL) { + accounts = new AccountAndUser[]{new AccountAndUser(requestedAccount, userId)}; + } else { + for (AccountAndUser runningAccount : mRunningAccounts) { + if (requestedAccount.equals(runningAccount.account)) { + accounts = ArrayUtils.appendElement(AccountAndUser.class, + accounts, runningAccount); + } } } + } else { + accounts = mRunningAccounts; } - } else { - accounts = mRunningAccounts; } if (ArrayUtils.isEmpty(accounts)) { @@ -3228,40 +3230,43 @@ public class SyncManager { } private void updateRunningAccountsH(EndPoint syncTargets) { - AccountAndUser[] oldAccounts = mRunningAccounts; - mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts(); - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Slog.v(TAG, "Accounts list: "); - for (AccountAndUser acc : mRunningAccounts) { - Slog.v(TAG, acc.toString()); + synchronized (mAccountsLock) { + AccountAndUser[] oldAccounts = mRunningAccounts; + mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts(); + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Slog.v(TAG, "Accounts list: "); + for (AccountAndUser acc : mRunningAccounts) { + Slog.v(TAG, acc.toString()); + } } - } - if (mLogger.enabled()) { - mLogger.log("updateRunningAccountsH: ", Arrays.toString(mRunningAccounts)); - } - removeStaleAccounts(); - - AccountAndUser[] accounts = mRunningAccounts; - for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) { - if (!containsAccountAndUser(accounts, - currentSyncContext.mSyncOperation.target.account, - currentSyncContext.mSyncOperation.target.userId)) { - Log.d(TAG, "canceling sync since the account is no longer running"); - sendSyncFinishedOrCanceledMessage(currentSyncContext, - null /* no result since this is a cancel */); + if (mLogger.enabled()) { + mLogger.log("updateRunningAccountsH: ", Arrays.toString(mRunningAccounts)); + } + removeStaleAccounts(); + + AccountAndUser[] accounts = mRunningAccounts; + for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) { + if (!containsAccountAndUser(accounts, + currentSyncContext.mSyncOperation.target.account, + currentSyncContext.mSyncOperation.target.userId)) { + Log.d(TAG, "canceling sync since the account is no longer running"); + sendSyncFinishedOrCanceledMessage(currentSyncContext, + null /* no result since this is a cancel */); + } } - } - if (syncTargets != null) { - // On account add, check if there are any settings to be restored. - for (AccountAndUser aau : mRunningAccounts) { - if (!containsAccountAndUser(oldAccounts, aau.account, aau.userId)) { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Account " + aau.account - + " added, checking sync restore data"); + if (syncTargets != null) { + // On account add, check if there are any settings to be restored. + for (AccountAndUser aau : mRunningAccounts) { + if (!containsAccountAndUser(oldAccounts, aau.account, aau.userId)) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Account " + aau.account + + " added, checking sync restore data"); + } + AccountSyncSettingsBackupHelper.accountAdded(mContext, + syncTargets.userId); + break; } - AccountSyncSettingsBackupHelper.accountAdded(mContext, syncTargets.userId); - break; } } } @@ -3442,13 +3447,15 @@ public class SyncManager { final EndPoint target = op.target; // Drop the sync if the account of this operation no longer exists. - AccountAndUser[] accounts = mRunningAccounts; - if (!containsAccountAndUser(accounts, target.account, target.userId)) { - if (isLoggable) { - Slog.v(TAG, " Dropping sync operation: account doesn't exist."); + synchronized (mAccountsLock) { + AccountAndUser[] accounts = mRunningAccounts; + if (!containsAccountAndUser(accounts, target.account, target.userId)) { + if (isLoggable) { + Slog.v(TAG, " Dropping sync operation: account doesn't exist."); + } + logAccountError("SYNC_OP_STATE_INVALID: account doesn't exist."); + return SYNC_OP_STATE_INVALID_NO_ACCOUNT; } - logAccountError("SYNC_OP_STATE_INVALID: account doesn't exist."); - return SYNC_OP_STATE_INVALID_NO_ACCOUNT; } // Drop this sync request if it isn't syncable. state = computeSyncable(target.account, target.userId, target.provider, true); diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java index 7e3c1ab50ad5..fe6e60f6159c 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java @@ -17,18 +17,26 @@ package com.android.server.devicestate; import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; +import static android.Manifest.permission.CONTROL_DEVICE_STATE; import android.annotation.NonNull; import android.content.Context; +import android.content.pm.PackageManager; import android.hardware.devicestate.IDeviceStateManager; +import android.os.Binder; +import android.os.ResultReceiver; +import android.os.ShellCallback; import android.util.IntArray; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.DumpUtils; import com.android.server.SystemService; import com.android.server.policy.DeviceStatePolicyImpl; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.Arrays; /** @@ -65,15 +73,20 @@ public final class DeviceStateManagerService extends SystemService { // The current committed device state. @GuardedBy("mLock") private int mCommittedState = INVALID_DEVICE_STATE; - // The device state that is currently pending callback from the policy to be committed. + // The device state that is currently awaiting callback from the policy to be committed. @GuardedBy("mLock") private int mPendingState = INVALID_DEVICE_STATE; // Whether or not the policy is currently waiting to be notified of the current pending state. @GuardedBy("mLock") private boolean mIsPolicyWaitingForState = false; // The device state that is currently requested and is next to be configured and committed. + // Can be overwritten by an override state value if requested. @GuardedBy("mLock") private int mRequestedState = INVALID_DEVICE_STATE; + // The most recently requested override state, or INVALID_DEVICE_STATE if no override is + // requested. + @GuardedBy("mLock") + private int mRequestedOverrideState = INVALID_DEVICE_STATE; public DeviceStateManagerService(@NonNull Context context) { this(context, new DeviceStatePolicyImpl()); @@ -97,7 +110,6 @@ public final class DeviceStateManagerService extends SystemService { * * @see #getPendingState() */ - @VisibleForTesting int getCommittedState() { synchronized (mLock) { return mCommittedState; @@ -119,13 +131,61 @@ public final class DeviceStateManagerService extends SystemService { * Returns the requested state. The service will configure the device to match the requested * state when possible. */ - @VisibleForTesting int getRequestedState() { synchronized (mLock) { return mRequestedState; } } + /** + * Overrides the current device state with the provided state. + * + * @return {@code true} if the override state is valid and supported, {@code false} otherwise. + */ + boolean setOverrideState(int overrideState) { + if (getContext().checkCallingOrSelfPermission(CONTROL_DEVICE_STATE) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Must hold permission " + CONTROL_DEVICE_STATE); + } + + synchronized (mLock) { + if (overrideState != INVALID_DEVICE_STATE && !isSupportedStateLocked(overrideState)) { + return false; + } + + mRequestedOverrideState = overrideState; + updatePendingStateLocked(); + } + + notifyPolicyIfNeeded(); + return true; + } + + /** + * Clears an override state set with {@link #setOverrideState(int)}. + */ + void clearOverrideState() { + setOverrideState(INVALID_DEVICE_STATE); + } + + /** + * Returns the current requested override state, or {@link #INVALID_DEVICE_STATE} is no override + * state is requested. + */ + int getOverrideState() { + synchronized (mLock) { + return mRequestedOverrideState; + } + } + + /** Returns the list of currently supported device states. */ + int[] getSupportedStates() { + synchronized (mLock) { + // Copy array to prevent external modification of internal state. + return Arrays.copyOf(mSupportedDeviceStates.toArray(), mSupportedDeviceStates.size()); + } + } + private void updateSupportedStates(int[] supportedDeviceStates) { // Must ensure sorted as isSupportedStateLocked() impl uses binary search. Arrays.sort(supportedDeviceStates, 0, supportedDeviceStates.length); @@ -135,11 +195,20 @@ public final class DeviceStateManagerService extends SystemService { if (mRequestedState != INVALID_DEVICE_STATE && !isSupportedStateLocked(mRequestedState)) { // The current requested state is no longer valid. We'll clear it here, though - // we won't actually update the current state with a call to - // updatePendingStateLocked() as doing so will not have any effect. + // we won't actually update the current state until a callback comes from the + // provider with the most recent state. mRequestedState = INVALID_DEVICE_STATE; } + if (mRequestedOverrideState != INVALID_DEVICE_STATE + && !isSupportedStateLocked(mRequestedOverrideState)) { + // The current override state is no longer valid. We'll clear it here and update + // the committed state if necessary. + mRequestedOverrideState = INVALID_DEVICE_STATE; + } + updatePendingStateLocked(); } + + notifyPolicyIfNeeded(); } /** @@ -168,27 +237,34 @@ public final class DeviceStateManagerService extends SystemService { } /** - * Tries to update the current configuring state with the current requested state. Must call + * Tries to update the current pending state with the current requested state. Must call * {@link #notifyPolicyIfNeeded()} to actually notify the policy that the state is being * changed. */ private void updatePendingStateLocked() { - if (mRequestedState == INVALID_DEVICE_STATE) { - // No currently requested state. + if (mPendingState != INVALID_DEVICE_STATE) { + // Have pending state, can not configure a new state until the state is committed. return; } - if (mPendingState != INVALID_DEVICE_STATE) { - // Have pending state, can not configure a new state until the state is committed. + int stateToConfigure; + if (mRequestedOverrideState != INVALID_DEVICE_STATE) { + stateToConfigure = mRequestedOverrideState; + } else { + stateToConfigure = mRequestedState; + } + + if (stateToConfigure == INVALID_DEVICE_STATE) { + // No currently requested state. return; } - if (mRequestedState == mCommittedState) { - // No need to notify the policy as the committed state matches the requested state. + if (stateToConfigure == mCommittedState) { + // The state requesting to be committed already matches the current committed state. return; } - mPendingState = mRequestedState; + mPendingState = stateToConfigure; mIsPolicyWaitingForState = true; } @@ -246,6 +322,21 @@ public final class DeviceStateManagerService extends SystemService { notifyPolicyIfNeeded(); } + private void dumpInternal(PrintWriter pw) { + pw.println("DEVICE STATE MANAGER (dumpsys device_state)"); + + synchronized (mLock) { + pw.println(" mCommittedState=" + toString(mCommittedState)); + pw.println(" mPendingState=" + toString(mPendingState)); + pw.println(" mRequestedState=" + toString(mRequestedState)); + pw.println(" mRequestedOverrideState=" + toString(mRequestedOverrideState)); + } + } + + private String toString(int state) { + return state == INVALID_DEVICE_STATE ? "(none)" : String.valueOf(state); + } + private final class DeviceStateProviderListener implements DeviceStateProvider.Listener { @Override public void onSupportedDeviceStatesChanged(int[] newDeviceStates) { @@ -271,6 +362,23 @@ public final class DeviceStateManagerService extends SystemService { /** Implementation of {@link IDeviceStateManager} published as a binder service. */ private final class BinderService extends IDeviceStateManager.Stub { + @Override // Binder call + public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, + String[] args, ShellCallback callback, ResultReceiver result) { + new DeviceStateManagerShellCommand(DeviceStateManagerService.this) + .exec(this, in, out, err, args, callback, result); + } + @Override // Binder call + public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { + if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; + + final long token = Binder.clearCallingIdentity(); + try { + dumpInternal(pw); + } finally { + Binder.restoreCallingIdentity(token); + } + } } } diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java new file mode 100644 index 000000000000..cf3b297545dc --- /dev/null +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.devicestate; + +import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; + +import android.os.ShellCommand; + +import java.io.PrintWriter; + +/** + * ShellCommands for {@link DeviceStateManagerService}. + * + * Use with {@code adb shell cmd device_state ...}. + */ +public class DeviceStateManagerShellCommand extends ShellCommand { + private final DeviceStateManagerService mInternal; + + public DeviceStateManagerShellCommand(DeviceStateManagerService service) { + mInternal = service; + } + + @Override + public int onCommand(String cmd) { + if (cmd == null) { + return handleDefaultCommands(cmd); + } + final PrintWriter pw = getOutPrintWriter(); + + switch (cmd) { + case "state": + return runState(pw); + case "print-states": + return runPrintStates(pw); + default: + return handleDefaultCommands(cmd); + } + } + + private void printState(PrintWriter pw) { + int committedState = mInternal.getCommittedState(); + int requestedState = mInternal.getRequestedState(); + int requestedOverrideState = mInternal.getOverrideState(); + + if (committedState == INVALID_DEVICE_STATE) { + pw.println("Device state: (invalid)"); + } else { + pw.println("Device state: " + committedState); + } + + if (requestedOverrideState != INVALID_DEVICE_STATE) { + pw.println("----------------------"); + if (requestedState == INVALID_DEVICE_STATE) { + pw.println("Base state: (invalid)"); + } else { + pw.println("Base state: " + requestedState); + } + pw.println("Override state: " + committedState); + } + } + + private int runState(PrintWriter pw) { + final String nextArg = getNextArg(); + if (nextArg == null) { + printState(pw); + } else if ("reset".equals(nextArg)) { + mInternal.clearOverrideState(); + } else { + int requestedState; + try { + requestedState = Integer.parseInt(nextArg); + } catch (NumberFormatException e) { + getErrPrintWriter().println("Error: requested state should be an integer"); + return -1; + } + + boolean success = mInternal.setOverrideState(requestedState); + if (!success) { + getErrPrintWriter().println("Error: failed to set override state. Run:"); + getErrPrintWriter().println(""); + getErrPrintWriter().println(" print-states"); + getErrPrintWriter().println(""); + getErrPrintWriter().println("to get the list of currently supported device states"); + return -1; + } + } + return 0; + } + + private int runPrintStates(PrintWriter pw) { + int[] states = mInternal.getSupportedStates(); + pw.print("Supported states: [ "); + for (int i = 0; i < states.length; i++) { + pw.print(states[i]); + if (i < states.length - 1) { + pw.print(", "); + } + } + pw.println(" ]"); + return 0; + } + + @Override + public void onHelp() { + PrintWriter pw = getOutPrintWriter(); + pw.println("Device state manager (device_state) commands:"); + pw.println(" help"); + pw.println(" Print this help text."); + pw.println(" state [reset|OVERRIDE_DEVICE_STATE]"); + pw.println(" Return or override device state."); + pw.println(" print-states"); + pw.println(" Return list of currently supported device states."); + } +} diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java index 73f788901dc9..5e1df27167c2 100644 --- a/services/core/java/com/android/server/display/ColorFade.java +++ b/services/core/java/com/android/server/display/ColorFade.java @@ -16,6 +16,8 @@ package com.android.server.display; +import static com.android.server.wm.utils.RotationAnimationUtils.hasProtectedContent; + import android.content.Context; import android.graphics.SurfaceTexture; import android.hardware.display.DisplayManagerInternal; @@ -35,7 +37,6 @@ import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; -import android.view.SurfaceSession; import com.android.server.LocalServices; import com.android.server.policy.WindowManagerPolicy; @@ -75,6 +76,7 @@ final class ColorFade { private static final int EGL_GL_COLORSPACE_KHR = 0x309D; private static final int EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT = 0x3490; + private static final int EGL_PROTECTED_CONTENT_EXT = 0x32C0; private final int mDisplayId; @@ -87,7 +89,6 @@ final class ColorFade { private int mDisplayLayerStack; // layer stack associated with primary display private int mDisplayWidth; // real width, not rotated private int mDisplayHeight; // real height, not rotated - private SurfaceSession mSurfaceSession; private SurfaceControl mSurfaceControl; private Surface mSurface; private NaturalSurfaceLayout mSurfaceLayout; @@ -97,7 +98,8 @@ final class ColorFade { private EGLSurface mEglSurface; private boolean mSurfaceVisible; private float mSurfaceAlpha; - private boolean mIsWideColor; + private boolean mLastWasWideColor; + private boolean mLastWasProtectedContent; // Texture names. We only use one texture, which contains the screenshot. private final int[] mTexNames = new int[1]; @@ -157,9 +159,28 @@ final class ColorFade { mDisplayWidth = displayInfo.getNaturalWidth(); mDisplayHeight = displayInfo.getNaturalHeight(); - // Prepare the surface for drawing. - if (!(createSurface() && createEglContext() && createEglSurface() && - captureScreenshotTextureAndSetViewport())) { + final IBinder token = SurfaceControl.getInternalDisplayToken(); + if (token == null) { + Slog.e(TAG, + "Failed to take screenshot because internal display is disconnected"); + return false; + } + boolean isWideColor = SurfaceControl.getActiveColorMode(token) + == Display.COLOR_MODE_DISPLAY_P3; + + // Set mPrepared here so if initialization fails, resources can be cleaned up. + mPrepared = true; + + SurfaceControl.ScreenshotHardwareBuffer hardwareBuffer = captureScreen(); + if (hardwareBuffer == null) { + dismiss(); + return false; + } + + boolean isProtected = hasProtectedContent(hardwareBuffer.getHardwareBuffer()); + if (!(createSurfaceControl(hardwareBuffer.containsSecureLayers()) + && createEglContext(isProtected) && createEglSurface(isProtected, isWideColor) + && setScreenshotTextureAndSetViewport(hardwareBuffer))) { dismiss(); return false; } @@ -180,7 +201,8 @@ final class ColorFade { // Done. mCreatedResources = true; - mPrepared = true; + mLastWasProtectedContent = isProtected; + mLastWasWideColor = isWideColor; // Dejanking optimization. // Some GL drivers can introduce a lot of lag in the first few frames as they @@ -466,7 +488,8 @@ final class ColorFade { mProjMatrix[15] = 1f; } - private boolean captureScreenshotTextureAndSetViewport() { + private boolean setScreenshotTextureAndSetViewport( + SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) { if (!attachEglContext()) { return false; } @@ -482,27 +505,9 @@ final class ColorFade { final SurfaceTexture st = new SurfaceTexture(mTexNames[0]); final Surface s = new Surface(st); try { - final IBinder token = SurfaceControl.getInternalDisplayToken(); - if (token == null) { - Slog.e(TAG, - "Failed to take screenshot because internal display is disconnected"); - return false; - } - - mIsWideColor = SurfaceControl.getActiveColorMode(token) - == Display.COLOR_MODE_DISPLAY_P3; - SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = - mDisplayManagerInternal.systemScreenshot(mDisplayId); - if (screenshotBuffer == null) { - Slog.e(TAG, "Failed to take screenshot. Buffer is null"); - return false; - } s.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(), screenshotBuffer.getColorSpace()); - if (screenshotBuffer.containsSecureLayers()) { - mTransaction.setSecure(mSurfaceControl, true).apply(); - } st.updateTexImage(); st.getTransformMatrix(mTexMatrix); } finally { @@ -535,7 +540,52 @@ final class ColorFade { } } - private boolean createEglContext() { + private SurfaceControl.ScreenshotHardwareBuffer captureScreen() { + SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = + mDisplayManagerInternal.systemScreenshot(mDisplayId); + if (screenshotBuffer == null) { + Slog.e(TAG, "Failed to take screenshot. Buffer is null"); + return null; + } + return screenshotBuffer; + } + + private boolean createSurfaceControl(boolean isSecure) { + if (mSurfaceControl != null) { + mTransaction.setSecure(mSurfaceControl, isSecure).apply(); + return true; + } + + try { + final SurfaceControl.Builder builder = new SurfaceControl.Builder() + .setName("ColorFade") + .setSecure(isSecure) + .setCallsite("ColorFade.createSurface"); + if (mMode == MODE_FADE) { + builder.setColorLayer(); + } else { + builder.setBufferSize(mDisplayWidth, mDisplayHeight); + } + mSurfaceControl = builder.build(); + } catch (OutOfResourcesException ex) { + Slog.e(TAG, "Unable to create surface.", ex); + return false; + } + + mTransaction.setLayerStack(mSurfaceControl, mDisplayLayerStack); + mTransaction.setWindowCrop(mSurfaceControl, mDisplayWidth, mDisplayHeight); + mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, mDisplayId, + mSurfaceControl); + mSurfaceLayout.onDisplayTransaction(mTransaction); + mTransaction.apply(); + + mSurface = new Surface(); + mSurface.copyFrom(mSurfaceControl); + + return true; + } + + private boolean createEglContext(boolean isProtected) { if (mEglDisplay == null) { mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); if (mEglDisplay == EGL14.EGL_NO_DISPLAY) { @@ -576,13 +626,25 @@ final class ColorFade { mEglConfig = eglConfigs[0]; } + // The old context needs to be destroyed if the protected flag has changed. The context will + // be recreated based on the protected flag + if (mEglContext != null && isProtected != mLastWasProtectedContent) { + EGL14.eglDestroyContext(mEglDisplay, mEglContext); + mEglContext = null; + } + if (mEglContext == null) { int[] eglContextAttribList = new int[] { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, + EGL14.EGL_NONE, EGL14.EGL_NONE, EGL14.EGL_NONE }; - mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, - EGL14.EGL_NO_CONTEXT, eglContextAttribList, 0); + if (isProtected) { + eglContextAttribList[2] = EGL_PROTECTED_CONTENT_EXT; + eglContextAttribList[3] = EGL14.EGL_TRUE; + } + mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, EGL14.EGL_NO_CONTEXT, + eglContextAttribList, 0); if (mEglContext == null) { logEglError("eglCreateContext"); return false; @@ -591,53 +653,34 @@ final class ColorFade { return true; } - private boolean createSurface() { - if (mSurfaceSession == null) { - mSurfaceSession = new SurfaceSession(); - } - - if (mSurfaceControl == null) { - try { - final SurfaceControl.Builder builder = new SurfaceControl.Builder(mSurfaceSession) - .setName("ColorFade") - .setCallsite("ColorFade.createSurface"); - if (mMode == MODE_FADE) { - builder.setColorLayer(); - } else { - builder.setBufferSize(mDisplayWidth, mDisplayHeight); - } - mSurfaceControl = builder.build(); - } catch (OutOfResourcesException ex) { - Slog.e(TAG, "Unable to create surface.", ex); - return false; - } - - mTransaction.setLayerStack(mSurfaceControl, mDisplayLayerStack); - mTransaction.setWindowCrop(mSurfaceControl, mDisplayWidth, mDisplayHeight); - mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, - mDisplayId, mSurfaceControl); - mSurfaceLayout.onDisplayTransaction(mTransaction); - mTransaction.apply(); - - mSurface = new Surface(); - mSurface.copyFrom(mSurfaceControl); - + private boolean createEglSurface(boolean isProtected, boolean isWideColor) { + // The old surface needs to be destroyed if either the protected flag or wide color flag has + // changed. The surface will be recreated based on the new flags. + boolean didContentAttributesChange = + isProtected != mLastWasProtectedContent || isWideColor != mLastWasWideColor; + if (mEglSurface != null && didContentAttributesChange) { + EGL14.eglDestroySurface(mEglDisplay, mEglSurface); + mEglSurface = null; } - return true; - } - private boolean createEglSurface() { if (mEglSurface == null) { int[] eglSurfaceAttribList = new int[] { EGL14.EGL_NONE, EGL14.EGL_NONE, + EGL14.EGL_NONE, + EGL14.EGL_NONE, EGL14.EGL_NONE }; + int index = 0; // If the current display is in wide color, then so is the screenshot. - if (mIsWideColor) { - eglSurfaceAttribList[0] = EGL_GL_COLORSPACE_KHR; - eglSurfaceAttribList[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT; + if (isWideColor) { + eglSurfaceAttribList[index++] = EGL_GL_COLORSPACE_KHR; + eglSurfaceAttribList[index++] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT; + } + if (isProtected) { + eglSurfaceAttribList[index++] = EGL_PROTECTED_CONTENT_EXT; + eglSurfaceAttribList[index] = EGL14.EGL_TRUE; } // turn our SurfaceControl into a Surface mEglSurface = EGL14.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index d4377e4870a5..fe6500e8942c 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -130,6 +130,14 @@ final class DisplayDeviceInfo { public static final int FLAG_TRUSTED = 1 << 13; /** + * Flag: Indicates that the display should not be a part of the default {@link DisplayGroup} and + * instead be part of a new {@link DisplayGroup}. + * + * @hide + */ + public static final int FLAG_OWN_DISPLAY_GROUP = 1 << 14; + + /** * Touch attachment: Display does not receive touch. */ public static final int TOUCH_NONE = 0; diff --git a/services/core/java/com/android/server/display/DisplayGroup.java b/services/core/java/com/android/server/display/DisplayGroup.java new file mode 100644 index 000000000000..f2413edd1a3a --- /dev/null +++ b/services/core/java/com/android/server/display/DisplayGroup.java @@ -0,0 +1,39 @@ +/* + * 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.display; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and + * operations. + */ +public class DisplayGroup { + + final List<LogicalDisplay> mDisplays = new ArrayList<>(); + + void addDisplay(LogicalDisplay display) { + if (!mDisplays.contains(display)) { + mDisplays.add(display); + } + } + + boolean removeDisplay(LogicalDisplay display) { + return mDisplays.remove(display); + } +} diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 60c83905ed9c..6a3e7b7a0ecd 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -23,6 +23,7 @@ import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; @@ -1292,6 +1293,7 @@ public final class DisplayManagerService extends SystemService { .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()) .setUseIdentityTransform(true) .setCaptureSecureLayers(true) + .setAllowProtected(true) .build(); return SurfaceControl.captureDisplay(captureArgs); } @@ -2024,6 +2026,9 @@ public final class DisplayManagerService extends SystemService { if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) { flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; } + if ((flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { + flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; + } if (projection != null) { try { @@ -2062,6 +2067,14 @@ public final class DisplayManagerService extends SystemService { } } + if (callingUid != Process.SYSTEM_UID + && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) { + if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { + throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + + "create a virtual display which is not in the default DisplayGroup."); + } + } + if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) { flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; } diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index 71b377cc2f11..c013145b5269 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -16,6 +16,7 @@ package com.android.server.display; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ContentResolver; @@ -50,11 +51,14 @@ import com.android.server.display.utils.AmbientFilter; import com.android.server.display.utils.AmbientFilterFactory; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; + /** * The DisplayModeDirector is responsible for determining what modes are allowed to be automatically * picked by the system based on system-wide and display-specific configuration. @@ -99,6 +103,29 @@ public class DisplayModeDirector { private boolean mAlwaysRespectAppRequest; + @IntDef(prefix = {"SWITCHING_TYPE_"}, value = { + SWITCHING_TYPE_NONE, + SWITCHING_TYPE_WITHIN_GROUPS, + SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SwitchingType {} + + // No mode switching will happen. + public static final int SWITCHING_TYPE_NONE = 0; + // Allow only refresh rate switching between modes in the same configuration group. This way + // only switches without visual interruptions for the user will be allowed. + public static final int SWITCHING_TYPE_WITHIN_GROUPS = 1; + // Allow refresh rate switching between all refresh rates even if the switch with have visual + // interruptions for the user. + public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2; + + /** + * The allowed refresh rate switching type. This is used by SurfaceFlinger. + */ + @SwitchingType + private int mModeSwitchingType = SWITCHING_TYPE_WITHIN_GROUPS; + public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler) { mContext = context; mHandler = new DisplayModeDirectorHandler(handler.getLooper()); @@ -290,14 +317,37 @@ public class DisplayModeDirector { appRequestSummary.maxRefreshRate)); } + // If the application requests a given mode with preferredModeId function, it will be + // stored as baseModeId. int baseModeId = defaultMode.getModeId(); if (availableModes.length > 0) { baseModeId = availableModes[0]; } - // filterModes function is going to filter the modes based on the voting system. If - // the application requests a given mode with preferredModeId function, it will be - // stored as baseModeId. + if (mModeSwitchingType == SWITCHING_TYPE_NONE) { + Display.Mode baseMode = null; + for (Display.Mode mode : modes) { + if (mode.getModeId() == baseModeId) { + baseMode = mode; + break; + } + } + if (baseMode == null) { + // This should never happen. + throw new IllegalStateException( + "The base mode with id " + baseModeId + + " is not in the list of supported modes."); + } + float fps = baseMode.getRefreshRate(); + return new DesiredDisplayModeSpecs(baseModeId, + /*allowGroupSwitching */ false, + new RefreshRateRange(fps, fps), + new RefreshRateRange(fps, fps)); + } + + boolean allowGroupSwitching = + mModeSwitchingType == SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS; return new DesiredDisplayModeSpecs(baseModeId, + allowGroupSwitching, new RefreshRateRange( primarySummary.minRefreshRate, primarySummary.maxRefreshRate), new RefreshRateRange( @@ -385,6 +435,26 @@ public class DisplayModeDirector { } /** + * Sets the display mode switching type. + * @param type + */ + public void setModeSwitchingType(@SwitchingType int type) { + synchronized (mLock) { + mModeSwitchingType = type; + } + } + + /** + * Returns the display mode switching type. + */ + @SwitchingType + public int getModeSwitchingType() { + synchronized (mLock) { + return mModeSwitchingType; + } + } + + /** * Print the object's state and debug information into the given stream. * * @param pw The stream to dump information to. @@ -416,6 +486,7 @@ public class DisplayModeDirector { pw.println(" " + Vote.priorityToString(p) + " -> " + vote); } } + pw.println(" mModeSwitchingType: " + switchingTypeToString(mModeSwitchingType)); pw.println(" mAlwaysRespectAppRequest: " + mAlwaysRespectAppRequest); mSettingsObserver.dumpLocked(pw); mAppRequestObserver.dumpLocked(pw); @@ -472,7 +543,6 @@ public class DisplayModeDirector { } private SparseArray<Vote> getOrCreateVotesByDisplay(int displayId) { - int index = mVotesByDisplay.indexOfKey(displayId); if (mVotesByDisplay.indexOfKey(displayId) >= 0) { return mVotesByDisplay.get(displayId); } else { @@ -482,6 +552,19 @@ public class DisplayModeDirector { } } + private static String switchingTypeToString(@SwitchingType int type) { + switch (type) { + case SWITCHING_TYPE_NONE: + return "SWITCHING_TYPE_NONE"; + case SWITCHING_TYPE_WITHIN_GROUPS: + return "SWITCHING_TYPE_WITHIN_GROUPS"; + case SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS: + return "SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS"; + default: + return "Unknown SwitchingType " + type; + } + } + @VisibleForTesting void injectSupportedModesByDisplay(SparseArray<Display.Mode[]> supportedModesByDisplay) { mSupportedModesByDisplay = supportedModesByDisplay; @@ -631,18 +714,26 @@ public class DisplayModeDirector { * SurfaceControl.DesiredDisplayConfigSpecs uses, and the mode ID used here. */ public static final class DesiredDisplayModeSpecs { + /** * Base mode ID. This is what system defaults to for all other settings, or * if the refresh rate range is not available. */ public int baseModeId; + + /** + * If true this will allow switching between modes in different display configuration + * groups. This way the user may see visual interruptions when the display mode changes. + */ + public boolean allowGroupSwitching; + /** * The primary refresh rate range. */ public final RefreshRateRange primaryRefreshRateRange; /** * The app request refresh rate range. Lower priority considerations won't be included in - * this range, allowing surface flinger to consider additional refresh rates for apps that + * this range, allowing SurfaceFlinger to consider additional refresh rates for apps that * call setFrameRate(). This range will be greater than or equal to the primary refresh rate * range, never smaller. */ @@ -654,9 +745,11 @@ public class DisplayModeDirector { } public DesiredDisplayModeSpecs(int baseModeId, + boolean allowGroupSwitching, @NonNull RefreshRateRange primaryRefreshRateRange, @NonNull RefreshRateRange appRequestRefreshRateRange) { this.baseModeId = baseModeId; + this.allowGroupSwitching = allowGroupSwitching; this.primaryRefreshRateRange = primaryRefreshRateRange; this.appRequestRefreshRateRange = appRequestRefreshRateRange; } @@ -666,10 +759,12 @@ public class DisplayModeDirector { */ @Override public String toString() { - return String.format("baseModeId=%d primaryRefreshRateRange=[%.0f %.0f]" + return String.format("baseModeId=%d allowGroupSwitching=%b" + + " primaryRefreshRateRange=[%.0f %.0f]" + " appRequestRefreshRateRange=[%.0f %.0f]", - baseModeId, primaryRefreshRateRange.min, primaryRefreshRateRange.max, - appRequestRefreshRateRange.min, appRequestRefreshRateRange.max); + baseModeId, allowGroupSwitching, primaryRefreshRateRange.min, + primaryRefreshRateRange.max, appRequestRefreshRateRange.min, + appRequestRefreshRateRange.max); } /** * Checks whether the two objects have the same values. @@ -689,6 +784,9 @@ public class DisplayModeDirector { if (baseModeId != desiredDisplayModeSpecs.baseModeId) { return false; } + if (allowGroupSwitching != desiredDisplayModeSpecs.allowGroupSwitching) { + return false; + } if (!primaryRefreshRateRange.equals(desiredDisplayModeSpecs.primaryRefreshRateRange)) { return false; } @@ -701,7 +799,8 @@ public class DisplayModeDirector { @Override public int hashCode() { - return Objects.hash(baseModeId, primaryRefreshRateRange, appRequestRefreshRateRange); + return Objects.hash(baseModeId, allowGroupSwitching, primaryRefreshRateRange, + appRequestRefreshRateRange); } /** @@ -709,6 +808,7 @@ public class DisplayModeDirector { */ public void copyFrom(DesiredDisplayModeSpecs other) { baseModeId = other.baseModeId; + allowGroupSwitching = other.allowGroupSwitching; primaryRefreshRateRange.min = other.primaryRefreshRateRange.min; primaryRefreshRateRange.max = other.primaryRefreshRateRange.max; appRequestRefreshRateRange.min = other.appRequestRefreshRateRange.min; diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 6597aa54d66b..9437677d8ab8 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -300,10 +300,16 @@ final class LocalDisplayAdapter extends DisplayAdapter { } } - // Check whether surface flinger spontaneously changed modes out from under us. - // Schedule traversals to ensure that the correct state is reapplied if necessary. + boolean activeModeChanged = false; + + // Check whether SurfaceFlinger or the display device changed the active mode out from + // under us. if (mActiveModeId != NO_DISPLAY_MODE_ID && mActiveModeId != activeRecord.mMode.getModeId()) { + Slog.d(TAG, "The active mode was changed from SurfaceFlinger or the display" + + "device."); + mActiveModeId = activeRecord.mMode.getModeId(); + activeModeChanged = true; sendTraversalRequestLocked(); } @@ -333,7 +339,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { boolean recordsChanged = records.size() != mSupportedModes.size() || modesAdded; // If the records haven't changed then we're done here. if (!recordsChanged) { - return false; + return activeModeChanged; } mSupportedModes.clear(); @@ -811,6 +817,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { LocalDisplayDevice::setDesiredDisplayModeSpecsAsync, this, getDisplayTokenLocked(), new SurfaceControl.DesiredDisplayConfigSpecs(baseConfigId, + mDisplayModeSpecs.allowGroupSwitching, mDisplayModeSpecs.primaryRefreshRateRange.min, mDisplayModeSpecs.primaryRefreshRateRange.max, mDisplayModeSpecs.appRequestRefreshRateRange.min, diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index a17a294cd1d7..e35becc93be0 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -280,6 +280,9 @@ final class LogicalDisplay { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0) { mBaseDisplayInfo.flags |= Display.FLAG_TRUSTED; } + if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) { + mBaseDisplayInfo.flags |= Display.FLAG_OWN_DISPLAY_GROUP; + } Rect maskingInsets = getMaskingInsets(deviceInfo); int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right; int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom; diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index fc3ba35c52ba..a843af5982b4 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -35,6 +35,9 @@ import java.util.function.Consumer; * Responsible for creating {@link LogicalDisplay}s and associating them to the * {@link DisplayDevice} objects supplied through {@link DisplayAdapter.Listener}. * + * Additionally this class will keep track of which {@link DisplayGroup} each + * {@link LogicalDisplay} belongs to. + * * For devices with a single internal display, the mapping is done once and left * alone. For devices with multiple built-in displays, such as foldable devices, * {@link LogicalDisplay}s can be remapped to different {@link DisplayDevice}s. @@ -91,6 +94,9 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { new SparseArray<LogicalDisplay>(); private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1; + /** A mapping from logical display id to display group. */ + private final SparseArray<DisplayGroup> mDisplayGroups = new SparseArray<>(); + private final DisplayDeviceRepository mDisplayDeviceRepo; private final PersistentDataStore mPersistentDataStore; private final Listener mListener; @@ -296,6 +302,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { mLogicalDisplays.put(displayId, display); + final DisplayGroup displayGroup; + if (isDefault || (deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) { + displayGroup = new DisplayGroup(); + } else { + displayGroup = mDisplayGroups.get(Display.DEFAULT_DISPLAY); + } + displayGroup.addDisplay(display); + mDisplayGroups.append(displayId, displayGroup); + mListener.onLogicalDisplayEventLocked(display, LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED); } @@ -314,10 +329,31 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { display.updateLocked(mDisplayDeviceRepo); if (!display.isValidLocked()) { mLogicalDisplays.removeAt(i); + mDisplayGroups.removeReturnOld(displayId).removeDisplay(display); mListener.onLogicalDisplayEventLocked(display, LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED); } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { + final int flags = display.getDisplayInfoLocked().flags; + final DisplayGroup defaultDisplayGroup = mDisplayGroups.get( + Display.DEFAULT_DISPLAY); + if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) { + // The display should have its own DisplayGroup. + if (defaultDisplayGroup.removeDisplay(display)) { + final DisplayGroup displayGroup = new DisplayGroup(); + displayGroup.addDisplay(display); + mDisplayGroups.append(display.getDisplayIdLocked(), displayGroup); + } + } else { + // The display should be a part of the default DisplayGroup. + final DisplayGroup displayGroup = mDisplayGroups.get(displayId); + if (displayGroup != defaultDisplayGroup) { + displayGroup.removeDisplay(display); + defaultDisplayGroup.addDisplay(display); + mDisplayGroups.put(displayId, defaultDisplayGroup); + } + } + final String oldUniqueId = mTempDisplayInfo.uniqueId; final String newUniqueId = display.getDisplayInfoLocked().uniqueId; final int eventMsg = TextUtils.equals(oldUniqueId, newUniqueId) diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 210d2979c807..ff4717b7131b 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -19,6 +19,7 @@ package com.android.server.display; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT; @@ -27,6 +28,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOUL import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; +import static com.android.server.display.DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP; import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED; import android.content.Context; @@ -386,6 +388,10 @@ public class VirtualDisplayAdapter extends DisplayAdapter { mInfo.flags &= ~DisplayDeviceInfo.FLAG_NEVER_BLANK; } else { mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY; + + if ((mFlags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) { + mInfo.flags |= FLAG_OWN_DISPLAY_GROUP; + } } if ((mFlags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 425fbc5687ec..5fddae53d632 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -66,10 +66,10 @@ final class Constants { public static final int ADDR_PLAYBACK_3 = 11; /** Logical address reserved for future usage */ - public static final int ADDR_RESERVED_1 = 12; + public static final int ADDR_BACKUP_1 = 12; /** Logical address reserved for future usage */ - public static final int ADDR_RESERVED_2 = 13; + public static final int ADDR_BACKUP_2 = 13; /** Logical address for TV other than the one assigned with {@link #ADDR_TV} */ public static final int ADDR_SPECIFIC_USE = 14; @@ -492,6 +492,15 @@ final class Constants { static final int DISABLED = 0; static final int ENABLED = 1; + @IntDef({ + VERSION_1_4, + VERSION_2_0 + }) + @interface CecVersion {} + static final int VERSION_1_3 = 0x04; + static final int VERSION_1_4 = 0x05; + static final int VERSION_2_0 = 0x06; + private Constants() { /* cannot be instantiated */ } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java index 652bf5a7a67f..e906a7c8132c 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java @@ -37,6 +37,7 @@ import com.android.server.hdmi.cec.config.XmlParser; import org.xmlpull.v1.XmlPullParserException; import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -81,7 +82,7 @@ public class HdmiCecConfig { @NonNull private final Context mContext; @NonNull private final StorageAdapter mStorageAdapter; - @Nullable private final CecSettings mProductConfig; + @Nullable private final CecSettings mSystemConfig; @Nullable private final CecSettings mVendorOverride; /** @@ -129,14 +130,14 @@ public class HdmiCecConfig { @VisibleForTesting HdmiCecConfig(@NonNull Context context, @NonNull StorageAdapter storageAdapter, - @Nullable CecSettings productConfig, + @Nullable CecSettings systemConfig, @Nullable CecSettings vendorOverride) { mContext = context; mStorageAdapter = storageAdapter; - mProductConfig = productConfig; + mSystemConfig = systemConfig; mVendorOverride = vendorOverride; - if (mProductConfig == null) { - Slog.i(TAG, "CEC master configuration XML missing."); + if (mSystemConfig == null) { + Slog.i(TAG, "CEC system configuration XML missing."); } if (mVendorOverride == null) { Slog.i(TAG, "CEC OEM configuration override XML missing."); @@ -145,7 +146,7 @@ public class HdmiCecConfig { HdmiCecConfig(@NonNull Context context) { this(context, new StorageAdapter(), - readSettingsFromFile(Environment.buildPath(Environment.getProductDirectory(), + readSettingsFromFile(Environment.buildPath(Environment.getRootDirectory(), ETC_DIR, CONFIG_FILE)), readSettingsFromFile(Environment.buildPath(Environment.getVendorDirectory(), ETC_DIR, CONFIG_FILE))); @@ -168,9 +169,32 @@ public class HdmiCecConfig { return null; } + @NonNull + @VisibleForTesting + static HdmiCecConfig createFromStrings(@NonNull Context context, + @NonNull StorageAdapter storageAdapter, + @Nullable String systemConfigXml, + @Nullable String vendorOverrideXml) { + CecSettings systemConfig = null; + CecSettings vendorOverride = null; + try { + if (systemConfigXml != null) { + systemConfig = XmlParser.read( + new ByteArrayInputStream(systemConfigXml.getBytes())); + } + if (vendorOverrideXml != null) { + vendorOverride = XmlParser.read( + new ByteArrayInputStream(vendorOverrideXml.getBytes())); + } + } catch (IOException | DatatypeConfigurationException | XmlPullParserException e) { + Slog.e(TAG, "Encountered an error while reading/parsing CEC config strings", e); + } + return new HdmiCecConfig(context, storageAdapter, systemConfig, vendorOverride); + } + @Nullable private Setting getSetting(@NonNull String name) { - if (mProductConfig == null) { + if (mSystemConfig == null) { return null; } if (mVendorOverride != null) { @@ -181,8 +205,8 @@ public class HdmiCecConfig { } } } - // If not found, try the product config. - for (Setting setting : mProductConfig.getSetting()) { + // If not found, try the system config. + for (Setting setting : mSystemConfig.getSetting()) { if (setting.getName().equals(name)) { return setting; } @@ -254,11 +278,11 @@ public class HdmiCecConfig { * Returns a list of all settings based on the XML metadata. */ public @CecSettingName List<String> getAllSettings() { - if (mProductConfig == null) { + if (mSystemConfig == null) { return new ArrayList<String>(); } List<String> allSettings = new ArrayList<String>(); - for (Setting setting : mProductConfig.getSetting()) { + for (Setting setting : mSystemConfig.getSetting()) { allSettings.add(setting.getName()); } return allSettings; @@ -268,12 +292,12 @@ public class HdmiCecConfig { * Returns a list of user-modifiable settings based on the XML metadata. */ public @CecSettingName List<String> getUserSettings() { - if (mProductConfig == null) { + if (mSystemConfig == null) { return new ArrayList<String>(); } Set<String> userSettings = new HashSet<String>(); - // First read from the product config. - for (Setting setting : mProductConfig.getSetting()) { + // First read from the system config. + for (Setting setting : mSystemConfig.getSetting()) { if (setting.getUserConfigurable()) { userSettings.add(setting.getName()); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index efe730231d36..19dc017a35d5 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -85,6 +85,8 @@ final class HdmiCecController { private static final int NUM_LOGICAL_ADDRESS = 16; + private static final int MAX_DEDICATED_ADDRESS = 11; + private static final int MAX_HDMI_MESSAGE_HISTORY = 250; private static final int INVALID_PHYSICAL_ADDRESS = 0xFFFF; @@ -104,7 +106,7 @@ final class HdmiCecController { private final Predicate<Integer> mSystemAudioAddressPredicate = new Predicate<Integer>() { @Override public boolean test(Integer address) { - return HdmiUtils.getTypeFromAddress(address) == Constants.ADDR_AUDIO_SYSTEM; + return HdmiUtils.isEligibleAddressForDevice(Constants.ADDR_AUDIO_SYSTEM, address); } }; @@ -195,42 +197,46 @@ final class HdmiCecController { }); } + /** + * Address allocation will check the following addresses (in order): + * <ul> + * <li>Given preferred logical address (if the address is valid for the given device + * type)</li> + * <li>All dedicated logical addresses for the given device type</li> + * <li>Backup addresses, if valid for the given device type</li> + * </ul> + */ @IoThreadOnly private void handleAllocateLogicalAddress(final int deviceType, int preferredAddress, final AllocateAddressCallback callback) { assertRunOnIoThread(); - int startAddress = preferredAddress; - // If preferred address is "unregistered", start address will be the smallest - // address matched with the given device type. - if (preferredAddress == Constants.ADDR_UNREGISTERED) { - for (int i = 0; i < NUM_LOGICAL_ADDRESS; ++i) { - if (deviceType == HdmiUtils.getTypeFromAddress(i)) { - startAddress = i; - break; - } + List<Integer> logicalAddressesToPoll = new ArrayList<>(); + if (HdmiUtils.isEligibleAddressForDevice(deviceType, preferredAddress)) { + logicalAddressesToPoll.add(preferredAddress); + } + for (int i = 0; i < NUM_LOGICAL_ADDRESS; ++i) { + if (!logicalAddressesToPoll.contains(i) && HdmiUtils.isEligibleAddressForDevice( + deviceType, i) && HdmiUtils.isEligibleAddressForCecVersion( + mService.getCecVersion(), i)) { + logicalAddressesToPoll.add(i); } } int logicalAddress = Constants.ADDR_UNREGISTERED; - // Iterates all possible addresses which has the same device type. - for (int i = 0; i < NUM_LOGICAL_ADDRESS; ++i) { - int curAddress = (startAddress + i) % NUM_LOGICAL_ADDRESS; - if (curAddress != Constants.ADDR_UNREGISTERED - && deviceType == HdmiUtils.getTypeFromAddress(curAddress)) { - boolean acked = false; - for (int j = 0; j < HdmiConfig.ADDRESS_ALLOCATION_RETRY; ++j) { - if (sendPollMessage(curAddress, curAddress, 1)) { - acked = true; - break; - } - } - // If sending <Polling Message> failed, it becomes new logical address for the - // device because no device uses it as logical address of the device. - if (!acked) { - logicalAddress = curAddress; + for (Integer logicalAddressToPoll : logicalAddressesToPoll) { + boolean acked = false; + for (int j = 0; j < HdmiConfig.ADDRESS_ALLOCATION_RETRY; ++j) { + if (sendPollMessage(logicalAddressToPoll, logicalAddressToPoll, 1)) { + acked = true; break; } } + // If sending <Polling Message> failed, it becomes new logical address for the + // device because no device uses it as logical address of the device. + if (!acked) { + logicalAddress = logicalAddressToPoll; + break; + } } final int assignedAddress = logicalAddress; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index 4325f797416e..960510693f6a 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -246,6 +246,10 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { // Indicates if current device is the active source or not @ServiceThreadOnly protected boolean isActiveSource() { + if (getDeviceInfo() == null) { + return false; + } + return getActiveSource().equals(getDeviceInfo().getLogicalAddress(), getDeviceInfo().getPhysicalAddress()); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 93cdca2d0c83..c2e80caadd3b 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -1368,9 +1368,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { private boolean checkRecorder(int recorderAddress) { HdmiDeviceInfo device = mService.getHdmiCecNetwork().getCecDeviceInfo(recorderAddress); - return (device != null) - && (HdmiUtils.getTypeFromAddress(recorderAddress) - == HdmiDeviceInfo.DEVICE_RECORDER); + return (device != null) && (HdmiUtils.isEligibleAddressForDevice( + HdmiDeviceInfo.DEVICE_RECORDER, recorderAddress)); } private boolean checkRecordSource(byte[] recordSource) { diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index 28bd97e4843c..7d766285bdfa 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -128,7 +128,7 @@ public class HdmiCecMessageValidator { FixedLengthValidator oneByteValidator = new FixedLengthValidator(1); addValidationInfo(Constants.MESSAGE_CEC_VERSION, oneByteValidator, DEST_DIRECT); addValidationInfo(Constants.MESSAGE_SET_MENU_LANGUAGE, - new FixedLengthValidator(3), DEST_BROADCAST); + new AsciiValidator(3), DEST_BROADCAST); // TODO: Handle messages for the Deck Control. @@ -148,12 +148,14 @@ public class HdmiCecMessageValidator { maxLengthValidator, DEST_ALL | SRC_UNREGISTERED); // Messages for the OSD. - addValidationInfo(Constants.MESSAGE_SET_OSD_STRING, maxLengthValidator, DEST_DIRECT); - addValidationInfo(Constants.MESSAGE_SET_OSD_NAME, maxLengthValidator, DEST_DIRECT); + addValidationInfo(Constants.MESSAGE_SET_OSD_STRING, new OsdStringValidator(), DEST_DIRECT); + addValidationInfo(Constants.MESSAGE_SET_OSD_NAME, new AsciiValidator(1, 14), DEST_DIRECT); // Messages for the Device Menu Control. - addValidationInfo(Constants.MESSAGE_MENU_REQUEST, oneByteValidator, DEST_DIRECT); - addValidationInfo(Constants.MESSAGE_MENU_STATUS, oneByteValidator, DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_MENU_REQUEST, new OneByteRangeValidator(0x00, 0x02), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_MENU_STATUS, new OneByteRangeValidator(0x00, 0x01), DEST_DIRECT); // Messages for the Remote Control Passthrough. // TODO: Parse the first parameter and determine if it can have the next parameter. @@ -161,7 +163,10 @@ public class HdmiCecMessageValidator { new VariableLengthValidator(1, 2), DEST_DIRECT); // Messages for the Power Status. - addValidationInfo(Constants.MESSAGE_REPORT_POWER_STATUS, oneByteValidator, DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_REPORT_POWER_STATUS, + new OneByteRangeValidator(0x00, 0x03), + DEST_DIRECT); // Messages for the General Protocol. addValidationInfo(Constants.MESSAGE_FEATURE_ABORT, @@ -173,12 +178,20 @@ public class HdmiCecMessageValidator { new FixedLengthValidator(3), DEST_DIRECT); addValidationInfo(Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR, oneByteValidator, DEST_DIRECT); - addValidationInfo(Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE, oneByteValidator, DEST_ALL); - addValidationInfo(Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS, - oneByteValidator, DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE, + new OneByteRangeValidator(0x00, 0x01), + DEST_ALL); + addValidationInfo( + Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS, + new OneByteRangeValidator(0x00, 0x01), + DEST_DIRECT); // Messages for the Audio Rate Control. - addValidationInfo(Constants.MESSAGE_SET_AUDIO_RATE, oneByteValidator, DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_SET_AUDIO_RATE, + new OneByteRangeValidator(0x00, 0x06), + DEST_DIRECT); // All Messages for the ARC have no parameters. @@ -299,6 +312,37 @@ public class HdmiCecMessageValidator { return (value >= min && value <= max); } + /** + * Check if the given value is a valid Display Control. A valid value is one which falls within + * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17) + * + * @param value Display Control + * @return true if the Display Control is valid + */ + private boolean isValidDisplayControl(int value) { + value = value & 0xFF; + return (value == 0x00 || value == 0x40 || value == 0x80 || value == 0xC0); + } + + /** + * Check if the given params has valid ASCII characters. + * A valid ASCII character is a printable character. It should fall within range description + * defined in CEC 1.4 Specification : Operand Descriptions (Section 17) + * + * @param params parameter consisting of string + * @param offset Start offset of string + * @param maxLength Maximum length of string to be evaluated + * @return true if the given type is valid + */ + private boolean isValidAsciiString(byte[] params, int offset, int maxLength) { + for (int i = offset; i < params.length && i < maxLength; i++) { + if (!isWithinRange(params[i], 0x20, 0x7E)) { + return false; + } + } + return true; + } + private class PhysicalAddressValidator implements ParameterValidator { @Override public int isValid(byte[] params) { @@ -359,4 +403,73 @@ public class HdmiCecMessageValidator { || params[0] == 0x1F); } } + + /** + * Check if the given parameters represents printable characters. + * A valid parameter should lie within the range description of ASCII defined in CEC 1.4 + * Specification : Operand Descriptions (Section 17) + */ + private class AsciiValidator implements ParameterValidator { + private final int mMinLength; + private final int mMaxLength; + + AsciiValidator(int length) { + mMinLength = length; + mMaxLength = length; + } + + AsciiValidator(int minLength, int maxLength) { + mMinLength = minLength; + mMaxLength = maxLength; + } + + @Override + public int isValid(byte[] params) { + // If the length is longer than expected, we assume it's OK since the parameter can be + // extended in the future version. + if (params.length < mMinLength) { + return ERROR_PARAMETER_SHORT; + } + return toErrorCode(isValidAsciiString(params, 0, mMaxLength)); + } + } + + /** + * Check if the given parameters is valid OSD String. + * A valid parameter should lie within the range description of ASCII defined in CEC 1.4 + * Specification : Operand Descriptions (Section 17) + */ + private class OsdStringValidator implements ParameterValidator { + @Override + public int isValid(byte[] params) { + // If the length is longer than expected, we assume it's OK since the parameter can be + // extended in the future version. + if (params.length < 2) { + return ERROR_PARAMETER_SHORT; + } + return toErrorCode( + // Display Control + isValidDisplayControl(params[0]) + // OSD String + && isValidAsciiString(params, 1, 14)); + } + } + + /** Check if the given parameters are one byte parameters and within range. */ + private class OneByteRangeValidator implements ParameterValidator { + private final int mMinValue, mMaxValue; + + OneByteRangeValidator(int minValue, int maxValue) { + mMinValue = minValue; + mMaxValue = maxValue; + } + + @Override + public int isValid(byte[] params) { + if (params.length < 1) { + return ERROR_PARAMETER_SHORT; + } + return toErrorCode(isWithinRange(params[0], mMinValue, mMaxValue)); + } + } } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java index 416302419a71..5d75a63d0c8d 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java @@ -18,6 +18,7 @@ package com.android.server.hdmi; import static com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; +import android.annotation.Nullable; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.HdmiPortInfo; @@ -242,6 +243,7 @@ class HdmiCecNetwork { * Returns null if no logical address matched */ @ServiceThreadOnly + @Nullable HdmiDeviceInfo getCecDeviceInfo(int logicalAddress) { assertRunOnServiceThread(); return mDeviceInfos.get(HdmiDeviceInfo.idForCecDevice(logicalAddress)); @@ -517,6 +519,10 @@ class HdmiCecNetwork { case Constants.MESSAGE_SET_OSD_NAME: handleSetOsdName(message); break; + case Constants.MESSAGE_DEVICE_VENDOR_ID: + handleDeviceVendorId(message); + break; + } } @@ -582,6 +588,24 @@ class HdmiCecNetwork { deviceInfo.getDevicePowerStatus())); } + @ServiceThreadOnly + private void handleDeviceVendorId(HdmiCecMessage message) { + assertRunOnServiceThread(); + int logicalAddress = message.getSource(); + int vendorId = HdmiUtils.threeBytesToInt(message.getParams()); + + HdmiDeviceInfo deviceInfo = getCecDeviceInfo(logicalAddress); + if (deviceInfo == null) { + Slog.i(TAG, "Unknown source device info for <Device Vendor ID> " + message); + } else { + HdmiDeviceInfo updatedDeviceInfo = new HdmiDeviceInfo(deviceInfo.getLogicalAddress(), + deviceInfo.getPhysicalAddress(), + deviceInfo.getPortId(), deviceInfo.getDeviceType(), vendorId, + deviceInfo.getDisplayName(), deviceInfo.getDevicePowerStatus()); + updateCecDevice(updatedDeviceInfo); + } + } + void addCecSwitch(int physicalAddress) { mCecSwitches.add(physicalAddress); } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index ee86593916ae..da4c6f115d55 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -26,6 +26,7 @@ import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE; import static com.android.server.hdmi.Constants.OPTION_MHL_INPUT_SWITCHING; import static com.android.server.hdmi.Constants.OPTION_MHL_POWER_CHARGE; import static com.android.server.hdmi.Constants.OPTION_MHL_SERVICE_CONTROL; +import static com.android.server.hdmi.Constants.VERSION_1_4; import static com.android.server.power.ShutdownThread.SHUTDOWN_ACTION_PROPERTY; import android.annotation.Nullable; @@ -79,6 +80,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.SystemService; +import com.android.server.hdmi.Constants.CecVersion; import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback; import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource; @@ -373,6 +375,9 @@ public class HdmiControlService extends SystemService { @Nullable private Looper mIoLooper; + @CecVersion + private int mCecVersion = Constants.VERSION_1_4; + // Last input port before switching to the MHL port. Should switch back to this port // when the mobile device sends the request one touch play with off. // Gets invalidated if we go to other port/input. @@ -660,6 +665,7 @@ public class HdmiControlService extends SystemService { String[] settings = new String[] { Global.HDMI_CONTROL_ENABLED, Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, + Global.HDMI_CEC_VERSION, Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED, Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, @@ -688,6 +694,9 @@ public class HdmiControlService extends SystemService { case Global.HDMI_CONTROL_ENABLED: setControlEnabled(enabled); break; + case Global.HDMI_CEC_VERSION: + initializeCec(INITIATED_BY_ENABLE_CEC); + break; case Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED: setHdmiCecVolumeControlEnabledInternal(enabled); break; @@ -753,6 +762,12 @@ public class HdmiControlService extends SystemService { return Global.getInt(cr, key, toInt(defVal)) == ENABLED; } + @VisibleForTesting + int readIntSetting(String key, int defVal) { + ContentResolver cr = getContext().getContentResolver(); + return Global.getInt(cr, key, defVal); + } + void writeBooleanSetting(String key, boolean value) { ContentResolver cr = getContext().getContentResolver(); Global.putInt(cr, key, toInt(value)); @@ -783,6 +798,8 @@ public class HdmiControlService extends SystemService { private void initializeCec(int initiatedBy) { mAddressAllocated = false; + mCecVersion = readIntSetting(Global.HDMI_CEC_VERSION, VERSION_1_4); + mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, true); mCecController.setLanguage(mMenuLanguage); initializeLocalDevices(initiatedBy); @@ -989,8 +1006,9 @@ public class HdmiControlService extends SystemService { /** * Returns version of CEC. */ + @CecVersion int getCecVersion() { - return mCecController.getVersion(); + return mCecVersion; } /** @@ -1543,7 +1561,7 @@ public class HdmiControlService extends SystemService { new HdmiDeviceInfo(activeSource.logicalAddress, activeSource.physicalAddress, pathToPortId(activeSource.physicalAddress), - HdmiUtils.getTypeFromAddress(activeSource.logicalAddress), 0, + HdmiUtils.getTypeFromAddress(activeSource.logicalAddress).get(0), 0, HdmiUtils.getDefaultDeviceName(activeSource.logicalAddress)) : new HdmiDeviceInfo(activeSource.physicalAddress, @@ -2204,6 +2222,7 @@ public class HdmiControlService extends SystemService { if (!DumpUtils.checkDumpPermission(getContext(), TAG, writer)) return; final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); + pw.println("mCecVersion: " + mCecVersion); pw.println("mProhibitMode: " + mProhibitMode); pw.println("mPowerStatus: " + mPowerStatus); diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java index a6951ef1958f..45aaa73b757b 100644 --- a/services/core/java/com/android/server/hdmi/HdmiUtils.java +++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java @@ -16,6 +16,10 @@ package com.android.server.hdmi; +import static com.android.server.hdmi.Constants.ADDR_BACKUP_1; +import static com.android.server.hdmi.Constants.ADDR_BACKUP_2; +import static com.android.server.hdmi.Constants.ADDR_TV; + import android.annotation.Nullable; import android.hardware.hdmi.HdmiDeviceInfo; import android.util.Slog; @@ -29,6 +33,8 @@ import com.android.server.hdmi.Constants.AudioCodec; import com.android.server.hdmi.Constants.FeatureOpcode; import com.android.server.hdmi.Constants.PathRelationship; +import com.google.android.collect.Lists; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -37,6 +43,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -48,23 +55,38 @@ final class HdmiUtils { private static final String TAG = "HdmiUtils"; - private static final int[] ADDRESS_TO_TYPE = { - HdmiDeviceInfo.DEVICE_TV, // ADDR_TV - HdmiDeviceInfo.DEVICE_RECORDER, // ADDR_RECORDER_1 - HdmiDeviceInfo.DEVICE_RECORDER, // ADDR_RECORDER_2 - HdmiDeviceInfo.DEVICE_TUNER, // ADDR_TUNER_1 - HdmiDeviceInfo.DEVICE_PLAYBACK, // ADDR_PLAYBACK_1 - HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, // ADDR_AUDIO_SYSTEM - HdmiDeviceInfo.DEVICE_TUNER, // ADDR_TUNER_2 - HdmiDeviceInfo.DEVICE_TUNER, // ADDR_TUNER_3 - HdmiDeviceInfo.DEVICE_PLAYBACK, // ADDR_PLAYBACK_2 - HdmiDeviceInfo.DEVICE_RECORDER, // ADDR_RECORDER_3 - HdmiDeviceInfo.DEVICE_TUNER, // ADDR_TUNER_4 - HdmiDeviceInfo.DEVICE_PLAYBACK, // ADDR_PLAYBACK_3 - HdmiDeviceInfo.DEVICE_RESERVED, - HdmiDeviceInfo.DEVICE_RESERVED, - HdmiDeviceInfo.DEVICE_TV, // ADDR_SPECIFIC_USE - }; + private static final Map<Integer, List<Integer>> ADDRESS_TO_TYPE = + new HashMap<Integer, List<Integer>>() { + { + put(Constants.ADDR_TV, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TV)); + put(Constants.ADDR_RECORDER_1, + Lists.newArrayList(HdmiDeviceInfo.DEVICE_RECORDER)); + put(Constants.ADDR_RECORDER_2, + Lists.newArrayList(HdmiDeviceInfo.DEVICE_RECORDER)); + put(Constants.ADDR_TUNER_1, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TUNER)); + put(Constants.ADDR_PLAYBACK_1, + Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK)); + put(Constants.ADDR_AUDIO_SYSTEM, + Lists.newArrayList(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM)); + put(Constants.ADDR_TUNER_2, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TUNER)); + put(Constants.ADDR_TUNER_3, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TUNER)); + put(Constants.ADDR_PLAYBACK_2, + Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK)); + put(Constants.ADDR_RECORDER_3, + Lists.newArrayList(HdmiDeviceInfo.DEVICE_RECORDER)); + put(Constants.ADDR_TUNER_4, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TUNER)); + put(Constants.ADDR_PLAYBACK_3, + Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK)); + put(Constants.ADDR_BACKUP_1, Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK, + HdmiDeviceInfo.DEVICE_RECORDER, HdmiDeviceInfo.DEVICE_TUNER, + HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR)); + put(Constants.ADDR_BACKUP_2, Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK, + HdmiDeviceInfo.DEVICE_RECORDER, HdmiDeviceInfo.DEVICE_TUNER, + HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR)); + put(Constants.ADDR_SPECIFIC_USE, Lists.newArrayList(ADDR_TV)); + put(Constants.ADDR_UNREGISTERED, Collections.emptyList()); + } + }; private static final String[] DEFAULT_NAMES = { "TV", @@ -79,8 +101,8 @@ final class HdmiUtils { "Recorder_3", "Tuner_4", "Playback_3", - "Reserved_1", - "Reserved_2", + "Backup_1", + "Backup_2", "Secondary_TV", }; @@ -101,21 +123,36 @@ final class HdmiUtils { * @return true if the given address is valid */ static boolean isValidAddress(int address) { - return (Constants.ADDR_TV <= address && address <= Constants.ADDR_SPECIFIC_USE); + return (ADDR_TV <= address && address <= Constants.ADDR_SPECIFIC_USE); + } + + static boolean isEligibleAddressForDevice(int deviceType, int logicalAddress) { + return isValidAddress(logicalAddress) + && ADDRESS_TO_TYPE.get(logicalAddress).contains(deviceType); + } + + static boolean isEligibleAddressForCecVersion(int cecVersion, int logicalAddress) { + if (isValidAddress(logicalAddress)) { + if (logicalAddress == ADDR_BACKUP_1 || logicalAddress == ADDR_BACKUP_2) { + return cecVersion == Constants.VERSION_2_0; + } + return true; + } + return false; } /** * Return the device type for the given logical address. * - * @param address logical address + * @param logicalAddress logical address * @return device type for the given logical address; DEVICE_INACTIVE * if the address is not valid. */ - static int getTypeFromAddress(int address) { - if (isValidAddress(address)) { - return ADDRESS_TO_TYPE[address]; + static List<Integer> getTypeFromAddress(int logicalAddress) { + if (isValidAddress(logicalAddress)) { + return ADDRESS_TO_TYPE.get(logicalAddress); } - return HdmiDeviceInfo.DEVICE_INACTIVE; + return Lists.newArrayList(HdmiDeviceInfo.DEVICE_INACTIVE); } /** @@ -142,10 +179,10 @@ final class HdmiUtils { * @throws IllegalArgumentException */ static void verifyAddressType(int logicalAddress, int deviceType) { - int actualDeviceType = getTypeFromAddress(logicalAddress); - if (actualDeviceType != deviceType) { + List<Integer> actualDeviceTypes = getTypeFromAddress(logicalAddress); + if (!actualDeviceTypes.contains(deviceType)) { throw new IllegalArgumentException("Device type missmatch:[Expected:" + deviceType - + ", Actual:" + actualDeviceType); + + ", Actual:" + actualDeviceTypes); } } diff --git a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java index ece78bfa2769..a7f34ed85e0d 100644 --- a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java +++ b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java @@ -259,7 +259,7 @@ final class HotplugDetectionAction extends HdmiCecFeatureAction { } private void mayDisableSystemAudioAndARC(int address) { - if (HdmiUtils.getTypeFromAddress(address) != HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) { + if (HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, address)) { return; } diff --git a/services/core/java/com/android/server/hdmi/NewDeviceAction.java b/services/core/java/com/android/server/hdmi/NewDeviceAction.java index edc7bd95a017..a307ea33abf7 100644 --- a/services/core/java/com/android/server/hdmi/NewDeviceAction.java +++ b/services/core/java/com/android/server/hdmi/NewDeviceAction.java @@ -183,8 +183,8 @@ final class NewDeviceAction extends HdmiCecFeatureAction { // Consume CEC messages we already got for this newly found device. tv().processDelayedMessages(mDeviceLogicalAddress); - if (HdmiUtils.getTypeFromAddress(mDeviceLogicalAddress) - == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) { + if (HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + mDeviceLogicalAddress)) { tv().onNewAvrAdded(deviceInfo); } } diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java index e78a86c21453..53f9a109d08d 100644 --- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java +++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java @@ -19,6 +19,7 @@ import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback; import android.hardware.hdmi.IHdmiControlCallback; import android.os.RemoteException; +import android.provider.Settings.Global; import android.util.Slog; import java.util.ArrayList; @@ -54,6 +55,8 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction { private int mPowerStatusCounter = 0; + private HdmiCecLocalDeviceSource mSource; + // Factory method. Ensures arguments are valid. static OneTouchPlayAction create(HdmiCecLocalDeviceSource source, int targetAddress, IHdmiControlCallback callback) { @@ -74,27 +77,33 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction { @Override boolean start() { + // Because only source device can create this action, it's safe to cast. + mSource = source(); sendCommand(HdmiCecMessageBuilder.buildTextViewOn(getSourceAddress(), mTargetAddress)); broadcastActiveSource(); + // If the device is not an audio system itself, request the connected audio system to + // turn on. + if (shouldTurnOnConnectedAudioSystem()) { + sendCommand(HdmiCecMessageBuilder.buildSystemAudioModeRequest(getSourceAddress(), + Constants.ADDR_AUDIO_SYSTEM, getSourcePath(), true)); + } queryDevicePowerStatus(); addTimer(mState, HdmiConfig.TIMEOUT_MS); return true; } private void broadcastActiveSource() { - // Because only source device can create this action, it's safe to cast. - HdmiCecLocalDeviceSource source = source(); - source.mService.setAndBroadcastActiveSourceFromOneDeviceType( + mSource.mService.setAndBroadcastActiveSourceFromOneDeviceType( 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 // device as well as claiming Active Source. - if (source.mService.audioSystem() != null) { - source = source.mService.audioSystem(); + if (mSource.mService.audioSystem() != null) { + mSource = mSource.mService.audioSystem(); } - source.setRoutingPort(Constants.CEC_SWITCH_HOME); - source.setLocalActivePort(Constants.CEC_SWITCH_HOME); + mSource.setRoutingPort(Constants.CEC_SWITCH_HOME); + mSource.setLocalActivePort(Constants.CEC_SWITCH_HOME); } private void queryDevicePowerStatus() { @@ -151,4 +160,14 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction { Slog.e(TAG, "Callback failed:" + e); } } + + private boolean shouldTurnOnConnectedAudioSystem() { + HdmiControlService service = mSource.mService; + if (service.isAudioSystemDevice()) { + return false; + } + String sendStandbyOnSleep = service.readStringSetting( + Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, ""); + return sendStandbyOnSleep.equals(HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST); + } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 9947ecd42e31..16a4b7250598 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -119,6 +119,7 @@ import android.text.style.SuggestionSpan; import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; +import android.util.IndentingPrintWriter; import android.util.Log; import android.util.LruCache; import android.util.Pair; @@ -161,7 +162,6 @@ import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; import com.android.internal.os.TransferPipe; import com.android.internal.util.DumpUtils; -import com.android.internal.util.IndentingPrintWriter; import com.android.internal.view.IInlineSuggestionsRequestCallback; import com.android.internal.view.IInlineSuggestionsResponseCallback; import com.android.internal.view.IInputContext; @@ -1713,7 +1713,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mSettings, context); mMenuController = new InputMethodMenuController(this); - mTracingThread = new HandlerThread("android.tracing", Process.THREAD_PRIORITY_BACKGROUND); + mTracingThread = new HandlerThread("android.tracing", Process.THREAD_PRIORITY_FOREGROUND); mTracingThread.start(); } diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index cdb73d8ad6a2..9ca4d35f4579 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -556,8 +556,8 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void registerLocationListener(String provider, LocationRequest request, - ILocationListener listener, String packageName, String attributionTag, - String listenerId) { + ILocationListener listener, String packageName, @Nullable String attributionTag, + @Nullable String listenerId) { CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, listenerId); int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), @@ -582,7 +582,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void registerLocationPendingIntent(String provider, LocationRequest request, - PendingIntent pendingIntent, String packageName, String attributionTag) { + PendingIntent pendingIntent, String packageName, @Nullable String attributionTag) { CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, AppOpsManager.toReceiverId(pendingIntent)); int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), diff --git a/services/core/java/com/android/server/location/LocationProviderManager.java b/services/core/java/com/android/server/location/LocationProviderManager.java index 179fb7d2f723..b4a172393ba6 100644 --- a/services/core/java/com/android/server/location/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/LocationProviderManager.java @@ -77,7 +77,6 @@ import android.util.SparseBooleanArray; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.internal.util.Preconditions; @@ -115,7 +114,6 @@ import java.util.Objects; class LocationProviderManager extends ListenerMultiplexer<Object, LocationProviderManager.LocationTransport, - LocationProviderManager.LocationListenerOperation, LocationProviderManager.Registration, ProviderRequest> implements AbstractLocationProvider.Listener { @@ -225,16 +223,8 @@ class LocationProviderManager extends } } - protected interface LocationListenerOperation extends ListenerOperation<LocationTransport> { - /** - * Must be implemented to return the location this operation intends to deliver. - */ - @Nullable - Location getLocation(); - } - protected abstract class Registration extends RemoteListenerRegistration<LocationRequest, - LocationTransport, LocationListenerOperation> { + LocationTransport> { private final @PermissionLevel int mPermissionLevel; @@ -310,7 +300,7 @@ class LocationProviderManager extends protected void onProviderListenerUnregister() {} @Override - protected final LocationListenerOperation onActive() { + protected final void onActive() { if (Build.IS_DEBUGGABLE) { Preconditions.checkState(Thread.holdsLock(mLock)); } @@ -319,11 +309,12 @@ class LocationProviderManager extends mLocationAttributionHelper.reportLocationStart(getIdentity(), getName(), getKey()); } onHighPowerUsageChanged(); - return onProviderListenerActive(); + + onProviderListenerActive(); } @Override - protected final LocationListenerOperation onInactive() { + protected final void onInactive() { if (Build.IS_DEBUGGABLE) { Preconditions.checkState(Thread.holdsLock(mLock)); } @@ -332,24 +323,21 @@ class LocationProviderManager extends if (!getRequest().isHiddenFromAppOps()) { mLocationAttributionHelper.reportLocationStop(getIdentity(), getName(), getKey()); } - return onProviderListenerInactive(); + + onProviderListenerInactive(); } /** * Subclasses may override this instead of {@link #onActive()}. */ @GuardedBy("mLock") - protected LocationListenerOperation onProviderListenerActive() { - return null; - } + protected void onProviderListenerActive() {} /** * Subclasses may override this instead of {@link #onInactive()} ()}. */ @GuardedBy("mLock") - protected LocationListenerOperation onProviderListenerInactive() { - return null; - } + protected void onProviderListenerInactive() {} @Override public final LocationRequest getRequest() { @@ -357,10 +345,8 @@ class LocationProviderManager extends } @GuardedBy("mLock") - final void initializeLastLocation(@Nullable Location location) { - if (mLastLocation == null) { - mLastLocation = location; - } + final void setLastDeliveredLocation(@Nullable Location location) { + mLastLocation = location; } @GuardedBy("mLock") @@ -541,16 +527,8 @@ class LocationProviderManager extends } @GuardedBy("mLock") - @Override - protected final LocationListenerOperation onExecuteOperation( - LocationListenerOperation operation) { - mLastLocation = operation.getLocation(); - return super.onExecuteOperation(operation); - } - - @GuardedBy("mLock") - @Nullable - abstract LocationListenerOperation acceptLocationChange(Location fineLocation); + abstract @Nullable ListenerOperation<LocationTransport> acceptLocationChange( + Location fineLocation); @Override public String toString() { @@ -656,7 +634,7 @@ class LocationProviderManager extends @GuardedBy("mLock") @Override - protected final LocationListenerOperation onProviderListenerActive() { + protected final void onProviderListenerActive() { // a new registration may not get a location immediately, the provider request may be // delayed. therefore we deliver a historical location if available. since delivering an // older location could be considered a breaking change for some applications, we only @@ -679,12 +657,10 @@ class LocationProviderManager extends getRequest().isLocationSettingsIgnored(), maxLocationAgeMs); if (lastLocation != null) { - return acceptLocationChange(lastLocation); + executeOperation(acceptLocationChange(lastLocation)); } } } - - return null; } @Override @@ -703,9 +679,9 @@ class LocationProviderManager extends } @GuardedBy("mLock") - @Nullable @Override - LocationListenerOperation acceptLocationChange(Location fineLocation) { + @Nullable ListenerOperation<LocationTransport> acceptLocationChange( + Location fineLocation) { if (Build.IS_DEBUGGABLE) { Preconditions.checkState(Thread.holdsLock(mLock)); } @@ -748,16 +724,20 @@ class LocationProviderManager extends return null; } - return new LocationListenerOperation() { - @Override - public Location getLocation() { - return location; - } + // deliver location + return new ListenerOperation<LocationTransport>() { + + private boolean mUseWakeLock; @Override public void onPreExecute() { + mUseWakeLock = !location.isFromMockProvider(); + + // update last delivered location + setLastDeliveredLocation(location); + // don't acquire a wakelock for mock locations to prevent abuse - if (!location.isFromMockProvider()) { + if (mUseWakeLock) { mWakeLock.acquire(WAKELOCK_TIMEOUT_MS); } } @@ -774,13 +754,13 @@ class LocationProviderManager extends } listener.deliverOnLocationChanged(deliveryLocation, - location.isFromMockProvider() ? null : mWakeLock::release); + mUseWakeLock ? mWakeLock::release : null); mLocationEventLog.logProviderDeliveredLocation(mName, getIdentity()); } @Override public void onPostExecute(boolean success) { - if (!success && !location.isFromMockProvider()) { + if (!success && mUseWakeLock) { mWakeLock.release(); } @@ -852,7 +832,8 @@ class LocationProviderManager extends } @Override - public void onOperationFailure(LocationListenerOperation operation, Exception exception) { + public void onOperationFailure(ListenerOperation<LocationTransport> operation, + Exception exception) { onTransportFailure(exception); } @@ -913,7 +894,8 @@ class LocationProviderManager extends } @Override - public void onOperationFailure(LocationListenerOperation operation, Exception exception) { + public void onOperationFailure(ListenerOperation<LocationTransport> operation, + Exception exception) { onTransportFailure(exception); } @@ -988,28 +970,24 @@ class LocationProviderManager extends @GuardedBy("mLock") @Override - protected LocationListenerOperation onProviderListenerActive() { + protected void onProviderListenerActive() { Location lastLocation = getLastLocationUnsafe( getIdentity().getUserId(), getPermissionLevel(), getRequest().isLocationSettingsIgnored(), MAX_CURRENT_LOCATION_AGE_MS); if (lastLocation != null) { - return acceptLocationChange(lastLocation); + executeOperation(acceptLocationChange(lastLocation)); } - - return null; } @GuardedBy("mLock") @Override - protected LocationListenerOperation onProviderListenerInactive() { + protected void onProviderListenerInactive() { if (!getRequest().isLocationSettingsIgnored()) { // if we go inactive for any reason, fail immediately - return acceptLocationChange(null); + executeOperation(acceptLocationChange(null)); } - - return null; } void deliverNull() { @@ -1035,9 +1013,9 @@ class LocationProviderManager extends } @GuardedBy("mLock") - @Nullable @Override - LocationListenerOperation acceptLocationChange(@Nullable Location fineLocation) { + @Nullable ListenerOperation<LocationTransport> acceptLocationChange( + @Nullable Location fineLocation) { if (Build.IS_DEBUGGABLE) { Preconditions.checkState(Thread.holdsLock(mLock)); } @@ -1059,36 +1037,21 @@ class LocationProviderManager extends Location location = getPermittedLocation(fineLocation, getPermissionLevel()); - return new LocationListenerOperation() { - @Override - public Location getLocation() { - return location; + // deliver location + return listener -> { + // if delivering to the same process, make a copy of the location first (since + // location is mutable) + Location deliveryLocation = location; + if (getIdentity().getPid() == Process.myPid() && location != null) { + deliveryLocation = new Location(location); } - @Override - public void operate(LocationTransport listener) { - // if delivering to the same process, make a copy of the location first (since - // location is mutable) - Location deliveryLocation = location; - if (getIdentity().getPid() == Process.myPid() && location != null) { - deliveryLocation = new Location(location); - } - - // we currently don't hold a wakelock for getCurrentLocation deliveries - try { - listener.deliverOnLocationChanged(deliveryLocation, null); - mLocationEventLog.logProviderDeliveredLocation(mName, getIdentity()); - } catch (Exception exception) { - if (exception instanceof RemoteException) { - Log.w(TAG, "registration " + this + " failed", exception); - } else { - throw new AssertionError(exception); - } - } + // we currently don't hold a wakelock for getCurrentLocation deliveries + listener.deliverOnLocationChanged(deliveryLocation, null); + mLocationEventLog.logProviderDeliveredLocation(mName, getIdentity()); - synchronized (mLock) { - remove(); - } + synchronized (mLock) { + remove(); } }; } @@ -1114,7 +1077,7 @@ class LocationProviderManager extends protected final Object mLock = new Object(); protected final String mName; - @Nullable private final PassiveLocationProviderManager mPassiveManager; + private final @Nullable PassiveLocationProviderManager mPassiveManager; protected final Context mContext; @@ -1178,7 +1141,7 @@ class LocationProviderManager extends protected final MockableLocationProvider mProvider; @GuardedBy("mLock") - @Nullable private OnAlarmListener mDelayedRegister; + private @Nullable OnAlarmListener mDelayedRegister; LocationProviderManager(Context context, Injector injector, String name, @Nullable PassiveLocationProviderManager passiveManager) { @@ -1254,13 +1217,11 @@ class LocationProviderManager extends return mName; } - @Nullable - public CallerIdentity getIdentity() { + public @Nullable CallerIdentity getIdentity() { return mProvider.getState().identity; } - @Nullable - public ProviderProperties getProperties() { + public @Nullable ProviderProperties getProperties() { return mProvider.getState().properties; } @@ -1381,9 +1342,8 @@ class LocationProviderManager extends } } - @Nullable - public Location getLastLocation(CallerIdentity identity, @PermissionLevel int permissionLevel, - boolean ignoreLocationSettings) { + public @Nullable Location getLastLocation(CallerIdentity identity, + @PermissionLevel int permissionLevel, boolean ignoreLocationSettings) { if (mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(), identity.getPackageName())) { return null; @@ -1426,9 +1386,9 @@ class LocationProviderManager extends * location, even if the permissionLevel is coarse. You are responsible for coarsening the * location if necessary. */ - @Nullable - public Location getLastLocationUnsafe(int userId, @PermissionLevel int permissionLevel, - boolean ignoreLocationSettings, long maximumAgeMs) { + public @Nullable Location getLastLocationUnsafe(int userId, + @PermissionLevel int permissionLevel, boolean ignoreLocationSettings, + long maximumAgeMs) { if (userId == UserHandle.USER_ALL) { // find the most recent location across all users Location lastLocation = null; @@ -1500,8 +1460,7 @@ class LocationProviderManager extends } } - @Nullable - public ICancellationSignal getCurrentLocation(LocationRequest request, + public @Nullable ICancellationSignal getCurrentLocation(LocationRequest request, CallerIdentity identity, int permissionLevel, ILocationCallback callback) { if (request.getDurationMillis() > GET_CURRENT_LOCATION_MAX_TIMEOUT_MS) { request = new LocationRequest.Builder(request) @@ -1519,7 +1478,7 @@ class LocationProviderManager extends synchronized (mLock) { final long ident = Binder.clearCallingIdentity(); try { - addRegistration(callback.asBinder(), registration); + putRegistration(callback.asBinder(), registration); if (!registration.isActive()) { // if the registration never activated, fail it immediately registration.deliverNull(); @@ -1560,7 +1519,7 @@ class LocationProviderManager extends synchronized (mLock) { final long ident = Binder.clearCallingIdentity(); try { - addRegistration(listener.asBinder(), registration); + putRegistration(listener.asBinder(), registration); } finally { Binder.restoreCallingIdentity(ident); } @@ -1578,7 +1537,7 @@ class LocationProviderManager extends synchronized (mLock) { final long identity = Binder.clearCallingIdentity(); try { - addRegistration(pendingIntent, registration); + putRegistration(pendingIntent, registration); } finally { Binder.restoreCallingIdentity(identity); } @@ -1673,7 +1632,7 @@ class LocationProviderManager extends Registration newRegistration) { // by saving the last delivered location state we are able to potentially delay the // resulting provider request longer and save additional power - newRegistration.initializeLastLocation(oldRegistration.getLastDeliveredLocation()); + newRegistration.setLastDeliveredLocation(oldRegistration.getLastDeliveredLocation()); super.onRegistrationReplaced(key, oldRegistration, newRegistration); } @@ -2056,7 +2015,9 @@ class LocationProviderManager extends setLastLocation(location, UserHandle.USER_ALL); // attempt listener delivery - deliverToListeners(registration -> registration.acceptLocationChange(location)); + deliverToListeners(registration -> { + return registration.acceptLocationChange(location); + }); // notify passive provider if (mPassiveManager != null) { @@ -2194,8 +2155,7 @@ class LocationProviderManager extends updateRegistrations(registration -> registration.getIdentity().getUserId() == userId); } - @Nullable - private Location getPermittedLocation(@Nullable Location fineLocation, + private @Nullable Location getPermittedLocation(@Nullable Location fineLocation, @PermissionLevel int permissionLevel) { switch (permissionLevel) { case PERMISSION_FINE: @@ -2250,10 +2210,10 @@ class LocationProviderManager extends private static class LastLocation { - @Nullable private Location mFineLocation; - @Nullable private Location mCoarseLocation; - @Nullable private Location mFineBypassLocation; - @Nullable private Location mCoarseBypassLocation; + private @Nullable Location mFineLocation; + private @Nullable Location mCoarseLocation; + private @Nullable Location mFineBypassLocation; + private @Nullable Location mCoarseBypassLocation; public void clearMock() { if (mFineLocation != null && mFineLocation.isFromMockProvider()) { @@ -2275,8 +2235,8 @@ class LocationProviderManager extends mCoarseLocation = null; } - @Nullable - public Location get(@PermissionLevel int permissionLevel, boolean ignoreLocationSettings) { + public @Nullable Location get(@PermissionLevel int permissionLevel, + boolean ignoreLocationSettings) { switch (permissionLevel) { case PERMISSION_FINE: if (ignoreLocationSettings) { @@ -2337,13 +2297,12 @@ class LocationProviderManager extends private static class SingleUseCallback extends IRemoteCallback.Stub implements Runnable, CancellationSignal.OnCancelListener { - @Nullable - public static SingleUseCallback wrap(@Nullable Runnable callback) { + public static @Nullable SingleUseCallback wrap(@Nullable Runnable callback) { return callback == null ? null : new SingleUseCallback(callback); } @GuardedBy("this") - @Nullable private Runnable mCallback; + private @Nullable Runnable mCallback; private SingleUseCallback(Runnable callback) { mCallback = Objects.requireNonNull(callback); 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 c91ee824ff61..7a59cba02dd9 100644 --- a/services/core/java/com/android/server/location/geofence/GeofenceManager.java +++ b/services/core/java/com/android/server/location/geofence/GeofenceManager.java @@ -41,7 +41,6 @@ import android.stats.location.LocationStatsEnums; import android.util.ArraySet; import com.android.internal.annotations.GuardedBy; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; import com.android.server.PendingIntentUtils; import com.android.server.location.LocationPermissions; import com.android.server.location.listeners.ListenerMultiplexer; @@ -60,8 +59,8 @@ import java.util.Objects; * Manages all geofences. */ public class GeofenceManager extends - ListenerMultiplexer<GeofenceKey, PendingIntent, ListenerOperation<PendingIntent>, - GeofenceManager.GeofenceRegistration, LocationRequest> implements + ListenerMultiplexer<GeofenceKey, PendingIntent, GeofenceManager.GeofenceRegistration, + LocationRequest> implements LocationListener { private static final String TAG = "GeofenceManager"; @@ -121,12 +120,10 @@ public class GeofenceManager extends } @Override - protected ListenerOperation<PendingIntent> onActive() { + protected void onActive() { Location location = getLastLocation(); if (location != null) { - return onLocationChanged(location); - } else { - return null; + executeOperation(onLocationChanged(location)); } } @@ -304,7 +301,7 @@ public class GeofenceManager extends final long identity = Binder.clearCallingIdentity(); try { - addRegistration(new GeofenceKey(pendingIntent, geofence), + putRegistration(new GeofenceKey(pendingIntent, geofence), new GeofenceRegistration(geofence, callerIdentity, pendingIntent)); } finally { Binder.restoreCallingIdentity(identity); 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 ec48d4cbcecd..7592d22a3a78 100644 --- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java +++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java @@ -32,7 +32,6 @@ import android.os.IInterface; import android.os.Process; import android.util.ArraySet; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.location.listeners.BinderListenerRegistration; @@ -60,7 +59,7 @@ import java.util.Objects; */ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInterface, TMergedRegistration> extends - ListenerMultiplexer<IBinder, TListener, ListenerOperation<TListener>, + ListenerMultiplexer<IBinder, TListener, GnssListenerMultiplexer<TRequest, TListener, TMergedRegistration> .GnssListenerRegistration, TMergedRegistration> { @@ -231,7 +230,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter TListener listener) { final long identity = Binder.clearCallingIdentity(); try { - addRegistration(listener.asBinder(), + putRegistration(listener.asBinder(), createRegistration(request, callerIdentity, listener)); } finally { Binder.restoreCallingIdentity(identity); diff --git a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java index 74284f357f61..4a3f94f9b73a 100644 --- a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java @@ -63,18 +63,16 @@ public final class GnssMeasurementsProvider extends @Nullable @Override - protected ListenerOperation<IGnssMeasurementsListener> onActive() { + protected void onActive() { mLocationAttributionHelper.reportHighPowerLocationStart( getIdentity(), GNSS_MEASUREMENTS_BUCKET, getKey()); - return null; } @Nullable @Override - protected ListenerOperation<IGnssMeasurementsListener> onInactive() { + protected void onInactive() { mLocationAttributionHelper.reportHighPowerLocationStop( getIdentity(), GNSS_MEASUREMENTS_BUCKET, getKey()); - return null; } } diff --git a/services/core/java/com/android/server/location/listeners/BinderListenerRegistration.java b/services/core/java/com/android/server/location/listeners/BinderListenerRegistration.java index bc675ceda970..d6b179bab5a2 100644 --- a/services/core/java/com/android/server/location/listeners/BinderListenerRegistration.java +++ b/services/core/java/com/android/server/location/listeners/BinderListenerRegistration.java @@ -23,8 +23,6 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Log; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; - /** * A registration that works with IBinder keys, and registers a DeathListener to automatically * remove the registration if the binder dies. The key for this registration must either be an @@ -34,7 +32,7 @@ import com.android.internal.listeners.ListenerExecutor.ListenerOperation; * @param <TListener> listener type */ public abstract class BinderListenerRegistration<TRequest, TListener> extends - RemoteListenerRegistration<TRequest, TListener, ListenerOperation<TListener>> implements + RemoteListenerRegistration<TRequest, TListener> implements Binder.DeathRecipient { /** diff --git a/services/core/java/com/android/server/location/listeners/ListenerMultiplexer.java b/services/core/java/com/android/server/location/listeners/ListenerMultiplexer.java index 0318ffb519ba..6b936169c82f 100644 --- a/services/core/java/com/android/server/location/listeners/ListenerMultiplexer.java +++ b/services/core/java/com/android/server/location/listeners/ListenerMultiplexer.java @@ -75,13 +75,11 @@ import java.util.function.Predicate; * * @param <TKey> key type * @param <TListener> listener type - * @param <TListenerOperation> listener operation type * @param <TRegistration> registration type * @param <TMergedRegistration> merged registration type */ public abstract class ListenerMultiplexer<TKey, TListener, - TListenerOperation extends ListenerOperation<TListener>, - TRegistration extends ListenerRegistration<TListener, TListenerOperation>, + TRegistration extends ListenerRegistration<TListener>, TMergedRegistration> { @GuardedBy("mRegistrations") @@ -218,10 +216,26 @@ public abstract class ListenerMultiplexer<TKey, TListener, protected void onInactive() {} /** - * Adds a new registration with the given key. This method cannot be called to add a - * registration re-entrantly. + * Puts a new registration with the given key, replacing any previous registration under the + * same key. This method cannot be called to put a registration re-entrantly. + */ + protected final void putRegistration(@NonNull TKey key, @NonNull TRegistration registration) { + replaceRegistration(key, key, registration); + } + + /** + * Atomically removes the registration with the old key and adds a new registration with the + * given key. If there was a registration for the old key, + * {@link #onRegistrationReplaced(Object, ListenerRegistration, ListenerRegistration)} will be + * invoked for the new registration and key instead of + * {@link #onRegistrationAdded(Object, ListenerRegistration)}, even though they may not share + * the same key. The old key may be the same value as the new key, in which case this function + * is equivalent to {@link #putRegistration(Object, ListenerRegistration)}. This method cannot + * be called to add a registration re-entrantly. */ - protected final void addRegistration(@NonNull TKey key, @NonNull TRegistration registration) { + protected final void replaceRegistration(@NonNull TKey oldKey, @NonNull TKey key, + @NonNull TRegistration registration) { + Objects.requireNonNull(oldKey); Objects.requireNonNull(key); Objects.requireNonNull(registration); @@ -229,6 +243,9 @@ public abstract class ListenerMultiplexer<TKey, TListener, // adding listeners reentrantly is not supported Preconditions.checkState(!mReentrancyGuard.isReentrant()); + // new key may only have a prior registration if the oldKey is the same as the key + Preconditions.checkArgument(oldKey == key || !mRegistrations.containsKey(key)); + // since adding a registration can invoke a variety of callbacks, we need to ensure // those callbacks themselves do not re-enter, as this could lead to out-of-order // callbacks. further, we buffer service updates since adding a registration may @@ -241,9 +258,11 @@ public abstract class ListenerMultiplexer<TKey, TListener, boolean wasEmpty = mRegistrations.isEmpty(); TRegistration oldRegistration = null; - int index = mRegistrations.indexOfKey(key); + int index = mRegistrations.indexOfKey(oldKey); if (index >= 0) { - oldRegistration = removeRegistration(index, false); + oldRegistration = removeRegistration(index, oldKey != key); + } + if (oldKey == key && index >= 0) { mRegistrations.setValueAt(index, registration); } else { mRegistrations.put(key, registration); @@ -316,7 +335,7 @@ public abstract class ListenerMultiplexer<TKey, TListener, * re-entrancy, and may be called to remove a registration re-entrantly. */ protected final void removeRegistration(@NonNull Object key, - @NonNull ListenerRegistration<?, ?> registration) { + @NonNull ListenerRegistration<?> registration) { synchronized (mRegistrations) { int index = mRegistrations.indexOfKey(key); if (index < 0) { @@ -478,15 +497,9 @@ public abstract class ListenerMultiplexer<TKey, TListener, if (++mActiveRegistrationsCount == 1) { onActive(); } - TListenerOperation operation = registration.onActive(); - if (operation != null) { - execute(registration, operation); - } + registration.onActive(); } else { - TListenerOperation operation = registration.onInactive(); - if (operation != null) { - execute(registration, operation); - } + registration.onInactive(); if (--mActiveRegistrationsCount == 0) { onInactive(); } @@ -502,16 +515,16 @@ public abstract class ListenerMultiplexer<TKey, TListener, * change the active state of the registration. */ protected final void deliverToListeners( - @NonNull Function<TRegistration, TListenerOperation> function) { + @NonNull Function<TRegistration, ListenerOperation<TListener>> function) { synchronized (mRegistrations) { try (ReentrancyGuard ignored = mReentrancyGuard.acquire()) { final int size = mRegistrations.size(); for (int i = 0; i < size; i++) { TRegistration registration = mRegistrations.valueAt(i); if (registration.isActive()) { - TListenerOperation operation = function.apply(registration); + ListenerOperation<TListener> operation = function.apply(registration); if (operation != null) { - execute(registration, operation); + registration.executeOperation(operation); } } } @@ -526,14 +539,14 @@ public abstract class ListenerMultiplexer<TKey, TListener, * deliverToListeners(registration -> operation); * </pre> */ - protected final void deliverToListeners(@NonNull TListenerOperation operation) { + protected final void deliverToListeners(@NonNull ListenerOperation<TListener> operation) { synchronized (mRegistrations) { try (ReentrancyGuard ignored = mReentrancyGuard.acquire()) { final int size = mRegistrations.size(); for (int i = 0; i < size; i++) { TRegistration registration = mRegistrations.valueAt(i); if (registration.isActive()) { - execute(registration, operation); + registration.executeOperation(operation); } } } @@ -545,10 +558,6 @@ public abstract class ListenerMultiplexer<TKey, TListener, onRegistrationActiveChanged(registration); } - private void execute(TRegistration registration, TListenerOperation operation) { - registration.executeInternal(operation); - } - /** * Dumps debug information. */ @@ -606,7 +615,7 @@ public abstract class ListenerMultiplexer<TKey, TListener, @GuardedBy("mRegistrations") private int mGuardCount; @GuardedBy("mRegistrations") - private @Nullable ArraySet<Entry<Object, ListenerRegistration<?, ?>>> mScheduledRemovals; + private @Nullable ArraySet<Entry<Object, ListenerRegistration<?>>> mScheduledRemovals; ReentrancyGuard() { mGuardCount = 0; @@ -622,7 +631,7 @@ public abstract class ListenerMultiplexer<TKey, TListener, } @GuardedBy("mRegistrations") - void markForRemoval(Object key, ListenerRegistration<?, ?> registration) { + void markForRemoval(Object key, ListenerRegistration<?> registration) { if (Build.IS_DEBUGGABLE) { Preconditions.checkState(Thread.holdsLock(mRegistrations)); } @@ -641,7 +650,7 @@ public abstract class ListenerMultiplexer<TKey, TListener, @Override public void close() { - ArraySet<Entry<Object, ListenerRegistration<?, ?>>> scheduledRemovals = null; + ArraySet<Entry<Object, ListenerRegistration<?>>> scheduledRemovals = null; Preconditions.checkState(mGuardCount > 0); if (--mGuardCount == 0) { @@ -656,7 +665,7 @@ public abstract class ListenerMultiplexer<TKey, TListener, try (UpdateServiceBuffer ignored = mUpdateServiceBuffer.acquire()) { final int size = scheduledRemovals.size(); for (int i = 0; i < size; i++) { - Entry<Object, ListenerRegistration<?, ?>> entry = scheduledRemovals.valueAt(i); + Entry<Object, ListenerRegistration<?>> entry = scheduledRemovals.valueAt(i); removeRegistration(entry.getKey(), entry.getValue()); } } diff --git a/services/core/java/com/android/server/location/listeners/ListenerRegistration.java b/services/core/java/com/android/server/location/listeners/ListenerRegistration.java index d7ecbcb7cfdf..fa21b3a8e369 100644 --- a/services/core/java/com/android/server/location/listeners/ListenerRegistration.java +++ b/services/core/java/com/android/server/location/listeners/ListenerRegistration.java @@ -17,11 +17,9 @@ package com.android.server.location.listeners; -import android.annotation.NonNull; import android.annotation.Nullable; import com.android.internal.listeners.ListenerExecutor; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; import java.util.Objects; import java.util.concurrent.Executor; @@ -31,11 +29,8 @@ import java.util.concurrent.Executor; * request, and an executor responsible for listener invocations. * * @param <TListener> listener type - * @param <TListenerOperation> listener operation type */ -public class ListenerRegistration<TListener, - TListenerOperation extends ListenerOperation<TListener>> implements - ListenerExecutor { +public class ListenerRegistration<TListener> implements ListenerExecutor { private final Executor mExecutor; @@ -70,18 +65,14 @@ public class ListenerRegistration<TListener, * returns a non-null operation, that operation will be invoked for the listener. Invoked * while holding the owning multiplexer's internal lock. */ - protected @Nullable TListenerOperation onActive() { - return null; - } + protected void onActive() {} /** * May be overridden by subclasses. Invoked when registration becomes inactive. If this returns * a non-null operation, that operation will be invoked for the listener. Invoked while holding * the owning multiplexer's internal lock. */ - protected @Nullable TListenerOperation onInactive() { - return null; - } + protected void onInactive() {} public final boolean isActive() { return mActive; @@ -114,27 +105,20 @@ public class ListenerRegistration<TListener, protected void onListenerUnregister() {} /** - * May be overridden by subclasses, however should rarely be needed. Invoked whenever a listener - * operation is submitted for execution, and allows the registration a chance to replace the - * listener operation or perform related bookkeeping. There is no guarantee a listener operation - * submitted or returned here will ever be invoked. Will always be invoked on the calling - * thread. - */ - protected TListenerOperation onExecuteOperation(@NonNull TListenerOperation operation) { - return operation; - } - - /** * May be overridden by subclasses to handle listener operation failures. The default behavior * is to further propagate any exceptions. Will always be invoked on the executor thread. */ - protected void onOperationFailure(TListenerOperation operation, Exception exception) { - throw new AssertionError(exception); + protected void onOperationFailure(ListenerOperation<TListener> operation, Exception e) { + throw new AssertionError(e); } - final void executeInternal(@NonNull TListenerOperation operation) { - executeSafely(mExecutor, () -> mListener, - onExecuteOperation(Objects.requireNonNull(operation)), this::onOperationFailure); + /** + * Executes the given listener operation, invoking + * {@link #onOperationFailure(ListenerOperation, Exception)} in case the listener operation + * fails. + */ + protected final void executeOperation(@Nullable ListenerOperation<TListener> operation) { + executeSafely(mExecutor, () -> mListener, operation, this::onOperationFailure); } @Override diff --git a/services/core/java/com/android/server/location/listeners/PendingIntentListenerRegistration.java b/services/core/java/com/android/server/location/listeners/PendingIntentListenerRegistration.java index e57b5322de8d..0aafb2929d56 100644 --- a/services/core/java/com/android/server/location/listeners/PendingIntentListenerRegistration.java +++ b/services/core/java/com/android/server/location/listeners/PendingIntentListenerRegistration.java @@ -21,8 +21,6 @@ import android.app.PendingIntent; import android.location.util.identity.CallerIdentity; import android.util.Log; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; - /** * A registration that works with PendingIntent keys, and registers a CancelListener to * automatically remove the registration if the PendingIntent is canceled. The key for this @@ -32,8 +30,7 @@ import com.android.internal.listeners.ListenerExecutor.ListenerOperation; * @param <TListener> listener type */ public abstract class PendingIntentListenerRegistration<TRequest, TListener> extends - RemoteListenerRegistration<TRequest, TListener, ListenerOperation<TListener>> implements - PendingIntent.CancelListener { + RemoteListenerRegistration<TRequest, TListener> implements PendingIntent.CancelListener { /** * Interface to allowed pending intent retrieval when keys are not themselves PendingIntents. @@ -73,7 +70,7 @@ public abstract class PendingIntentListenerRegistration<TRequest, TListener> ext protected void onPendingIntentListenerUnregister() {} @Override - public void onOperationFailure(ListenerOperation<TListener> operation, Exception e) { + protected void onOperationFailure(ListenerOperation<TListener> operation, Exception e) { if (e instanceof PendingIntent.CanceledException) { Log.w(getOwner().getTag(), "registration " + this + " removed", e); remove(); diff --git a/services/core/java/com/android/server/location/listeners/RemoteListenerRegistration.java b/services/core/java/com/android/server/location/listeners/RemoteListenerRegistration.java index 242bf323f6cd..4eca577dcf4f 100644 --- a/services/core/java/com/android/server/location/listeners/RemoteListenerRegistration.java +++ b/services/core/java/com/android/server/location/listeners/RemoteListenerRegistration.java @@ -24,7 +24,6 @@ import android.location.util.identity.CallerIdentity; import android.os.Process; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; import com.android.server.FgThread; import java.util.Objects; @@ -38,11 +37,9 @@ import java.util.concurrent.Executor; * * @param <TRequest> request type * @param <TListener> listener type - * @param <TListenerOperation> listener operation type */ -public abstract class RemoteListenerRegistration<TRequest, TListener, - TListenerOperation extends ListenerOperation<TListener>> extends - RemovableListenerRegistration<TRequest, TListener, TListenerOperation> { +public abstract class RemoteListenerRegistration<TRequest, TListener> extends + RemovableListenerRegistration<TRequest, TListener> { @VisibleForTesting public static final Executor IN_PROCESS_EXECUTOR = FgThread.getExecutor(); diff --git a/services/core/java/com/android/server/location/listeners/RemovableListenerRegistration.java b/services/core/java/com/android/server/location/listeners/RemovableListenerRegistration.java index d3b5f6696167..618ff24b873b 100644 --- a/services/core/java/com/android/server/location/listeners/RemovableListenerRegistration.java +++ b/services/core/java/com/android/server/location/listeners/RemovableListenerRegistration.java @@ -18,8 +18,6 @@ package com.android.server.location.listeners; import android.annotation.Nullable; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; - import java.util.Objects; import java.util.concurrent.Executor; @@ -29,11 +27,9 @@ import java.util.concurrent.Executor; * * @param <TRequest> request type * @param <TListener> listener type - * @param <TListenerOperation> listener operation type */ -public abstract class RemovableListenerRegistration<TRequest, TListener, - TListenerOperation extends ListenerOperation<TListener>> extends - RequestListenerRegistration<TRequest, TListener, TListenerOperation> { +public abstract class RemovableListenerRegistration<TRequest, TListener> extends + RequestListenerRegistration<TRequest, TListener> { private volatile @Nullable Object mKey; @@ -47,8 +43,7 @@ public abstract class RemovableListenerRegistration<TRequest, TListener, * with. Often this is easiest to accomplish by defining registration subclasses as non-static * inner classes of the multiplexer they are to be used with. */ - protected abstract ListenerMultiplexer<?, ? super TListener, ? - super TListenerOperation, ?, ?> getOwner(); + protected abstract ListenerMultiplexer<?, ? super TListener, ?, ?> getOwner(); /** * Returns the key associated with this registration. May not be invoked before diff --git a/services/core/java/com/android/server/location/listeners/RequestListenerRegistration.java b/services/core/java/com/android/server/location/listeners/RequestListenerRegistration.java index d97abae59dd3..0c2fc9142d92 100644 --- a/services/core/java/com/android/server/location/listeners/RequestListenerRegistration.java +++ b/services/core/java/com/android/server/location/listeners/RequestListenerRegistration.java @@ -16,8 +16,6 @@ package com.android.server.location.listeners; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; - import java.util.concurrent.Executor; /** @@ -25,11 +23,9 @@ import java.util.concurrent.Executor; * * @param <TRequest> request type * @param <TListener> listener type - * @param <TListenerOperation> listener operation type */ -public class RequestListenerRegistration<TRequest, TListener, - TListenerOperation extends ListenerOperation<TListener>> extends - ListenerRegistration<TListener, TListenerOperation> { +public class RequestListenerRegistration<TRequest, TListener> extends + ListenerRegistration<TListener> { private final TRequest mRequest; diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java index 8f05636eed9c..f5d648910d90 100644 --- a/services/core/java/com/android/server/notification/ZenLog.java +++ b/services/core/java/com/android/server/notification/ZenLog.java @@ -39,7 +39,7 @@ public class ZenLog { // the ZenLog is *very* verbose, so be careful about setting this to true private static final boolean DEBUG = false; - private static final int SIZE = Build.IS_DEBUGGABLE ? 100 : 20; + private static final int SIZE = Build.IS_DEBUGGABLE ? 200 : 100; private static final long[] TIMES = new long[SIZE]; private static final int[] TYPES = new int[SIZE]; @@ -136,9 +136,14 @@ public class ZenLog { public static void traceConfig(String reason, ZenModeConfig oldConfig, ZenModeConfig newConfig) { - append(TYPE_CONFIG, reason - + "," + (newConfig != null ? newConfig.toString() : null) - + "," + ZenModeConfig.diff(oldConfig, newConfig)); + ZenModeConfig.Diff diff = ZenModeConfig.diff(oldConfig, newConfig); + if (diff.isEmpty()) { + append(TYPE_CONFIG, reason + " no changes"); + } else { + append(TYPE_CONFIG, reason + + ",\n" + (newConfig != null ? newConfig.toString() : null) + + ",\n" + ZenModeConfig.diff(oldConfig, newConfig)); + } } public static void traceDisableEffects(NotificationRecord record, String reason) { diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java index 571f79915484..50b4d438984c 100644 --- a/services/core/java/com/android/server/notification/ZenModeConditions.java +++ b/services/core/java/com/android/server/notification/ZenModeConditions.java @@ -108,7 +108,7 @@ public class ZenModeConditions implements ConditionProviders.Callback { @Override public void onServiceAdded(ComponentName component) { if (DEBUG) Log.d(TAG, "onServiceAdded " + component); - mHelper.setConfig(mHelper.getConfig(), component, "zmc.onServiceAdded"); + mHelper.setConfig(mHelper.getConfig(), component, "zmc.onServiceAdded:" + component); } @Override diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index 7992fea4a675..a12932a88487 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -1018,29 +1018,17 @@ public abstract class ApexManager { // the /apex directory is just a symlink to /system/apex. List<ActiveApexInfo> result = new ArrayList<>(); File apexDir = Environment.getApexDirectory(); - // In flattened configuration, init special-case the art directory and bind-mounts - // com.android.art.{release|debug} to com.android.art. At the time of writing, these - // directories are copied from the kArtApexDirNames variable in - // system/core/init/mount_namespace.cpp. - String[] skipDirs = {"com.android.art.release", "com.android.art.debug"}; if (apexDir.isDirectory()) { File[] files = apexDir.listFiles(); // listFiles might be null if system server doesn't have permission to read // a directory. if (files != null) { for (File file : files) { - if (file.isDirectory() && !file.getName().contains("@")) { - boolean skip = false; - for (String skipDir : skipDirs) { - if (file.getName().equals(skipDir)) { - skip = true; - break; - } - } - if (!skip) { - result.add( - new ActiveApexInfo(file, Environment.getRootDirectory())); - } + if (file.isDirectory() && !file.getName().contains("@") + // In flattened configuration, init special-cases the art directory + // and bind-mounts com.android.art.debug to com.android.art. + && !file.getName().equals("com.android.art.debug")) { + result.add(new ActiveApexInfo(file, Environment.getRootDirectory())); } } } diff --git a/services/core/java/com/android/server/pm/IncrementalStates.java b/services/core/java/com/android/server/pm/IncrementalStates.java index 26ace47776be..72803ac35a3f 100644 --- a/services/core/java/com/android/server/pm/IncrementalStates.java +++ b/services/core/java/com/android/server/pm/IncrementalStates.java @@ -119,6 +119,33 @@ public final class IncrementalStates { } } + /** + * Change the startable state if the app has crashed or ANR'd during loading. + * If the app is not loading (i.e., fully loaded), this event doesn't change startable state. + */ + public void onCrashOrAnr() { + if (DEBUG) { + Slog.i(TAG, "received package crash or ANR event"); + } + final boolean startableStateChanged; + synchronized (mLock) { + if (mStartableState.isStartable() && mLoadingState.isLoading()) { + // Changing from startable -> unstartable only if app is still loading. + mStartableState.adoptNewStartableStateLocked(false); + startableStateChanged = true; + } else { + // If the app is fully loaded, the crash or ANR is caused by the app itself, so + // we do not change the startable state. + startableStateChanged = false; + } + } + if (startableStateChanged) { + mHandler.post(PooledLambda.obtainRunnable( + IncrementalStates::reportStartableState, + IncrementalStates.this).recycleOnUse()); + } + } + private void reportStartableState() { final Callback callback; final boolean startable; diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 8eebf2a8d9d9..b679c0fbab83 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -16,6 +16,7 @@ package com.android.server.pm; +import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.pm.LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS; @@ -32,6 +33,7 @@ import android.app.IApplicationThread; import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; import android.app.usage.UsageStatsManagerInternal; +import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -1018,6 +1020,32 @@ public class LauncherAppsService extends SystemService { } @Override + public PendingIntent getActivityLaunchIntent(ComponentName component, Bundle opts, + UserHandle user) { + if (!canAccessProfile(user.getIdentifier(), "Cannot start activity")) { + throw new ActivityNotFoundException("Activity could not be found"); + } + + final Intent launchIntent = getMainActivityLaunchIntent(component, user); + if (launchIntent == null) { + throw new SecurityException("Attempt to launch activity without " + + " category Intent.CATEGORY_LAUNCHER " + component); + } + + final long ident = Binder.clearCallingIdentity(); + try { + // If we reach here, we've verified that the caller has access to the profile and + // is launching an exported activity with CATEGORY_LAUNCHER so we can clear the + // calling identity to mirror the startActivityAsUser() call which does not validate + // the calling user + return PendingIntent.getActivityAsUser(mContext, 0 /* requestCode */, launchIntent, + FLAG_IMMUTABLE, opts, user); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override public void startActivityAsUser(IApplicationThread caller, String callingPackage, String callingFeatureId, ComponentName component, Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException { @@ -1025,9 +1053,24 @@ public class LauncherAppsService extends SystemService { return; } + Intent launchIntent = getMainActivityLaunchIntent(component, user); + if (launchIntent == null) { + throw new SecurityException("Attempt to launch activity without " + + " category Intent.CATEGORY_LAUNCHER " + component); + } + launchIntent.setSourceBounds(sourceBounds); + + mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage, + callingFeatureId, launchIntent, /* resultTo= */ null, + Intent.FLAG_ACTIVITY_NEW_TASK, opts, user.getIdentifier()); + } + + /** + * Returns the main activity launch intent for the given component package. + */ + private Intent getMainActivityLaunchIntent(ComponentName component, UserHandle user) { Intent launchIntent = new Intent(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); - launchIntent.setSourceBounds(sourceBounds); launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); launchIntent.setPackage(component.getPackageName()); @@ -1066,15 +1109,12 @@ public class LauncherAppsService extends SystemService { } } if (!canLaunch) { - throw new SecurityException("Attempt to launch activity without " - + " category Intent.CATEGORY_LAUNCHER " + component); + return null; } } finally { Binder.restoreCallingIdentity(ident); } - mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage, - callingFeatureId, launchIntent, /* resultTo= */ null, - Intent.FLAG_ACTIVITY_NEW_TASK, opts, user.getIdentifier()); + return launchIntent; } @Override diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 410fbe57bf26..e63a05aa6b73 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -222,6 +222,7 @@ import android.content.pm.SharedLibraryInfo; import android.content.pm.Signature; import android.content.pm.SigningInfo; import android.content.pm.SuspendDialogInfo; +import android.content.pm.TestUtilityService; import android.content.pm.UserInfo; import android.content.pm.VerifierDeviceIdentity; import android.content.pm.VerifierInfo; @@ -336,6 +337,7 @@ import com.android.internal.os.SomeArgs; import com.android.internal.os.Zygote; import com.android.internal.telephony.CarrierAppUtils; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.CollectionUtils; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; @@ -479,7 +481,7 @@ import java.util.function.Supplier; * </pre> */ public class PackageManagerService extends IPackageManager.Stub - implements PackageSender { + implements PackageSender, TestUtilityService { static final String TAG = "PackageManager"; public static final boolean DEBUG_SETTINGS = false; static final boolean DEBUG_PREFERRED = false; @@ -819,6 +821,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean mPromoteSystemApps; private final PackageManagerInternal mPmInternal; + private final TestUtilityService mTestUtilityService; @GuardedBy("mLock") @@ -1192,6 +1195,7 @@ public class PackageManagerService extends IPackageManager.Stub public IPermissionManager permissionManagerService; public PendingPackageBroadcasts pendingPackageBroadcasts; public PackageManagerInternal pmInternal; + public TestUtilityService testUtilityService; public ProcessLoggingHandler processLoggingHandler; public ProtectedPackages protectedPackages; public @NonNull String requiredInstallerPackage; @@ -2956,6 +2960,7 @@ public class PackageManagerService extends IPackageManager.Stub mPendingBroadcasts = testParams.pendingPackageBroadcasts; mPermissionManagerService = testParams.permissionManagerService; mPmInternal = testParams.pmInternal; + mTestUtilityService = testParams.testUtilityService; mProcessLoggingHandler = testParams.processLoggingHandler; mProtectedPackages = testParams.protectedPackages; mSeparateProcesses = testParams.separateProcesses; @@ -3026,6 +3031,8 @@ public class PackageManagerService extends IPackageManager.Stub // Expose private service for system components to use. mPmInternal = new PackageManagerInternalImpl(); + LocalServices.addService(TestUtilityService.class, this); + mTestUtilityService = LocalServices.getService(TestUtilityService.class); LocalServices.addService(PackageManagerInternal.class, mPmInternal); mUserManager = injector.getUserManagerService(); mComponentResolver = injector.getComponentResolver(); @@ -12298,9 +12305,8 @@ public class PackageManagerService extends IPackageManager.Stub // user-installed version of the application will be ignored. if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { if (mExpectingBetter.containsKey(pkg.getPackageName())) { - logCriticalInfo(Log.WARN, - "Relax SCAN_REQUIRE_KNOWN requirement for package " - + pkg.getPackageName()); + Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package " + + pkg.getPackageName()); } else { PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName()); if (known != null) { @@ -12687,12 +12693,17 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager.addAllPermissionGroups(pkg, chatty); } + // If a permission has had its defining app changed, or it has had its protection + // upgraded, we need to revoke apps that hold it + final List<String> permissionsWithChangedDefinition; // Don't allow ephemeral applications to define new permissions. if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { + permissionsWithChangedDefinition = null; Slog.w(TAG, "Permissions from package " + pkg.getPackageName() + " ignored: instant apps cannot define new permissions."); } else { - mPermissionManager.addAllPermissions(pkg, chatty); + permissionsWithChangedDefinition = + mPermissionManager.addAllPermissions(pkg, chatty); } int collectionSize = ArrayUtils.size(pkg.getInstrumentations()); @@ -12721,7 +12732,10 @@ public class PackageManagerService extends IPackageManager.Stub } } - if (oldPkg != null) { + boolean hasOldPkg = oldPkg != null; + boolean hasPermissionDefinitionChanges = + !CollectionUtils.isEmpty(permissionsWithChangedDefinition); + if (hasOldPkg || hasPermissionDefinitionChanges) { // We need to call revokeRuntimePermissionsIfGroupChanged async as permission // revoke callbacks from this method might need to kill apps which need the // mPackages lock on a different thread. This would dead lock. @@ -12732,9 +12746,16 @@ public class PackageManagerService extends IPackageManager.Stub // won't be granted yet, hence new packages are no problem. final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet()); - AsyncTask.execute(() -> + AsyncTask.execute(() -> { + if (hasOldPkg) { mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, - allPackageNames)); + allPackageNames); + } + if (hasPermissionDefinitionChanges) { + mPermissionManager.revokeRuntimePermissionsIfPermissionDefinitionChanged( + permissionsWithChangedDefinition, allPackageNames); + } + }); } } @@ -13304,13 +13325,21 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) { final int callingUid = Binder.getCallingUid(); - PackageManagerServiceUtils - .enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled", callingUid); + final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID + || callingUid == Process.SYSTEM_UID; + if (!calledFromSystemOrPhone) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, + "setSystemAppHiddenUntilInstalled"); + } + synchronized (mLock) { final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); if (pkgSetting == null || !pkgSetting.isSystem()) { return; } + if (pkgSetting.getPkg().isCoreApp() && !calledFromSystemOrPhone) { + throw new SecurityException("Only system or phone callers can modify core apps"); + } pkgSetting.getPkgState().setHiddenUntilInstalled(hidden); final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName); if (disabledPs == null) { @@ -13323,14 +13352,22 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) { final int callingUid = Binder.getCallingUid(); - PackageManagerServiceUtils - .enforceSystemOrPhoneCaller("setSystemAppInstallState", callingUid); + final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID + || callingUid == Process.SYSTEM_UID; + if (!calledFromSystemOrPhone) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, + "setSystemAppHiddenUntilInstalled"); + } + synchronized (mLock) { final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); // The target app should always be in system if (pkgSetting == null || !pkgSetting.isSystem()) { return false; } + if (pkgSetting.getPkg().isCoreApp() && !calledFromSystemOrPhone) { + throw new SecurityException("Only system or phone callers can modify core apps"); + } // Check if the install state is the same if (pkgSetting.getInstalled(userId) == installed) { return false; @@ -25843,6 +25880,20 @@ public class PackageManagerService extends IPackageManager.Stub } return ps.getIncrementalStates(); } + + @Override + public void notifyPackageCrashOrAnr(@NonNull String packageName) { + final PackageSetting ps; + synchronized (mLock) { + ps = mSettings.mPackages.get(packageName); + if (ps == null) { + Slog.w(TAG, "Failed notifyPackageCrash. Package " + packageName + + " is not installed"); + return; + } + } + ps.setStatesOnCrashOrAnr(); + } } @@ -26336,9 +26387,39 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public void holdLock(int durationMs) { + public IBinder getHoldLockToken() { + if (!Build.IS_DEBUGGABLE) { + throw new SecurityException("getHoldLockToken requires a debuggable build"); + } + mContext.enforceCallingPermission( - Manifest.permission.INJECT_EVENTS, "holdLock requires shell identity"); + Manifest.permission.INJECT_EVENTS, + "getHoldLockToken requires INJECT_EVENTS permission"); + + final Binder token = new Binder(); + token.attachInterface(this, "holdLock:" + Binder.getCallingUid()); + return token; + } + + @Override + public void verifyHoldLockToken(IBinder token) { + if (!Build.IS_DEBUGGABLE) { + throw new SecurityException("holdLock requires a debuggable build"); + } + + if (token == null) { + throw new SecurityException("null holdLockToken"); + } + + if (token.queryLocalInterface("holdLock:" + Binder.getCallingUid()) != this) { + throw new SecurityException("Invalid holdLock() token"); + } + } + + @Override + public void holdLock(IBinder token, int durationMs) { + mTestUtilityService.verifyHoldLockToken(token); + synchronized (mLock) { SystemClock.sleep(durationMs); } diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java index e5dad8570254..b05fd47383fd 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java @@ -103,7 +103,8 @@ import java.util.zip.GZIPInputStream; * {@hide} */ public class PackageManagerServiceUtils { - private final static long SEVEN_DAYS_IN_MILLISECONDS = 7 * 24 * 60 * 60 * 1000; + private static final long SEVEN_DAYS_IN_MILLISECONDS = 7 * 24 * 60 * 60 * 1000; + private static final long MAX_CRITICAL_INFO_DUMP_SIZE = 3 * 1000 * 1000; // 3MB public final static Predicate<PackageSetting> REMOVE_IF_NULL_PKG = pkgSetting -> pkgSetting.pkg == null; @@ -349,7 +350,12 @@ public class PackageManagerServiceUtils { } public static void dumpCriticalInfo(ProtoOutputStream proto) { - try (BufferedReader in = new BufferedReader(new FileReader(getSettingsProblemFile()))) { + final File file = getSettingsProblemFile(); + final long skipSize = file.length() - MAX_CRITICAL_INFO_DUMP_SIZE; + try (BufferedReader in = new BufferedReader(new FileReader(file))) { + if (skipSize > 0) { + in.skip(skipSize); + } String line = null; while ((line = in.readLine()) != null) { if (line.contains("ignored: updated version")) continue; @@ -360,7 +366,12 @@ public class PackageManagerServiceUtils { } public static void dumpCriticalInfo(PrintWriter pw, String msg) { - try (BufferedReader in = new BufferedReader(new FileReader(getSettingsProblemFile()))) { + final File file = getSettingsProblemFile(); + final long skipSize = file.length() - MAX_CRITICAL_INFO_DUMP_SIZE; + try (BufferedReader in = new BufferedReader(new FileReader(file))) { + if (skipSize > 0) { + in.skip(skipSize); + } String line = null; while ((line = in.readLine()) != null) { if (line.contains("ignored: updated version")) continue; diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index be7c7c6ff1d6..ac76cf71ef67 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -772,6 +772,14 @@ public abstract class PackageSettingBase extends SettingBase { } /** + * Called to indicate that the running app has crashed or ANR'd. This might change the startable + * state of the package, depending on whether the package is fully loaded. + */ + public void setStatesOnCrashOrAnr() { + incrementalStates.onCrashOrAnr(); + } + + /** * Called to set the callback to listen for startable state changes. */ public void setIncrementalStatesCallback(IncrementalStates.Callback callback) { diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 3bad3cb1d372..8dbd46482ae2 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -1059,19 +1059,26 @@ public class StagingManager { onPreRebootVerificationComplete(session); return; } - switch (msg.what) { - case MSG_PRE_REBOOT_VERIFICATION_START: - handlePreRebootVerification_Start(session); - break; - case MSG_PRE_REBOOT_VERIFICATION_APEX: - handlePreRebootVerification_Apex(session, rollbackId); - break; - case MSG_PRE_REBOOT_VERIFICATION_APK: - handlePreRebootVerification_Apk(session); - break; - case MSG_PRE_REBOOT_VERIFICATION_END: - handlePreRebootVerification_End(session); - break; + try { + switch (msg.what) { + case MSG_PRE_REBOOT_VERIFICATION_START: + handlePreRebootVerification_Start(session); + break; + case MSG_PRE_REBOOT_VERIFICATION_APEX: + handlePreRebootVerification_Apex(session, rollbackId); + break; + case MSG_PRE_REBOOT_VERIFICATION_APK: + handlePreRebootVerification_Apk(session); + break; + case MSG_PRE_REBOOT_VERIFICATION_END: + handlePreRebootVerification_End(session); + break; + } + } catch (Exception e) { + Slog.e(TAG, "Pre-reboot verification failed due to unhandled exception", e); + onPreRebootVerificationFailure(session, + SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, + "Pre-reboot verification failed due to unhandled exception: " + e); } } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index a0344e27f96c..7f29cd94bfca 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -4458,7 +4458,7 @@ public class UserManagerService extends IUserManager.Stub { } } if (userInfo == null) { - throw new SecurityException("userId can only be the calling user or a managed " + throw new SecurityException("userId can only be the calling user or a " + "profile associated with this user"); } return userInfo.creationTime; diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 6ffc5983417a..155d71673e06 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -74,6 +74,8 @@ public final class BasePermission { private static final String ATTR_PACKAGE = "package"; private static final String TAG_ITEM = "item"; + private boolean mPermissionDefinitionChanged; + @NonNull private PermissionInfo mPermissionInfo; @@ -122,6 +124,10 @@ public final class BasePermission { return mPermissionInfo.packageName; } + public boolean isPermissionDefinitionChanged() { + return mPermissionDefinitionChanged; + } + public int getType() { return mType; } @@ -148,6 +154,10 @@ public final class BasePermission { mReconciled = permissionInfo != null; } + public void setPermissionDefinitionChanged(boolean shouldOverride) { + mPermissionDefinitionChanged = shouldOverride; + } + public boolean hasGids() { return mGids.length != 0; } @@ -364,6 +374,7 @@ public final class BasePermission { @NonNull AndroidPackage pkg, Collection<BasePermission> permissionTrees, boolean chatty) { // Allow system apps to redefine non-system permissions + boolean ownerChanged = false; if (bp != null && !Objects.equals(bp.mPermissionInfo.packageName, p.packageName)) { final boolean currentOwnerIsSystem; if (!bp.mReconciled) { @@ -389,6 +400,7 @@ public final class BasePermission { String msg = "New decl " + pkg + " of permission " + p.name + " is system; overriding " + bp.mPermissionInfo.packageName; PackageManagerService.reportSettingsProblem(Log.WARN, msg); + ownerChanged = true; bp = null; } } @@ -396,6 +408,7 @@ public final class BasePermission { if (bp == null) { bp = new BasePermission(p.name, p.packageName, TYPE_MANIFEST); } + boolean wasNormal = bp.isNormal(); StringBuilder r = null; if (!bp.mReconciled) { if (bp.mPermissionInfo.packageName == null @@ -435,6 +448,11 @@ public final class BasePermission { r.append("DUP:"); r.append(p.name); } + if (bp.isRuntime() && (ownerChanged || wasNormal)) { + // If this is a runtime permission and the owner has changed, or this was a normal + // permission, then permission state should be cleaned up + bp.mPermissionDefinitionChanged = true; + } if (PackageManagerService.DEBUG_PACKAGE_SCANNING && r != null) { Log.d(TAG, " Permissions: " + r); } 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 4d43969578cd..da4ef63d6945 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -2327,8 +2327,74 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - private void addAllPermissions(AndroidPackage pkg, boolean chatty) { + /** + * If permissions are upgraded to runtime, or their owner changes to the system, then any + * granted permissions must be revoked. + * + * @param permissionsToRevoke A list of permission names to revoke + * @param allPackageNames All package names + * @param permissionCallback Callback for permission changed + */ + private void revokeRuntimePermissionsIfPermissionDefinitionChanged( + @NonNull List<String> permissionsToRevoke, + @NonNull ArrayList<String> allPackageNames, + @NonNull PermissionCallback permissionCallback) { + + final int[] userIds = mUserManagerInt.getUserIds(); + final int numPermissions = permissionsToRevoke.size(); + final int numUserIds = userIds.length; + final int numPackages = allPackageNames.size(); + final int callingUid = Binder.getCallingUid(); + + for (int permNum = 0; permNum < numPermissions; permNum++) { + String permName = permissionsToRevoke.get(permNum); + BasePermission bp = mSettings.getPermission(permName); + if (bp == null || !bp.isRuntime()) { + continue; + } + for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) { + final int userId = userIds[userIdNum]; + for (int packageNum = 0; packageNum < numPackages; packageNum++) { + final String packageName = allPackageNames.get(packageNum); + final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId); + if (uid < Process.FIRST_APPLICATION_UID) { + // do not revoke from system apps + continue; + } + final int permissionState = checkPermissionImpl(permName, packageName, + userId); + final int flags = getPermissionFlags(permName, packageName, userId); + final int flagMask = FLAG_PERMISSION_SYSTEM_FIXED + | FLAG_PERMISSION_POLICY_FIXED + | FLAG_PERMISSION_GRANTED_BY_DEFAULT + | FLAG_PERMISSION_GRANTED_BY_ROLE; + if (permissionState == PackageManager.PERMISSION_GRANTED + && (flags & flagMask) == 0) { + EventLog.writeEvent(0x534e4554, "154505240", uid, + "Revoking permission " + permName + " from package " + + packageName + " due to definition change"); + EventLog.writeEvent(0x534e4554, "168319670", uid, + "Revoking permission " + permName + " from package " + + packageName + " due to definition change"); + Slog.e(TAG, "Revoking permission " + permName + " from package " + + packageName + " due to definition change"); + try { + revokeRuntimePermissionInternal(permName, packageName, + false, callingUid, userId, null, permissionCallback); + } catch (Exception e) { + Slog.e(TAG, "Could not revoke " + permName + " from " + + packageName, e); + } + } + } + } + bp.setPermissionDefinitionChanged(false); + } + } + + private List<String> addAllPermissions(AndroidPackage pkg, boolean chatty) { final int N = ArrayUtils.size(pkg.getPermissions()); + ArrayList<String> definitionChangedPermissions = new ArrayList<>(); for (int i=0; i<N; i++) { ParsedPermission p = pkg.getPermissions().get(i); @@ -2369,8 +2435,12 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (bp.isInstalled()) { p.setFlags(p.getFlags() | PermissionInfo.FLAG_INSTALLED); } + if (bp.isPermissionDefinitionChanged()) { + definitionChangedPermissions.add(p.getName()); + } } } + return definitionChangedPermissions; } private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) { @@ -4750,9 +4820,18 @@ public class PermissionManagerService extends IPermissionManager.Stub { PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage, oldPackage, allPackageNames, mDefaultPermissionCallback); } + + @Override + public void revokeRuntimePermissionsIfPermissionDefinitionChanged( + @NonNull List<String> permissionsToRevoke, + @NonNull ArrayList<String> allPackageNames) { + PermissionManagerService.this.revokeRuntimePermissionsIfPermissionDefinitionChanged( + permissionsToRevoke, allPackageNames, mDefaultPermissionCallback); + } + @Override - public void addAllPermissions(AndroidPackage pkg, boolean chatty) { - PermissionManagerService.this.addAllPermissions(pkg, chatty); + public List<String> addAllPermissions(AndroidPackage pkg, boolean chatty) { + return PermissionManagerService.this.addAllPermissions(pkg, chatty); } @Override public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java index 5ea3458fcbfa..20e9c5dcb521 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java @@ -256,12 +256,26 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager @NonNull ArrayList<String> allPackageNames); /** + * Some permissions might have been owned by a non-system package, and the system then defined + * said permission. Some other permissions may one have been install permissions, but are now + * runtime or higher. These permissions should be revoked. + * + * @param permissionsToRevoke A list of permission names to revoke + * @param allPackageNames All packages + */ + public abstract void revokeRuntimePermissionsIfPermissionDefinitionChanged( + @NonNull List<String> permissionsToRevoke, + @NonNull ArrayList<String> allPackageNames); + + /** * Add all permissions in the given package. * <p> * NOTE: argument {@code groupTEMP} is temporary until mPermissionGroups is moved to * the permission settings. + * + * @return A list of BasePermissions that were updated, and need to be revoked from packages */ - public abstract void addAllPermissions(@NonNull AndroidPackage pkg, boolean chatty); + public abstract List<String> addAllPermissions(@NonNull AndroidPackage pkg, boolean chatty); public abstract void addAllPermissionGroups(@NonNull AndroidPackage pkg, boolean chatty); public abstract void removeAllPermissions(@NonNull AndroidPackage pkg, boolean chatty); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 0983e10d2965..8b677a99b22a 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -1468,10 +1468,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; if (mHasFeatureLeanback) { isSetupComplete &= isTvUserSetupComplete(); + } else if (mHasFeatureAuto) { + isSetupComplete &= isAutoUserSetupComplete(); } return isSetupComplete; } + private boolean isAutoUserSetupComplete() { + return Settings.Secure.getIntForUser(mContext.getContentResolver(), + "android.car.SETUP_WIZARD_IN_PROGRESS", 0, UserHandle.USER_CURRENT) == 0; + } + private boolean isTvUserSetupComplete() { return Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 55cb7f32e1b7..fb47ebbcaa07 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -706,12 +706,12 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D @Override public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver, - @BiometricAuthenticator.Modality int biometricModality, boolean requireConfirmation, + int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId, String opPackageName, long operationId) { enforceBiometricDialog(); if (mBar != null) { try { - mBar.showAuthenticationDialog(promptInfo, receiver, biometricModality, + mBar.showAuthenticationDialog(promptInfo, receiver, sensorIds, credentialAllowed, requireConfirmation, userId, opPackageName, operationId); } catch (RemoteException ex) { } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 13e23f766668..0a7f08bfbe8c 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -499,7 +499,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // process that it is hidden. private boolean mLastDeferHidingClient; // If true we will defer setting mClientVisible to false // and reporting to the client that it is hidden. - private boolean mSetToSleep; // have we told the activity to sleep? boolean nowVisible; // is this activity's window visible? boolean mClientVisibilityDeferred;// was the visibility change message to client deferred? boolean idle; // has the activity gone idle? @@ -906,7 +905,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A pw.print(" finishing="); pw.println(finishing); pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused); pw.print(" inHistory="); pw.print(inHistory); - pw.print(" setToSleep="); pw.print(mSetToSleep); pw.print(" idle="); pw.print(idle); pw.print(" mStartingWindowState="); pw.println(startingWindowStateToString(mStartingWindowState)); @@ -1364,6 +1362,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } else if (mLetterbox != null) { mLetterbox.hide(); } + task.maybeUpdateLetterboxBounds(this, getLetterboxParams(w)); } void updateLetterboxSurface(WindowState winHint) { @@ -1377,6 +1376,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } + @Nullable + private Rect getLetterboxParams(WindowState w) { + boolean isLetterboxed = w.isLetterboxedAppWindow() && fillsParent(); + return isLetterboxed ? getBounds() : null; + } + Rect getLetterboxInsets() { if (mLetterbox != null) { return mLetterbox.getInsets(); @@ -4675,14 +4680,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } - // Check if the activity is on a sleeping display - // TODO b/163993448 mSetToSleep is required when restarting an existing activity, try to - // remove it if possible. - if (mSetToSleep && mDisplayContent.isSleeping()) { - return false; + // Check if the activity is on a sleeping display, canTurnScreenOn will also check + // keyguard visibility + if (mDisplayContent.isSleeping()) { + return canTurnScreenOn(); + } else { + return mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this); } - - return mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this); } void updateVisibilityIgnoringKeyguard(boolean behindFullscreenActivity) { @@ -4719,7 +4723,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A stack.mUndrawnActivitiesBelowTopTranslucent.add(this); } setVisibility(true); - mSetToSleep = false; app.postPendingUiCleanMsg(true); if (reportToClient) { mClientVisibilityDeferred = false; @@ -5118,9 +5121,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, StopActivityItem.obtain(configChangeFlags)); - if (stack.shouldSleepOrShutDownActivities()) { - setSleeping(true); - } mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT); } catch (Exception e) { // Maybe just ignore exceptions here... if the process has crashed, our death @@ -5711,10 +5711,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return mVisibleRequested || nowVisible || mState == PAUSING || mState == RESUMED; } - void setSleeping(boolean sleeping) { - mSetToSleep = sleeping; - } - static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { final ActivityRecord r = ActivityRecord.forTokenLocked(token); if (r == null || r.getParent() == null) { @@ -7561,7 +7557,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } final Task stack = getRootTask(); - return stack != null + return mCurrentLaunchCanTurnScreenOn && stack != null && mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this); } diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index a8079cfa1c85..a068d2b7c823 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -820,7 +820,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } mService.getPackageManagerInternalLocked().notifyPackageUse( r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY); - r.setSleeping(false); r.forceNewConfig = false; mService.getAppWarningsLocked().onStartActivity(r); r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index c8a8f81ebca1..25b2523b1a3e 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1195,7 +1195,12 @@ class ActivityStarter { } } - mService.onStartActivitySetDidAppSwitch(); + // Only allow app switching to be resumed if activity is not a restricted background + // activity, otherwise any background activity started in background task can stop + // home button protection mode. + if (!restrictedBgActivity) { + mService.onStartActivitySetDidAppSwitch(); + } mController.doPendingActivityLaunches(false); mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, @@ -1260,6 +1265,20 @@ class ActivityStarter { return false; } + // Always allow home application to start activities. + if (mService.mHomeProcess != null && callingUid == mService.mHomeProcess.mUid) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")"); + } + return false; + } + + // App switching will be allowed if BAL app switching flag is not enabled, or if + // its app switching rule allows it. + // This is used to block background activity launch even if the app is still + // visible to user after user clicking home button. + final boolean appSwitchAllowed = mService.getBalAppSwitchesAllowed(); + // don't abort if the callingUid has a visible window or is a persistent system process final int callingUidProcState = mService.getUidState(callingUid); final boolean callingUidHasAnyVisibleWindow = @@ -1269,7 +1288,8 @@ class ActivityStarter { || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP; final boolean isCallingUidPersistentSystemProcess = callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; - if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) { + if ((appSwitchAllowed && callingUidHasAnyVisibleWindow) + || isCallingUidPersistentSystemProcess) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid + ", isCallingUidPersistentSystemProcess = " @@ -1295,6 +1315,7 @@ class ActivityStarter { || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; if (realCallingUid != callingUid) { // don't abort if the realCallingUid has a visible window + // TODO(b/171459802): We should check appSwitchAllowed also if (realCallingUidHasAnyVisibleWindow) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid @@ -1376,7 +1397,7 @@ class ActivityStarter { // don't abort if the callerApp or other processes of that uid are allowed in any way if (callerApp != null) { // first check the original calling process - if (callerApp.areBackgroundActivityStartsAllowed()) { + if (callerApp.areBackgroundActivityStartsAllowed(appSwitchAllowed)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: callerApp process (pid = " + callerApp.getPid() + ", uid = " + callerAppUid + ") is allowed"); @@ -1389,7 +1410,8 @@ class ActivityStarter { if (uidProcesses != null) { for (int i = uidProcesses.size() - 1; i >= 0; i--) { final WindowProcessController proc = uidProcesses.valueAt(i); - if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) { + if (proc != callerApp + && proc.areBackgroundActivityStartsAllowed(appSwitchAllowed)) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "Background activity start allowed: process " + proc.getPid() @@ -2546,6 +2568,10 @@ class ActivityStarter { private void resumeTargetStackIfNeeded() { if (mDoResume) { + final ActivityRecord next = mTargetStack.topRunningActivity(true /* focusableOnly */); + if (next != null) { + next.setCurrentLaunchCanTurnScreenOn(true); + } mRootWindowContainer.resumeFocusedStacksTopActivities(mTargetStack, null, mOptions); } else { ActivityOptions.abort(mOptions); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 8e5add916620..a02701f8ad00 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -23,6 +23,7 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; +import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REMOVE_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; @@ -39,6 +40,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST; import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED; import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; @@ -159,9 +161,11 @@ import android.app.WindowConfiguration; import android.app.admin.DevicePolicyCache; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; +import android.app.compat.CompatChanges; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.EnterPipRequestedItem; import android.app.usage.UsageStatsManagerInternal; +import android.compat.annotation.ChangeId; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ContentResolver; @@ -340,6 +344,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** This activity is being relaunched due to a free-resize operation. */ public static final int RELAUNCH_REASON_FREE_RESIZE = 2; + /** + * Apps are blocked from starting activities in the foreground after the user presses home. + */ + @ChangeId + public static final long BLOCK_ACTIVITY_STARTS_AFTER_HOME = 159433730L; + Context mContext; /** @@ -1295,6 +1305,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { a.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; a.colorMode = ActivityInfo.COLOR_MODE_DEFAULT; a.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; + a.resizeMode = RESIZE_MODE_UNRESIZEABLE; final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchActivityType(ACTIVITY_TYPE_DREAM); @@ -1594,7 +1605,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void startRecentsActivity(Intent intent, long eventTime, @Nullable IRecentsAnimationRunner recentsAnimationRunner) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "startRecentsActivity()"); final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); @@ -2180,7 +2191,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public RootTaskInfo getFocusedRootTaskInfo() throws RemoteException { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getFocusedRootTaskInfo()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "getFocusedRootTaskInfo()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -2197,7 +2208,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void setFocusedRootTask(int taskId) { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedRootTask()"); + enforceTaskPermission("setFocusedRootTask()"); ProtoLog.d(WM_DEBUG_FOCUS, "setFocusedRootTask: taskId=%d", taskId); final long callingId = Binder.clearCallingIdentity(); try { @@ -2219,7 +2230,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void setFocusedTask(int taskId) { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()"); + enforceTaskPermission("setFocusedTask()"); ProtoLog.d(WM_DEBUG_FOCUS, "setFocusedTask: taskId=%d", taskId); final long callingId = Binder.clearCallingIdentity(); try { @@ -2241,7 +2252,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void restartActivityProcessIfVisible(IBinder activityToken) { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "restartActivityProcess()"); + enforceTaskPermission("restartActivityProcess()"); final long callingId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -2365,7 +2376,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public Rect getTaskBounds(int taskId) { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()"); + enforceTaskPermission("getTaskBounds()"); final long ident = Binder.clearCallingIdentity(); Rect rect = new Rect(); try { @@ -2392,7 +2403,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public ActivityManager.TaskDescription getTaskDescription(int id) { synchronized (mGlobalLock) { enforceCallerIsRecentsOrHasPermission( - MANAGE_ACTIVITY_STACKS, "getTaskDescription()"); + MANAGE_ACTIVITY_TASKS, "getTaskDescription()"); final Task tr = mRootWindowContainer.anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS); if (tr != null) { @@ -2407,7 +2418,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { return setTaskWindowingModeSplitScreenPrimary(taskId, toTop); } - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "setTaskWindowingMode()"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { @@ -2624,8 +2635,35 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { throw new SecurityException(msg); } + /** + * Return true if app switch protection will be handled by background activity launch logic. + */ + boolean getBalAppSwitchesProtectionEnabled() { + return CompatChanges.isChangeEnabled(BLOCK_ACTIVITY_STARTS_AFTER_HOME); + } + + /** + * Return true if app switching is allowed. + */ + boolean getBalAppSwitchesAllowed() { + if (getBalAppSwitchesProtectionEnabled()) { + // Apps no longer able to start BAL again until app switching is resumed. + return mAppSwitchesAllowedTime == 0; + } else { + // Legacy behavior, BAL logic won't block app switching. + return true; + } + } + boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, int callingPid, int callingUid, String name) { + + // Background activity launch logic replaces app switching protection, so allow + // apps to start activity here now. + if (getBalAppSwitchesProtectionEnabled()) { + return true; + } + if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { return true; } @@ -2764,7 +2802,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToRootTask()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "moveTaskToRootTask()"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { @@ -2803,7 +2841,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, boolean toTop) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "setTaskWindowingModeSplitScreenPrimary()"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); @@ -2880,7 +2918,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void removeRootTasksInWindowingModes(int[] windowingModes) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "removeRootTasksInWindowingModes()"); synchronized (mGlobalLock) { @@ -2895,7 +2933,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void removeRootTasksWithActivityTypes(int[] activityTypes) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "removeRootTasksWithActivityTypes()"); synchronized (mGlobalLock) { @@ -2922,7 +2960,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public List<RootTaskInfo> getAllRootTaskInfos() { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllRootTaskInfos()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "getAllRootTaskInfos()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -2935,7 +2973,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public RootTaskInfo getRootTaskInfo(int windowingMode, int activityType) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getRootTaskInfo()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "getRootTaskInfo()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -2948,7 +2986,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public List<RootTaskInfo> getAllRootTaskInfosOnDisplay(int displayId) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "getAllRootTaskInfosOnDisplay()"); final long ident = Binder.clearCallingIdentity(); try { @@ -2963,7 +3001,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public RootTaskInfo getRootTaskInfoOnDisplay(int windowingMode, int activityType, int displayId) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getRootTaskInfoOnDisplay()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "getRootTaskInfoOnDisplay()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -2976,7 +3014,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "cancelRecentsAnimation()"); final long callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { @@ -3004,7 +3042,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void startSystemLockTaskMode(int taskId) { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode"); + enforceTaskPermission("startSystemLockTaskMode"); // This makes inner call to look as if it was initiated by system. final long ident = Binder.clearCallingIdentity(); try { @@ -3035,7 +3073,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void stopSystemLockTaskMode() throws RemoteException { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode"); + enforceTaskPermission("stopSystemLockTaskMode"); stopLockTaskModeInternal(null, true /* isSystemCaller */); } @@ -3369,7 +3407,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean resizeTask(int taskId, Rect bounds, int resizeMode) { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()"); + enforceTaskPermission("resizeTask()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -3543,7 +3581,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** Sets the task stack listener that gets callbacks when a task stack changes. */ @Override public void registerTaskStackListener(ITaskStackListener listener) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "registerTaskStackListener()"); mTaskChangeNotificationController.registerTaskStackListener(listener); } @@ -3551,7 +3589,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** Unregister a task stack listener so that it stops receiving callbacks. */ @Override public void unregisterTaskStackListener(ITaskStackListener listener) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "unregisterTaskStackListener()"); mTaskChangeNotificationController.unregisterTaskStackListener(listener); } @@ -3606,12 +3644,35 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } /** This can be called with or without the global lock held. */ - private void enforceCallerIsRecentsOrHasPermission(String permission, String func) { - if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) { + void enforceCallerIsRecentsOrHasPermission(String permission, String func) { + if (getRecentTasks().isCallerRecents(Binder.getCallingUid())) { + return; + } + + if (permission.equals(MANAGE_ACTIVITY_TASKS) || permission.equals(MANAGE_ACTIVITY_STACKS)) { + enforceTaskPermission(func); + } else { mAmInternal.enforceCallingPermission(permission, func); } } + static void enforceTaskPermission(String func) { + if (checkCallingPermission(MANAGE_ACTIVITY_TASKS) == PackageManager.PERMISSION_GRANTED) { + return; + } + + if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) == PackageManager.PERMISSION_GRANTED) { + Slog.w(TAG, "MANAGE_ACTIVITY_STACKS is deprecated, " + + "please use alternative permission: MANAGE_ACTIVITY_TASKS"); + return; + } + + String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid() + ", uid=" + + Binder.getCallingUid() + " requires android.permission.MANAGE_ACTIVITY_TASKS"; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + @VisibleForTesting int checkGetTasksPermission(String permission, int pid, int uid) { return checkPermission(permission, pid, uid); @@ -3976,7 +4037,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_TASKS, "suppressResizeConfigChanges()"); synchronized (mGlobalLock) { mSuppressResizeConfigChanges = suppress; @@ -3993,7 +4054,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public boolean moveTopActivityToPinnedRootTask(int rootTaskId, Rect bounds) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "moveTopActivityToPinnedRootTask()"); synchronized (mGlobalLock) { if (!mSupportsPictureInPicture) { @@ -4111,13 +4172,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - @Override - public int getMaxNumPictureInPictureActions(IBinder token) { - // Currently, this is a static constant, but later, we may change this to be dependent on - // the context of the activity - return 3; - } - /** * Checks the state of the system and the activity associated with the given {@param token} to * verify that picture-in-picture is supported for that activity. @@ -4155,7 +4209,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } // Truncate the number of actions if necessary - params.truncateActions(getMaxNumPictureInPictureActions(token)); + params.truncateActions(ActivityTaskManager.getMaxNumPictureInPictureActions(mContext)); return r; } @@ -4178,7 +4232,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void resizePrimarySplitScreen(Rect dockedBounds, Rect tempDockedTaskBounds, Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePrimarySplitScreen()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "resizePrimarySplitScreen()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -4216,7 +4270,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void setSplitScreenResizing(boolean resizing) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "setSplitScreenResizing()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -4229,8 +4283,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public IWindowOrganizerController getWindowOrganizerController() { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, - "getWindowOrganizerController()"); + enforceTaskPermission("getWindowOrganizerController()"); return mWindowOrganizerController; } @@ -4371,7 +4424,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void cancelTaskWindowTransition(int taskId) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "cancelTaskWindowTransition()"); final long ident = Binder.clearCallingIdentity(); try { @@ -4645,7 +4698,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME; mLastStopAppSwitchesTime = SystemClock.uptimeMillis(); mDidAppSwitch = false; - getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME); + // If BAL app switching enabled, app switches are blocked not delayed. + if (!getBalAppSwitchesProtectionEnabled()) { + getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME); + } } } @@ -4772,8 +4828,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void clearLaunchParamsForPackages(List<String> packageNames) { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, - "clearLaunchParamsForPackages"); + enforceTaskPermission("clearLaunchParamsForPackages"); synchronized (mGlobalLock) { for (int i = 0; i < packageNames.size(); ++i) { mStackSupervisor.mLaunchParamsPersister.removeRecordForPackage(packageNames.get(i)); @@ -4786,8 +4841,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void requestPictureInPictureMode(IBinder token) throws RemoteException { - mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, - "requestPictureInPictureMode"); + enforceTaskPermission("requestPictureInPictureMode"); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -6881,8 +6935,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) { - mAmInternal.enforceCallingPermission( - MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent"); + enforceTaskPermission("startConfirmDeviceCredentialIntent"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index 5e1a26b91863..ce20dbdb2997 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -397,6 +397,10 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { } void setOrganizer(IDisplayAreaOrganizer organizer) { + setOrganizer(organizer, false /* skipDisplayAreaAppeared */); + } + + void setOrganizer(IDisplayAreaOrganizer organizer, boolean skipDisplayAreaAppeared) { if (mOrganizer == organizer) return; IDisplayAreaOrganizer lastOrganizer = mOrganizer; // Update the new display area organizer before calling sendDisplayAreaVanished since it @@ -404,7 +408,9 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { // about it. mOrganizer = organizer; sendDisplayAreaVanished(lastOrganizer); - sendDisplayAreaAppeared(); + if (!skipDisplayAreaAppeared) { + sendDisplayAreaAppeared(); + } } void sendDisplayAreaAppeared() { diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java index dd92f507a33d..43b9a218d072 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java +++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java @@ -16,21 +16,22 @@ package com.android.server.wm; -import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; - - import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; +import android.content.pm.ParceledListSlice; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.view.SurfaceControl; +import android.window.DisplayAreaAppearedInfo; import android.window.IDisplayAreaOrganizer; import android.window.IDisplayAreaOrganizerController; import com.android.internal.protolog.common.ProtoLog; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerController.Stub { private static final String TAG = "DisplayAreaOrganizerController"; @@ -62,13 +63,14 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl mGlobalLock = atm.mGlobalLock; } - private void enforceStackPermission(String func) { - mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func); + private void enforceTaskPermission(String func) { + mService.enforceTaskPermission(func); } @Override - public void registerOrganizer(IDisplayAreaOrganizer organizer, int feature) { - enforceStackPermission("registerOrganizer()"); + public ParceledListSlice<DisplayAreaAppearedInfo> registerOrganizer( + IDisplayAreaOrganizer organizer, int feature) { + enforceTaskPermission("registerOrganizer()"); final long uid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { @@ -86,12 +88,18 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl } catch (RemoteException e) { // Oh well... } + + final List<DisplayAreaAppearedInfo> displayAreaInfos = new ArrayList<>(); mService.mRootWindowContainer.forAllDisplayAreas((da) -> { if (da.mFeatureId != feature) return; - da.setOrganizer(organizer); + da.setOrganizer(organizer, true /* skipDisplayAreaAppeared */); + displayAreaInfos.add(new DisplayAreaAppearedInfo(da.getDisplayAreaInfo(), + new SurfaceControl(da.getSurfaceControl(), + "DisplayAreaOrganizerController.registerOrganizer"))); }); mOrganizersByFeatureIds.put(feature, organizer); + return new ParceledListSlice<>(displayAreaInfos); } } finally { Binder.restoreCallingIdentity(origId); @@ -100,7 +108,7 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl @Override public void unregisterOrganizer(IDisplayAreaOrganizer organizer) { - enforceStackPermission("unregisterTaskOrganizer()"); + enforceTaskPermission("unregisterTaskOrganizer()"); final long uid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 8da6c813f591..26c5d70a2c45 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5018,6 +5018,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp || windowingMode == WINDOWING_MODE_MULTI_WINDOW); } + static boolean canReuseExistingTask(int windowingMode, int activityType) { + // Existing Tasks can be reused if a new stack will be created anyway, or for the Dream - + // because there can only ever be one DreamActivity. + return alwaysCreateStack(windowingMode, activityType) + || activityType == ACTIVITY_TYPE_DREAM; + } + @Nullable Task getFocusedStack() { return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedStack); @@ -5460,7 +5467,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return; } - if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp) { + if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp + && animatingRecents.isVisible()) { // The recents activity should be going to be invisible (switch to another app or // return to original top). Only clear the top launching record without finishing // the transform immediately because it won't affect display orientation. And before diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index baa26e62b3b5..7a42b0db0c52 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -55,7 +55,6 @@ import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN; -import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; @@ -991,9 +990,7 @@ public class DisplayPolicy { "DisplayPolicy"); } if ((attrs.privateFlags & PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP) != 0) { - mContext.enforcePermission( - android.Manifest.permission.MANAGE_ACTIVITY_STACKS, callingPid, callingUid, - "DisplayPolicy"); + ActivityTaskManagerService.enforceTaskPermission("DisplayPolicy"); } switch (attrs.type) { diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 72ecf6be430d..2ea4b57d9de3 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -16,8 +16,6 @@ package com.android.server.wm; -import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.IInputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; @@ -118,6 +116,10 @@ class DragState { * without having a WM lock. */ volatile boolean mAnimationCompleted = false; + /** + * The display on which the drag is happening. If it goes into a different display this will + * be updated. + */ DisplayContent mDisplayContent; @Nullable private ValueAnimator mAnimator; @@ -308,7 +310,9 @@ class DragState { // Pause rotations before a drag. ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during drag"); - mDisplayContent.getDisplayRotation().pause(); + mService.mRoot.forAllDisplays(dc -> { + dc.getDisplayRotation().pause(); + }); } void tearDown() { @@ -323,7 +327,9 @@ class DragState { // Resume rotations after a drag. ProtoLog.d(WM_DEBUG_ORIENTATION, "Resuming rotation after drag"); - mDisplayContent.getDisplayRotation().resume(); + mService.mRoot.forAllDisplays(dc -> { + dc.getDisplayRotation().resume(); + }); } } @@ -371,9 +377,9 @@ class DragState { Slog.d(TAG_WM, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")"); } - mDisplayContent.forAllWindows(w -> { + mService.mRoot.forAllWindows(w -> { sendDragStartedLocked(w, touchX, touchY, mDataDescription, mData); - }, false /* traverseTopToBottom */ ); + }, false /* traverseTopToBottom */); } /* helper - send a ACTION_DRAG_STARTED event, if the diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java index c49690157c08..e90436ef3b91 100644 --- a/services/core/java/com/android/server/wm/LockTaskController.java +++ b/services/core/java/com/android/server/wm/LockTaskController.java @@ -430,7 +430,7 @@ public class LockTaskController { // instead of the app calling startLockTaskMode. In this case // {@link Task.mLockTaskUid} will be 0, so we compare the callingUid to the // {@link Task.effectiveUid} instead. Also caller with - // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task. + // {@link MANAGE_ACTIVITY_TASKS} can stop any lock task. if (callingUid != task.mLockTaskUid && (task.mLockTaskUid != 0 || callingUid != task.effectiveUid)) { throw new SecurityException("Invalid uid, expected " + task.mLockTaskUid diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index c1e518b8b82c..04b303053d8f 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -55,6 +55,7 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_L import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 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.dumpHistoryList; import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; @@ -2779,7 +2780,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (allowDelay) { result &= stack.goToSleepIfPossible(shuttingDown); } else { - stack.goToSleep(); + stack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + !PRESERVE_WINDOWS); } } return result; diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index 7ed22a1f7777..1a27b1bc4a6e 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -181,9 +181,25 @@ class ScreenRotationAnimation { mSurfaceRotationAnimationController = new SurfaceRotationAnimationController(); // Check whether the current screen contains any secure content. - final boolean isSecure = displayContent.hasSecureWindowOnScreen(); + boolean isSecure = displayContent.hasSecureWindowOnScreen(); + final int displayId = displayContent.getDisplayId(); final SurfaceControl.Transaction t = mService.mTransactionFactory.get(); + try { + SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = + mService.mDisplayManagerInternal.systemScreenshot(displayId); + if (screenshotBuffer == null) { + Slog.w(TAG, "Unable to take screenshot of display " + displayId); + return; + } + + // If the screenshot contains secure layers, we have to make sure the + // screenshot surface we display it in also has FLAG_SECURE so that + // the user can not screenshot secure layers via the screenshot surface. + if (screenshotBuffer.containsSecureLayers()) { + isSecure = true; + } + mBackColorSurface = displayContent.makeChildSurface(null) .setName("BackColorSurface") .setColorLayer() @@ -203,51 +219,39 @@ class ScreenRotationAnimation { .setCallsite("ScreenRotationAnimation") .build(); - // Capture a screenshot into the surface we just created. - final int displayId = displayContent.getDisplayId(); final Surface surface = mService.mSurfaceFactory.get(); - // In case display bounds change, screenshot buffer and surface may mismatch so set a - // scaling mode. + // In case display bounds change, screenshot buffer and surface may mismatch so + // set a scaling mode. surface.copyFrom(mScreenshotLayer); surface.setScalingMode(Surface.SCALING_MODE_SCALE_TO_WINDOW); - SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = - mService.mDisplayManagerInternal.systemScreenshot(displayId); - if (screenshotBuffer != null) { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, - "ScreenRotationAnimation#getMedianBorderLuma"); - mStartLuma = RotationAnimationUtils.getMedianBorderLuma( - screenshotBuffer.getHardwareBuffer(), screenshotBuffer.getColorSpace()); - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - try { - surface.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(), - screenshotBuffer.getColorSpace()); - } catch (RuntimeException e) { - Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage()); - } - // If the screenshot contains secure layers, we have to make sure the - // screenshot surface we display it in also has FLAG_SECURE so that - // the user can not screenshot secure layers via the screenshot surface. - if (screenshotBuffer.containsSecureLayers()) { - t.setSecure(mScreenshotLayer, true); - } - t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE); - t.reparent(mBackColorSurface, displayContent.getSurfaceControl()); - t.setLayer(mBackColorSurface, -1); - t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma}); - t.setAlpha(mBackColorSurface, 1); - t.show(mScreenshotLayer); - t.show(mBackColorSurface); - } else { - Slog.w(TAG, "Unable to take screenshot of display " + displayId); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, + "ScreenRotationAnimation#getMedianBorderLuma"); + mStartLuma = RotationAnimationUtils.getMedianBorderLuma( + screenshotBuffer.getHardwareBuffer(), screenshotBuffer.getColorSpace()); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + try { + surface.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(), + screenshotBuffer.getColorSpace()); + } catch (RuntimeException e) { + Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage()); } + + t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE); + t.reparent(mBackColorSurface, displayContent.getSurfaceControl()); + t.setLayer(mBackColorSurface, -1); + t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma}); + t.setAlpha(mBackColorSurface, 1); + t.show(mScreenshotLayer); + t.show(mBackColorSurface); surface.destroy(); + } catch (OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate freeze surface", e); } ProtoLog.i(WM_SHOW_SURFACE_ALLOC, - " FREEZE %s: CREATE", mScreenshotLayer); + " FREEZE %s: CREATE", mScreenshotLayer); setRotation(t, realOriginalRotation); t.apply(); } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 72edb86283d2..6fbd35164874 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -20,7 +20,12 @@ import static android.Manifest.permission.DEVICE_POWER; import static android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; +import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY; +import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT; +import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK; +import static android.content.Intent.EXTRA_SHORTCUT_ID; +import static android.content.Intent.EXTRA_TASK_ID; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; @@ -49,6 +54,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.Trace; import android.os.UserHandle; +import android.text.TextUtils; import android.util.ArraySet; import android.util.MergedConfiguration; import android.util.Slog; @@ -297,18 +303,25 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { */ @VisibleForTesting public void validateAndResolveDragMimeTypeExtras(ClipData data, int callingUid) { + if (Binder.getCallingUid() == Process.SYSTEM_UID) { + throw new IllegalStateException("Need to validate before calling identify is cleared"); + } final ClipDescription desc = data != null ? data.getDescription() : null; if (desc == null) { return; } // Ensure that only one of the app mime types are set final boolean hasActivity = desc.hasMimeType(MIMETYPE_APPLICATION_ACTIVITY); - int appMimeTypeCount = (hasActivity ? 1 : 0); + final boolean hasShortcut = desc.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT); + final boolean hasTask = desc.hasMimeType(MIMETYPE_APPLICATION_TASK); + int appMimeTypeCount = (hasActivity ? 1 : 0) + + (hasShortcut ? 1 : 0) + + (hasTask ? 1 : 0); if (appMimeTypeCount == 0) { return; } else if (appMimeTypeCount > 1) { throw new IllegalArgumentException("Can not specify more than one of activity, " - + "or task mime types"); + + "shortcut, or task mime types"); } // Ensure that data is provided and that they are intents if (data.getItemCount() == 0) { @@ -344,6 +357,28 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } finally { Binder.restoreCallingIdentity(origId); } + } else if (hasShortcut) { + mService.mAtmService.enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS, + "performDrag"); + for (int i = 0; i < data.getItemCount(); i++) { + final Intent intent = data.getItemAt(i).getIntent(); + final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); + if (!intent.hasExtra(EXTRA_SHORTCUT_ID) + || TextUtils.isEmpty(intent.getStringExtra(EXTRA_SHORTCUT_ID)) + || user == null) { + throw new IllegalArgumentException("Clip item must include the shortcut id and " + + "the user to launch for."); + } + } + } else if (hasTask) { + mService.mAtmService.enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS, + "performDrag"); + for (int i = 0; i < data.getItemCount(); i++) { + final Intent intent = data.getItemAt(i).getIntent(); + if (intent.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID) == INVALID_TASK_ID) { + throw new IllegalArgumentException("Clip item must include the task id."); + } + } } } diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java index d9365c5d0666..6f434e05c800 100644 --- a/services/core/java/com/android/server/wm/SurfaceFreezer.java +++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java @@ -137,6 +137,7 @@ class SurfaceFreezer { new SurfaceControl.LayerCaptureArgs.Builder(target) .setSourceCrop(cropBounds) .setCaptureSecureLayers(true) + .setAllowProtected(true) .build(); return SurfaceControl.captureLayers(captureArgs); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 557c92e9704e..5bc5b47d5cfc 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -149,6 +149,7 @@ import static com.android.server.wm.WindowContainerChildProto.TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static com.android.server.wm.WindowManagerService.MIN_TASK_LETTERBOX_ASPECT_RATIO; import static com.android.server.wm.WindowManagerService.dipToPixel; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM; @@ -528,6 +529,11 @@ class Task extends WindowContainer<WindowContainer> { // {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag of the root activity. boolean mSupportsPictureInPicture; + // Activity bounds if this task or its top activity is presented in letterbox mode and + // {@code null} otherwise. + @Nullable + private Rect mLetterboxActivityBounds; + // Whether the task is currently being drag-resized private boolean mDragResizing; private int mDragResizeMode; @@ -790,6 +796,10 @@ class Task extends WindowContainer<WindowContainer> { */ boolean mTaskAppearedSent; + // If the sending of the task appear signal should be deferred until this flag is set back to + // false. + private boolean mDeferTaskAppear; + /** * This task was created by the task organizer which has the following implementations. * <ul> @@ -802,14 +812,20 @@ class Task extends WindowContainer<WindowContainer> { @VisibleForTesting boolean mCreatedByOrganizer; + // Tracking cookie for the creation of this task. + IBinder mLaunchCookie; + /** * Don't use constructor directly. Use {@link TaskDisplayArea#createStackUnchecked()} instead. */ - Task(ActivityTaskManagerService atmService, int id, int activityType, - ActivityInfo info, Intent intent, boolean createdByOrganizer) { + Task(ActivityTaskManagerService atmService, int id, int activityType, ActivityInfo info, + Intent intent, boolean createdByOrganizer, boolean deferTaskAppear, + IBinder launchCookie) { this(atmService, id, info, intent, null /*voiceSession*/, null /*voiceInteractor*/, null /*taskDescription*/, null /*stack*/); mCreatedByOrganizer = createdByOrganizer; + mLaunchCookie = launchCookie; + mDeferTaskAppear = deferTaskAppear; setActivityType(activityType); } @@ -2821,16 +2837,25 @@ class Task extends WindowContainer<WindowContainer> { int windowingMode = getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode(); + final int parentWindowingMode = newParentConfig.windowConfiguration.getWindowingMode(); // Resolve override windowing mode to fullscreen for home task (even on freeform // display), or split-screen if in split-screen mode. if (getActivityType() == ACTIVITY_TYPE_HOME && windowingMode == WINDOWING_MODE_UNDEFINED) { - final int parentWindowingMode = newParentConfig.windowConfiguration.getWindowingMode(); windowingMode = WindowConfiguration.isSplitScreenWindowingMode(parentWindowingMode) ? parentWindowingMode : WINDOWING_MODE_FULLSCREEN; getResolvedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode); } + // Do not allow non-resizable non-pinned tasks to be in a multi-window mode - they should + // use their parent's windowing mode, or fullscreen. + if (!isResizeable() && windowingMode != WINDOWING_MODE_PINNED + && WindowConfiguration.inMultiWindowMode(windowingMode)) { + windowingMode = WindowConfiguration.inMultiWindowMode(parentWindowingMode) + ? WINDOWING_MODE_FULLSCREEN : parentWindowingMode; + getResolvedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode); + } + if (isLeafTask()) { resolveLeafOnlyOverrideConfigs(newParentConfig, mTmpBounds /* previousBounds */); } @@ -2921,13 +2946,35 @@ class Task extends WindowContainer<WindowContainer> { final int parentWidth = parentBounds.width(); final int parentHeight = parentBounds.height(); - final float aspect = ((float) parentHeight) / parentWidth; + float aspect = Math.max(parentWidth, parentHeight) + / (float) Math.min(parentWidth, parentHeight); + + // Adjust the Task letterbox bounds to fit the app request aspect ratio in order to use the + // extra available space. + if (refActivity != null) { + final float maxAspectRatio = refActivity.info.maxAspectRatio; + final float minAspectRatio = refActivity.info.minAspectRatio; + if (aspect > maxAspectRatio && maxAspectRatio != 0) { + aspect = maxAspectRatio; + } else if (aspect < minAspectRatio) { + aspect = minAspectRatio; + } + } + + // Override from config_letterboxAspectRatio or via ADB with set-letterbox-aspect-ratio. + final float letterboxAspectRatioOverride = mWmService.getTaskLetterboxAspectRatio(); + // Activity min/max aspect ratio restrictions will be respected by the activity-level + // letterboxing (size-compat mode). Therefore this override can control the maximum screen + // area that can be occupied by the app in the letterbox mode. + aspect = letterboxAspectRatioOverride > MIN_TASK_LETTERBOX_ASPECT_RATIO + ? letterboxAspectRatioOverride : aspect; + if (forcedOrientation == ORIENTATION_LANDSCAPE) { - final int height = (int) (parentWidth / aspect); + final int height = (int) Math.rint(parentWidth / aspect); final int top = parentBounds.centerY() - height / 2; outBounds.set(parentBounds.left, top, parentBounds.right, top + height); } else { - final int width = (int) (parentHeight * aspect); + final int width = (int) Math.rint(parentHeight / aspect); final int left = parentBounds.centerX() - width / 2; outBounds.set(left, parentBounds.top, left + width, parentBounds.bottom); } @@ -3333,7 +3380,9 @@ class Task extends WindowContainer<WindowContainer> { } boolean isResizeable(boolean checkSupportsPip) { - return (mAtmService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode) + final boolean forceResizable = mAtmService.mForceResizableActivities + && getActivityType() == ACTIVITY_TYPE_STANDARD; + return (forceResizable || ActivityInfo.isResizeableMode(mResizeMode) || (checkSupportsPip && mSupportsPictureInPicture)); } @@ -4058,11 +4107,18 @@ class Task extends WindowContainer<WindowContainer> { info.resizeMode = top != null ? top.mResizeMode : mResizeMode; info.topActivityType = top.getActivityType(); info.isResizeable = isResizeable(); + // Don't query getTopNonFinishingActivity().getBounds() directly because when fillTaskInfo + // is triggered for the first time after activities change, getBounds() may return non final + // bounds, e.g. fullscreen bounds instead of letterboxed bounds. To work around this, + // assigning bounds from ActivityRecord#layoutLetterbox when they are ready. + info.letterboxActivityBounds = Rect.copyOrNull(mLetterboxActivityBounds); + info.positionInParent = getRelativePosition(); info.pictureInPictureParams = getPictureInPictureParams(); info.topActivityInfo = mReuseActivitiesReport.top != null ? mReuseActivitiesReport.top.info : null; + info.addLaunchCookie(mLaunchCookie); forAllActivities(r -> { info.addLaunchCookie(r.mLaunchCookie); }); @@ -4076,6 +4132,21 @@ class Task extends WindowContainer<WindowContainer> { ? null : rootActivity.pictureInPictureArgs; } + void maybeUpdateLetterboxBounds( + ActivityRecord activityRecord, @Nullable Rect letterboxActivityBounds) { + if (isOrganized() + && mReuseActivitiesReport.top == activityRecord + // Want to force update only if letterbox bounds have changed. + && !Objects.equals( + mLetterboxActivityBounds, + letterboxActivityBounds)) { + mLetterboxActivityBounds = Rect.copyOrNull(letterboxActivityBounds); + // Forcing update to reduce visual jank during the transition. + mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged( + this, /* force= */ true); + } + } + /** * Returns a {@link TaskInfo} with information from this task. */ @@ -4817,6 +4888,13 @@ class Task extends WindowContainer<WindowContainer> { return mHasBeenVisible; } + void setDeferTaskAppear(boolean deferTaskAppear) { + mDeferTaskAppear = deferTaskAppear; + if (!mDeferTaskAppear) { + sendTaskAppeared(); + } + } + /** In the case that these conditions are true, we want to send the Task to the organizer: * 1. An organizer has been set * 2. The Task was created by the organizer @@ -4831,6 +4909,10 @@ class Task extends WindowContainer<WindowContainer> { return false; } + if (mDeferTaskAppear) { + return false; + } + if (mCreatedByOrganizer) { return true; } @@ -5264,14 +5346,12 @@ class Task extends WindowContainer<WindowContainer> { taskDisplayArea.moveHomeStackToFront(reason + " returnToHome"); } - if (isRootTask()) { - taskDisplayArea.positionChildAt(POSITION_TOP, this, false /* includingParents */, - reason); - } + final Task lastFocusedTask = isRootTask() ? taskDisplayArea.getFocusedStack() : null; if (task == null) { task = this; } task.getParent().positionChildAt(POSITION_TOP, task, true /* includingParents */); + taskDisplayArea.updateLastFocusedRootTask(lastFocusedTask, reason); } /** @@ -5294,8 +5374,9 @@ class Task extends WindowContainer<WindowContainer> { if (parentTask != null) { parentTask.moveToBack(reason, this); } else { - displayArea.positionChildAt(POSITION_BOTTOM, this, false /*includingParents*/, - reason); + final Task lastFocusedTask = displayArea.getFocusedStack(); + displayArea.positionChildAt(POSITION_BOTTOM, this, false /*includingParents*/); + displayArea.updateLastFocusedRootTask(lastFocusedTask, reason); } if (task != null && task != this) { positionChildAtBottom(task); @@ -5342,8 +5423,6 @@ class Task extends WindowContainer<WindowContainer> { } void awakeFromSleepingLocked() { - // Ensure activities are no longer sleeping. - forAllActivities((Consumer<ActivityRecord>) (r) -> r.setSleeping(false)); if (mPausingActivity != null) { Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause"); mPausingActivity.activityPaused(true); @@ -5397,27 +5476,13 @@ class Task extends WindowContainer<WindowContainer> { } if (shouldSleep) { - goToSleep(); + ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + !PRESERVE_WINDOWS); } return shouldSleep; } - void goToSleep() { - // Make sure all visible activities are now sleeping. This will update the activity's - // visibility and onStop() will be called. - forAllActivities((r) -> { - if (r.isState(STARTED, RESUMED, PAUSING, PAUSED, STOPPING, STOPPED)) { - r.setSleeping(true); - } - }); - - // Ensure visibility after updating sleep states without updating configuration, - // as activities are about to be sent to sleep. - ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, - !PRESERVE_WINDOWS); - } - private boolean containsActivityFromStack(List<ActivityRecord> rs) { for (ActivityRecord r : rs) { if (r.getRootTask() == this) { @@ -5714,8 +5779,9 @@ class Task extends WindowContainer<WindowContainer> { boolean preserveWindows, boolean notifyClients) { mStackSupervisor.beginActivityVisibilityUpdate(); try { - mEnsureActivitiesVisibleHelper.process(starting, configChanges, preserveWindows, - notifyClients); + forAllLeafTasks(task -> task.mEnsureActivitiesVisibleHelper.process( + starting, configChanges, preserveWindows, notifyClients), + true /* traverseTopToBottom */); if (mTranslucentActivityWaiting != null && mUndrawnActivitiesBelowTopTranslucent.isEmpty()) { @@ -5902,6 +5968,8 @@ class Task extends WindowContainer<WindowContainer> { if (mResumedActivity == next && next.isState(RESUMED) && taskDisplayArea.getWindowingMode() != WINDOWING_MODE_FREEFORM && taskDisplayArea.allResumedActivitiesComplete()) { + // The activity may be waiting for stop, but that is no longer appropriate for it. + mStackSupervisor.mStoppingActivities.remove(next); // Make sure we have executed any pending transitions, since there // should be nothing left to do at this point. executeAppTransition(options); @@ -5948,7 +6016,6 @@ class Task extends WindowContainer<WindowContainer> { // The activity may be waiting for stop, but that is no longer // appropriate for it. mStackSupervisor.mStoppingActivities.remove(next); - next.setSleeping(false); if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next); @@ -6221,7 +6288,6 @@ class Task extends WindowContainer<WindowContainer> { EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next), next.getTask().mTaskId, next.shortComponentName); - next.setSleeping(false); mAtmService.getAppWarningsLocked().onResumeActivity(next); next.app.setPendingUiCleanAndForceProcessStateUpTo(mAtmService.mTopProcessState); next.clearOptionsLocked(); @@ -6822,13 +6888,10 @@ class Task extends WindowContainer<WindowContainer> { // get calculated incorrectly. mDisplayContent.deferUpdateImeTarget(); - // Shift all activities with this task up to the top - // of the stack, keeping them in the same internal order. - positionChildAtTop(tr); - // Don't refocus if invisible to current user final ActivityRecord top = tr.getTopNonFinishingActivity(); if (top == null || !top.okToShowLocked()) { + positionChildAtTop(tr); if (top != null) { mStackSupervisor.mRecentTasks.add(top.getTask()); } @@ -6836,20 +6899,15 @@ class Task extends WindowContainer<WindowContainer> { return; } - // Set focus to the top running activity of this stack. - final ActivityRecord r = topRunningActivity(); - if (r != null) { - r.moveFocusableActivityToTop(reason); - } + // Set focus to the top running activity of this task and move all its parents to top. + top.moveFocusableActivityToTop(reason); if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr); if (noAnimation) { mDisplayContent.prepareAppTransitionOld(TRANSIT_OLD_NONE, false /* alwaysKeepCurrent */); mDisplayContent.prepareAppTransition(TRANSIT_NONE); - if (r != null) { - mStackSupervisor.mNoAnimActivities.add(r); - } + mStackSupervisor.mNoAnimActivities.add(top); ActivityOptions.abort(options); } else { updateTransitLocked(TRANSIT_OLD_TASK_TO_FRONT, TRANSIT_TO_FRONT, @@ -7188,7 +7246,7 @@ class Task extends WindowContainer<WindowContainer> { ActivityRecord source, ActivityOptions options) { Task task; - if (DisplayContent.alwaysCreateStack(getWindowingMode(), getActivityType())) { + if (DisplayContent.canReuseExistingTask(getWindowingMode(), getActivityType())) { // This stack will only contain one task, so just return itself since all stacks ara now // tasks and all tasks are now stacks. task = reuseAsLeafTask(voiceSession, voiceInteractor, intent, info, activity); @@ -7453,6 +7511,12 @@ class Task extends WindowContainer<WindowContainer> { outPos.y -= outset; } + private Point getRelativePosition() { + Point position = new Point(); + getRelativePosition(position); + return position; + } + boolean shouldIgnoreInput() { if (inSplitScreenPrimaryWindowingMode() && !isFocusable()) { return true; diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 9392666fbf54..e7213192dfd3 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -50,6 +50,7 @@ import android.app.WindowConfiguration; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.os.IBinder; import android.os.UserHandle; import android.util.IntArray; import android.util.Slog; @@ -334,29 +335,6 @@ final class TaskDisplayArea extends DisplayArea<Task> { return true; } - void positionChildAt(int position, Task child, boolean includingParents, - String updateLastFocusedTaskReason) { - final Task prevFocusedTask = updateLastFocusedTaskReason != null ? getFocusedStack() : null; - - positionChildAt(position, child, includingParents); - - if (updateLastFocusedTaskReason == null) { - return; - } - - final Task currentFocusedStack = getFocusedStack(); - if (currentFocusedStack == prevFocusedTask) { - return; - } - - mLastFocusedStack = prevFocusedTask; - EventLogTags.writeWmFocusedStack(mRootWindowContainer.mCurrentUser, - mDisplayContent.mDisplayId, - currentFocusedStack == null ? -1 : currentFocusedStack.getRootTaskId(), - mLastFocusedStack == null ? -1 : mLastFocusedStack.getRootTaskId(), - updateLastFocusedTaskReason); - } - @Override void positionChildAt(int position, Task child, boolean includingParents) { final boolean moveToTop = position >= getChildCount() - 1; @@ -996,6 +974,13 @@ final class TaskDisplayArea extends DisplayArea<Task> { false /* createdByOrganizer */); } + Task createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info, + Intent intent, boolean createdByOrganizer) { + return createStack(windowingMode, activityType, onTop, null /* info */, null /* intent */, + false /* createdByOrganizer */ , false /* deferTaskAppear */, + null /* launchCookie */); + } + /** * Creates a stack matching the input windowing mode and activity type on this display. * @@ -1013,10 +998,14 @@ final class TaskDisplayArea extends DisplayArea<Task> { * @param intent The intent that started this task. * @param createdByOrganizer @{code true} if this is created by task organizer, @{code false} * otherwise. + * @param deferTaskAppear @{code true} if the task appeared signal should be deferred. + * @param launchCookie Launch cookie used for tracking/association of the task we are + * creating. * @return The newly created stack. */ Task createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info, - Intent intent, boolean createdByOrganizer) { + Intent intent, boolean createdByOrganizer, boolean deferTaskAppear, + IBinder launchCookie) { if (activityType == ACTIVITY_TYPE_UNDEFINED && !createdByOrganizer) { // Can't have an undefined stack type yet...so re-map to standard. Anyone that wants // anything else should be passing it in anyways...except for the task organizer. @@ -1048,7 +1037,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { final int stackId = getNextStackId(); return createStackUnchecked(windowingMode, activityType, stackId, onTop, info, intent, - createdByOrganizer); + createdByOrganizer, deferTaskAppear, launchCookie); } /** @return the root task to create the next task in. */ @@ -1078,8 +1067,9 @@ final class TaskDisplayArea extends DisplayArea<Task> { } @VisibleForTesting - Task createStackUnchecked(int windowingMode, int activityType, int stackId, - boolean onTop, ActivityInfo info, Intent intent, boolean createdByOrganizer) { + Task createStackUnchecked(int windowingMode, int activityType, int stackId, boolean onTop, + ActivityInfo info, Intent intent, boolean createdByOrganizer, boolean deferTaskAppear, + IBinder launchCookie) { if (windowingMode == WINDOWING_MODE_PINNED && activityType != ACTIVITY_TYPE_STANDARD) { throw new IllegalArgumentException("Stack with windowing mode cannot with non standard " + "activity type."); @@ -1097,7 +1087,7 @@ final class TaskDisplayArea extends DisplayArea<Task> { } final Task stack = new Task(mAtmService, stackId, activityType, - info, intent, createdByOrganizer); + info, intent, createdByOrganizer, deferTaskAppear, launchCookie); if (launchRootTask != null) { launchRootTask.addChild(stack, onTop ? POSITION_TOP : POSITION_BOTTOM); if (onTop) { @@ -1189,6 +1179,24 @@ final class TaskDisplayArea extends DisplayArea<Task> { return mLastFocusedStack; } + void updateLastFocusedRootTask(Task prevFocusedTask, String updateLastFocusedTaskReason) { + if (updateLastFocusedTaskReason == null) { + return; + } + + final Task currentFocusedTask = getFocusedStack(); + if (currentFocusedTask == prevFocusedTask) { + return; + } + + mLastFocusedStack = prevFocusedTask; + EventLogTags.writeWmFocusedStack(mRootWindowContainer.mCurrentUser, + mDisplayContent.mDisplayId, + currentFocusedTask == null ? -1 : currentFocusedTask.getRootTaskId(), + mLastFocusedStack == null ? -1 : mLastFocusedStack.getRootTaskId(), + updateLastFocusedTaskReason); + } + boolean allResumedActivitiesComplete() { for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityRecord r = getStackAt(stackNdx).getResumedActivity(); diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 6504f00905e7..2c39c2b4a98e 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -16,7 +16,6 @@ package com.android.server.wm; -import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; @@ -53,6 +52,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import java.util.WeakHashMap; import java.util.function.Consumer; @@ -155,9 +155,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } void onTaskInfoChanged(Task task, ActivityManager.RunningTaskInfo taskInfo) { - if (!task.mCreatedByOrganizer && !task.mTaskAppearedSent) { - // Skip if the task has not yet received taskAppeared(), except for tasks created - // by the organizer that don't receive that signal + if (!task.mTaskAppearedSent) { + // Skip if the task has not yet received taskAppeared(). return; } ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task info changed taskId=%d", task.mTaskId); @@ -178,9 +177,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { void onBackPressedOnTaskRoot(Task task) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task back pressed on root taskId=%d", task.mTaskId); - if (!task.mCreatedByOrganizer && !task.mTaskAppearedSent) { - // Skip if the task has not yet received taskAppeared(), except for tasks created - // by the organizer that don't receive that signal + if (!task.mTaskAppearedSent) { + // Skip if the task has not yet received taskAppeared(). return; } if (!task.isOrganized()) { @@ -294,8 +292,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mGlobalLock = atm.mGlobalLock; } - private void enforceStackPermission(String func) { - mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func); + private void enforceTaskPermission(String func) { + mService.enforceTaskPermission(func); } /** @@ -311,7 +309,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { */ @Override public ParceledListSlice<TaskAppearedInfo> registerTaskOrganizer(ITaskOrganizer organizer) { - enforceStackPermission("registerTaskOrganizer()"); + enforceTaskPermission("registerTaskOrganizer()"); final int uid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { @@ -356,7 +354,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { @Override public void unregisterTaskOrganizer(ITaskOrganizer organizer) { - enforceStackPermission("unregisterTaskOrganizer()"); + enforceTaskPermission("unregisterTaskOrganizer()"); final int uid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { @@ -401,33 +399,42 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } @Override - public RunningTaskInfo createRootTask(int displayId, int windowingMode) { - enforceStackPermission("createRootTask()"); + public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) { + enforceTaskPermission("createRootTask()"); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId); if (display == null) { - return null; + ProtoLog.e(WM_DEBUG_WINDOW_ORGANIZER, + "createRootTask unknown displayId=%d", displayId); + return; } - ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Create root task displayId=%d winMode=%d", - displayId, windowingMode); - final Task task = display.getDefaultTaskDisplayArea().createStack(windowingMode, - ACTIVITY_TYPE_UNDEFINED, false /* onTop */, null /* info */, new Intent(), - true /* createdByOrganizer */); - RunningTaskInfo out = task.getTaskInfo(); - mLastSentTaskInfos.put(task, out); - return out; + createRootTask(display, windowingMode, launchCookie); } } finally { Binder.restoreCallingIdentity(origId); } } + @VisibleForTesting + Task createRootTask(DisplayContent display, int windowingMode, @Nullable IBinder launchCookie) { + ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Create root task displayId=%d winMode=%d", + display.mDisplayId, windowingMode); + // We want to defer the task appear signal until the task is fully created and attached to + // to the hierarchy so that the complete starting configuration is in the task info we send + // over to the organizer. + final Task task = display.getDefaultTaskDisplayArea().createStack(windowingMode, + ACTIVITY_TYPE_UNDEFINED, false /* onTop */, null /* info */, new Intent(), + true /* createdByOrganizer */, true /* deferTaskAppear */, launchCookie); + task.setDeferTaskAppear(false /* deferTaskAppear */); + return task; + } + @Override public boolean deleteRootTask(WindowContainerToken token) { - enforceStackPermission("deleteRootTask()"); + enforceTaskPermission("deleteRootTask()"); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -475,6 +482,12 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { boolean changed = lastInfo == null || mTmpTaskInfo.topActivityType != lastInfo.topActivityType || mTmpTaskInfo.isResizeable != lastInfo.isResizeable + || !Objects.equals( + mTmpTaskInfo.letterboxActivityBounds, + lastInfo.letterboxActivityBounds) + || !Objects.equals( + mTmpTaskInfo.positionInParent, + lastInfo.positionInParent) || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams || mTmpTaskInfo.getConfiguration().windowConfiguration.getWindowingMode() != lastInfo.getConfiguration().windowConfiguration.getWindowingMode() @@ -515,7 +528,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { @Override public WindowContainerToken getImeTarget(int displayId) { - enforceStackPermission("getImeTarget()"); + enforceTaskPermission("getImeTarget()"); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -538,7 +551,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { @Override public void setLaunchRoot(int displayId, @Nullable WindowContainerToken token) { - enforceStackPermission("setLaunchRoot()"); + enforceTaskPermission("setLaunchRoot()"); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -572,7 +585,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { @Override public List<RunningTaskInfo> getChildTasks(WindowContainerToken parent, @Nullable int[] activityTypes) { - enforceStackPermission("getChildTasks()"); + enforceTaskPermission("getChildTasks()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -613,7 +626,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { @Override public List<RunningTaskInfo> getRootTasks(int displayId, @Nullable int[] activityTypes) { - enforceStackPermission("getRootTasks()"); + enforceTaskPermission("getRootTasks()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -643,7 +656,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { @Override public void setInterceptBackPressedOnTaskRoot(WindowContainerToken token, boolean interceptBackPressed) { - enforceStackPermission("setInterceptBackPressedOnTaskRoot()"); + enforceTaskPermission("setInterceptBackPressedOnTaskRoot()"); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 0585679f7fbb..01d628b48a27 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -19,7 +19,6 @@ package com.android.server.wm; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; import static android.Manifest.permission.INPUT_CONSUMER; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; -import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.MANAGE_APP_TOKENS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS; @@ -153,6 +152,7 @@ import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; +import android.content.pm.TestUtilityService; import android.content.res.Configuration; import android.content.res.TypedArray; import android.database.ContentObserver; @@ -453,6 +453,14 @@ public class WindowManagerService extends IWindowManager.Stub /** System UI can create more window context... */ private static final int SYSTEM_UI_MULTIPLIER = 2; + /** + * Override of task letterbox aspect ratio that is set via ADB with + * set-task-letterbox-aspect-ratio or via {@link + * com.android.internal.R.dimen.config_taskLetterboxAspectRatio} will be ignored + * if it is <= this value. + */ + static final float MIN_TASK_LETTERBOX_ASPECT_RATIO = 1.0f; + final WindowManagerConstants mConstants; final WindowTracing mWindowTracing; @@ -564,6 +572,7 @@ public class WindowManagerService extends IWindowManager.Stub final AppOpsManager mAppOps; final PackageManagerInternal mPmInternal; + private final TestUtilityService mTestUtilityService; final DisplayWindowSettings mDisplayWindowSettings; @@ -960,6 +969,10 @@ public class WindowManagerService extends IWindowManager.Stub private boolean mAnimationsDisabled = false; boolean mPointerLocationEnabled = false; + // Aspect ratio of task level letterboxing, values <= MIN_TASK_LETTERBOX_ASPECT_RATIO will be + // ignored. + private float mTaskLetterboxAspectRatio; + final InputManagerService mInputManager; final DisplayManagerInternal mDisplayManagerInternal; final DisplayManager mDisplayManager; @@ -1188,6 +1201,8 @@ public class WindowManagerService extends IWindowManager.Stub com.android.internal.R.bool.config_perDisplayFocusEnabled); mAssistantOnTopOfDream = context.getResources().getBoolean( com.android.internal.R.bool.config_assistantOnTopOfDream); + mTaskLetterboxAspectRatio = context.getResources().getFloat( + com.android.internal.R.dimen.config_taskLetterboxAspectRatio); mInputManager = inputManager; // Must be before createDisplayContentLocked. mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); @@ -1265,6 +1280,7 @@ public class WindowManagerService extends IWindowManager.Stub mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener); mPmInternal = LocalServices.getService(PackageManagerInternal.class); + mTestUtilityService = LocalServices.getService(TestUtilityService.class); final IntentFilter suspendPackagesFilter = new IntentFilter(); suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED); @@ -3752,6 +3768,53 @@ public class WindowManagerService extends IWindowManager.Stub } } + /** + * Overrides the aspect ratio of task level letterboxing. If given value is <= {@link + * #MIN_TASK_LETTERBOX_ASPECT_RATIO}, both it and a value of {@link + * com.android.internal.R.dimen.config_taskLetterboxAspectRatio} will be ignored and + * the framework implementation will be used to determine the aspect ratio. + */ + void setTaskLetterboxAspectRatio(float aspectRatio) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + mTaskLetterboxAspectRatio = aspectRatio; + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + /** + * Resets the aspect ratio of task level letterboxing to {@link + * com.android.internal.R.dimen.config_taskLetterboxAspectRatio}. + */ + void resetTaskLetterboxAspectRatio() { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + mTaskLetterboxAspectRatio = mContext.getResources().getFloat( + com.android.internal.R.dimen.config_taskLetterboxAspectRatio); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + /** + * Gets the aspect ratio of task level letterboxing. + */ + float getTaskLetterboxAspectRatio() { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + return mTaskLetterboxAspectRatio; + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + @Override public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) { mAtmInternal.enforceCallerIsRecentsOrHasPermission( @@ -3953,10 +4016,7 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void setDisplayWindowRotationController(IDisplayWindowRotationController controller) { - if (mContext.checkCallingOrSelfPermission(MANAGE_ACTIVITY_STACKS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Must hold permission " + MANAGE_ACTIVITY_STACKS); - } + mAtmService.enforceTaskPermission("setDisplayWindowRotationController"); try { synchronized (mGlobalLock) { if (mDisplayRotationController != null) { @@ -4225,10 +4285,7 @@ public class WindowManagerService extends IWindowManager.Stub /** Registers a hierarchy listener that gets callbacks when the hierarchy changes. */ @Override public void registerDisplayWindowListener(IDisplayWindowListener listener) { - if (mContext.checkCallingOrSelfPermission(MANAGE_ACTIVITY_STACKS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Must hold permission " + MANAGE_ACTIVITY_STACKS); - } + mAtmService.enforceTaskPermission("registerDisplayWindowListener"); final long ident = Binder.clearCallingIdentity(); try { mDisplayNotificationController.registerListener(listener); @@ -4240,10 +4297,7 @@ public class WindowManagerService extends IWindowManager.Stub /** Unregister a hierarchy listener so that it stops receiving callbacks. */ @Override public void unregisterDisplayWindowListener(IDisplayWindowListener listener) { - if (mContext.checkCallingOrSelfPermission(MANAGE_ACTIVITY_STACKS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Must hold permission " + MANAGE_ACTIVITY_STACKS); - } + mAtmService.enforceTaskPermission("unregisterDisplayWindowListener"); mDisplayNotificationController.unregisterListener(listener); } @@ -6925,9 +6979,6 @@ public class WindowManagerService extends IWindowManager.Stub if (!checkCallingPermission(READ_FRAME_BUFFER, "requestScrollCapture()")) { throw new SecurityException("Requires READ_FRAME_BUFFER permission"); } - if (behindClient != null && !isWindowToken(behindClient)) { - throw new IllegalArgumentException("behindClient must be a window token"); - } final long token = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -8352,9 +8403,8 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void holdLock(int durationMs) { - mContext.enforceCallingPermission( - Manifest.permission.INJECT_EVENTS, "holdLock requires shell identity"); + public void holdLock(IBinder token, int durationMs) { + mTestUtilityService.verifyHoldLockToken(token); synchronized (mGlobalLock) { SystemClock.sleep(durationMs); diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index fe312e6b4c46..a3a9c1ce9219 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -111,6 +111,10 @@ public class WindowManagerShellCommand extends ShellCommand { return runGetIgnoreOrientationRequest(pw); case "dump-visible-window-views": return runDumpVisibleWindowViews(pw); + case "set-task-letterbox-aspect-ratio": + return runSetTaskLetterboxAspectRatio(pw); + case "get-task-letterbox-aspect-ratio": + return runGetTaskLetterboxAspectRatio(pw); case "reset": return runReset(pw); default: @@ -509,6 +513,38 @@ public class WindowManagerShellCommand extends ShellCommand { return 0; } + private int runSetTaskLetterboxAspectRatio(PrintWriter pw) throws RemoteException { + final float aspectRatio; + try { + String arg = getNextArgRequired(); + if ("reset".equals(arg)) { + mInternal.resetTaskLetterboxAspectRatio(); + return 0; + } + aspectRatio = Float.parseFloat(arg); + } catch (NumberFormatException e) { + getErrPrintWriter().println("Error: bad aspect ratio format " + e); + return -1; + } catch (IllegalArgumentException e) { + getErrPrintWriter().println( + "Error: 'reset' or aspect ratio should be provided as an argument " + e); + return -1; + } + + mInternal.setTaskLetterboxAspectRatio(aspectRatio); + return 0; + } + + private int runGetTaskLetterboxAspectRatio(PrintWriter pw) throws RemoteException { + final float aspectRatio = mInternal.getTaskLetterboxAspectRatio(); + if (aspectRatio <= WindowManagerService.MIN_TASK_LETTERBOX_ASPECT_RATIO) { + pw.println("Letterbox aspect ratio is not set"); + } else { + pw.println("Letterbox aspect ratio is " + aspectRatio); + } + return 0; + } + private int runReset(PrintWriter pw) throws RemoteException { int displayId = getDisplayId(getNextArg()); @@ -533,6 +569,9 @@ public class WindowManagerShellCommand extends ShellCommand { // set-ignore-orientation-request mInterface.setIgnoreOrientationRequest(displayId, false /* ignoreOrientationRequest */); + // set-task-letterbox-aspect-ratio + mInternal.resetTaskLetterboxAspectRatio(); + pw.println("Reset all settings for displayId=" + displayId); return 0; } @@ -563,6 +602,12 @@ public class WindowManagerShellCommand extends ShellCommand { pw.println(" set-ignore-orientation-request [-d DISPLAY_ID] [true|1|false|0]"); pw.println(" get-ignore-orientation-request [-d DISPLAY_ID] "); pw.println(" If app requested orientation should be ignored."); + pw.println(" set-task-letterbox-aspect-ratio [reset|aspectRatio]"); + pw.println(" get-task-letterbox-aspect-ratio"); + pw.println(" Aspect ratio of task level letterboxing. If aspectRatio <= " + + WindowManagerService.MIN_TASK_LETTERBOX_ASPECT_RATIO); + pw.println(" both it and R.dimen.config_taskLetterboxAspectRatio will be ignored"); + pw.println(" and framework implementation will be used to determine aspect ratio."); pw.println(" reset [-d DISPLAY_ID]"); pw.println(" Reset all override settings."); if (!IS_USER) { diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index ae152d253d17..51857dcd323b 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -16,7 +16,6 @@ package com.android.server.wm; -import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; @@ -117,7 +116,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub @Override public IBinder startTransition(int type, @Nullable IBinder transitionToken, @Nullable WindowContainerTransaction t) { - enforceStackPermission("startTransition()"); + enforceTaskPermission("startTransition()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -144,7 +143,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub public int finishTransition(@NonNull IBinder transitionToken, @Nullable WindowContainerTransaction t, @Nullable IWindowContainerTransactionCallback callback) { - enforceStackPermission("finishTransition()"); + enforceTaskPermission("finishTransition()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -168,7 +167,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub private int applyTransaction(@NonNull WindowContainerTransaction t, @Nullable IWindowContainerTransactionCallback callback, @Nullable Transition transition) { - enforceStackPermission("applySyncTransaction()"); + enforceTaskPermission("applySyncTransaction()"); int syncId = -1; if (t == null) { throw new IllegalArgumentException( @@ -491,13 +490,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub @Override public ITaskOrganizerController getTaskOrganizerController() { - enforceStackPermission("getTaskOrganizerController()"); + enforceTaskPermission("getTaskOrganizerController()"); return mTaskOrganizerController; } @Override public IDisplayAreaOrganizerController getDisplayAreaOrganizerController() { - enforceStackPermission("getDisplayAreaOrganizerController()"); + enforceTaskPermission("getDisplayAreaOrganizerController()"); return mDisplayAreaOrganizerController; } @@ -573,7 +572,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub @Override public void registerTransitionPlayer(ITransitionPlayer player) { - enforceStackPermission("registerTransitionPlayer()"); + enforceTaskPermission("registerTransitionPlayer()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -584,7 +583,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } } - private void enforceStackPermission(String func) { - mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func); + private void enforceTaskPermission(String func) { + mService.enforceTaskPermission(func); } } diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 2e7905c64049..2d69dcbcfbd0 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -505,29 +505,33 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio } } - boolean areBackgroundActivityStartsAllowed() { - // allow if any activity in the caller has either started or finished very recently, and - // it must be started or finished after last stop app switches time. - final long now = SystemClock.uptimeMillis(); - if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS - || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) { - // if activity is started and finished before stop app switch time, we should not - // let app to be able to start background activity even it's in grace period. - if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime() - || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) { + boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed) { + // If app switching is not allowed, we ignore all the start activity grace period + // exception so apps cannot start itself in onPause() after pressing home button. + if (appSwitchAllowed) { + // allow if any activity in the caller has either started or finished very recently, and + // it must be started or finished after last stop app switches time. + final long now = SystemClock.uptimeMillis(); + if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS + || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) { + // if activity is started and finished before stop app switch time, we should not + // let app to be able to start background activity even it's in grace period. + if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime() + || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "[WindowProcessController(" + mPid + + ")] Activity start allowed: within " + + ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period"); + } + return true; + } if (DEBUG_ACTIVITY_STARTS) { - Slog.d(TAG, "[WindowProcessController(" + mPid - + ")] Activity start allowed: within " - + ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period"); + Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start within " + + ACTIVITY_BG_START_GRACE_PERIOD_MS + + "ms grace period but also within stop app switch window"); } - return true; - } - if (DEBUG_ACTIVITY_STARTS) { - Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start within " - + ACTIVITY_BG_START_GRACE_PERIOD_MS - + "ms grace period but also within stop app switch window"); - } + } } // allow if the proc is instrumenting with background activity starts privs if (mInstrumentingWithBackgroundActivityStartPrivileges) { @@ -539,7 +543,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio return true; } // allow if the caller has an activity in any foreground task - if (hasActivityInVisibleTask()) { + if (appSwitchAllowed && hasActivityInVisibleTask()) { if (DEBUG_ACTIVITY_STARTS) { Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start allowed: process has activity in foreground task"); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 3f15ff8ebd25..ab2f42426153 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2176,6 +2176,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final DisplayContent dc = getDisplayContent(); if (isInputMethodTarget()) { + // Make sure to set mInputMethodTarget as null when the removed window is the IME + // target, in case computeImeTarget may use the outdated target. + dc.mInputMethodTarget = null; dc.computeImeTarget(true /* updateImeTarget */); } if (dc.mInputMethodInputTarget == this) { diff --git a/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java b/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java index 141561839ce3..261dda7ab15d 100644 --- a/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java +++ b/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java @@ -17,6 +17,7 @@ package com.android.server.wm.utils; import static android.hardware.HardwareBuffer.RGBA_8888; +import static android.hardware.HardwareBuffer.USAGE_PROTECTED_CONTENT; import android.graphics.Color; import android.graphics.ColorSpace; @@ -38,12 +39,21 @@ import java.util.Arrays; public class RotationAnimationUtils { /** + * @return whether the hardwareBuffer passed in is marked as protected. + */ + public static boolean hasProtectedContent(HardwareBuffer hardwareBuffer) { + return (hardwareBuffer.getUsage() & USAGE_PROTECTED_CONTENT) == USAGE_PROTECTED_CONTENT; + } + + /** * Converts the provided {@link HardwareBuffer} and converts it to a bitmap to then sample the * luminance at the borders of the bitmap * @return the average luminance of all the pixels at the borders of the bitmap */ public static float getMedianBorderLuma(HardwareBuffer hardwareBuffer, ColorSpace colorSpace) { - if (hardwareBuffer == null || hardwareBuffer.getFormat() != RGBA_8888) { + // Cannot read content from buffer with protected usage. + if (hardwareBuffer == null || hardwareBuffer.getFormat() != RGBA_8888 + || hasProtectedContent(hardwareBuffer)) { return 0; } diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 9f83bafbed75..aac60b406ca8 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -27,7 +27,6 @@ cc_library_static { "com_android_server_adb_AdbDebuggingManager.cpp", "com_android_server_am_BatteryStatsService.cpp", "com_android_server_biometrics_SurfaceToNativeHandleConverter.cpp", - "com_android_server_connectivity_Vpn.cpp", "com_android_server_ConsumerIrService.cpp", "com_android_server_devicepolicy_CryptoTestHelper.cpp", "com_android_server_gpu_GpuService.cpp", @@ -62,6 +61,8 @@ cc_library_static { "com_android_server_pm_PackageManagerShellCommandDataLoader.cpp", "onload.cpp", ":lib_networkStatsFactory_native", + // TODO: move the file below to the connectivity APEX + "com_android_server_connectivity_Vpn.cpp", ], include_dirs: [ diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp index d39c7a6fd8df..5d78f127f77f 100644 --- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp +++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp @@ -17,7 +17,6 @@ #define LOG_TAG "BatteryStatsService" //#define LOG_NDEBUG 0 -#include <climits> #include <errno.h> #include <fcntl.h> #include <inttypes.h> @@ -28,6 +27,7 @@ #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> +#include <climits> #include <unordered_map> #include <utility> @@ -66,10 +66,9 @@ using IPowerV1_0 = android::hardware::power::V1_0::IPower; namespace android { -#define LAST_RESUME_REASON "/sys/kernel/wakeup_reasons/last_resume_reason" -#define MAX_REASON_SIZE 512 - static bool wakeup_init = false; +static std::mutex mReasonsMutex; +static std::vector<std::string> mWakeupReasons; static sem_t wakeup_sem; extern sp<ISuspendControlService> getSuspendControl(); @@ -115,9 +114,25 @@ struct PowerHalDeathRecipient : virtual public hardware::hidl_death_recipient { sp<PowerHalDeathRecipient> gDeathRecipient = new PowerHalDeathRecipient(); class WakeupCallback : public BnSuspendCallback { - public: - binder::Status notifyWakeup(bool success) override { +public: + binder::Status notifyWakeup(bool success, + const std::vector<std::string>& wakeupReasons) override { ALOGI("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted"); + bool reasonsCaptured = false; + { + std::unique_lock<std::mutex> reasonsLock(mReasonsMutex, std::defer_lock); + if (reasonsLock.try_lock() && mWakeupReasons.empty()) { + mWakeupReasons = std::move(wakeupReasons); + reasonsCaptured = true; + } + } + if (!reasonsCaptured) { + ALOGE("Failed to write wakeup reasons. Reasons dropped:"); + for (auto wakeupReason : wakeupReasons) { + ALOGE("\t%s", wakeupReason.c_str()); + } + } + int ret = sem_post(&wakeup_sem); if (ret < 0) { char buf[80]; @@ -157,8 +172,6 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf) // Wait for wakeup. ALOGV("Waiting for wakeup..."); - // TODO(b/116747600): device can suspend and wakeup after sem_wait() finishes and before wakeup - // reason is recorded, i.e. BatteryStats might occasionally miss wakeup events. int ret = sem_wait(&wakeup_sem); if (ret < 0) { char buf[80]; @@ -168,20 +181,27 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf) return 0; } - FILE *fp = fopen(LAST_RESUME_REASON, "r"); - if (fp == NULL) { - ALOGE("Failed to open %s", LAST_RESUME_REASON); - return -1; - } - char* mergedreason = (char*)env->GetDirectBufferAddress(outBuf); int remainreasonlen = (int)env->GetDirectBufferCapacity(outBuf); ALOGV("Reading wakeup reasons"); + std::vector<std::string> wakeupReasons; + { + std::unique_lock<std::mutex> reasonsLock(mReasonsMutex, std::defer_lock); + if (reasonsLock.try_lock() && !mWakeupReasons.empty()) { + wakeupReasons = std::move(mWakeupReasons); + mWakeupReasons.clear(); + } + } + + if (wakeupReasons.empty()) { + return 0; + } + char* mergedreasonpos = mergedreason; - char reasonline[128]; int i = 0; - while (fgets(reasonline, sizeof(reasonline), fp) != NULL) { + for (auto wakeupReason : wakeupReasons) { + auto reasonline = const_cast<char*>(wakeupReason.c_str()); char* pos = reasonline; char* endPos; int len; @@ -238,10 +258,6 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf) *mergedreasonpos = 0; } - if (fclose(fp) != 0) { - ALOGE("Failed to close %s", LAST_RESUME_REASON); - return -1; - } return mergedreasonpos - mergedreason; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index db23ceabae64..f9e06dca13ed 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1649,6 +1649,29 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } /** + * Creates a new {@link CallerIdentity} object to represent the caller's identity. + * If an {@code adminComponent} is specified, then the caller must be an admin and + * the provided component name must match the caller's UID. + * + * If a package name is provided, then the caller doesn't have to be an admin, and the + * provided package must belong to the caller's UID. + * + * If neither is provided, the caller identity is returned as-is. + * + * Note: this method should only be called when the caller may not be an admin. If the caller + * is not an admin, the ComponentName in the returned identity will be null. + */ + private CallerIdentity getNonPrivilegedOrAdminCallerIdentity( + @Nullable ComponentName adminComponent, + @Nullable String callerPackage) { + if (adminComponent != null) { + return getCallerIdentity(adminComponent); + } + + return getNonPrivilegedOrAdminCallerIdentityUsingPackage(callerPackage); + } + + /** * Retrieves the active admin of the caller. This method should not be called directly and * should only be called by {@link #getAdminCallerIdentity}, * {@link #getNonPrivilegedOrAdminCallerIdentity}, {@link #getAdminCallerIdentityUsingPackage} @@ -2315,14 +2338,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final boolean isDeviceOwner = isDeviceOwner(admin.info.getComponent(), userId); final boolean isProfileOwner = isProfileOwner(admin.info.getComponent(), userId); - if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { - throw new SecurityException("Admin " + admin.info.getComponent() - + " does not own the device"); - } - if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { - throw new SecurityException("Admin " + admin.info.getComponent() - + " does not own the profile"); - } if (DA_DISALLOWED_POLICIES.contains(reqPolicy) && !isDeviceOwner && !isProfileOwner) { throw new SecurityException("Admin " + admin.info.getComponent() + " is not a device owner or profile owner, so may not use policy: " @@ -2428,20 +2443,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ensureLocked(); final boolean ownsDevice = isDeviceOwner(admin.info.getComponent(), userId); final boolean ownsProfile = isProfileOwner(admin.info.getComponent(), userId); - final boolean ownsProfileOnOrganizationOwnedDevice = - isProfileOwnerOfOrganizationOwnedDevice(admin.info.getComponent(), userId); - - if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { - return ownsDevice; - } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { - // DO always has the PO power. - return ownsDevice || ownsProfileOnOrganizationOwnedDevice || ownsProfile; - } else { - boolean allowedToUsePolicy = ownsDevice || ownsProfile - || !DA_DISALLOWED_POLICIES.contains(reqPolicy) - || getTargetSdk(admin.info.getPackageName(), userId) < Build.VERSION_CODES.Q; - return allowedToUsePolicy && admin.info.usesPolicy(reqPolicy); - } + + boolean allowedToUsePolicy = ownsDevice || ownsProfile + || !DA_DISALLOWED_POLICIES.contains(reqPolicy) + || getTargetSdk(admin.info.getPackageName(), userId) < Build.VERSION_CODES.Q; + return allowedToUsePolicy && admin.info.usesPolicy(reqPolicy); } void sendAdminCommandLocked(ActiveAdmin admin, String action) { @@ -3234,7 +3240,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } Objects.requireNonNull(adminReceiver, "ComponentName is null"); - enforceShell("forceRemoveActiveAdmin"); + Preconditions.checkCallAuthorization(isAdb(getCallerIdentity()), + "Non-shell user attempted to call forceRemoveActiveAdmin"); mInjector.binderWithCleanCallingIdentity(() -> { synchronized (getLockObject()) { if (!isAdminTestOnlyLocked(adminReceiver, userHandle)) { @@ -3313,13 +3320,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return (admin != null) && admin.testOnlyAdmin; } - private void enforceShell(String method) { - final int callingUid = mInjector.binderGetCallingUid(); - if (callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID) { - throw new SecurityException("Non-shell user attempted to call " + method); - } - } - @Override public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) { if (!mHasFeature) { @@ -5488,22 +5488,17 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { public List<String> getDelegatedScopes(ComponentName who, String delegatePackage) throws SecurityException { Objects.requireNonNull(delegatePackage, "Delegate package is null"); + final CallerIdentity caller = getNonPrivilegedOrAdminCallerIdentity(who, delegatePackage); - // Retrieve the user ID of the calling process. - final int callingUid = mInjector.binderGetCallingUid(); - final int userId = UserHandle.getUserId(callingUid); + // Ensure the caller may call this method: + // * Either it's an admin + // * Or it's an app identified by its calling package name (the + // getNonPrivilegedOrAdminCallerIdentity method validated the UID and package match). + Preconditions.checkCallAuthorization( + (caller.hasAdminComponent() && (isProfileOwner(caller) || isDeviceOwner(caller))) + || delegatePackage != null); synchronized (getLockObject()) { - // Ensure calling process is device/profile owner. - if (who != null) { - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); - // Or ensure calling process is delegatePackage itself. - } else { - if (!isCallingFromPackage(delegatePackage, callingUid)) { - throw new SecurityException("Caller with uid " + callingUid + " is not " - + delegatePackage); - } - } - final DevicePolicyData policy = getUserData(userId); + final DevicePolicyData policy = getUserData(caller.getUserId()); // Retrieve the scopes assigned to delegatePackage, or null if no scope was given. final List<String> scopes = policy.mDelegationMap.get(delegatePackage); return scopes == null ? Collections.EMPTY_LIST : scopes; @@ -7254,10 +7249,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { throw new IllegalArgumentException("Invalid component " + admin + " for device owner"); } - final boolean hasIncompatibleAccountsOrNonAdb = - hasIncompatibleAccountsOrNonAdbNoLock(userId, admin); + + final CallerIdentity caller = getCallerIdentity(); synchronized (getLockObject()) { - enforceCanSetDeviceOwnerLocked(admin, userId, hasIncompatibleAccountsOrNonAdb); + enforceCanSetDeviceOwnerLocked(caller, admin, userId); final ActiveAdmin activeAdmin = getActiveAdminUncheckedLocked(admin, userId); if (activeAdmin == null || getUserData(userId).mRemovingAdmins.contains(admin)) { @@ -7266,7 +7261,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // Shutting down backup manager service permanently. toggleBackupServiceActive(UserHandle.USER_SYSTEM, /* makeActive= */ false); - if (isAdb()) { + if (isAdb(caller)) { // Log device owner provisioning was started using adb. MetricsLogger.action(mContext, PROVISIONING_ENTRY_POINT_ADB, LOG_TAG_DEVICE_OWNER); DevicePolicyEventLogger @@ -7622,10 +7617,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { + " not installed for userId:" + userHandle); } - final boolean hasIncompatibleAccountsOrNonAdb = - hasIncompatibleAccountsOrNonAdbNoLock(userHandle, who); + final CallerIdentity caller = getCallerIdentity(); synchronized (getLockObject()) { - enforceCanSetProfileOwnerLocked(who, userHandle, hasIncompatibleAccountsOrNonAdb); + enforceCanSetProfileOwnerLocked(caller, who, userHandle); final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); if (admin == null || getUserData(userHandle).mRemovingAdmins.contains(who)) { @@ -7643,7 +7637,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } - if (isAdb()) { + if (isAdb(caller)) { // Log profile owner provisioning was started using adb. MetricsLogger.action(mContext, PROVISIONING_ENTRY_POINT_ADB, LOG_TAG_PROFILE_OWNER); DevicePolicyEventLogger @@ -7836,6 +7830,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; } + final CallerIdentity caller = getCallerIdentity(); if (userHandle != mOwners.getDeviceOwnerUserId() && !mOwners.hasProfileOwner(userHandle) && getManagedUserId(userHandle) == -1) { // No managed device, user or profile, so setting provisioning state makes no sense. @@ -7847,7 +7842,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { boolean transitionCheckNeeded = true; // Calling identity/permission checks. - if (isAdb()) { + if (isAdb(caller)) { // ADB shell can only move directly from un-managed to finalized as part of directly // setting profile-owner or device-owner. if (getUserProvisioningState(userHandle) != @@ -7893,7 +7888,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // Current user has a managed-profile, but current user is not managed, so // rather than moving to finalized state, go back to unmanaged once // profile provisioning is complete. - if (newState == DevicePolicyManager.STATE_USER_UNMANAGED) { + if (newState == DevicePolicyManager.STATE_USER_PROFILE_FINALIZED) { return; } break; @@ -8210,8 +8205,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { * - SYSTEM_UID * - adb unless hasIncompatibleAccountsOrNonAdb is true. */ - private void enforceCanSetProfileOwnerLocked(@Nullable ComponentName owner, int userHandle, - boolean hasIncompatibleAccountsOrNonAdb) { + private void enforceCanSetProfileOwnerLocked(CallerIdentity caller, + @Nullable ComponentName owner, int userHandle) { UserInfo info = getUserInfo(userHandle); if (info == null) { // User doesn't exist. @@ -8229,9 +8224,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { throw new IllegalStateException("Trying to set the profile owner, but the user " + "already has a device owner."); } - if (isAdb()) { + if (isAdb(caller)) { if ((mIsWatch || hasUserSetupCompleted(userHandle)) - && hasIncompatibleAccountsOrNonAdb) { + && hasIncompatibleAccountsOrNonAdbNoLock(caller, userHandle, owner)) { throw new IllegalStateException("Not allowed to set the profile owner because " + "there are already some accounts on the profile"); } @@ -8270,16 +8265,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { * The Device owner can only be set by adb or an app with the MANAGE_PROFILE_AND_DEVICE_OWNERS * permission. */ - private void enforceCanSetDeviceOwnerLocked(@Nullable ComponentName owner, - @UserIdInt int userId, - boolean hasIncompatibleAccountsOrNonAdb) { - if (!isAdb()) { + private void enforceCanSetDeviceOwnerLocked(CallerIdentity caller, + @Nullable ComponentName owner, @UserIdInt int userId) { + if (!isAdb(caller)) { Preconditions.checkCallAuthorization( hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)); } - final int code = checkDeviceOwnerProvisioningPreConditionLocked( - owner, userId, isAdb(), hasIncompatibleAccountsOrNonAdb); + final int code = checkDeviceOwnerProvisioningPreConditionLocked(owner, userId, + isAdb(caller), hasIncompatibleAccountsOrNonAdbNoLock(caller, userId, owner)); if (code != CODE_OK) { throw new IllegalStateException(computeProvisioningErrorString(code, userId)); } @@ -8362,37 +8356,27 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } private void enforceDeviceOwnerOrManageUsers() { - synchronized (getLockObject()) { - if (getActiveAdminWithPolicyForUidLocked(null, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, - mInjector.binderGetCallingUid()) != null) { - return; - } + final CallerIdentity caller = getCallerIdentity(); + if (isDeviceOwner(caller)) { + return; } - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + Preconditions.checkCallAuthorization(canManageUsers(caller)); } private void enforceProfileOwnerOrSystemUser() { - synchronized (getLockObject()) { - if (getActiveAdminWithPolicyForUidLocked(null, - DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid()) - != null) { - return; - } + final CallerIdentity caller = getCallerIdentity(); + if (isDeviceOwner(caller) || isProfileOwner(caller)) { + return; } - Preconditions.checkState(isCallerWithSystemUid(), + Preconditions.checkState(isSystemUid(caller), "Only profile owner, device owner and system may call this method."); } private void enforceProfileOwnerOrFullCrossUsersPermission(CallerIdentity caller, int userId) { - if (userId == caller.getUserId()) { - synchronized (getLockObject()) { - if (getActiveAdminWithPolicyForUidLocked(null, - DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, caller.getUid()) != null) { - // Device Owner/Profile Owner may access the user it runs on. - return; - } - } + if ((userId == caller.getUserId()) && (isProfileOwner(caller) || isDeviceOwner(caller))) { + // Device Owner/Profile Owner may access the user it runs on. + return; } Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId)); } @@ -9285,10 +9269,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { throw new IllegalArgumentException("profileOwner " + profileOwner + " and admin " + admin + " are not in the same package"); } + final CallerIdentity caller = getCallerIdentity(admin); // Only allow the system user to use this method - if (!mInjector.binderGetCallingUserHandle().isSystem()) { - throw new SecurityException("createAndManageUser was called from non-system user"); - } + Preconditions.checkCallAuthorization(caller.getUserHandle().isSystem(), + "createAndManageUser was called from non-system user"); + Preconditions.checkCallAuthorization(isDeviceOwner(caller)); final boolean ephemeral = (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0; final boolean demo = (flags & DevicePolicyManager.MAKE_USER_DEMO) != 0 && UserManager.isDeviceInDemoMode(mContext); @@ -9298,8 +9283,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // Create user. UserHandle user = null; synchronized (getLockObject()) { - getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); - final int callingUid = mInjector.binderGetCallingUid(); final long id = mInjector.binderClearCallingIdentity(); try { @@ -11161,25 +11144,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isActiveDeviceOwner(int uid) { - synchronized (getLockObject()) { - return getActiveAdminWithPolicyForUidLocked( - null, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, uid) != null; - } + return isDeviceOwner(new CallerIdentity(uid, null, null)); } @Override public boolean isActiveProfileOwner(int uid) { - synchronized (getLockObject()) { - return getActiveAdminWithPolicyForUidLocked( - null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, uid) != null; - } + return isProfileOwner(new CallerIdentity(uid, null, null)); } @Override public boolean isActiveSupervisionApp(int uid) { + if (!isProfileOwner(new CallerIdentity(uid, null, null))) { + return false; + } synchronized (getLockObject()) { - final ActiveAdmin admin = getActiveAdminWithPolicyForUidLocked( - null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, uid); + final ActiveAdmin admin = getProfileOwnerAdminLocked(UserHandle.getUserId(uid)); if (admin == null) { return false; } @@ -11682,7 +11661,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void clearSystemUpdatePolicyFreezePeriodRecord() { - enforceShell("clearSystemUpdatePolicyFreezePeriodRecord"); + Preconditions.checkCallAuthorization(isAdb(getCallerIdentity()), + "Non-shell user attempted to call clearSystemUpdatePolicyFreezePeriodRecord"); synchronized (getLockObject()) { // Print out current record to help diagnosed CTS failures Slog.i(LOG_TAG, "Clear freeze period record: " @@ -11705,6 +11685,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .getPackageName(); try { String[] pkgs = mInjector.getIPackageManager().getPackagesForUid(appUid); + if (pkgs == null) { + return false; + } + for (String pkg : pkgs) { if (deviceOwnerPackageName.equals(pkg)) { return true; @@ -12588,23 +12572,23 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void markProfileOwnerOnOrganizationOwnedDevice(ComponentName who, int userId) { - // As the caller is the system, it must specify the component name of the profile owner - // as a safety check. - Objects.requireNonNull(who); - if (!mHasFeature) { return; } + // As the caller is the system, it must specify the component name of the profile owner + // as a safety check. + Objects.requireNonNull(who); + final CallerIdentity caller = getCallerIdentity(); // Only adb or system apps with the right permission can mark a profile owner on // organization-owned device. - if (!(isAdb() || hasCallingPermission(permission.MARK_DEVICE_ORGANIZATION_OWNED))) { + if (!(isAdb(caller) || hasCallingPermission(permission.MARK_DEVICE_ORGANIZATION_OWNED))) { throw new SecurityException( "Only the system can mark a profile owner of organization-owned device."); } - if (isAdb()) { - if (hasIncompatibleAccountsOrNonAdbNoLock(userId, who)) { + if (isAdb(caller)) { + if (hasIncompatibleAccountsOrNonAdbNoLock(caller, userId, who)) { throw new SecurityException( "Can only be called from ADB if the device has no accounts."); } @@ -12925,7 +12909,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public long forceSecurityLogs() { - enforceShell("forceSecurityLogs"); + Preconditions.checkCallAuthorization(isAdb(getCallerIdentity()), + "Non-shell user attempted to call forceSecurityLogs"); if (!mInjector.securityLogGetLoggingEnabledProperty()) { throw new IllegalStateException("logging is not available"); } @@ -13293,9 +13278,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { * * DO NOT CALL IT WITH THE DPMS LOCK HELD. */ - private boolean hasIncompatibleAccountsOrNonAdbNoLock( + private boolean hasIncompatibleAccountsOrNonAdbNoLock(CallerIdentity caller, int userId, @Nullable ComponentName owner) { - if (!isAdb()) { + if (!isAdb(caller)) { return true; } wtfIfInLock(); @@ -13350,9 +13335,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private boolean isAdb() { - final int callingUid = mInjector.binderGetCallingUid(); - return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID; + private boolean isAdb(CallerIdentity caller) { + return isShellUid(caller) || isRootUid(caller); } @Override @@ -13414,7 +13398,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public long forceNetworkLogs() { - enforceShell("forceNetworkLogs"); + Preconditions.checkCallAuthorization(isAdb(getCallerIdentity()), + "Non-shell user attempted to call forceNetworkLogs"); synchronized (getLockObject()) { if (!isNetworkLoggingEnabledInternalLocked()) { throw new IllegalStateException("logging is not available"); diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 975e2265b60c..e116a353c723 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -76,14 +76,18 @@ import android.provider.Settings; import android.server.ServerProtoEnums; import android.sysprop.VoldProperties; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.EventLog; +import android.util.IndentingPrintWriter; import android.util.Pair; import android.util.Slog; +import android.util.TimeUtils; import android.view.contentcapture.ContentCaptureManager; import com.android.i18n.timezone.ZoneInfoDb; import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BinderInternal; import com.android.internal.os.RuntimeInit; @@ -188,14 +192,20 @@ import dalvik.system.VMRuntime; import com.google.android.startop.iorap.IorapForwardingService; import java.io.File; +import java.io.FileDescriptor; import java.io.IOException; +import java.io.PrintWriter; +import java.util.Arrays; import java.util.LinkedList; import java.util.Locale; import java.util.Timer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; -public final class SystemServer { +/** + * Entry point to {@code system_server}. + */ +public final class SystemServer implements Dumpable { private static final String TAG = "SystemServer"; @@ -384,6 +394,9 @@ public final class SystemServer { private Future<?> mZygotePreload; private Future<?> mBlobStoreServiceStart; + private final SystemServerDumper mDumper = new SystemServerDumper(); + + /** * The pending WTF to be logged into dropbox. */ @@ -446,6 +459,75 @@ public final class SystemServer { mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed")); } + @Override + public void dump(IndentingPrintWriter pw, String[] args) { + pw.printf("Runtime restart: %b\n", mRuntimeRestart); + pw.printf("Start count: %d\n", mStartCount); + pw.print("Runtime start-up time: "); + TimeUtils.formatDuration(mRuntimeStartUptime, pw); pw.println(); + pw.print("Runtime start-elapsed time: "); + TimeUtils.formatDuration(mRuntimeStartElapsedTime, pw); pw.println(); + } + + private final class SystemServerDumper extends Binder { + + @GuardedBy("mDumpables") + private final ArrayMap<String, Dumpable> mDumpables = new ArrayMap<>(4); + + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + final boolean hasArgs = args != null && args.length > 0; + + synchronized (mDumpables) { + if (hasArgs && "--list".equals(args[0])) { + final int dumpablesSize = mDumpables.size(); + for (int i = 0; i < dumpablesSize; i++) { + pw.println(mDumpables.keyAt(i)); + } + return; + } + + if (hasArgs && "--name".equals(args[0])) { + if (args.length < 2) { + pw.println("Must pass at least one argument to --name"); + return; + } + final String name = args[1]; + final Dumpable dumpable = mDumpables.get(name); + if (dumpable == null) { + pw.printf("No dummpable named %s\n", name); + return; + } + + try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ")) { + // Strip --name DUMPABLE from args + final String[] actualArgs = Arrays.copyOfRange(args, 2, args.length); + dumpable.dump(ipw, actualArgs); + } + return; + } + + final int dumpablesSize = mDumpables.size(); + try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ")) { + for (int i = 0; i < dumpablesSize; i++) { + final Dumpable dumpable = mDumpables.valueAt(i); + ipw.printf("%s:\n", dumpable.getDumpableName()); + ipw.increaseIndent(); + dumpable.dump(ipw, args); + ipw.decreaseIndent(); + ipw.println(); + } + } + } + } + + private void addDumpable(@NonNull Dumpable dumpable) { + synchronized (mDumpables) { + mDumpables.put(dumpable.getDumpableName(), dumpable); + } + } + } + private void run() { TimingsTraceAndSlog t = new TimingsTraceAndSlog(); try { @@ -572,13 +654,21 @@ public final class SystemServer { // Call per-process mainline module initialization. ActivityThread.initializeMainlineModules(); + // Sets the dumper service + ServiceManager.addService("system_server_dumper", mDumper); + mDumper.addDumpable(this); + // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); + mDumper.addDumpable(mSystemServiceManager); + LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Prepare the thread pool for init tasks that can be parallelized - SystemServerInitThreadPool.start(); + SystemServerInitThreadPool tp = SystemServerInitThreadPool.start(); + mDumper.addDumpable(tp); + // Attach JVMTI agent if this is a debuggable build and the system property is set. if (Build.IS_DEBUGGABLE) { // Property is of the form "library_path=parameters". @@ -2321,7 +2411,11 @@ public final class SystemServer { if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { t.traceBegin("StartCarServiceHelperService"); - mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS); + final SystemService cshs = mSystemServiceManager + .startService(CAR_SERVICE_HELPER_SERVICE_CLASS); + if (cshs instanceof Dumpable) { + mDumper.addDumpable((Dumpable) cshs); + } t.traceEnd(); } diff --git a/services/net/Android.bp b/services/net/Android.bp index 3c9322d2dfdc..1ccd512a9daf 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -66,5 +66,8 @@ filegroup { ":framework-annotations", "java/android/net/util/NetworkConstants.java", ], - visibility: ["//frameworks/base/packages/Tethering"], + visibility: [ + "//frameworks/base/packages/Tethering", + "//packages/modules/Connectivity/Tethering" + ], } diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java index 0ab15017a2b4..6a6fb82897bb 100644 --- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java @@ -252,6 +252,46 @@ public class LocalDisplayAdapterTest { } @Test + public void testAfterDisplayChange_ActiveModeIsUpdated() throws Exception { + SurfaceControl.DisplayConfig[] configs = new SurfaceControl.DisplayConfig[]{ + createFakeDisplayConfig(1920, 1080, 60f), + createFakeDisplayConfig(1920, 1080, 50f) + }; + FakeDisplay display = new FakeDisplay(PORT_A, configs, /* activeConfig */ 0); + setUpDisplay(display); + updateAvailableDisplays(); + mAdapter.registerLocked(); + waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS); + + assertThat(mListener.addedDisplays.size()).isEqualTo(1); + assertThat(mListener.changedDisplays).isEmpty(); + + DisplayDeviceInfo displayDeviceInfo = mListener.addedDisplays.get(0) + .getDisplayDeviceInfoLocked(); + + Display.Mode activeMode = getModeById(displayDeviceInfo, displayDeviceInfo.modeId); + assertThat(activeMode.matches(1920, 1080, 60f)).isTrue(); + + // Change the display + display.activeConfig = 1; + setUpDisplay(display); + mInjector.getTransmitter().sendHotplug(display, /* connected */ true); + waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS); + + assertThat(SurfaceControl.getActiveConfig(display.token)).isEqualTo(1); + + assertThat(mListener.addedDisplays.size()).isEqualTo(1); + assertThat(mListener.changedDisplays.size()).isEqualTo(1); + + DisplayDevice displayDevice = mListener.changedDisplays.get(0); + displayDevice.applyPendingDisplayDeviceInfoChangesLocked(); + displayDeviceInfo = displayDevice.getDisplayDeviceInfoLocked(); + + activeMode = getModeById(displayDeviceInfo, displayDeviceInfo.modeId); + assertThat(activeMode.matches(1920, 1080, 50f)).isTrue(); + } + + @Test public void testAfterDisplayChange_HdrCapabilitiesAreUpdated() throws Exception { FakeDisplay display = new FakeDisplay(PORT_A); Display.HdrCapabilities initialHdrCapabilities = new Display.HdrCapabilities(new int[0], @@ -389,7 +429,12 @@ public class LocalDisplayAdapterTest { public Display.HdrCapabilities hdrCapabilities = new Display.HdrCapabilities(new int[0], 1000, 1000, 0); public SurfaceControl.DesiredDisplayConfigSpecs desiredDisplayConfigSpecs = - new SurfaceControl.DesiredDisplayConfigSpecs(0, 60.f, 60.f, 60.f, 60.f); + new SurfaceControl.DesiredDisplayConfigSpecs(/* defaultConfig */ 0, + /* allowGroupSwitching */ false, + /* primaryRefreshRateMin */ 60.f, + /* primaryRefreshRateMax */ 60.f, + /* appRefreshRateMin */ 60.f, + /* appRefreshRateMax */60.f); private FakeDisplay(int port) { this.address = createDisplayAddress(port); diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java index 18bd6b17f340..79542084ac36 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java @@ -16,6 +16,7 @@ package com.android.server.job.controllers; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder; @@ -27,6 +28,7 @@ import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX; import static com.android.server.job.JobSchedulerService.FREQUENT_INDEX; import static com.android.server.job.JobSchedulerService.NEVER_INDEX; import static com.android.server.job.JobSchedulerService.RARE_INDEX; +import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import static com.android.server.job.JobSchedulerService.WORKING_INDEX; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; @@ -39,6 +41,7 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; @@ -68,6 +71,7 @@ import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.SystemClock; +import android.provider.DeviceConfig; import android.util.SparseBooleanArray; import androidx.test.runner.AndroidJUnit4; @@ -78,6 +82,7 @@ import com.android.server.job.JobSchedulerService.Constants; import com.android.server.job.JobServiceContext; import com.android.server.job.JobStore; import com.android.server.job.controllers.QuotaController.ExecutionStats; +import com.android.server.job.controllers.QuotaController.QcConstants; import com.android.server.job.controllers.QuotaController.TimingSession; import com.android.server.usage.AppStandbyInternal; @@ -86,16 +91,19 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoSession; import org.mockito.quality.Strictness; +import org.mockito.stubbing.Answer; import java.time.Clock; import java.time.Duration; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executor; @RunWith(AndroidJUnit4.class) public class QuotaControllerTest { @@ -113,6 +121,7 @@ public class QuotaControllerTest { private QuotaController.QcConstants mQcConstants; private int mSourceUid; private IUidObserver mUidObserver; + DeviceConfig.Properties.Builder mDeviceConfigPropertiesBuilder; private MockitoSession mMockingSession; @Mock @@ -133,6 +142,7 @@ public class QuotaControllerTest { mMockingSession = mockitoSession() .initMocks(this) .strictness(Strictness.LENIENT) + .spyStatic(DeviceConfig.class) .mockStatic(LocalServices.class) .startMocking(); @@ -164,6 +174,18 @@ public class QuotaControllerTest { // Used in QuotaController.Handler. mJobStore = JobStore.initAndGetForTesting(mContext, mContext.getFilesDir()); when(mJobSchedulerService.getJobStore()).thenReturn(mJobStore); + // Used in QuotaController.QcConstants + doAnswer((Answer<Void>) invocationOnMock -> null) + .when(() -> DeviceConfig.addOnPropertiesChangedListener( + anyString(), any(Executor.class), + any(DeviceConfig.OnPropertiesChangedListener.class))); + mDeviceConfigPropertiesBuilder = + new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER); + doAnswer( + (Answer<DeviceConfig.Properties>) invocationOnMock + -> mDeviceConfigPropertiesBuilder.build()) + .when(() -> DeviceConfig.getProperties( + eq(DeviceConfig.NAMESPACE_JOB_SCHEDULER), ArgumentMatchers.<String>any())); // Freeze the clocks at 24 hours after this moment in time. Several tests create sessions // in the past, and QuotaController sometimes floors values at 0, so if the test time @@ -285,7 +307,9 @@ public class QuotaControllerTest { private void trackJobs(JobStatus... jobs) { for (JobStatus job : jobs) { mJobStore.add(job); - mQuotaController.maybeStartTrackingJobLocked(job, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + } } } @@ -313,6 +337,22 @@ public class QuotaControllerTest { return new TimingSession(start, start + duration, count); } + private void setDeviceConfigLong(String key, long val) { + mDeviceConfigPropertiesBuilder.setLong(key, val); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForUpdatedConstantsLocked(); + mQcConstants.processConstantLocked(mDeviceConfigPropertiesBuilder.build(), key); + } + } + + private void setDeviceConfigInt(String key, int val) { + mDeviceConfigPropertiesBuilder.setInt(key, val); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForUpdatedConstantsLocked(); + mQcConstants.processConstantLocked(mDeviceConfigPropertiesBuilder.build(), key); + } + } + @Test public void testSaveTimingSession() { assertNull(mQuotaController.getTimingSessions(0, "com.android.test")); @@ -362,7 +402,9 @@ public class QuotaControllerTest { mQuotaController.saveTimingSession(0, "com.android.test", two); mQuotaController.saveTimingSession(0, "com.android.test", one); - mQuotaController.deleteObsoleteSessionsLocked(); + synchronized (mQuotaController.mLock) { + mQuotaController.deleteObsoleteSessionsLocked(); + } assertEquals(expected, mQuotaController.getTimingSessions(0, "com.android.test")); } @@ -396,15 +438,21 @@ public class QuotaControllerTest { expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_RARE; final int uid = 10001; - mQuotaController.onAppRemovedLocked("com.android.test.remove", uid); + synchronized (mQuotaController.mLock) { + mQuotaController.onAppRemovedLocked("com.android.test.remove", uid); + } assertNull(mQuotaController.getTimingSessions(0, "com.android.test.remove")); assertEquals(expected, mQuotaController.getTimingSessions(0, "com.android.test.stay")); - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test.remove", RARE_INDEX)); - assertNotEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test.stay", RARE_INDEX)); - - assertFalse(mQuotaController.getForegroundUids().get(uid)); + synchronized (mQuotaController.mLock) { + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked( + 0, "com.android.test.remove", RARE_INDEX)); + assertNotEquals(expectedStats, + mQuotaController.getExecutionStatsLocked( + 0, "com.android.test.stay", RARE_INDEX)); + + assertFalse(mQuotaController.getForegroundUids().get(uid)); + } } @Test @@ -435,13 +483,15 @@ public class QuotaControllerTest { expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_RARE; expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_RARE; - mQuotaController.onUserRemovedLocked(0); - assertNull(mQuotaController.getTimingSessions(0, "com.android.test")); - assertEquals(expected, mQuotaController.getTimingSessions(10, "com.android.test")); - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test", RARE_INDEX)); - assertNotEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(10, "com.android.test", RARE_INDEX)); + synchronized (mQuotaController.mLock) { + mQuotaController.onUserRemovedLocked(0); + assertNull(mQuotaController.getTimingSessions(0, "com.android.test")); + assertEquals(expected, mQuotaController.getTimingSessions(10, "com.android.test")); + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked(0, "com.android.test", RARE_INDEX)); + assertNotEquals(expectedStats, + mQuotaController.getExecutionStatsLocked(10, "com.android.test", RARE_INDEX)); + } } @Test @@ -470,7 +520,9 @@ public class QuotaControllerTest { inputStats.sessionCountLimit = expectedStats.sessionCountLimit = 100; // Invalid time is now +24 hours since there are no sessions at all for the app. expectedStats.expirationTimeElapsed = now + 24 * HOUR_IN_MILLIS; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test.not.run", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test.not.run", inputStats); + } assertEquals(expectedStats, inputStats); inputStats.windowSizeMs = expectedStats.windowSizeMs = MINUTE_IN_MILLIS; @@ -482,7 +534,9 @@ public class QuotaControllerTest { expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS; expectedStats.bgJobCountInMaxPeriod = 15; expectedStats.sessionCountInWindow = 0; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); inputStats.windowSizeMs = expectedStats.windowSizeMs = 3 * MINUTE_IN_MILLIS; @@ -493,7 +547,9 @@ public class QuotaControllerTest { expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS; expectedStats.bgJobCountInMaxPeriod = 15; expectedStats.sessionCountInWindow = 1; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); inputStats.windowSizeMs = expectedStats.windowSizeMs = 5 * MINUTE_IN_MILLIS; @@ -505,7 +561,9 @@ public class QuotaControllerTest { expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS; expectedStats.bgJobCountInMaxPeriod = 15; expectedStats.sessionCountInWindow = 1; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); inputStats.windowSizeMs = expectedStats.windowSizeMs = 49 * MINUTE_IN_MILLIS; @@ -517,7 +575,9 @@ public class QuotaControllerTest { expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS; expectedStats.bgJobCountInMaxPeriod = 15; expectedStats.sessionCountInWindow = 1; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); inputStats.windowSizeMs = expectedStats.windowSizeMs = 50 * MINUTE_IN_MILLIS; @@ -528,7 +588,9 @@ public class QuotaControllerTest { expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS; expectedStats.bgJobCountInMaxPeriod = 15; expectedStats.sessionCountInWindow = 2; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); inputStats.windowSizeMs = expectedStats.windowSizeMs = HOUR_IN_MILLIS; @@ -542,7 +604,9 @@ public class QuotaControllerTest { expectedStats.bgJobCountInMaxPeriod = 15; expectedStats.sessionCountInWindow = 3; expectedStats.inQuotaTimeElapsed = now + 11 * MINUTE_IN_MILLIS; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); inputStats.windowSizeMs = expectedStats.windowSizeMs = 2 * HOUR_IN_MILLIS; @@ -556,7 +620,9 @@ public class QuotaControllerTest { expectedStats.bgJobCountInMaxPeriod = 15; expectedStats.sessionCountInWindow = 4; expectedStats.inQuotaTimeElapsed = now + 5 * MINUTE_IN_MILLIS; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); inputStats.windowSizeMs = expectedStats.windowSizeMs = 3 * HOUR_IN_MILLIS; @@ -571,7 +637,9 @@ public class QuotaControllerTest { // App goes under job execution time limit in ~61 minutes, but will be under job count limit // in 65 minutes. expectedStats.inQuotaTimeElapsed = now + 65 * MINUTE_IN_MILLIS; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); inputStats.windowSizeMs = expectedStats.windowSizeMs = 6 * HOUR_IN_MILLIS; @@ -584,7 +652,9 @@ public class QuotaControllerTest { expectedStats.bgJobCountInMaxPeriod = 15; expectedStats.sessionCountInWindow = 5; expectedStats.inQuotaTimeElapsed = now + 4 * HOUR_IN_MILLIS + 5 * MINUTE_IN_MILLIS; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); // Make sure expirationTimeElapsed is set correctly when it's dependent on the max period. @@ -603,7 +673,9 @@ public class QuotaControllerTest { expectedStats.sessionCountInWindow = 5; expectedStats.inQuotaTimeElapsed = now + 6 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); mQuotaController.getTimingSessions(0, "com.android.test") @@ -620,7 +692,9 @@ public class QuotaControllerTest { expectedStats.sessionCountInWindow = 5; expectedStats.inQuotaTimeElapsed = now + 6 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS; - mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats); + } assertEquals(expectedStats, inputStats); } @@ -641,18 +715,23 @@ public class QuotaControllerTest { for (int i = 1; i < mQcConstants.MAX_JOB_COUNT_RARE; ++i) { JobStatus jobStatus = createJobStatus("testUpdateExecutionStatsLocked_WithTimer", i); setStandbyBucket(RARE_INDEX, jobStatus); // 24 hour window - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(7000); expectedStats.expirationTimeElapsed = sElapsedRealtimeClock.millis(); expectedStats.executionTimeInWindowMs = expectedStats.executionTimeInMaxPeriodMs = 7000 * i; expectedStats.bgJobCountInWindow = expectedStats.bgJobCountInMaxPeriod = i; - mQuotaController.updateExecutionStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); - assertEquals(expectedStats, inputStats); - assertTrue(mQuotaController.isWithinQuotaLocked(SOURCE_USER_ID, SOURCE_PACKAGE, - RARE_INDEX)); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); + assertEquals(expectedStats, inputStats); + assertTrue(mQuotaController.isWithinQuotaLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); + } assertTrue("Job not ready: " + jobStatus, jobStatus.isReady()); } @@ -670,16 +749,21 @@ public class QuotaControllerTest { // Active timer is under quota, so out of quota due to old session. expectedStats.inQuotaTimeElapsed = sElapsedRealtimeClock.millis() + 18 * HOUR_IN_MILLIS + 10 * MINUTE_IN_MILLIS; - mQuotaController.updateExecutionStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); - assertEquals(expectedStats, inputStats); - assertFalse( - mQuotaController.isWithinQuotaLocked(SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); + assertEquals(expectedStats, inputStats); + assertFalse( + mQuotaController.isWithinQuotaLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); + } // Quota should be exceeded due to activity in active timer. JobStatus jobStatus = createJobStatus("testUpdateExecutionStatsLocked_WithTimer", 0); setStandbyBucket(RARE_INDEX, jobStatus); // 24 hour window - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(10000); expectedStats.executionTimeInWindowMs += 10000; @@ -690,11 +774,14 @@ public class QuotaControllerTest { // time has passed since active timer. expectedStats.inQuotaTimeElapsed = sElapsedRealtimeClock.millis() + expectedStats.windowSizeMs; - mQuotaController.updateExecutionStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); - assertEquals(expectedStats, inputStats); - assertFalse( - mQuotaController.isWithinQuotaLocked(SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); - assertFalse("Job unexpectedly ready: " + jobStatus, jobStatus.isReady()); + synchronized (mQuotaController.mLock) { + mQuotaController.updateExecutionStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); + assertEquals(expectedStats, inputStats); + assertFalse( + mQuotaController.isWithinQuotaLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); + assertFalse("Job unexpectedly ready: " + jobStatus, jobStatus.isReady()); + } } /** @@ -724,8 +811,10 @@ public class QuotaControllerTest { expectedStats.executionTimeInMaxPeriodMs = 33 * MINUTE_IN_MILLIS; expectedStats.bgJobCountInMaxPeriod = 20; expectedStats.sessionCountInWindow = 1; - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test", ACTIVE_INDEX)); + synchronized (mQuotaController.mLock) { + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked(0, "com.android.test", ACTIVE_INDEX)); + } // Working expectedStats.windowSizeMs = 2 * HOUR_IN_MILLIS; @@ -739,8 +828,10 @@ public class QuotaControllerTest { expectedStats.sessionCountInWindow = 2; expectedStats.inQuotaTimeElapsed = now + 3 * MINUTE_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS; - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test", WORKING_INDEX)); + synchronized (mQuotaController.mLock) { + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked(0, "com.android.test", WORKING_INDEX)); + } // Frequent expectedStats.windowSizeMs = 8 * HOUR_IN_MILLIS; @@ -754,8 +845,11 @@ public class QuotaControllerTest { expectedStats.sessionCountInWindow = 3; expectedStats.inQuotaTimeElapsed = now + 6 * HOUR_IN_MILLIS + 3 * MINUTE_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS; - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test", FREQUENT_INDEX)); + synchronized (mQuotaController.mLock) { + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX)); + } // Rare expectedStats.windowSizeMs = 24 * HOUR_IN_MILLIS; @@ -769,8 +863,10 @@ public class QuotaControllerTest { expectedStats.sessionCountInWindow = 4; expectedStats.inQuotaTimeElapsed = now + 22 * HOUR_IN_MILLIS + 3 * MINUTE_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS; - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test", RARE_INDEX)); + synchronized (mQuotaController.mLock) { + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked(0, "com.android.test", RARE_INDEX)); + } } /** @@ -797,32 +893,41 @@ public class QuotaControllerTest { expectedStats.executionTimeInMaxPeriodMs = MINUTE_IN_MILLIS; expectedStats.bgJobCountInMaxPeriod = 2; expectedStats.sessionCountInWindow = 1; - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test", ACTIVE_INDEX)); + synchronized (mQuotaController.mLock) { + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked(0, "com.android.test", ACTIVE_INDEX)); + } // Working expectedStats.windowSizeMs = 2 * HOUR_IN_MILLIS; expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_WORKING; expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_WORKING; expectedStats.expirationTimeElapsed = 2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS; - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test", WORKING_INDEX)); + synchronized (mQuotaController.mLock) { + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked(0, "com.android.test", WORKING_INDEX)); + } // Frequent expectedStats.windowSizeMs = 8 * HOUR_IN_MILLIS; expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_FREQUENT; expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_FREQUENT; expectedStats.expirationTimeElapsed = 8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS; - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test", FREQUENT_INDEX)); + synchronized (mQuotaController.mLock) { + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX)); + } // Rare expectedStats.windowSizeMs = 24 * HOUR_IN_MILLIS; expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_RARE; expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_RARE; expectedStats.expirationTimeElapsed = 24 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS; - assertEquals(expectedStats, - mQuotaController.getExecutionStatsLocked(0, "com.android.test", RARE_INDEX)); + synchronized (mQuotaController.mLock) { + assertEquals(expectedStats, + mQuotaController.getExecutionStatsLocked(0, "com.android.test", RARE_INDEX)); + } } /** @@ -858,111 +963,123 @@ public class QuotaControllerTest { advanceElapsedClock(40 * MINUTE_IN_MILLIS); } - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 0; - mQcConstants.updateConstants(); - - mQuotaController.invalidateAllExecutionStatsLocked(); - assertEquals(0, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); - assertEquals(32, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); - assertEquals(128, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); - assertEquals(160, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 500; - mQcConstants.updateConstants(); - - mQuotaController.invalidateAllExecutionStatsLocked(); - assertEquals(0, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); - assertEquals(22, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); - assertEquals(88, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); - assertEquals(110, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 1000; - mQcConstants.updateConstants(); - - mQuotaController.invalidateAllExecutionStatsLocked(); - assertEquals(0, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); - assertEquals(22, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); - assertEquals(88, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); - assertEquals(110, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 5 * SECOND_IN_MILLIS; - mQcConstants.updateConstants(); - - mQuotaController.invalidateAllExecutionStatsLocked(); - assertEquals(0, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); - assertEquals(14, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); - assertEquals(56, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); - assertEquals(70, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = MINUTE_IN_MILLIS; - mQcConstants.updateConstants(); - - mQuotaController.invalidateAllExecutionStatsLocked(); - assertEquals(0, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); - assertEquals(4, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); - assertEquals(16, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); - assertEquals(20, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 5 * MINUTE_IN_MILLIS; - mQcConstants.updateConstants(); - - mQuotaController.invalidateAllExecutionStatsLocked(); - assertEquals(0, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); - assertEquals(2, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); - assertEquals(8, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); - assertEquals(10, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 15 * MINUTE_IN_MILLIS; - mQcConstants.updateConstants(); - - mQuotaController.invalidateAllExecutionStatsLocked(); - assertEquals(0, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); - assertEquals(2, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); - assertEquals(8, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); - assertEquals(10, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, 0); + + synchronized (mQuotaController.mLock) { + mQuotaController.invalidateAllExecutionStatsLocked(); + assertEquals(0, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); + assertEquals(32, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); + assertEquals(128, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); + assertEquals(160, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + } + + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, 500); + + synchronized (mQuotaController.mLock) { + mQuotaController.invalidateAllExecutionStatsLocked(); + assertEquals(0, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); + assertEquals(22, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); + assertEquals(88, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); + assertEquals(110, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + } + + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, 1000); + + synchronized (mQuotaController.mLock) { + mQuotaController.invalidateAllExecutionStatsLocked(); + assertEquals(0, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); + assertEquals(22, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); + assertEquals(88, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); + assertEquals(110, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + } + + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + 5 * SECOND_IN_MILLIS); + + synchronized (mQuotaController.mLock) { + mQuotaController.invalidateAllExecutionStatsLocked(); + assertEquals(0, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); + assertEquals(14, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); + assertEquals(56, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); + assertEquals(70, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + } + + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + MINUTE_IN_MILLIS); + + synchronized (mQuotaController.mLock) { + mQuotaController.invalidateAllExecutionStatsLocked(); + assertEquals(0, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); + assertEquals(4, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); + assertEquals(16, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); + assertEquals(20, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + } + + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + 5 * MINUTE_IN_MILLIS); + + synchronized (mQuotaController.mLock) { + mQuotaController.invalidateAllExecutionStatsLocked(); + assertEquals(0, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); + assertEquals(2, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); + assertEquals(8, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); + assertEquals(10, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + } + + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + 15 * MINUTE_IN_MILLIS); + + synchronized (mQuotaController.mLock) { + mQuotaController.invalidateAllExecutionStatsLocked(); + assertEquals(0, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); + assertEquals(2, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); + assertEquals(8, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); + assertEquals(10, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + } // QuotaController caps the duration at 15 minutes, so there shouldn't be any difference // between an hour and 15 minutes. - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = HOUR_IN_MILLIS; - mQcConstants.updateConstants(); - - mQuotaController.invalidateAllExecutionStatsLocked(); - assertEquals(0, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); - assertEquals(2, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); - assertEquals(8, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); - assertEquals(10, mQuotaController.getExecutionStatsLocked( - 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, HOUR_IN_MILLIS); + + synchronized (mQuotaController.mLock) { + mQuotaController.invalidateAllExecutionStatsLocked(); + assertEquals(0, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow); + assertEquals(2, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX).sessionCountInWindow); + assertEquals(8, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow); + assertEquals(10, mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX).sessionCountInWindow); + } } /** @@ -982,20 +1099,25 @@ public class QuotaControllerTest { createTimingSession(now - (2 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5)); mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - (6 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5)); - final ExecutionStats originalStatsActive = mQuotaController.getExecutionStatsLocked(0, - "com.android.test", ACTIVE_INDEX); - final ExecutionStats originalStatsWorking = mQuotaController.getExecutionStatsLocked(0, - "com.android.test", WORKING_INDEX); - final ExecutionStats originalStatsFrequent = mQuotaController.getExecutionStatsLocked(0, - "com.android.test", FREQUENT_INDEX); - final ExecutionStats originalStatsRare = mQuotaController.getExecutionStatsLocked(0, - "com.android.test", RARE_INDEX); + final ExecutionStats originalStatsActive; + final ExecutionStats originalStatsWorking; + final ExecutionStats originalStatsFrequent; + final ExecutionStats originalStatsRare; + synchronized (mQuotaController.mLock) { + originalStatsActive = mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX); + originalStatsWorking = mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX); + originalStatsFrequent = mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX); + originalStatsRare = mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX); + } // Advance clock so that the working stats shouldn't be the same. advanceElapsedClock(MINUTE_IN_MILLIS); // Change frequent bucket size so that the stats need to be recalculated. - mQcConstants.WINDOW_SIZE_FREQUENT_MS = 6 * HOUR_IN_MILLIS; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_FREQUENT_MS, 6 * HOUR_IN_MILLIS); ExecutionStats expectedStats = new ExecutionStats(); expectedStats.windowSizeMs = originalStatsActive.windowSizeMs; @@ -1008,8 +1130,11 @@ public class QuotaControllerTest { expectedStats.bgJobCountInMaxPeriod = originalStatsActive.bgJobCountInMaxPeriod; expectedStats.sessionCountInWindow = originalStatsActive.sessionCountInWindow; expectedStats.inQuotaTimeElapsed = originalStatsActive.inQuotaTimeElapsed; - final ExecutionStats newStatsActive = mQuotaController.getExecutionStatsLocked(0, - "com.android.test", ACTIVE_INDEX); + final ExecutionStats newStatsActive; + synchronized (mQuotaController.mLock) { + newStatsActive = mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", ACTIVE_INDEX); + } // Stats for the same bucket should use the same object. assertTrue(originalStatsActive == newStatsActive); assertEquals(expectedStats, newStatsActive); @@ -1022,8 +1147,11 @@ public class QuotaControllerTest { expectedStats.bgJobCountInWindow = originalStatsWorking.bgJobCountInWindow; expectedStats.sessionCountInWindow = originalStatsWorking.sessionCountInWindow; expectedStats.inQuotaTimeElapsed = originalStatsWorking.inQuotaTimeElapsed; - final ExecutionStats newStatsWorking = mQuotaController.getExecutionStatsLocked(0, - "com.android.test", WORKING_INDEX); + final ExecutionStats newStatsWorking; + synchronized (mQuotaController.mLock) { + newStatsWorking = mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", WORKING_INDEX); + } assertTrue(originalStatsWorking == newStatsWorking); assertNotEquals(expectedStats, newStatsWorking); @@ -1035,8 +1163,11 @@ public class QuotaControllerTest { expectedStats.bgJobCountInWindow = originalStatsFrequent.bgJobCountInWindow; expectedStats.sessionCountInWindow = originalStatsFrequent.sessionCountInWindow; expectedStats.inQuotaTimeElapsed = originalStatsFrequent.inQuotaTimeElapsed; - final ExecutionStats newStatsFrequent = mQuotaController.getExecutionStatsLocked(0, - "com.android.test", FREQUENT_INDEX); + final ExecutionStats newStatsFrequent; + synchronized (mQuotaController.mLock) { + newStatsFrequent = mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", FREQUENT_INDEX); + } assertTrue(originalStatsFrequent == newStatsFrequent); assertNotEquals(expectedStats, newStatsFrequent); @@ -1048,8 +1179,11 @@ public class QuotaControllerTest { expectedStats.bgJobCountInWindow = originalStatsRare.bgJobCountInWindow; expectedStats.sessionCountInWindow = originalStatsRare.sessionCountInWindow; expectedStats.inQuotaTimeElapsed = originalStatsRare.inQuotaTimeElapsed; - final ExecutionStats newStatsRare = mQuotaController.getExecutionStatsLocked(0, - "com.android.test", RARE_INDEX); + final ExecutionStats newStatsRare; + synchronized (mQuotaController.mLock) { + newStatsRare = mQuotaController.getExecutionStatsLocked( + 0, "com.android.test", RARE_INDEX); + } assertTrue(originalStatsRare == newStatsRare); assertEquals(expectedStats, newStatsRare); } @@ -1063,26 +1197,36 @@ public class QuotaControllerTest { job.setStandbyBucket(RARE_INDEX); setCharging(); - assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS, - mQuotaController.getMaxJobExecutionTimeMsLocked((job))); + synchronized (mQuotaController.mLock) { + assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS, + mQuotaController.getMaxJobExecutionTimeMsLocked((job))); + } setDischarging(); setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); - assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS, - mQuotaController.getMaxJobExecutionTimeMsLocked((job))); + synchronized (mQuotaController.mLock) { + assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS, + mQuotaController.getMaxJobExecutionTimeMsLocked((job))); + } // Top-started job setProcessState(ActivityManager.PROCESS_STATE_TOP); - mQuotaController.maybeStartTrackingJobLocked(job, null); - mQuotaController.prepareForExecutionLocked(job); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + mQuotaController.prepareForExecutionLocked(job); + } setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); - assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS, - mQuotaController.getMaxJobExecutionTimeMsLocked((job))); - mQuotaController.maybeStopTrackingJobLocked(job, null, false); + synchronized (mQuotaController.mLock) { + assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS, + mQuotaController.getMaxJobExecutionTimeMsLocked((job))); + mQuotaController.maybeStopTrackingJobLocked(job, null, false); + } setProcessState(ActivityManager.PROCESS_STATE_RECEIVER); - assertEquals(7 * MINUTE_IN_MILLIS, - mQuotaController.getMaxJobExecutionTimeMsLocked(job)); + synchronized (mQuotaController.mLock) { + assertEquals(7 * MINUTE_IN_MILLIS, + mQuotaController.getMaxJobExecutionTimeMsLocked(job)); + } } /** @@ -1108,30 +1252,46 @@ public class QuotaControllerTest { createTimingSession(now - (9 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5)); setStandbyBucket(RARE_INDEX); - assertEquals(30 * SECOND_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + assertEquals(30 * SECOND_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } setStandbyBucket(FREQUENT_INDEX); - assertEquals(MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + assertEquals(MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } setStandbyBucket(WORKING_INDEX); - assertEquals(5 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(7 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + assertEquals(5 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(7 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } // ACTIVE window = allowed time, so jobs can essentially run non-stop until they reach the // max execution time. setStandbyBucket(ACTIVE_INDEX); - assertEquals(7 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + assertEquals(7 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } } /** @@ -1146,11 +1306,15 @@ public class QuotaControllerTest { now - (24 * HOUR_IN_MILLIS + 8 * MINUTE_IN_MILLIS), 4 * HOUR_IN_MILLIS, 5)); setStandbyBucket(WORKING_INDEX); - assertEquals(8 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - // Max time will phase out, so should use bucket limit. - assertEquals(10 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + assertEquals(8 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + // Max time will phase out, so should use bucket limit. + assertEquals(10 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); // Close to boundary. @@ -1159,10 +1323,14 @@ public class QuotaControllerTest { 4 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS, 5)); setStandbyBucket(WORKING_INDEX); - assertEquals(5 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(10 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + assertEquals(5 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(10 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); // Far from boundary. @@ -1171,10 +1339,14 @@ public class QuotaControllerTest { now - (20 * HOUR_IN_MILLIS), 4 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS, 5)); setStandbyBucket(WORKING_INDEX); - assertEquals(3 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(3 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + assertEquals(3 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(3 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } } /** @@ -1196,13 +1368,17 @@ public class QuotaControllerTest { createTimingSession( now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5)); - // Both max and bucket time have 8 minutes left. - assertEquals(8 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - // Max time essentially free. Bucket time has 2 min phase out plus original 8 minute - // window time. - assertEquals(10 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + // Both max and bucket time have 8 minutes left. + assertEquals(8 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + // Max time essentially free. Bucket time has 2 min phase out plus original 8 minute + // window time. + assertEquals(10 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); // Overlap boundary. @@ -1218,23 +1394,32 @@ public class QuotaControllerTest { createTimingSession( now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5)); - // Both max and bucket time have 8 minutes left. - assertEquals(8 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - // Max time only has one minute phase out. Bucket time has 2 minute phase out. - assertEquals(9 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + // Both max and bucket time have 8 minutes left. + assertEquals(8 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + // Max time only has one minute phase out. Bucket time has 2 minute phase out. + assertEquals(9 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } } @Test public void testIsWithinQuotaLocked_NeverApp() { - assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test.never", NEVER_INDEX)); + synchronized (mQuotaController.mLock) { + assertFalse( + mQuotaController.isWithinQuotaLocked(0, "com.android.test.never", NEVER_INDEX)); + } } @Test public void testIsWithinQuotaLocked_Charging() { setCharging(); - assertTrue(mQuotaController.isWithinQuotaLocked(0, "com.android.test", RARE_INDEX)); + synchronized (mQuotaController.mLock) { + assertTrue(mQuotaController.isWithinQuotaLocked(0, "com.android.test", RARE_INDEX)); + } } @Test @@ -1246,7 +1431,9 @@ public class QuotaControllerTest { mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5)); mQuotaController.incrementJobCount(0, "com.android.test", 5); - assertTrue(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); + synchronized (mQuotaController.mLock) { + assertTrue(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); + } } @Test @@ -1259,15 +1446,19 @@ public class QuotaControllerTest { mQuotaController.saveTimingSession(0, "com.android.test.spam", createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, jobCount)); mQuotaController.incrementJobCount(0, "com.android.test.spam", jobCount); - assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test.spam", - WORKING_INDEX)); + synchronized (mQuotaController.mLock) { + assertFalse(mQuotaController.isWithinQuotaLocked( + 0, "com.android.test.spam", WORKING_INDEX)); + } mQuotaController.saveTimingSession(0, "com.android.test.frequent", createTimingSession(now - (2 * HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 2000)); mQuotaController.saveTimingSession(0, "com.android.test.frequent", createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 500)); - assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test.frequent", - FREQUENT_INDEX)); + synchronized (mQuotaController.mLock) { + assertFalse(mQuotaController.isWithinQuotaLocked( + 0, "com.android.test.frequent", FREQUENT_INDEX)); + } } @Test @@ -1281,7 +1472,9 @@ public class QuotaControllerTest { mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - (5 * MINUTE_IN_MILLIS), 4 * MINUTE_IN_MILLIS, 5)); mQuotaController.incrementJobCount(0, "com.android.test", 5); - assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); + synchronized (mQuotaController.mLock) { + assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); + } } @Test @@ -1294,7 +1487,9 @@ public class QuotaControllerTest { mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, jobCount)); mQuotaController.incrementJobCount(0, "com.android.test", jobCount); - assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); + synchronized (mQuotaController.mLock) { + assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); + } } @Test @@ -1306,32 +1501,42 @@ public class QuotaControllerTest { setStandbyBucket(ACTIVE_INDEX, jobStatus); setProcessState(ActivityManager.PROCESS_STATE_BACKUP); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + } for (int i = 0; i < 20; ++i) { advanceElapsedClock(SECOND_IN_MILLIS); setProcessState(ActivityManager.PROCESS_STATE_SERVICE); setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); } - mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + } advanceElapsedClock(15 * SECOND_IN_MILLIS); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + } for (int i = 0; i < 20; ++i) { advanceElapsedClock(SECOND_IN_MILLIS); setProcessState(ActivityManager.PROCESS_STATE_SERVICE); setProcessState(ActivityManager.PROCESS_STATE_RECEIVER); } - mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + } advanceElapsedClock(10 * MINUTE_IN_MILLIS + 30 * SECOND_IN_MILLIS); - assertEquals(2, mQuotaController.getExecutionStatsLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, ACTIVE_INDEX).jobCountInRateLimitingWindow); - assertTrue(mQuotaController.isWithinQuotaLocked(jobStatus)); - assertTrue(jobStatus.isReady()); + synchronized (mQuotaController.mLock) { + assertEquals(2, mQuotaController.getExecutionStatsLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, ACTIVE_INDEX).jobCountInRateLimitingWindow); + assertTrue(mQuotaController.isWithinQuotaLocked(jobStatus)); + assertTrue(jobStatus.isReady()); + } } @Test @@ -1368,44 +1573,54 @@ public class QuotaControllerTest { doReturn(new String[]{fgChangerPkgName}) .when(packageManager).getPackagesForUid(fgChangerUid); - mQuotaController.maybeStartTrackingJobLocked(unaffected, null); - mQuotaController.prepareForExecutionLocked(unaffected); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(unaffected, null); + mQuotaController.prepareForExecutionLocked(unaffected); - mQuotaController.maybeStartTrackingJobLocked(fgStateChanger, null); - mQuotaController.prepareForExecutionLocked(fgStateChanger); + mQuotaController.maybeStartTrackingJobLocked(fgStateChanger, null); + mQuotaController.prepareForExecutionLocked(fgStateChanger); + } for (int i = 0; i < 20; ++i) { advanceElapsedClock(SECOND_IN_MILLIS); setProcessState(ActivityManager.PROCESS_STATE_TOP, fgChangerUid); setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING, fgChangerUid); } - mQuotaController.maybeStopTrackingJobLocked(fgStateChanger, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(fgStateChanger, null, false); + } advanceElapsedClock(15 * SECOND_IN_MILLIS); - mQuotaController.maybeStartTrackingJobLocked(fgStateChanger, null); - mQuotaController.prepareForExecutionLocked(fgStateChanger); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(fgStateChanger, null); + mQuotaController.prepareForExecutionLocked(fgStateChanger); + } for (int i = 0; i < 20; ++i) { advanceElapsedClock(SECOND_IN_MILLIS); setProcessState(ActivityManager.PROCESS_STATE_TOP, fgChangerUid); setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING, fgChangerUid); } - mQuotaController.maybeStopTrackingJobLocked(fgStateChanger, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(fgStateChanger, null, false); - mQuotaController.maybeStopTrackingJobLocked(unaffected, null, false); + mQuotaController.maybeStopTrackingJobLocked(unaffected, null, false); - assertTrue(mQuotaController.isWithinQuotaLocked(unaffected)); - assertTrue(unaffected.isReady()); - assertFalse(mQuotaController.isWithinQuotaLocked(fgStateChanger)); - assertFalse(fgStateChanger.isReady()); + assertTrue(mQuotaController.isWithinQuotaLocked(unaffected)); + assertTrue(unaffected.isReady()); + assertFalse(mQuotaController.isWithinQuotaLocked(fgStateChanger)); + assertFalse(fgStateChanger.isReady()); + } assertEquals(1, mQuotaController.getTimingSessions(SOURCE_USER_ID, unaffectedPkgName).size()); assertEquals(42, mQuotaController.getTimingSessions(SOURCE_USER_ID, fgChangerPkgName).size()); - for (int i = ACTIVE_INDEX; i < RARE_INDEX; ++i) { - assertEquals(42, mQuotaController.getExecutionStatsLocked( - SOURCE_USER_ID, fgChangerPkgName, i).jobCountInRateLimitingWindow); - assertEquals(1, mQuotaController.getExecutionStatsLocked( - SOURCE_USER_ID, unaffectedPkgName, i).jobCountInRateLimitingWindow); + synchronized (mQuotaController.mLock) { + for (int i = ACTIVE_INDEX; i < RARE_INDEX; ++i) { + assertEquals(42, mQuotaController.getExecutionStatsLocked( + SOURCE_USER_ID, fgChangerPkgName, i).jobCountInRateLimitingWindow); + assertEquals(1, mQuotaController.getExecutionStatsLocked( + SOURCE_USER_ID, unaffectedPkgName, i).jobCountInRateLimitingWindow); + } } } @@ -1413,11 +1628,10 @@ public class QuotaControllerTest { public void testIsWithinQuotaLocked_TimingSession() { setDischarging(); final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQcConstants.MAX_SESSION_COUNT_RARE = 3; - mQcConstants.MAX_SESSION_COUNT_FREQUENT = 4; - mQcConstants.MAX_SESSION_COUNT_WORKING = 5; - mQcConstants.MAX_SESSION_COUNT_ACTIVE = 6; - mQcConstants.updateConstants(); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_RARE, 3); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_FREQUENT, 4); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_WORKING, 5); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_ACTIVE, 6); for (int i = 0; i < 7; ++i) { mQuotaController.saveTimingSession(0, "com.android.test", @@ -1425,25 +1639,30 @@ public class QuotaControllerTest { 2)); mQuotaController.incrementJobCount(0, "com.android.test", 2); - assertEquals("Rare has incorrect quota status with " + (i + 1) + " sessions", - i < 2, - mQuotaController.isWithinQuotaLocked(0, "com.android.test", RARE_INDEX)); - assertEquals("Frequent has incorrect quota status with " + (i + 1) + " sessions", - i < 3, - mQuotaController.isWithinQuotaLocked(0, "com.android.test", FREQUENT_INDEX)); - assertEquals("Working has incorrect quota status with " + (i + 1) + " sessions", - i < 4, - mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); - assertEquals("Active has incorrect quota status with " + (i + 1) + " sessions", - i < 5, - mQuotaController.isWithinQuotaLocked(0, "com.android.test", ACTIVE_INDEX)); + synchronized (mQuotaController.mLock) { + assertEquals("Rare has incorrect quota status with " + (i + 1) + " sessions", + i < 2, + mQuotaController.isWithinQuotaLocked(0, "com.android.test", RARE_INDEX)); + assertEquals("Frequent has incorrect quota status with " + (i + 1) + " sessions", + i < 3, + mQuotaController.isWithinQuotaLocked( + 0, "com.android.test", FREQUENT_INDEX)); + assertEquals("Working has incorrect quota status with " + (i + 1) + " sessions", + i < 4, + mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); + assertEquals("Active has incorrect quota status with " + (i + 1) + " sessions", + i < 5, + mQuotaController.isWithinQuotaLocked(0, "com.android.test", ACTIVE_INDEX)); + } } } @Test public void testMaybeScheduleCleanupAlarmLocked() { // No sessions saved yet. - mQuotaController.maybeScheduleCleanupAlarmLocked(); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleCleanupAlarmLocked(); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_CLEANUP), any(), any()); // Test with only one timing session saved. @@ -1451,7 +1670,9 @@ public class QuotaControllerTest { final long end = now - (6 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS); mQuotaController.saveTimingSession(0, "com.android.test", new TimingSession(now - 6 * HOUR_IN_MILLIS, end, 1)); - mQuotaController.maybeScheduleCleanupAlarmLocked(); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleCleanupAlarmLocked(); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(end + 24 * HOUR_IN_MILLIS), eq(TAG_CLEANUP), any(), any()); @@ -1460,7 +1681,9 @@ public class QuotaControllerTest { createTimingSession(now - 3 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1)); mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - HOUR_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleCleanupAlarmLocked(); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleCleanupAlarmLocked(); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(end + 24 * HOUR_IN_MILLIS), eq(TAG_CLEANUP), any(), any()); } @@ -1477,8 +1700,10 @@ public class QuotaControllerTest { setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); // No sessions saved yet. - mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE, - standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); @@ -1491,27 +1716,35 @@ public class QuotaControllerTest { createTimingSession(now - 12 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1)); mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, createTimingSession(now - 7 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE, - standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, createTimingSession(now - 2 * HOUR_IN_MILLIS, 55 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE, - standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); JobStatus jobStatus = createJobStatus("testMaybeScheduleStartAlarmLocked_Active", 1); setStandbyBucket(standbyBucket, jobStatus); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(5 * MINUTE_IN_MILLIS); - // Timer has only been going for 5 minutes in the past 10 minutes, which is under the window - // size limit, but the total execution time for the past 24 hours is 6 hours, so the job no - // longer has quota. - assertEquals(0, mQuotaController.getRemainingExecutionTimeLocked(jobStatus)); - mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE, - standbyBucket); + synchronized (mQuotaController.mLock) { + // Timer has only been going for 5 minutes in the past 10 minutes, which is under the + // window size limit, but the total execution time for the past 24 hours is 6 hours, so + // the job no longer has quota. + assertEquals(0, mQuotaController.getRemainingExecutionTimeLocked(jobStatus)); + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, times(1)).set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); } @@ -1526,15 +1759,19 @@ public class QuotaControllerTest { // Working set window size is 2 hours. final int standbyBucket = WORKING_INDEX; - // No sessions saved yet. - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + // No sessions saved yet. + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Test with timing sessions out of window. final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - 10 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Test with timing sessions in window but still in quota. @@ -1544,7 +1781,9 @@ public class QuotaControllerTest { end - MINUTE_IN_MILLIS + 2 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS; mQuotaController.saveTimingSession(0, "com.android.test", new TimingSession(now - 2 * HOUR_IN_MILLIS, end, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Add some more sessions, but still in quota. @@ -1552,18 +1791,24 @@ public class QuotaControllerTest { createTimingSession(now - HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1)); mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - (50 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Test when out of quota. mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - 30 * MINUTE_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); // Alarm already scheduled, so make sure it's not scheduled again. - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); } @@ -1579,14 +1824,18 @@ public class QuotaControllerTest { final int standbyBucket = FREQUENT_INDEX; // No sessions saved yet. - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Test with timing sessions out of window. final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - 10 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Test with timing sessions in window but still in quota. @@ -1594,7 +1843,9 @@ public class QuotaControllerTest { final long expectedAlarmTime = start + 8 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS; mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Add some more sessions, but still in quota. @@ -1602,18 +1853,24 @@ public class QuotaControllerTest { createTimingSession(now - 3 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1)); mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - HOUR_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Test when out of quota. mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); // Alarm already scheduled, so make sure it's not scheduled again. - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); } @@ -1629,18 +1886,21 @@ public class QuotaControllerTest { final int standbyBucket = RARE_INDEX; // Prevent timing session throttling from affecting the test. - mQcConstants.MAX_SESSION_COUNT_RARE = 50; - mQcConstants.updateConstants(); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_RARE, 50); // No sessions saved yet. - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Test with timing sessions out of window. final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - 25 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Test with timing sessions in window but still in quota. @@ -1652,7 +1912,9 @@ public class QuotaControllerTest { + mQcConstants.IN_QUOTA_BUFFER_MS; mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Add some more sessions, but still in quota. @@ -1660,18 +1922,24 @@ public class QuotaControllerTest { createTimingSession(now - 3 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1)); mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - HOUR_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Test when out of quota. mQuotaController.saveTimingSession(0, "com.android.test", createTimingSession(now - HOUR_IN_MILLIS, 2 * MINUTE_IN_MILLIS, 1)); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); // Alarm already scheduled, so make sure it's not scheduled again. - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); } @@ -1703,7 +1971,9 @@ public class QuotaControllerTest { InOrder inOrder = inOrder(mAlarmManager); // Start in ACTIVE bucket. - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", ACTIVE_INDEX); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", ACTIVE_INDEX); + } inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); inOrder.verify(mAlarmManager, never()).cancel(any(AlarmManager.OnAlarmListener.class)); @@ -1712,34 +1982,46 @@ public class QuotaControllerTest { final long expectedWorkingAlarmTime = outOfQuotaTime + (2 * HOUR_IN_MILLIS) + mQcConstants.IN_QUOTA_BUFFER_MS; - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", WORKING_INDEX); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", WORKING_INDEX); + } inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); final long expectedFrequentAlarmTime = outOfQuotaTime + (8 * HOUR_IN_MILLIS) + mQcConstants.IN_QUOTA_BUFFER_MS; - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", FREQUENT_INDEX); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", FREQUENT_INDEX); + } inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedFrequentAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); final long expectedRareAlarmTime = outOfQuotaTime + (24 * HOUR_IN_MILLIS) + mQcConstants.IN_QUOTA_BUFFER_MS; - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", RARE_INDEX); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", RARE_INDEX); + } inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedRareAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); // And back up again. - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", FREQUENT_INDEX); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", FREQUENT_INDEX); + } inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedFrequentAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", WORKING_INDEX); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", WORKING_INDEX); + } inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); - mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", ACTIVE_INDEX); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", ACTIVE_INDEX); + } inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); inOrder.verify(mAlarmManager, times(1)).cancel(any(AlarmManager.OnAlarmListener.class)); @@ -1749,28 +2031,34 @@ public class QuotaControllerTest { public void testMaybeScheduleStartAlarmLocked_JobCount_RateLimitingWindow() { // Set rate limiting period different from allowed time to confirm code sets based on // the former. - mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 10 * MINUTE_IN_MILLIS; - mQcConstants.RATE_LIMITING_WINDOW_MS = 5 * MINUTE_IN_MILLIS; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, 10 * MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_RATE_LIMITING_WINDOW_MS, 5 * MINUTE_IN_MILLIS); final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); final int standbyBucket = WORKING_INDEX; - ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID, - SOURCE_PACKAGE, standbyBucket); + ExecutionStats stats; + synchronized (mQuotaController.mLock) { + stats = mQuotaController.getExecutionStatsLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } stats.jobCountInRateLimitingWindow = mQcConstants.MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW + 2; // Invalid time in the past, so the count shouldn't be used. stats.jobRateLimitExpirationTimeElapsed = now - 5 * MINUTE_IN_MILLIS / 2; - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Valid time in the future, so the count should be used. stats.jobRateLimitExpirationTimeElapsed = now + 5 * MINUTE_IN_MILLIS / 2; final long expectedWorkingAlarmTime = stats.jobRateLimitExpirationTimeElapsed; - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); } @@ -1790,8 +2078,9 @@ public class QuotaControllerTest { @Test public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedBufferSize() { // Make sure any new value is used correctly. - mQcConstants.IN_QUOTA_BUFFER_MS *= 2; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, + mQcConstants.IN_QUOTA_BUFFER_MS * 2); + runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck(); mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck(); @@ -1800,8 +2089,9 @@ public class QuotaControllerTest { @Test public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedAllowedTime() { // Make sure any new value is used correctly. - mQcConstants.ALLOWED_TIME_PER_PERIOD_MS /= 2; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, + mQcConstants.ALLOWED_TIME_PER_PERIOD_MS / 2); + runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck(); mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck(); @@ -1810,8 +2100,9 @@ public class QuotaControllerTest { @Test public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedMaxTime() { // Make sure any new value is used correctly. - mQcConstants.MAX_EXECUTION_TIME_MS /= 2; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, + mQcConstants.MAX_EXECUTION_TIME_MS / 2); + runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck(); mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck(); @@ -1820,10 +2111,13 @@ public class QuotaControllerTest { @Test public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedEverything() { // Make sure any new value is used correctly. - mQcConstants.IN_QUOTA_BUFFER_MS *= 2; - mQcConstants.ALLOWED_TIME_PER_PERIOD_MS /= 2; - mQcConstants.MAX_EXECUTION_TIME_MS /= 2; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, + mQcConstants.IN_QUOTA_BUFFER_MS * 2); + setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, + mQcConstants.ALLOWED_TIME_PER_PERIOD_MS / 2); + setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, + mQcConstants.MAX_EXECUTION_TIME_MS / 2); + runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck(); mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck(); @@ -1852,8 +2146,10 @@ public class QuotaControllerTest { // is 2 hours + (QUOTA_BUFFER_MS - contributionMs) after the start of the second session. final long expectedAlarmTime = now - HOUR_IN_MILLIS + 2 * HOUR_IN_MILLIS + (mQcConstants.IN_QUOTA_BUFFER_MS - contributionMs); - mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE, - standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); } @@ -1883,35 +2179,40 @@ public class QuotaControllerTest { final long expectedAlarmTime = now - 20 * HOUR_IN_MILLIS + 24 * HOUR_IN_MILLIS + (mQcConstants.IN_QUOTA_BUFFER_MS - contributionMs); - mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE, - standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); } @Test public void testConstantsUpdating_ValidValues() { - mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 5 * MINUTE_IN_MILLIS; - mQcConstants.IN_QUOTA_BUFFER_MS = 2 * MINUTE_IN_MILLIS; - mQcConstants.WINDOW_SIZE_ACTIVE_MS = 15 * MINUTE_IN_MILLIS; - mQcConstants.WINDOW_SIZE_WORKING_MS = 30 * MINUTE_IN_MILLIS; - mQcConstants.WINDOW_SIZE_FREQUENT_MS = 45 * MINUTE_IN_MILLIS; - mQcConstants.WINDOW_SIZE_RARE_MS = 60 * MINUTE_IN_MILLIS; - mQcConstants.MAX_EXECUTION_TIME_MS = 3 * HOUR_IN_MILLIS; - mQcConstants.MAX_JOB_COUNT_ACTIVE = 5000; - mQcConstants.MAX_JOB_COUNT_WORKING = 4000; - mQcConstants.MAX_JOB_COUNT_FREQUENT = 3000; - mQcConstants.MAX_JOB_COUNT_RARE = 2000; - mQcConstants.RATE_LIMITING_WINDOW_MS = 15 * MINUTE_IN_MILLIS; - mQcConstants.MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW = 500; - mQcConstants.MAX_SESSION_COUNT_ACTIVE = 500; - mQcConstants.MAX_SESSION_COUNT_WORKING = 400; - mQcConstants.MAX_SESSION_COUNT_FREQUENT = 300; - mQcConstants.MAX_SESSION_COUNT_RARE = 200; - mQcConstants.MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = 50; - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 10 * SECOND_IN_MILLIS; - - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, 5 * MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, 2 * MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, 15 * MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_WORKING_MS, 30 * MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_FREQUENT_MS, 45 * MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RARE_MS, 60 * MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RESTRICTED_MS, 120 * MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, 3 * HOUR_IN_MILLIS); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_ACTIVE, 5000); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_WORKING, 4000); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_FREQUENT, 3000); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_RARE, 2000); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_RESTRICTED, 2000); + setDeviceConfigLong(QcConstants.KEY_RATE_LIMITING_WINDOW_MS, 15 * MINUTE_IN_MILLIS); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, 500); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_ACTIVE, 500); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_WORKING, 400); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_FREQUENT, 300); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_RARE, 200); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_RESTRICTED, 100); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW, 50); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + 10 * SECOND_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_MIN_QUOTA_CHECK_DELAY_MS, 7 * MINUTE_IN_MILLIS); assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()); assertEquals(2 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs()); @@ -1920,6 +2221,8 @@ public class QuotaControllerTest { assertEquals(45 * MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[FREQUENT_INDEX]); assertEquals(60 * MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[RARE_INDEX]); + assertEquals(120 * MINUTE_IN_MILLIS, + mQuotaController.getBucketWindowSizes()[RESTRICTED_INDEX]); assertEquals(3 * HOUR_IN_MILLIS, mQuotaController.getMaxExecutionTimeMs()); assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getRateLimitingWindowMs()); assertEquals(500, mQuotaController.getMaxJobCountPerRateLimitingWindow()); @@ -1927,39 +2230,44 @@ public class QuotaControllerTest { assertEquals(4000, mQuotaController.getBucketMaxJobCounts()[WORKING_INDEX]); assertEquals(3000, mQuotaController.getBucketMaxJobCounts()[FREQUENT_INDEX]); assertEquals(2000, mQuotaController.getBucketMaxJobCounts()[RARE_INDEX]); + assertEquals(2000, mQuotaController.getBucketMaxJobCounts()[RESTRICTED_INDEX]); assertEquals(50, mQuotaController.getMaxSessionCountPerRateLimitingWindow()); assertEquals(500, mQuotaController.getBucketMaxSessionCounts()[ACTIVE_INDEX]); assertEquals(400, mQuotaController.getBucketMaxSessionCounts()[WORKING_INDEX]); assertEquals(300, mQuotaController.getBucketMaxSessionCounts()[FREQUENT_INDEX]); assertEquals(200, mQuotaController.getBucketMaxSessionCounts()[RARE_INDEX]); + assertEquals(100, mQuotaController.getBucketMaxSessionCounts()[RESTRICTED_INDEX]); assertEquals(10 * SECOND_IN_MILLIS, mQuotaController.getTimingSessionCoalescingDurationMs()); + assertEquals(7 * MINUTE_IN_MILLIS, mQuotaController.getMinQuotaCheckDelayMs()); } @Test public void testConstantsUpdating_InvalidValues() { // Test negatives/too low. - mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = -MINUTE_IN_MILLIS; - mQcConstants.IN_QUOTA_BUFFER_MS = -MINUTE_IN_MILLIS; - mQcConstants.WINDOW_SIZE_ACTIVE_MS = -MINUTE_IN_MILLIS; - mQcConstants.WINDOW_SIZE_WORKING_MS = -MINUTE_IN_MILLIS; - mQcConstants.WINDOW_SIZE_FREQUENT_MS = -MINUTE_IN_MILLIS; - mQcConstants.WINDOW_SIZE_RARE_MS = -MINUTE_IN_MILLIS; - mQcConstants.MAX_EXECUTION_TIME_MS = -MINUTE_IN_MILLIS; - mQcConstants.MAX_JOB_COUNT_ACTIVE = -1; - mQcConstants.MAX_JOB_COUNT_WORKING = 1; - mQcConstants.MAX_JOB_COUNT_FREQUENT = 1; - mQcConstants.MAX_JOB_COUNT_RARE = 1; - mQcConstants.RATE_LIMITING_WINDOW_MS = 15 * SECOND_IN_MILLIS; - mQcConstants.MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW = 0; - mQcConstants.MAX_SESSION_COUNT_ACTIVE = -1; - mQcConstants.MAX_SESSION_COUNT_WORKING = 0; - mQcConstants.MAX_SESSION_COUNT_FREQUENT = -3; - mQcConstants.MAX_SESSION_COUNT_RARE = 0; - mQcConstants.MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = 0; - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = -1; - - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, -MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, -MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, -MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_WORKING_MS, -MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_FREQUENT_MS, -MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RARE_MS, -MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RESTRICTED_MS, -MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, -MINUTE_IN_MILLIS); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_ACTIVE, -1); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_WORKING, 1); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_FREQUENT, 1); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_RARE, 1); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_RESTRICTED, -1); + setDeviceConfigLong(QcConstants.KEY_RATE_LIMITING_WINDOW_MS, 15 * SECOND_IN_MILLIS); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, 0); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_ACTIVE, -1); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_WORKING, 0); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_FREQUENT, -3); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_RARE, 0); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_RESTRICTED, -5); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW, 0); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, -1); + setDeviceConfigLong(QcConstants.KEY_MIN_QUOTA_CHECK_DELAY_MS, -1); assertEquals(MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()); assertEquals(0, mQuotaController.getInQuotaBufferMs()); @@ -1967,6 +2275,7 @@ public class QuotaControllerTest { assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[WORKING_INDEX]); assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[FREQUENT_INDEX]); assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[RARE_INDEX]); + assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[RESTRICTED_INDEX]); assertEquals(HOUR_IN_MILLIS, mQuotaController.getMaxExecutionTimeMs()); assertEquals(30 * SECOND_IN_MILLIS, mQuotaController.getRateLimitingWindowMs()); assertEquals(10, mQuotaController.getMaxJobCountPerRateLimitingWindow()); @@ -1974,35 +2283,37 @@ public class QuotaControllerTest { assertEquals(10, mQuotaController.getBucketMaxJobCounts()[WORKING_INDEX]); assertEquals(10, mQuotaController.getBucketMaxJobCounts()[FREQUENT_INDEX]); assertEquals(10, mQuotaController.getBucketMaxJobCounts()[RARE_INDEX]); + assertEquals(10, mQuotaController.getBucketMaxJobCounts()[RESTRICTED_INDEX]); assertEquals(10, mQuotaController.getMaxSessionCountPerRateLimitingWindow()); assertEquals(1, mQuotaController.getBucketMaxSessionCounts()[ACTIVE_INDEX]); assertEquals(1, mQuotaController.getBucketMaxSessionCounts()[WORKING_INDEX]); assertEquals(1, mQuotaController.getBucketMaxSessionCounts()[FREQUENT_INDEX]); assertEquals(1, mQuotaController.getBucketMaxSessionCounts()[RARE_INDEX]); + assertEquals(0, mQuotaController.getBucketMaxSessionCounts()[RESTRICTED_INDEX]); assertEquals(0, mQuotaController.getTimingSessionCoalescingDurationMs()); + assertEquals(0, mQuotaController.getMinQuotaCheckDelayMs()); // Invalid configurations. // In_QUOTA_BUFFER should never be greater than ALLOWED_TIME_PER_PERIOD - mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 2 * MINUTE_IN_MILLIS; - mQcConstants.IN_QUOTA_BUFFER_MS = 5 * MINUTE_IN_MILLIS; - - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, 2 * MINUTE_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, 5 * MINUTE_IN_MILLIS); assertTrue(mQuotaController.getInQuotaBufferMs() <= mQuotaController.getAllowedTimePerPeriodMs()); // Test larger than a day. Controller should cap at one day. - mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 25 * HOUR_IN_MILLIS; - mQcConstants.IN_QUOTA_BUFFER_MS = 25 * HOUR_IN_MILLIS; - mQcConstants.WINDOW_SIZE_ACTIVE_MS = 25 * HOUR_IN_MILLIS; - mQcConstants.WINDOW_SIZE_WORKING_MS = 25 * HOUR_IN_MILLIS; - mQcConstants.WINDOW_SIZE_FREQUENT_MS = 25 * HOUR_IN_MILLIS; - mQcConstants.WINDOW_SIZE_RARE_MS = 25 * HOUR_IN_MILLIS; - mQcConstants.MAX_EXECUTION_TIME_MS = 25 * HOUR_IN_MILLIS; - mQcConstants.RATE_LIMITING_WINDOW_MS = 25 * HOUR_IN_MILLIS; - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 25 * HOUR_IN_MILLIS; - - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, 25 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, 25 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, 25 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_WORKING_MS, 25 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_FREQUENT_MS, 25 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RARE_MS, 25 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RESTRICTED_MS, 30 * 24 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, 25 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_RATE_LIMITING_WINDOW_MS, 25 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + 25 * HOUR_IN_MILLIS); + setDeviceConfigLong(QcConstants.KEY_MIN_QUOTA_CHECK_DELAY_MS, 25 * HOUR_IN_MILLIS); assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()); assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs()); @@ -2010,10 +2321,13 @@ public class QuotaControllerTest { assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[WORKING_INDEX]); assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[FREQUENT_INDEX]); assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[RARE_INDEX]); + assertEquals(7 * 24 * HOUR_IN_MILLIS, + mQuotaController.getBucketWindowSizes()[RESTRICTED_INDEX]); assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getMaxExecutionTimeMs()); assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getRateLimitingWindowMs()); assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getTimingSessionCoalescingDurationMs()); + assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getMinQuotaCheckDelayMs()); } /** Tests that TimingSessions aren't saved when the device is charging. */ @@ -2022,13 +2336,19 @@ public class QuotaControllerTest { setCharging(); JobStatus jobStatus = createJobStatus("testTimerTracking_Charging", 1); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(5 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); } @@ -2039,41 +2359,63 @@ public class QuotaControllerTest { setProcessState(ActivityManager.PROCESS_STATE_BACKUP); JobStatus jobStatus = createJobStatus("testTimerTracking_Discharging", 1); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); List<TimingSession> expected = new ArrayList<>(); long start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(5 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + } expected.add(createTimingSession(start, 5 * SECOND_IN_MILLIS, 1)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); // Test overlapping jobs. JobStatus jobStatus2 = createJobStatus("testTimerTracking_Discharging", 2); - mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null); + } JobStatus jobStatus3 = createJobStatus("testTimerTracking_Discharging", 3); - mQuotaController.maybeStartTrackingJobLocked(jobStatus3, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus3, null); + } advanceElapsedClock(SECOND_IN_MILLIS); start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.prepareForExecutionLocked(jobStatus2); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.prepareForExecutionLocked(jobStatus3); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus3); + } advanceElapsedClock(20 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus3, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus3, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false); + } expected.add(createTimingSession(start, MINUTE_IN_MILLIS, 3)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); } @@ -2087,11 +2429,17 @@ public class QuotaControllerTest { setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); JobStatus jobStatus = createJobStatus("testTimerTracking_ChargingAndDischarging", 1); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + } JobStatus jobStatus2 = createJobStatus("testTimerTracking_ChargingAndDischarging", 2); - mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null); + } JobStatus jobStatus3 = createJobStatus("testTimerTracking_ChargingAndDischarging", 3); - mQuotaController.maybeStartTrackingJobLocked(jobStatus3, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus3, null); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); List<TimingSession> expected = new ArrayList<>(); @@ -2099,12 +2447,16 @@ public class QuotaControllerTest { // should be counted. setCharging(); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); setDischarging(); long start = JobSchedulerService.sElapsedRealtimeClock.millis(); advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus, jobStatus, true); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, jobStatus, true); + } expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); @@ -2118,23 +2470,35 @@ public class QuotaControllerTest { // shouldn't be included in either job count. setDischarging(); start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.prepareForExecutionLocked(jobStatus2); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); setCharging(); expected.add(createTimingSession(start, 20 * SECOND_IN_MILLIS, 2)); - mQuotaController.prepareForExecutionLocked(jobStatus3); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus3); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus3, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus3, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); setDischarging(); start = JobSchedulerService.sElapsedRealtimeClock.millis(); advanceElapsedClock(20 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + } expected.add(createTimingSession(start, 20 * SECOND_IN_MILLIS, 1)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); @@ -2142,13 +2506,17 @@ public class QuotaControllerTest { // during the discharging period should be counted. setDischarging(); start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null); - mQuotaController.prepareForExecutionLocked(jobStatus2); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null); + mQuotaController.prepareForExecutionLocked(jobStatus2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); setCharging(); advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false); + } assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); } @@ -2159,42 +2527,63 @@ public class QuotaControllerTest { setProcessState(ActivityManager.PROCESS_STATE_RECEIVER); JobStatus jobStatus = createJobStatus("testTimerTracking_AllBackground", 1); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); - + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); List<TimingSession> expected = new ArrayList<>(); // Test single job. long start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(5 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + } expected.add(createTimingSession(start, 5 * SECOND_IN_MILLIS, 1)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); // Test overlapping jobs. JobStatus jobStatus2 = createJobStatus("testTimerTracking_AllBackground", 2); - mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null); + } JobStatus jobStatus3 = createJobStatus("testTimerTracking_AllBackground", 3); - mQuotaController.maybeStartTrackingJobLocked(jobStatus3, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus3, null); + } advanceElapsedClock(SECOND_IN_MILLIS); start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.prepareForExecutionLocked(jobStatus2); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.prepareForExecutionLocked(jobStatus3); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus3); + } advanceElapsedClock(20 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus3, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus3, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false); + } expected.add(createTimingSession(start, MINUTE_IN_MILLIS, 3)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); } @@ -2206,16 +2595,22 @@ public class QuotaControllerTest { JobStatus jobStatus = createJobStatus("testTimerTracking_AllForeground", 1); setProcessState(ActivityManager.PROCESS_STATE_TOP); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(5 * SECOND_IN_MILLIS); // Change to a state that should still be considered foreground. setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); advanceElapsedClock(5 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); } @@ -2230,18 +2625,24 @@ public class QuotaControllerTest { JobStatus jobBg1 = createJobStatus("testTimerTracking_ForegroundAndBackground", 1); JobStatus jobBg2 = createJobStatus("testTimerTracking_ForegroundAndBackground", 2); JobStatus jobFg3 = createJobStatus("testTimerTracking_ForegroundAndBackground", 3); - mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); - mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); - mQuotaController.maybeStartTrackingJobLocked(jobFg3, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); + mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); + mQuotaController.maybeStartTrackingJobLocked(jobFg3, null); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); List<TimingSession> expected = new ArrayList<>(); // UID starts out inactive. setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); long start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.prepareForExecutionLocked(jobBg1); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobBg1); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true); + } expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); @@ -2253,16 +2654,24 @@ public class QuotaControllerTest { // App remains in foreground state after coming to foreground, so there should only be one // session. start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); - mQuotaController.prepareForExecutionLocked(jobBg2); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); + mQuotaController.prepareForExecutionLocked(jobBg2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); - mQuotaController.prepareForExecutionLocked(jobFg3); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobFg3); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobFg3, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobFg3, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); + } assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); advanceElapsedClock(SECOND_IN_MILLIS); @@ -2273,25 +2682,39 @@ public class QuotaControllerTest { // * The first should have a count of 1 // * The second should have a count of 2 since it will include both jobs start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); - mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); - mQuotaController.maybeStartTrackingJobLocked(jobFg3, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); + mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); + mQuotaController.maybeStartTrackingJobLocked(jobFg3, null); + } setProcessState(ActivityManager.PROCESS_STATE_LAST_ACTIVITY); - mQuotaController.prepareForExecutionLocked(jobBg1); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobBg1); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); - mQuotaController.prepareForExecutionLocked(jobFg3); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobFg3); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); // UID "inactive" now start = JobSchedulerService.sElapsedRealtimeClock.millis(); setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING); - mQuotaController.prepareForExecutionLocked(jobBg2); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobBg2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobFg3, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobFg3, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); + } expected.add(createTimingSession(start, 20 * SECOND_IN_MILLIS, 2)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); } @@ -2307,21 +2730,34 @@ public class QuotaControllerTest { JobStatus jobFg1 = createJobStatus("testTimerTracking_JobCount_Foreground", 1); JobStatus jobFg2 = createJobStatus("testTimerTracking_JobCount_Foreground", 2); - mQuotaController.maybeStartTrackingJobLocked(jobFg1, null); - mQuotaController.maybeStartTrackingJobLocked(jobFg2, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobFg1, null); + mQuotaController.maybeStartTrackingJobLocked(jobFg2, null); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); - ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID, - SOURCE_PACKAGE, standbyBucket); + ExecutionStats stats; + synchronized (mQuotaController.mLock) { + stats = mQuotaController.getExecutionStatsLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } assertEquals(0, stats.jobCountInRateLimitingWindow); setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); - mQuotaController.prepareForExecutionLocked(jobFg1); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobFg1); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.prepareForExecutionLocked(jobFg2); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobFg2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobFg1, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobFg1, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobFg2, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobFg2, null, false); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(0, stats.jobCountInRateLimitingWindow); @@ -2335,21 +2771,32 @@ public class QuotaControllerTest { final int standbyBucket = WORKING_INDEX; JobStatus jobBg1 = createJobStatus("testTimerTracking_JobCount_Background", 1); JobStatus jobBg2 = createJobStatus("testTimerTracking_JobCount_Background", 2); - mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); - mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); + ExecutionStats stats; + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); + mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); - ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID, - SOURCE_PACKAGE, standbyBucket); + stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID, + SOURCE_PACKAGE, standbyBucket); + } assertEquals(0, stats.jobCountInRateLimitingWindow); setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING); - mQuotaController.prepareForExecutionLocked(jobBg1); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobBg1); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.prepareForExecutionLocked(jobBg2); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobBg2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg1, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg1, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); + } assertEquals(2, stats.jobCountInRateLimitingWindow); } @@ -2365,19 +2812,25 @@ public class QuotaControllerTest { JobStatus jobBg2 = createJobStatus("testTimerTracking_TopAndNonTop", 2); JobStatus jobFg1 = createJobStatus("testTimerTracking_TopAndNonTop", 3); JobStatus jobTop = createJobStatus("testTimerTracking_TopAndNonTop", 4); - mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); - mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); - mQuotaController.maybeStartTrackingJobLocked(jobFg1, null); - mQuotaController.maybeStartTrackingJobLocked(jobTop, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); + mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); + mQuotaController.maybeStartTrackingJobLocked(jobFg1, null); + mQuotaController.maybeStartTrackingJobLocked(jobTop, null); + } assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); List<TimingSession> expected = new ArrayList<>(); // UID starts out inactive. setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); long start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.prepareForExecutionLocked(jobBg1); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobBg1); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true); + } expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); @@ -2389,16 +2842,24 @@ public class QuotaControllerTest { // App remains in top state after coming to top, so there should only be one // session. start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); - mQuotaController.prepareForExecutionLocked(jobBg2); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); + mQuotaController.prepareForExecutionLocked(jobBg2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); setProcessState(ActivityManager.PROCESS_STATE_TOP); - mQuotaController.prepareForExecutionLocked(jobTop); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobTop); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobTop, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobTop, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); + } assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); advanceElapsedClock(SECOND_IN_MILLIS); @@ -2411,31 +2872,47 @@ public class QuotaControllerTest { // * The second should have a count of 2, which accounts for the bg2 and fg, but not top // jobs. start = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); - mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); - mQuotaController.maybeStartTrackingJobLocked(jobTop, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobBg1, null); + mQuotaController.maybeStartTrackingJobLocked(jobBg2, null); + mQuotaController.maybeStartTrackingJobLocked(jobTop, null); + } setProcessState(ActivityManager.PROCESS_STATE_LAST_ACTIVITY); - mQuotaController.prepareForExecutionLocked(jobBg1); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobBg1); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); setProcessState(ActivityManager.PROCESS_STATE_TOP); - mQuotaController.prepareForExecutionLocked(jobTop); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobTop); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true); + } advanceElapsedClock(5 * SECOND_IN_MILLIS); setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); - mQuotaController.prepareForExecutionLocked(jobFg1); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobFg1); + } advanceElapsedClock(5 * SECOND_IN_MILLIS); setProcessState(ActivityManager.PROCESS_STATE_TOP); advanceElapsedClock(10 * SECOND_IN_MILLIS); // UID "inactive" now start = JobSchedulerService.sElapsedRealtimeClock.millis(); setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING); - mQuotaController.prepareForExecutionLocked(jobBg2); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobBg2); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobTop, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobTop, null, false); + } advanceElapsedClock(10 * SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); - mQuotaController.maybeStopTrackingJobLocked(jobFg1, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false); + mQuotaController.maybeStopTrackingJobLocked(jobFg1, null, false); + } expected.add(createTimingSession(start, 20 * SECOND_IN_MILLIS, 2)); assertEquals(expected, mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); } @@ -2463,20 +2940,28 @@ public class QuotaControllerTest { // UID starts out inactive. setProcessState(ActivityManager.PROCESS_STATE_SERVICE); // Start the job. - mQuotaController.prepareForExecutionLocked(jobBg); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobBg); + } advanceElapsedClock(remainingTimeMs / 2); // New job starts after UID is in the foreground. Since the app is now in the foreground, it // should continue to have remainingTimeMs / 2 time remaining. setProcessState(ActivityManager.PROCESS_STATE_TOP); - mQuotaController.prepareForExecutionLocked(jobTop); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobTop); + } advanceElapsedClock(remainingTimeMs); // Wait for some extra time to allow for job processing. inOrder.verify(mJobSchedulerService, timeout(remainingTimeMs + 2 * SECOND_IN_MILLIS).times(0)) .onControllerStateChanged(); - assertEquals(remainingTimeMs / 2, mQuotaController.getRemainingExecutionTimeLocked(jobBg)); - assertEquals(remainingTimeMs / 2, mQuotaController.getRemainingExecutionTimeLocked(jobTop)); + synchronized (mQuotaController.mLock) { + assertEquals(remainingTimeMs / 2, + mQuotaController.getRemainingExecutionTimeLocked(jobBg)); + assertEquals(remainingTimeMs / 2, + mQuotaController.getRemainingExecutionTimeLocked(jobTop)); + } // Go to a background state. setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING); advanceElapsedClock(remainingTimeMs / 2 + 1); @@ -2498,7 +2983,9 @@ public class QuotaControllerTest { inOrder.verify(mJobSchedulerService, timeout(SECOND_IN_MILLIS).times(1)) .onControllerStateChanged(); trackJobs(jobFg, jobTop); - mQuotaController.prepareForExecutionLocked(jobTop); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobTop); + } assertTrue(jobTop.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); assertTrue(jobFg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); assertTrue(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); @@ -2530,7 +3017,9 @@ public class QuotaControllerTest { @Test public void testTracking_OutOfQuota() { JobStatus jobStatus = createJobStatus("testTracking_OutOfQuota", 1); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + } setStandbyBucket(WORKING_INDEX, jobStatus); // 2 hour window setProcessState(ActivityManager.PROCESS_STATE_HOME); // Now the package only has two seconds to run. @@ -2541,7 +3030,9 @@ public class QuotaControllerTest { 10 * MINUTE_IN_MILLIS - remainingTimeMs, 1)); // Start the job. - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(remainingTimeMs); // Wait for some extra time to allow for job processing. @@ -2560,7 +3051,9 @@ public class QuotaControllerTest { @Test public void testTracking_RollingQuota() { JobStatus jobStatus = createJobStatus("testTracking_OutOfQuota", 1); - mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(jobStatus, null); + } setStandbyBucket(WORKING_INDEX, jobStatus); // 2 hour window setProcessState(ActivityManager.PROCESS_STATE_SERVICE); Handler handler = mQuotaController.getHandler(); @@ -2577,9 +3070,13 @@ public class QuotaControllerTest { createTimingSession(now - HOUR_IN_MILLIS, 9 * MINUTE_IN_MILLIS + 50 * SECOND_IN_MILLIS, 1)); - assertEquals(remainingTimeMs, mQuotaController.getRemainingExecutionTimeLocked(jobStatus)); - // Start the job. - mQuotaController.prepareForExecutionLocked(jobStatus); + synchronized (mQuotaController.mLock) { + assertEquals(remainingTimeMs, + mQuotaController.getRemainingExecutionTimeLocked(jobStatus)); + + // Start the job. + mQuotaController.prepareForExecutionLocked(jobStatus); + } advanceElapsedClock(remainingTimeMs); // Wait for some extra time to allow for job processing. @@ -2590,8 +3087,11 @@ public class QuotaControllerTest { // The job used up the remaining quota, but in that time, the same amount of time in the // old TimingSession also fell out of the quota window, so it should still have the same // amount of remaining time left its quota. - assertEquals(remainingTimeMs, - mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + synchronized (mQuotaController.mLock) { + assertEquals(remainingTimeMs, + mQuotaController.getRemainingExecutionTimeLocked( + SOURCE_USER_ID, SOURCE_PACKAGE)); + } // Handler is told to check when the quota will be consumed, not when the initial // remaining time is over. verify(handler, atLeast(1)).sendMessageDelayed(any(), eq(10 * SECOND_IN_MILLIS)); @@ -2619,27 +3119,33 @@ public class QuotaControllerTest { doNothing().when(mQuotaController).maybeScheduleCleanupAlarmLocked(); // Essentially disable session throttling. - mQcConstants.MAX_SESSION_COUNT_WORKING = - mQcConstants.MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = Integer.MAX_VALUE; - mQcConstants.updateConstants(); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_WORKING, Integer.MAX_VALUE); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW, + Integer.MAX_VALUE); final int standbyBucket = WORKING_INDEX; setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); // No sessions saved yet. - mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE, - standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Ran jobs up to the job limit. All of them should be allowed to run. for (int i = 0; i < mQcConstants.MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW; ++i) { JobStatus job = createJobStatus("testStartAlarmScheduled_JobCount_AllowedTime", i); setStandbyBucket(WORKING_INDEX, job); - mQuotaController.maybeStartTrackingJobLocked(job, null); - assertTrue(job.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); - mQuotaController.prepareForExecutionLocked(job); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + assertTrue(job.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); + mQuotaController.prepareForExecutionLocked(job); + } advanceElapsedClock(SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(job, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(job, null, false); + } advanceElapsedClock(SECOND_IN_MILLIS); } // Start alarm shouldn't have been scheduled since the app was in quota up until this point. @@ -2649,11 +3155,16 @@ public class QuotaControllerTest { JobStatus throttledJob = createJobStatus( "testStartAlarmScheduled_JobCount_AllowedTime", 42); setStandbyBucket(WORKING_INDEX, throttledJob); - mQuotaController.maybeStartTrackingJobLocked(throttledJob, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(throttledJob, null); + } assertFalse(throttledJob.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); - ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID, - SOURCE_PACKAGE, standbyBucket); + ExecutionStats stats; + synchronized (mQuotaController.mLock) { + stats = mQuotaController.getExecutionStatsLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } final long expectedWorkingAlarmTime = stats.jobRateLimitExpirationTimeElapsed; verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); @@ -2671,19 +3182,21 @@ public class QuotaControllerTest { doNothing().when(mQuotaController).maybeScheduleCleanupAlarmLocked(); // Essentially disable job count throttling. - mQcConstants.MAX_JOB_COUNT_FREQUENT = - mQcConstants.MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW = Integer.MAX_VALUE; + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_FREQUENT, Integer.MAX_VALUE); + setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, + Integer.MAX_VALUE); // Make sure throttling is because of COUNT_PER_RATE_LIMITING_WINDOW. - mQcConstants.MAX_SESSION_COUNT_FREQUENT = - mQcConstants.MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW + 1; - mQcConstants.updateConstants(); + setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_FREQUENT, + mQcConstants.MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW + 1); final int standbyBucket = FREQUENT_INDEX; setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); // No sessions saved yet. - mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE, - standbyBucket); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeScheduleStartAlarmLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); // Ran jobs up to the job limit. All of them should be allowed to run. @@ -2691,12 +3204,16 @@ public class QuotaControllerTest { JobStatus job = createJobStatus( "testStartAlarmScheduled_TimingSessionCount_AllowedTime", i); setStandbyBucket(FREQUENT_INDEX, job); - mQuotaController.maybeStartTrackingJobLocked(job, null); - assertTrue("Constraint not satisfied for job #" + (i + 1), - job.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); - mQuotaController.prepareForExecutionLocked(job); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + assertTrue("Constraint not satisfied for job #" + (i + 1), + job.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); + mQuotaController.prepareForExecutionLocked(job); + } advanceElapsedClock(SECOND_IN_MILLIS); - mQuotaController.maybeStopTrackingJobLocked(job, null, false); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(job, null, false); + } advanceElapsedClock(SECOND_IN_MILLIS); } // Start alarm shouldn't have been scheduled since the app was in quota up until this point. @@ -2705,13 +3222,18 @@ public class QuotaControllerTest { // The app is now out of session count quota JobStatus throttledJob = createJobStatus( "testStartAlarmScheduled_TimingSessionCount_AllowedTime", 42); - mQuotaController.maybeStartTrackingJobLocked(throttledJob, null); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(throttledJob, null); + } assertFalse(throttledJob.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); assertEquals(JobSchedulerService.sElapsedRealtimeClock.millis(), throttledJob.getWhenStandbyDeferred()); - ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID, - SOURCE_PACKAGE, standbyBucket); + ExecutionStats stats; + synchronized (mQuotaController.mLock) { + stats = mQuotaController.getExecutionStatsLocked( + SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + } final long expectedWorkingAlarmTime = stats.sessionRateLimitExpirationTimeElapsed; verify(mAlarmManager, times(1)) .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any()); diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java index 3614763fecab..9d847153661f 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java @@ -52,6 +52,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoSession; @@ -632,6 +633,50 @@ public class TimeControllerTest { } @Test + public void testDelayAlarmSchedulingCoalescedIntervals() { + doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt()); + + final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); + + JobStatus jobLatest = createJobStatus("testDelayAlarmSchedulingCoalescedIntervals", + createJob().setMinimumLatency(HOUR_IN_MILLIS)); + JobStatus jobMiddle = createJobStatus("testDelayAlarmSchedulingCoalescedIntervals", + createJob().setMinimumLatency(TimeController.DELAY_COALESCE_TIME_MS / 2)); + JobStatus jobEarliest = createJobStatus("testDelayAlarmSchedulingCoalescedIntervals", + createJob().setMinimumLatency(TimeController.DELAY_COALESCE_TIME_MS / 10)); + + ArgumentCaptor<AlarmManager.OnAlarmListener> listenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + InOrder inOrder = inOrder(mAlarmManager); + + mTimeController.maybeStartTrackingJobLocked(jobEarliest, null); + mTimeController.maybeStartTrackingJobLocked(jobMiddle, null); + mTimeController.maybeStartTrackingJobLocked(jobLatest, null); + inOrder.verify(mAlarmManager, times(1)) + .set(anyInt(), eq(now + TimeController.DELAY_COALESCE_TIME_MS / 10), anyLong(), + anyLong(), eq(TAG_DELAY), + listenerCaptor.capture(), any(), any()); + final AlarmManager.OnAlarmListener delayListener = listenerCaptor.getValue(); + + advanceElapsedClock(TimeController.DELAY_COALESCE_TIME_MS / 10); + delayListener.onAlarm(); + // The next delay alarm time should be TimeController.DELAY_COALESCE_TIME_MS after the last + // time the delay alarm fired. + inOrder.verify(mAlarmManager, times(1)) + .set(anyInt(), eq(now + TimeController.DELAY_COALESCE_TIME_MS / 10 + + TimeController.DELAY_COALESCE_TIME_MS), anyLong(), + anyLong(), eq(TAG_DELAY), any(), any(), any()); + + advanceElapsedClock(TimeController.DELAY_COALESCE_TIME_MS); + delayListener.onAlarm(); + // The last job is significantly after the coalesce time, so the 3rd scheduling shouldn't be + // affected by the first two jobs' alarms. + inOrder.verify(mAlarmManager, times(1)) + .set(anyInt(), eq(now + HOUR_IN_MILLIS), anyLong(), + anyLong(), eq(TAG_DELAY), any(), any(), any()); + } + + @Test public void testEvaluateStateLocked_Delay() { final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); diff --git a/services/tests/mockingservicestests/src/com/android/server/location/listeners/ListenerMultiplexerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/listeners/ListenerMultiplexerTest.java index 29d3f29ad7e1..d7fef604d25b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/listeners/ListenerMultiplexerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/listeners/ListenerMultiplexerTest.java @@ -34,7 +34,6 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.listeners.ListenerExecutor.ListenerOperation; import com.android.server.location.listeners.ListenerMultiplexer.UpdateServiceLock; import org.junit.Before; @@ -59,6 +58,9 @@ public class ListenerMultiplexerTest { void onRegistrationAdded(Consumer<TestListenerRegistration> consumer, TestListenerRegistration registration); + void onRegistrationReplaced(Consumer<TestListenerRegistration> consumer, + TestListenerRegistration oldRegistration, TestListenerRegistration newRegistration); + void onRegistrationRemoved(Consumer<TestListenerRegistration> consumer, TestListenerRegistration registration); @@ -90,8 +92,39 @@ public class ListenerMultiplexerTest { assertThat(mMultiplexer.mRegistered).isTrue(); assertThat(mMultiplexer.mMergedRequest).isEqualTo(0); + mMultiplexer.addListener(1, consumer); + mInOrder.verify(mCallbacks).onRegistrationRemoved(eq(consumer), + any(TestListenerRegistration.class)); + mInOrder.verify(mCallbacks).onRegistrationReplaced(eq(consumer), + any(TestListenerRegistration.class), any(TestListenerRegistration.class)); + assertThat(mMultiplexer.mRegistered).isTrue(); + assertThat(mMultiplexer.mMergedRequest).isEqualTo(1); + + mMultiplexer.notifyListeners(); + verify(consumer).accept(any(TestListenerRegistration.class)); + } + + @Test + public void testReplace() { + Consumer<TestListenerRegistration> oldConsumer = mock(Consumer.class); + Consumer<TestListenerRegistration> consumer = mock(Consumer.class); + + mMultiplexer.addListener(0, oldConsumer); + mInOrder.verify(mCallbacks).onRegister(); + mInOrder.verify(mCallbacks).onRegistrationAdded(eq(oldConsumer), + any(TestListenerRegistration.class)); + mInOrder.verify(mCallbacks).onActive(); + mMultiplexer.replaceListener(1, oldConsumer, consumer); + mInOrder.verify(mCallbacks).onRegistrationRemoved(eq(oldConsumer), + any(TestListenerRegistration.class)); + mInOrder.verify(mCallbacks).onRegistrationReplaced(eq(consumer), + any(TestListenerRegistration.class), any(TestListenerRegistration.class)); + assertThat(mMultiplexer.mRegistered).isTrue(); + assertThat(mMultiplexer.mMergedRequest).isEqualTo(1); + mMultiplexer.notifyListeners(); verify(consumer).accept(any(TestListenerRegistration.class)); + verify(oldConsumer, never()).accept(any(TestListenerRegistration.class)); } @Test @@ -319,8 +352,7 @@ public class ListenerMultiplexerTest { } private static class TestListenerRegistration extends - RequestListenerRegistration<Integer, Consumer<TestListenerRegistration>, - ListenerOperation<Consumer<TestListenerRegistration>>> { + RequestListenerRegistration<Integer, Consumer<TestListenerRegistration>> { boolean mActive = true; @@ -332,9 +364,7 @@ public class ListenerMultiplexerTest { private static class TestMultiplexer extends ListenerMultiplexer<Consumer<TestListenerRegistration>, - Consumer<TestListenerRegistration>, - ListenerOperation<Consumer<TestListenerRegistration>>, TestListenerRegistration, - Integer> { + Consumer<TestListenerRegistration>, TestListenerRegistration, Integer> { boolean mRegistered; int mMergedRequest; @@ -351,7 +381,13 @@ public class ListenerMultiplexerTest { } public void addListener(Integer request, Consumer<TestListenerRegistration> consumer) { - addRegistration(consumer, new TestListenerRegistration(request, consumer)); + putRegistration(consumer, new TestListenerRegistration(request, consumer)); + } + + public void replaceListener(Integer request, Consumer<TestListenerRegistration> oldConsumer, + Consumer<TestListenerRegistration> consumer) { + replaceRegistration(oldConsumer, consumer, + new TestListenerRegistration(request, consumer)); } public void removeListener(Consumer<TestListenerRegistration> consumer) { @@ -422,6 +458,13 @@ public class ListenerMultiplexerTest { } @Override + protected void onRegistrationReplaced(Consumer<TestListenerRegistration> consumer, + TestListenerRegistration oldRegistration, + TestListenerRegistration newRegistration) { + mCallbacks.onRegistrationReplaced(consumer, oldRegistration, newRegistration); + } + + @Override protected void onRegistrationRemoved(Consumer<TestListenerRegistration> consumer, TestListenerRegistration registration) { mCallbacks.onRegistrationRemoved(consumer, registration); diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index 79936ce6d623..26fd0a21f10f 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -45,7 +45,7 @@ <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD"/> <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT"/> - <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"/> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/> <uses-permission android:name="android.permission.INSTALL_PACKAGES"/> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/> <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/> diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java index d2d85c860cd5..e76c5a476c48 100644 --- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java @@ -46,7 +46,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.test.FakeSettingsProvider; -import com.android.server.LocalServices; import com.android.server.statusbar.StatusBarManagerInternal; import org.junit.Before; @@ -158,16 +157,16 @@ public class GestureLauncherServiceTest { } @Test - public void testIsPanicButtonGestureEnabled_settingDisabled() { - withPanicGestureEnabledSettingValue(false); - assertFalse(mGestureLauncherService.isPanicButtonGestureEnabled( + public void testIsEmergencyGestureEnabled_settingDisabled() { + withEmergencyGestureEnabledSettingValue(false); + assertFalse(mGestureLauncherService.isEmergencyGestureEnabled( mContext, FAKE_USER_ID)); } @Test - public void testIsPanicButtonGestureEnabled_settingEnabled() { - withPanicGestureEnabledSettingValue(true); - assertTrue(mGestureLauncherService.isPanicButtonGestureEnabled( + public void testIsEmergencyGestureEnabled_settingEnabled() { + withEmergencyGestureEnabledSettingValue(true); + assertTrue(mGestureLauncherService.isEmergencyGestureEnabled( mContext, FAKE_USER_ID)); } @@ -181,10 +180,10 @@ public class GestureLauncherServiceTest { } @Test - public void testHandlePanicGesture_userSetupComplete() { + public void testHandleEmergencyGesture_userSetupComplete() { withUserSetupCompleteValue(true); - assertTrue(mGestureLauncherService.handlePanicButtonGesture()); + assertTrue(mGestureLauncherService.handleEmergencyGesture()); } @Test @@ -196,10 +195,10 @@ public class GestureLauncherServiceTest { } @Test - public void testHandlePanicGesture_userSetupNotComplete() { + public void testHandleEmergencyGesture_userSetupNotComplete() { withUserSetupCompleteValue(false); - assertFalse(mGestureLauncherService.handlePanicButtonGesture()); + assertFalse(mGestureLauncherService.handleEmergencyGesture()); } @Test @@ -223,9 +222,9 @@ public class GestureLauncherServiceTest { } @Test - public void testInterceptPowerKeyDown_firstPowerDown_panicGestureNotLaunched() { - withPanicGestureEnabledSettingValue(true); - mGestureLauncherService.updatePanicButtonGestureEnabled(); + public void testInterceptPowerKeyDown_firstPowerDown_emergencyGestureNotLaunched() { + withEmergencyGestureEnabledSettingValue(true); + mGestureLauncherService.updateEmergencyGestureEnabled(); long eventTime = INITIAL_EVENT_TIME_MILLIS + GestureLauncherService.POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS - 1; @@ -425,12 +424,12 @@ public class GestureLauncherServiceTest { @Test public void - testInterceptPowerKeyDown_fiveInboundPresses_cameraAndPanicEnabled_bothLaunch() { + testInterceptPowerKeyDown_fiveInboundPresses_cameraAndEmergencyEnabled_bothLaunch() { withCameraDoubleTapPowerEnableConfigValue(true); withCameraDoubleTapPowerDisableSettingValue(0); - withPanicGestureEnabledSettingValue(true); + withEmergencyGestureEnabledSettingValue(true); mGestureLauncherService.updateCameraDoubleTapPowerEnabled(); - mGestureLauncherService.updatePanicButtonGestureEnabled(); + mGestureLauncherService.updateEmergencyGestureEnabled(); withUserSetupCompleteValue(true); // First button press does nothing @@ -476,7 +475,7 @@ public class GestureLauncherServiceTest { assertEquals(1, tapCounts.get(0).intValue()); assertEquals(2, tapCounts.get(1).intValue()); - // Continue the button presses for the panic gesture. + // Continue the button presses for the emergency gesture. // Presses 3 and 4 should not trigger any gesture for (int i = 0; i < 2; i++) { @@ -490,7 +489,7 @@ public class GestureLauncherServiceTest { assertFalse(outLaunched.value); } - // Fifth button press should trigger the panic flow + // Fifth button press should trigger the emergency flow eventTime += interval; keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, IGNORED_REPEAT); @@ -513,9 +512,9 @@ public class GestureLauncherServiceTest { @Test public void - testInterceptPowerKeyDown_fiveInboundPresses_panicGestureEnabled_launchesPanicFlow() { - withPanicGestureEnabledSettingValue(true); - mGestureLauncherService.updatePanicButtonGestureEnabled(); + testInterceptPowerKeyDown_fiveInboundPresses_emergencyGestureEnabled_launchesFlow() { + withEmergencyGestureEnabledSettingValue(true); + mGestureLauncherService.updateEmergencyGestureEnabled(); withUserSetupCompleteValue(true); // First button press does nothing @@ -542,7 +541,7 @@ public class GestureLauncherServiceTest { assertFalse(outLaunched.value); } - // Fifth button press should trigger the panic flow + // Fifth button press should trigger the emergency flow eventTime += interval; keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, IGNORED_REPEAT); @@ -565,9 +564,9 @@ public class GestureLauncherServiceTest { @Test public void - testInterceptPowerKeyDown_tenInboundPresses_panicGestureEnabled_pressesIntercepted() { - withPanicGestureEnabledSettingValue(true); - mGestureLauncherService.updatePanicButtonGestureEnabled(); + testInterceptPowerKeyDown_tenInboundPresses_emergencyGestureEnabled_keyIntercepted() { + withEmergencyGestureEnabledSettingValue(true); + mGestureLauncherService.updateEmergencyGestureEnabled(); withUserSetupCompleteValue(true); // First button press does nothing @@ -594,7 +593,7 @@ public class GestureLauncherServiceTest { assertFalse(outLaunched.value); } - // Fifth button press should trigger the panic flow + // Fifth button press should trigger the emergency flow eventTime += interval; keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, IGNORED_REPEAT); @@ -1128,10 +1127,10 @@ public class GestureLauncherServiceTest { UserHandle.USER_CURRENT); } - private void withPanicGestureEnabledSettingValue(boolean enable) { + private void withEmergencyGestureEnabledSettingValue(boolean enable) { Settings.Secure.putIntForUser( mContentResolver, - Settings.Secure.PANIC_GESTURE_ENABLED, + Settings.Secure.EMERGENCY_GESTURE_ENABLED, enable ? 1 : 0, UserHandle.USER_CURRENT); } diff --git a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java index 8d60de9abe99..fba321e07207 100644 --- a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java @@ -52,6 +52,8 @@ import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.Process; +import android.os.RemoteException; +import android.os.SystemClock; import android.os.UserHandle; import android.os.VibrationAttributes; import android.os.VibrationEffect; @@ -76,7 +78,11 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.Arrays; import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; /** * Tests for {@link VibratorService}. @@ -444,6 +450,42 @@ public class VibratorServiceTest { } @Test + public void vibrate_withWaveform_totalVibrationTimeRespected() throws Exception { + int totalDuration = 10_000; // 10s + int stepDuration = 25; // 25ms + + // 25% of the first waveform step will be spent on the native on() call. + mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); + doAnswer(invocation -> { + Thread.currentThread().sleep(stepDuration / 4); + return null; + }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong()); + // 25% of each waveform step will be spent on the native setAmplitude() call.. + doAnswer(invocation -> { + Thread.currentThread().sleep(stepDuration / 4); + return null; + }).when(mNativeWrapperMock).vibratorSetAmplitude(anyInt()); + + VibratorService service = createService(); + + int stepCount = totalDuration / stepDuration; + long[] timings = new long[stepCount]; + int[] amplitudes = new int[stepCount]; + Arrays.fill(timings, stepDuration); + Arrays.fill(amplitudes, VibrationEffect.DEFAULT_AMPLITUDE); + VibrationEffect effect = VibrationEffect.createWaveform(timings, amplitudes, -1); + + int perceivedDuration = vibrateAndMeasure(service, effect, /* timeoutSecs= */ 15); + int delay = Math.abs(perceivedDuration - totalDuration); + + // Allow some delay for thread scheduling and callback triggering. + int maxDelay = (int) (0.05 * totalDuration); // < 5% of total duration + assertTrue("Waveform with perceived delay of " + delay + "ms," + + " expected less than " + maxDelay + "ms", + delay < maxDelay); + } + + @Test public void vibrate_withOneShotAndNativeCallbackTriggered_finishesVibration() { VibratorService service = createService(); doAnswer(invocation -> { @@ -699,16 +741,41 @@ public class VibratorServiceTest { vibrate(service, effect, ALARM_ATTRS); } - private void vibrate(VibratorService service, VibrationEffect effect, AudioAttributes attrs) { - VibrationAttributes attributes = new VibrationAttributes.Builder(attrs, effect).build(); - vibrate(service, effect, attributes); - } - private void vibrate(VibratorService service, VibrationEffect effect, VibrationAttributes attributes) { service.vibrate(UID, PACKAGE_NAME, effect, attributes, "some reason", service); } + private int vibrateAndMeasure( + VibratorService service, VibrationEffect effect, long timeoutSecs) throws Exception { + AtomicLong startTime = new AtomicLong(0); + AtomicLong endTime = new AtomicLong(0); + CountDownLatch startedCount = new CountDownLatch(1); + CountDownLatch finishedCount = new CountDownLatch(1); + service.registerVibratorStateListener(new IVibratorStateListener() { + @Override + public void onVibrating(boolean vibrating) throws RemoteException { + if (vibrating) { + startTime.set(SystemClock.uptimeMillis()); + startedCount.countDown(); + } else if (startedCount.getCount() == 0) { + endTime.set(SystemClock.uptimeMillis()); + finishedCount.countDown(); + } + } + + @Override + public IBinder asBinder() { + return mVibratorStateListenerBinderMock; + } + }); + + vibrate(service, effect); + + assertTrue(finishedCount.await(timeoutSecs, TimeUnit.SECONDS)); + return (int) (endTime.get() - startTime.get()); + } + private void mockVibratorCapabilities(int capabilities) { when(mNativeWrapperMock.vibratorGetCapabilities()).thenReturn((long) capabilities); } diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java index 241b5a9523b1..b360ae88b1ba 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java @@ -81,6 +81,7 @@ import com.android.server.appop.AppOpsService; import com.android.server.wm.ActivityTaskManagerService; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -128,11 +129,14 @@ public class ActivityManagerServiceTest { sPackageManagerInternal = mock(PackageManagerInternal.class); doReturn(new ComponentName("", "")).when(sPackageManagerInternal) .getSystemUiServiceComponent(); - // Remove stale instance of PackageManagerInternal if there is any - LocalServices.removeServiceForTest(PackageManagerInternal.class); LocalServices.addService(PackageManagerInternal.class, sPackageManagerInternal); } + @AfterClass + public static void tearDownOnce() { + LocalServices.removeServiceForTest(PackageManagerInternal.class); + } + @Rule public ServiceThreadRule mServiceThreadRule = new ServiceThreadRule(); private Context mContext = getInstrumentation().getTargetContext(); diff --git a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java index 377bfd1170a6..24f8eabdf545 100644 --- a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java +++ b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java @@ -18,17 +18,25 @@ package com.android.server.am; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +import android.content.ComponentName; import android.content.Context; +import android.content.pm.PackageManagerInternal; import android.os.Handler; import androidx.test.annotation.UiThreadTest; import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; +import com.android.server.LocalServices; import com.android.server.appop.AppOpsService; import com.android.server.wm.ActivityTaskManagerService; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -42,6 +50,18 @@ import java.io.File; @FlakyTest(bugId = 113616538) public class AppErrorDialogTest { + @BeforeClass + public static void setUpOnce() { + final PackageManagerInternal pm = mock(PackageManagerInternal.class); + doReturn(new ComponentName("", "")).when(pm).getSystemUiServiceComponent(); + LocalServices.addService(PackageManagerInternal.class, pm); + } + + @AfterClass + public static void tearDownOnce() { + LocalServices.removeServiceForTest(PackageManagerInternal.class); + } + @Rule public ServiceThreadRule mServiceThreadRule = new ServiceThreadRule(); diff --git a/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java b/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java index b2d7177e04eb..4f58c87e61ea 100644 --- a/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java +++ b/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java @@ -35,6 +35,7 @@ import android.content.pm.PackageManagerInternal; import com.android.server.LocalServices; import com.android.server.wm.ActivityTaskManagerService; +import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -63,8 +64,6 @@ public class OomAdjusterTests { sPackageManagerInternal = mock(PackageManagerInternal.class); doReturn(new ComponentName("", "")).when(sPackageManagerInternal) .getSystemUiServiceComponent(); - // Remove stale instance of PackageManagerInternal if there is any - LocalServices.removeServiceForTest(PackageManagerInternal.class); LocalServices.addService(PackageManagerInternal.class, sPackageManagerInternal); // We need to run with dexmaker share class loader to make use of @@ -78,13 +77,18 @@ public class OomAdjusterTests { sService.mConstants = new ActivityManagerConstants(sContext, sService, sContext.getMainThreadHandler()); sService.mOomAdjuster = new OomAdjuster(sService, sService.mProcessList, null); - LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); LocalServices.addService(UsageStatsManagerInternal.class, mock(UsageStatsManagerInternal.class)); sService.mUsageStatsService = LocalServices.getService(UsageStatsManagerInternal.class); }); } + @AfterClass + public static void tearDownOnce() { + LocalServices.removeServiceForTest(PackageManagerInternal.class); + LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); + } + @Before public void setUpProcess() { // Need to run with dexmaker share class loader to mock package private class. diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java index f0be9f1d3213..3b6059406785 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java @@ -262,7 +262,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService).showAuthenticationDialog( eq(mBiometricService.mCurrentAuthSession.mPromptInfo), any(IBiometricSysuiReceiver.class), - eq(0), + AdditionalMatchers.aryEq(new int[0]) /* sensorIds */, + eq(true) /* credentialAllowed */, anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), @@ -345,7 +346,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService).showAuthenticationDialog( eq(mBiometricService.mCurrentAuthSession.mPromptInfo), any(IBiometricSysuiReceiver.class), - eq(BiometricAuthenticator.TYPE_FACE), + AdditionalMatchers.aryEq(new int[] {SENSOR_ID_FACE}), + eq(false) /* credentialAllowed */, eq(false) /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), @@ -477,7 +479,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService).showAuthenticationDialog( eq(mBiometricService.mCurrentAuthSession.mPromptInfo), any(IBiometricSysuiReceiver.class), - eq(BiometricAuthenticator.TYPE_FINGERPRINT), + any(), + eq(false) /* credentialAllowed */, anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), @@ -530,7 +533,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService).showAuthenticationDialog( eq(mBiometricService.mCurrentAuthSession.mPromptInfo), any(IBiometricSysuiReceiver.class), - eq(0 /* biometricModality */), + AdditionalMatchers.aryEq(new int[0]) /* sensorIds */, + eq(true) /* credentialAllowed */, anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), @@ -696,7 +700,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService, never()).showAuthenticationDialog( any(PromptInfo.class), any(IBiometricSysuiReceiver.class), - anyInt(), + any() /* sensorIds */, + anyBoolean() /* credentialAllowed */, anyBoolean() /* requireConfirmation */, anyInt() /* userId */, anyString(), @@ -796,7 +801,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService).showAuthenticationDialog( eq(mBiometricService.mCurrentAuthSession.mPromptInfo), any(IBiometricSysuiReceiver.class), - eq(0 /* biometricModality */), + AdditionalMatchers.aryEq(new int[0]) /* sensorIds */, + eq(true) /* credentialAllowed */, anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), @@ -874,7 +880,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService).showAuthenticationDialog( eq(mBiometricService.mCurrentAuthSession.mPromptInfo), any(IBiometricSysuiReceiver.class), - eq(0 /* biometricModality */), + AdditionalMatchers.aryEq(new int[0]) /* sensorIds */, + eq(true) /* credentialAllowed */, anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), @@ -1383,7 +1390,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService).showAuthenticationDialog( eq(mBiometricService.mCurrentAuthSession.mPromptInfo), any(IBiometricSysuiReceiver.class), - eq(BiometricAuthenticator.TYPE_FINGERPRINT /* biometricModality */), + AdditionalMatchers.aryEq(new int[] {testId}), + eq(false) /* credentialAllowed */, anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), @@ -1403,7 +1411,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService).showAuthenticationDialog( eq(mBiometricService.mCurrentAuthSession.mPromptInfo), any(IBiometricSysuiReceiver.class), - eq(BiometricAuthenticator.TYPE_NONE /* biometricModality */), + AdditionalMatchers.aryEq(new int[0]) /* sensorIds */, + eq(true) /* credentialAllowed */, anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), @@ -1426,7 +1435,8 @@ public class BiometricServiceTest { verify(mBiometricService.mStatusBarService).showAuthenticationDialog( eq(mBiometricService.mCurrentAuthSession.mPromptInfo), any(IBiometricSysuiReceiver.class), - eq(BiometricAuthenticator.TYPE_FINGERPRINT /* biometricModality */), + AdditionalMatchers.aryEq(new int[] {testId}) /* sensorIds */, + eq(false) /* credentialAllowed */, anyBoolean() /* requireConfirmation */, anyInt() /* userId */, eq(TEST_PACKAGE_NAME), 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 30b1b3e78ad3..c4f7b9547277 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -2814,7 +2814,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { exerciseUserProvisioningTransitions(CALLER_USER_HANDLE, DevicePolicyManager.STATE_USER_PROFILE_COMPLETE, - DevicePolicyManager.STATE_USER_UNMANAGED); + DevicePolicyManager.STATE_USER_PROFILE_FINALIZED); } public void testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile() diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java index 058794a3b9e9..9b182a71f419 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java @@ -105,6 +105,30 @@ public final class DeviceStateManagerServiceTest { } @Test + public void requestOverrideState() { + mService.setOverrideState(OTHER_DEVICE_STATE); + // Committed state changes as there is a requested override. + assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE); + assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE); + assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE); + + // Committed state is set back to the requested state once the override is cleared. + mService.clearOverrideState(); + assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE); + assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE); + } + + @Test + public void requestOverrideState_unsupportedState() { + mService.setOverrideState(UNSUPPORTED_DEVICE_STATE); + // Committed state remains the same as the override state is unsupported. + assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE); + assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE); + } + + @Test public void supportedStatesChanged() { assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); assertEquals(mService.getPendingState(), INVALID_DEVICE_STATE); @@ -146,6 +170,23 @@ public final class DeviceStateManagerServiceTest { assertEquals(mService.getRequestedState(), OTHER_DEVICE_STATE); } + @Test + public void supportedStatesChanged_unsupportedOverrideState() { + mService.setOverrideState(OTHER_DEVICE_STATE); + // Committed state changes as there is a requested override. + assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE); + assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE); + assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE); + + mProvider.notifySupportedDeviceStates(new int []{ DEFAULT_DEVICE_STATE }); + + // Committed state is set back to the requested state as the override state is no longer + // supported. + assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE); + assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE); + } + private static final class TestDeviceStatePolicy implements DeviceStatePolicy { private final DeviceStateProvider mProvider; private int mLastDeviceStateRequestedToConfigure = INVALID_DEVICE_STATE; diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java index b8dbd6267bc5..325ba118c711 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java @@ -16,6 +16,8 @@ package com.android.server.display; +import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; @@ -33,8 +35,6 @@ import com.android.server.display.DisplayModeDirector.BrightnessObserver; import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs; import com.android.server.display.DisplayModeDirector.Vote; -import com.google.common.truth.Truth; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -90,9 +90,9 @@ public class DisplayModeDirectorTest { // With no votes present, DisplayModeDirector should allow any refresh rate. DesiredDisplayModeSpecs modeSpecs = createDirectorFromFpsRange(60, 90).getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(modeSpecs.baseModeId).isEqualTo(60); - Truth.assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(0f); - Truth.assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(Float.POSITIVE_INFINITY); + assertThat(modeSpecs.baseModeId).isEqualTo(60); + assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(0f); + assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(Float.POSITIVE_INFINITY); int numPriorities = DisplayModeDirector.Vote.MAX_PRIORITY - DisplayModeDirector.Vote.MIN_PRIORITY + 1; @@ -112,10 +112,10 @@ public class DisplayModeDirectorTest { votes.put(priority, Vote.forRefreshRates(minFps + i, maxFps - i)); director.injectVotesByDisplay(votesByDisplay); modeSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(modeSpecs.baseModeId).isEqualTo(minFps + i); - Truth.assertThat(modeSpecs.primaryRefreshRateRange.min) + assertThat(modeSpecs.baseModeId).isEqualTo(minFps + i); + assertThat(modeSpecs.primaryRefreshRateRange.min) .isEqualTo((float) (minFps + i)); - Truth.assertThat(modeSpecs.primaryRefreshRateRange.max) + assertThat(modeSpecs.primaryRefreshRateRange.max) .isEqualTo((float) (maxFps - i)); } } @@ -132,9 +132,9 @@ public class DisplayModeDirectorTest { votes.put(Vote.MIN_PRIORITY, Vote.forRefreshRates(70, 80)); director.injectVotesByDisplay(votesByDisplay); modeSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(modeSpecs.baseModeId).isEqualTo(70); - Truth.assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(70f); - Truth.assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(80f); + assertThat(modeSpecs.baseModeId).isEqualTo(70); + assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(70f); + assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(80f); } } @@ -153,9 +153,9 @@ public class DisplayModeDirectorTest { director.injectVotesByDisplay(votesByDisplay); DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.baseModeId).isEqualTo(60); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.baseModeId).isEqualTo(60); } @Test @@ -172,32 +172,32 @@ public class DisplayModeDirectorTest { votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60)); director.injectVotesByDisplay(votesByDisplay); DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); votes.clear(); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 90)); votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(90, 90)); director.injectVotesByDisplay(votesByDisplay); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90); votes.clear(); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(90, 90)); votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60)); director.injectVotesByDisplay(votesByDisplay); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90); votes.clear(); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 60)); votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(90, 90)); director.injectVotesByDisplay(votesByDisplay); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); } @Test @@ -219,29 +219,29 @@ public class DisplayModeDirectorTest { votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60)); director.injectVotesByDisplay(votesByDisplay); DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f); - Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.max).isAtLeast(90f); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f); + assertThat(desiredSpecs.appRequestRefreshRateRange.max).isAtLeast(90f); votes.put(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE, Vote.forRefreshRates(90, Float.POSITIVE_INFINITY)); director.injectVotesByDisplay(votesByDisplay); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isAtLeast(90f); - Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f); - Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.max).isAtLeast(90f); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isAtLeast(90f); + assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f); + assertThat(desiredSpecs.appRequestRefreshRateRange.max).isAtLeast(90f); votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(75, 75)); director.injectVotesByDisplay(votesByDisplay); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(75); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(75); - Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.min) + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(75); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(75); + assertThat(desiredSpecs.appRequestRefreshRateRange.min) .isWithin(FLOAT_TOLERANCE) .of(75); - Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.max) + assertThat(desiredSpecs.appRequestRefreshRateRange.max) .isWithin(FLOAT_TOLERANCE) .of(75); } @@ -251,10 +251,10 @@ public class DisplayModeDirectorTest { float appRequestMin, float appRequestMax) { DesiredDisplayModeSpecs specs = director.getDesiredDisplayModeSpecsWithInjectedFpsSettings( minFps, peakFps, defaultFps); - Truth.assertThat(specs.primaryRefreshRateRange.min).isEqualTo(primaryMin); - Truth.assertThat(specs.primaryRefreshRateRange.max).isEqualTo(primaryMax); - Truth.assertThat(specs.appRequestRefreshRateRange.min).isEqualTo(appRequestMin); - Truth.assertThat(specs.appRequestRefreshRateRange.max).isEqualTo(appRequestMax); + assertThat(specs.primaryRefreshRateRange.min).isEqualTo(primaryMin); + assertThat(specs.primaryRefreshRateRange.max).isEqualTo(primaryMax); + assertThat(specs.appRequestRefreshRateRange.min).isEqualTo(appRequestMin); + assertThat(specs.appRequestRefreshRateRange.max).isEqualTo(appRequestMax); } @Test @@ -318,26 +318,84 @@ public class DisplayModeDirectorTest { director.injectVotesByDisplay(votesByDisplay); - Truth.assertThat(director.shouldAlwaysRespectAppRequestedMode()).isFalse(); + assertThat(director.shouldAlwaysRespectAppRequestedMode()).isFalse(); DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.baseModeId).isEqualTo(60); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.baseModeId).isEqualTo(60); director.setShouldAlwaysRespectAppRequestedMode(true); - Truth.assertThat(director.shouldAlwaysRespectAppRequestedMode()).isTrue(); + assertThat(director.shouldAlwaysRespectAppRequestedMode()).isTrue(); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90); - Truth.assertThat(desiredSpecs.baseModeId).isEqualTo(90); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90); + assertThat(desiredSpecs.baseModeId).isEqualTo(90); director.setShouldAlwaysRespectAppRequestedMode(false); - Truth.assertThat(director.shouldAlwaysRespectAppRequestedMode()).isFalse(); + assertThat(director.shouldAlwaysRespectAppRequestedMode()).isFalse(); + + desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.baseModeId).isEqualTo(60); + } + + @Test + public void testVotingWithSwitchingTypeNone() { + final int displayId = 0; + DisplayModeDirector director = createDirectorFromFpsRange(0, 90); + SparseArray<Vote> votes = new SparseArray<>(); + SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>(); + votesByDisplay.put(displayId, votes); + votes.put(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE, Vote.forRefreshRates(30, 90)); + votes.put(Vote.PRIORITY_LOW_POWER_MODE, Vote.forRefreshRates(0, 60)); + + + director.injectVotesByDisplay(votesByDisplay); + assertThat(director.getModeSwitchingType()) + .isNotEqualTo(DisplayModeDirector.SWITCHING_TYPE_NONE); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.appRequestRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(0); + assertThat(desiredSpecs.appRequestRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); + assertThat(desiredSpecs.baseModeId).isEqualTo(30); + + director.setModeSwitchingType(DisplayModeDirector.SWITCHING_TYPE_NONE); + assertThat(director.getModeSwitchingType()) + .isEqualTo(DisplayModeDirector.SWITCHING_TYPE_NONE); desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60); - Truth.assertThat(desiredSpecs.baseModeId).isEqualTo(60); + assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30); + assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(30); + assertThat(desiredSpecs.appRequestRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30); + assertThat(desiredSpecs.appRequestRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(30); + assertThat(desiredSpecs.baseModeId).isEqualTo(30); + } + + @Test + public void testVotingWithSwitchingTypeWithinGroups() { + final int displayId = 0; + DisplayModeDirector director = createDirectorFromFpsRange(0, 90); + + director.setModeSwitchingType(DisplayModeDirector.SWITCHING_TYPE_WITHIN_GROUPS); + assertThat(director.getModeSwitchingType()) + .isEqualTo(DisplayModeDirector.SWITCHING_TYPE_WITHIN_GROUPS); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + assertThat(desiredSpecs.allowGroupSwitching).isFalse(); + } + + @Test + public void testVotingWithSwitchingTypeWithinAndAcrossGroups() { + final int displayId = 0; + DisplayModeDirector director = createDirectorFromFpsRange(0, 90); + + director.setModeSwitchingType(DisplayModeDirector.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS); + assertThat(director.getModeSwitchingType()) + .isEqualTo(DisplayModeDirector.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS); + DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId); + assertThat(desiredSpecs.allowGroupSwitching).isTrue(); } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java index a1eb0378a210..ae9c6188619f 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java @@ -26,26 +26,16 @@ import android.hardware.hdmi.HdmiControlManager; import android.platform.test.annotations.Presubmit; import android.provider.Settings.Global; import android.sysprop.HdmiProperties; -import android.util.Slog; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; -import com.android.server.hdmi.cec.config.CecSettings; -import com.android.server.hdmi.cec.config.XmlParser; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import javax.xml.datatype.DatatypeConfigurationException; @SmallTest @Presubmit @@ -65,13 +55,15 @@ public final class HdmiCecConfigTest { @Test public void getAllCecSettings_NoMasterXml() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig(null, null); + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, null, null); assertThat(hdmiCecConfig.getAllSettings()).isEmpty(); } @Test public void getAllCecSettings_Empty() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + "</cec-settings>", null); @@ -80,7 +72,8 @@ public final class HdmiCecConfigTest { @Test public void getAllCecSettings_BasicSanity() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"hdmi_cec_enabled\"" @@ -108,13 +101,15 @@ public final class HdmiCecConfigTest { @Test public void getUserCecSettings_NoMasterXml() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig(null, null); + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, null, null); assertThat(hdmiCecConfig.getUserSettings()).isEmpty(); } @Test public void getUserCecSettings_Empty() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + "</cec-settings>", null); @@ -123,7 +118,8 @@ public final class HdmiCecConfigTest { @Test public void getUserCecSettings_OnlyMasterXml() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"hdmi_cec_enabled\"" @@ -151,7 +147,8 @@ public final class HdmiCecConfigTest { @Test public void getUserCecSettings_WithOverride() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"hdmi_cec_enabled\"" @@ -190,14 +187,16 @@ public final class HdmiCecConfigTest { @Test public void getAllowedValues_NoMasterXml() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig(null, null); + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, null, null); assertThrows(IllegalArgumentException.class, () -> hdmiCecConfig.getAllowedValues("foo")); } @Test public void getAllowedValues_InvalidSetting() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + "</cec-settings>", null); @@ -207,7 +206,8 @@ public final class HdmiCecConfigTest { @Test public void getAllowedValues_BasicSanity() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"send_standby_on_sleep\"" @@ -229,14 +229,16 @@ public final class HdmiCecConfigTest { @Test public void getDefaultValue_NoMasterXml() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig(null, null); + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, null, null); assertThrows(IllegalArgumentException.class, () -> hdmiCecConfig.getDefaultValue("foo")); } @Test public void getDefaultValue_InvalidSetting() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + "</cec-settings>", null); @@ -246,7 +248,8 @@ public final class HdmiCecConfigTest { @Test public void getDefaultValue_BasicSanity() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"send_standby_on_sleep\"" @@ -266,14 +269,16 @@ public final class HdmiCecConfigTest { @Test public void getValue_NoMasterXml() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig(null, null); + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, null, null); assertThrows(IllegalArgumentException.class, () -> hdmiCecConfig.getValue("foo")); } @Test public void getValue_InvalidSetting() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + "</cec-settings>", null); @@ -287,7 +292,8 @@ public final class HdmiCecConfigTest { Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV)) .thenReturn(HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST); - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"send_standby_on_sleep\"" @@ -313,7 +319,8 @@ public final class HdmiCecConfigTest { .NONE.name().toLowerCase())) .thenReturn(HdmiProperties.power_state_change_on_active_source_lost_values .STANDBY_NOW.name().toLowerCase()); - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"power_state_change_on_active_source_lost\"" @@ -333,14 +340,16 @@ public final class HdmiCecConfigTest { @Test public void setValue_NoMasterXml() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig(null, null); + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, null, null); assertThrows(IllegalArgumentException.class, () -> hdmiCecConfig.setValue("foo", "bar")); } @Test public void setValue_InvalidSetting() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + "</cec-settings>", null); @@ -350,7 +359,8 @@ public final class HdmiCecConfigTest { @Test public void setValue_NotConfigurable() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"send_standby_on_sleep\"" @@ -371,7 +381,8 @@ public final class HdmiCecConfigTest { @Test public void setValue_InvalidValue() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"send_standby_on_sleep\"" @@ -392,7 +403,8 @@ public final class HdmiCecConfigTest { @Test public void setValue_GlobalSetting_BasicSanity() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"send_standby_on_sleep\"" @@ -414,7 +426,8 @@ public final class HdmiCecConfigTest { @Test public void setValue_SystemProperty_BasicSanity() { - HdmiCecConfig hdmiCecConfig = createHdmiCecConfig( + HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings( + mContext, mStorageAdapter, "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" + "<cec-settings>" + " <setting name=\"power_state_change_on_active_source_lost\"" @@ -435,22 +448,4 @@ public final class HdmiCecConfigTest { HdmiProperties.power_state_change_on_active_source_lost_values .STANDBY_NOW.name().toLowerCase()); } - - private HdmiCecConfig createHdmiCecConfig(String productConfigXml, String vendorOverrideXml) { - CecSettings productConfig = null; - CecSettings vendorOverride = null; - try { - if (productConfigXml != null) { - productConfig = XmlParser.read( - new ByteArrayInputStream(productConfigXml.getBytes())); - } - if (vendorOverrideXml != null) { - vendorOverride = XmlParser.read( - new ByteArrayInputStream(vendorOverrideXml.getBytes())); - } - } catch (IOException | DatatypeConfigurationException | XmlPullParserException e) { - Slog.e(TAG, "Encountered an error while reading/parsing CEC config strings", e); - } - return new HdmiCecConfig(mContext, mStorageAdapter, productConfig, vendorOverride); - } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java index 6e7ec2a88140..81c3be5f9f75 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java @@ -20,6 +20,8 @@ import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_PLAYBACK; import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV; import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; +import static com.android.server.hdmi.Constants.ADDR_BACKUP_1; +import static com.android.server.hdmi.Constants.ADDR_BACKUP_2; import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1; import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2; import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_3; @@ -68,9 +70,15 @@ public class HdmiCecControllerTest { Looper getServiceLooper() { return mMyLooper; } + + @Override + int getCecVersion() { + return mCecVersion; + } } private HdmiCecController mHdmiCecController; + private int mCecVersion = Constants.VERSION_1_4; private int mLogicalAddress = 16; private AllocateAddressCallback mCallback = new AllocateAddressCallback() { @@ -191,4 +199,61 @@ public class HdmiCecControllerTest { mTestLooper.dispatchAll(); assertEquals(ADDR_UNREGISTERED, mLogicalAddress); } + + @Test + public void testAllocateLogicalAddress_PlaybackNonPreferred_2_0_BackupOne() { + mCecVersion = Constants.VERSION_2_0; + + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_2, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_3, SendMessageResult.SUCCESS); + mHdmiCecController.allocateLogicalAddress(DEVICE_PLAYBACK, ADDR_UNREGISTERED, mCallback); + mTestLooper.dispatchAll(); + assertEquals(ADDR_BACKUP_1, mLogicalAddress); + } + + @Test + public void testAllocateLogicalAddress_PlaybackNonPreferred_2_0_BackupTwo() { + mCecVersion = Constants.VERSION_2_0; + + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_2, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_3, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_BACKUP_1, SendMessageResult.SUCCESS); + mHdmiCecController.allocateLogicalAddress(DEVICE_PLAYBACK, ADDR_UNREGISTERED, mCallback); + mTestLooper.dispatchAll(); + assertEquals(ADDR_BACKUP_2, mLogicalAddress); + } + + @Test + public void testAllocateLogicalAddress_PlaybackPreferredOccupiedDedicatedBelowAvailable() { + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_2, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_3, SendMessageResult.SUCCESS); + mHdmiCecController.allocateLogicalAddress(DEVICE_PLAYBACK, ADDR_PLAYBACK_2, mCallback); + mTestLooper.dispatchAll(); + assertEquals(ADDR_PLAYBACK_1, mLogicalAddress); + } + + @Test + public void testAllocateLogicalAddress_PlaybackPreferredOccupiedDedicatedAboveAvailable() { + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_2, SendMessageResult.SUCCESS); + mHdmiCecController.allocateLogicalAddress(DEVICE_PLAYBACK, ADDR_PLAYBACK_2, mCallback); + mTestLooper.dispatchAll(); + assertEquals(ADDR_PLAYBACK_3, mLogicalAddress); + } + + @Test + public void testAllocateLogicalAddress_PlaybackNonPreferred_2_0_AllOccupied() { + mCecVersion = Constants.VERSION_2_0; + + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_2, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_3, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_BACKUP_1, SendMessageResult.SUCCESS); + mNativeWrapper.setPollAddressResponse(ADDR_BACKUP_2, SendMessageResult.SUCCESS); + mHdmiCecController.allocateLogicalAddress(DEVICE_PLAYBACK, ADDR_UNREGISTERED, mCallback); + mTestLooper.dispatchAll(); + assertEquals(ADDR_UNREGISTERED, mLogicalAddress); + } } 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 c436cc846564..433f6e7938e2 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java @@ -29,6 +29,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.HdmiPortInfo; +import android.hardware.hdmi.IHdmiControlCallback; import android.media.AudioManager; import android.os.Handler; import android.os.IPowerManager; @@ -834,4 +835,42 @@ public class HdmiCecLocalDeviceAudioSystemTest { assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse(); } + + @Test + @Ignore("b/151150320") + public void oneTouchPlay() { + mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() { + @Override + public void onComplete(int result) { + } + }); + mTestLooper.dispatchAll(); + + HdmiCecMessage textViewOn_fromPlayback = HdmiCecMessageBuilder.buildTextViewOn( + mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV); + HdmiCecMessage activeSource_fromPlayback = HdmiCecMessageBuilder.buildActiveSource( + mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), + SELF_PHYSICAL_ADDRESS); + HdmiCecMessage systemAudioModeRequest_fromPlayback = + HdmiCecMessageBuilder.buildSystemAudioModeRequest( + mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), + ADDR_AUDIO_SYSTEM, SELF_PHYSICAL_ADDRESS, true); + HdmiCecMessage textViewOn_fromAudioSystem = HdmiCecMessageBuilder.buildTextViewOn( + mHdmiCecLocalDeviceAudioSystem.getDeviceInfo().getLogicalAddress(), ADDR_TV); + HdmiCecMessage activeSource_fromAudioSystem = HdmiCecMessageBuilder.buildActiveSource( + mHdmiCecLocalDeviceAudioSystem.getDeviceInfo().getLogicalAddress(), + SELF_PHYSICAL_ADDRESS); + HdmiCecMessage systemAudioModeRequest_fromAudioSystem = + HdmiCecMessageBuilder.buildSystemAudioModeRequest( + mHdmiCecLocalDeviceAudioSystem.getDeviceInfo().getLogicalAddress(), + ADDR_AUDIO_SYSTEM, SELF_PHYSICAL_ADDRESS, true); + assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn_fromPlayback); + assertThat(mNativeWrapper.getResultMessages()).contains(activeSource_fromPlayback); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain( + systemAudioModeRequest_fromPlayback); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn_fromAudioSystem); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource_fromAudioSystem); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain( + systemAudioModeRequest_fromAudioSystem); + } } 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 1c04d98327c9..440befcb3368 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -26,6 +26,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPortInfo; +import android.hardware.hdmi.IHdmiControlCallback; import android.os.Handler; import android.os.IPowerManager; import android.os.IThermalService; @@ -974,4 +975,73 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); assertThat(mStandby).isFalse(); } + + @Test + public void oneTouchPlay_SendStandbyOnSleepToTv() { + mHdmiCecLocalDevicePlayback.mService.writeStringSetting( + Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, + HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV); + mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() { + @Override + public void onComplete(int result) { + } + }); + mTestLooper.dispatchAll(); + + HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress, + ADDR_TV); + HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource( + mPlaybackLogicalAddress, mPlaybackPhysicalAddress); + HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest( + mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true); + assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn); + assertThat(mNativeWrapper.getResultMessages()).contains(activeSource); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(systemAudioModeRequest); + } + + @Test + public void oneTouchPlay_SendStandbyOnSleepBroadcast() { + mHdmiCecLocalDevicePlayback.mService.writeStringSetting( + Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, + HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST); + mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() { + @Override + public void onComplete(int result) { + } + }); + mTestLooper.dispatchAll(); + + HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress, + ADDR_TV); + HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource( + mPlaybackLogicalAddress, mPlaybackPhysicalAddress); + HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest( + mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true); + assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn); + assertThat(mNativeWrapper.getResultMessages()).contains(activeSource); + assertThat(mNativeWrapper.getResultMessages()).contains(systemAudioModeRequest); + } + + @Test + public void oneTouchPlay_SendStandbyOnSleepNone() { + mHdmiCecLocalDevicePlayback.mService.writeStringSetting( + Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, + HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE); + mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() { + @Override + public void onComplete(int result) { + } + }); + mTestLooper.dispatchAll(); + + HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress, + ADDR_TV); + HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource( + mPlaybackLogicalAddress, mPlaybackPhysicalAddress); + HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest( + mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true); + assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn); + assertThat(mNativeWrapper.getResultMessages()).contains(activeSource); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(systemAudioModeRequest); + } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java index 5a05fc6eda4c..470294073535 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -17,6 +17,7 @@ package com.android.server.hdmi; import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_DESTINATION; +import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_PARAMETER; import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_PARAMETER_SHORT; import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_SOURCE; import static com.android.server.hdmi.HdmiCecMessageValidator.OK; @@ -65,10 +66,120 @@ public class HdmiCecMessageValidatorTest { @Test public void isValid_reportPowerStatus() { assertMessageValidity("04:90:00").isEqualTo(OK); + assertMessageValidity("04:90:03:05").isEqualTo(OK); assertMessageValidity("0F:90:00").isEqualTo(ERROR_DESTINATION); assertMessageValidity("F0:90").isEqualTo(ERROR_SOURCE); assertMessageValidity("04:90").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("04:90:04").isEqualTo(ERROR_PARAMETER); + } + + @Test + public void isValid_menuRequest() { + assertMessageValidity("40:8D:00").isEqualTo(OK); + assertMessageValidity("40:8D:02:04").isEqualTo(OK); + + assertMessageValidity("0F:8D:00").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:8D").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:8D").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:8D:03").isEqualTo(ERROR_PARAMETER); + } + + @Test + public void isValid_menuStatus() { + assertMessageValidity("40:8E:00").isEqualTo(OK); + assertMessageValidity("40:8E:01:00").isEqualTo(OK); + + assertMessageValidity("0F:8E:00").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:8E").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:8E").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:8E:02").isEqualTo(ERROR_PARAMETER); + } + + @Test + public void isValid_setSystemAudioMode() { + assertMessageValidity("40:72:00").isEqualTo(OK); + assertMessageValidity("4F:72:01:03").isEqualTo(OK); + + assertMessageValidity("F0:72").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:72").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:72:02").isEqualTo(ERROR_PARAMETER); + } + + @Test + public void isValid_systemAudioModeStatus() { + assertMessageValidity("40:7E:00").isEqualTo(OK); + assertMessageValidity("40:7E:01:01").isEqualTo(OK); + + assertMessageValidity("0F:7E:00").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:7E").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:7E").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:7E:02").isEqualTo(ERROR_PARAMETER); + } + + @Test + public void isValid_setAudioRate() { + assertMessageValidity("40:9A:00").isEqualTo(OK); + assertMessageValidity("40:9A:03").isEqualTo(OK); + assertMessageValidity("40:9A:06:02").isEqualTo(OK); + + assertMessageValidity("0F:9A:00").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:9A").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:9A").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:9A:07").isEqualTo(ERROR_PARAMETER); + } + + @Test + public void isValid_setMenuLanguage() { + assertMessageValidity("4F:32:53:50:41").isEqualTo(OK); + assertMessageValidity("0F:32:45:4E:47:8C:49:D3:48").isEqualTo(OK); + + assertMessageValidity("40:32:53:50:41").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:32").isEqualTo(ERROR_SOURCE); + assertMessageValidity("4F:32:45:55").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("4F:32:19:7F:83").isEqualTo(ERROR_PARAMETER); + } + + @Test + public void isValid_setOsdString() { + assertMessageValidity("40:64:80:41").isEqualTo(OK); + // Even though the parameter string in this message is longer than 14 bytes, it is accepted + // as this parameter might be extended in future versions. + assertMessageValidity("04:64:00:4C:69:76:69:6E:67:52:6F:6F:6D:20:54:56:C4").isEqualTo(OK); + + assertMessageValidity("4F:64:40:41").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:64:C0:41").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:64:00").isEqualTo(ERROR_PARAMETER_SHORT); + // Invalid Display Control + assertMessageValidity("40:64:20:4C:69:76").isEqualTo(ERROR_PARAMETER); + // Invalid ASCII characters + assertMessageValidity("40:64:40:4C:69:7F").isEqualTo(ERROR_PARAMETER); + } + + @Test + public void isValid_setOsdName() { + assertMessageValidity("40:47:4C:69:76:69:6E:67:52:6F:6F:6D:54:56").isEqualTo(OK); + assertMessageValidity("40:47:54:56").isEqualTo(OK); + + assertMessageValidity("4F:47:54:56").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:47:54:56").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:47").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:47:4C:69:7F").isEqualTo(ERROR_PARAMETER); + } + + @Test + public void isValid_recordStatus() { + assertMessageValidity("40:0A:01").isEqualTo(OK); + assertMessageValidity("40:0A:13").isEqualTo(OK); + assertMessageValidity("40:0A:1F:04:01").isEqualTo(OK); + + assertMessageValidity("0F:0A:01").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:0A:01").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:0A").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:0A:00").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:0A:0F").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:0A:1D").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:0A:30").isEqualTo(ERROR_PARAMETER); } private IntegerSubject assertMessageValidity(String message) { diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java index 4f18582bf83f..080b52bbbc6a 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java @@ -285,12 +285,34 @@ public class HdmiCecNetworkTest { } @Test + public void cecDevices_tracking_reportVendorId() { + int logicalAddress = Constants.ADDR_PLAYBACK_1; + int vendorId = 1234; + mHdmiCecNetwork.handleCecMessage( + HdmiCecMessageBuilder.buildDeviceVendorIdCommand(logicalAddress, vendorId)); + + assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1); + + HdmiDeviceInfo cecDeviceInfo = mHdmiCecNetwork.getCecDeviceInfo(logicalAddress); + assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress); + assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo( + Constants.INVALID_PHYSICAL_ADDRESS); + assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_RESERVED); + assertThat(cecDeviceInfo.getDisplayName()).isEqualTo( + HdmiUtils.getDefaultDeviceName(logicalAddress)); + assertThat(cecDeviceInfo.getVendorId()).isEqualTo(vendorId); + assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo( + HdmiControlManager.POWER_STATUS_UNKNOWN); + } + + @Test public void cecDevices_tracking_updatesDeviceInfo() { int logicalAddress = Constants.ADDR_PLAYBACK_1; int physicalAddress = 0x1000; int type = HdmiDeviceInfo.DEVICE_PLAYBACK; int powerStatus = HdmiControlManager.POWER_STATUS_ON; String osdName = "Test Device"; + int vendorId = 1234; mHdmiCecNetwork.handleCecMessage( HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(logicalAddress, @@ -301,6 +323,8 @@ public class HdmiCecNetworkTest { mHdmiCecNetwork.handleCecMessage( HdmiCecMessageBuilder.buildSetOsdNameCommand(logicalAddress, Constants.ADDR_BROADCAST, osdName)); + mHdmiCecNetwork.handleCecMessage( + HdmiCecMessageBuilder.buildDeviceVendorIdCommand(logicalAddress, vendorId)); assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1); @@ -309,6 +333,7 @@ public class HdmiCecNetworkTest { assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo(physicalAddress); assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(type); assertThat(cecDeviceInfo.getDisplayName()).isEqualTo(osdName); + assertThat(cecDeviceInfo.getVendorId()).isEqualTo(vendorId); assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo(powerStatus); } @@ -382,6 +407,30 @@ public class HdmiCecNetworkTest { } @Test + public void cecDevices_tracking_updatesVendorId() { + int logicalAddress = Constants.ADDR_PLAYBACK_1; + int vendorId = 1234; + int updatedVendorId = 12345; + mHdmiCecNetwork.handleCecMessage( + HdmiCecMessageBuilder.buildDeviceVendorIdCommand(logicalAddress, vendorId)); + mHdmiCecNetwork.handleCecMessage( + HdmiCecMessageBuilder.buildDeviceVendorIdCommand(logicalAddress, updatedVendorId)); + + assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1); + + HdmiDeviceInfo cecDeviceInfo = mHdmiCecNetwork.getCecDeviceInfo(logicalAddress); + assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress); + assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo( + Constants.INVALID_PHYSICAL_ADDRESS); + assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_RESERVED); + assertThat(cecDeviceInfo.getDisplayName()).isEqualTo( + HdmiUtils.getDefaultDeviceName(logicalAddress)); + assertThat(cecDeviceInfo.getVendorId()).isEqualTo(updatedVendorId); + assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo( + HdmiControlManager.POWER_STATUS_UNKNOWN); + } + + @Test public void cecDevices_tracking_clearDevices() { int logicalAddress = Constants.ADDR_PLAYBACK_1; mHdmiCecNetwork.handleCecMessage( 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 8f631a307f15..68b46c408028 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -382,6 +382,45 @@ public class HdmiControlServiceTest { assertThat(callback2.mVolumeControlEnabled).isTrue(); } + @Test + public void getCecVersion_default() { + // Set the Settings value to "null" to emulate it being empty and force the default value. + Settings.Global.putString(mContextSpy.getContentResolver(), + Settings.Global.HDMI_CEC_VERSION, + null); + mHdmiControlService.setControlEnabled(true); + assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_1_4); + } + + @Test + public void getCecVersion_1_4() { + Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION, + Constants.VERSION_1_4); + mHdmiControlService.setControlEnabled(true); + assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_1_4); + } + + @Test + public void getCecVersion_2_0() { + Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION, + Constants.VERSION_2_0); + mHdmiControlService.setControlEnabled(true); + assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_2_0); + } + + @Test + public void getCecVersion_change() { + Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION, + Constants.VERSION_1_4); + mHdmiControlService.setControlEnabled(true); + assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_1_4); + + Settings.Global.putInt(mContextSpy.getContentResolver(), Settings.Global.HDMI_CEC_VERSION, + Constants.VERSION_2_0); + mHdmiControlService.setControlEnabled(true); + assertThat(mHdmiControlService.getCecVersion()).isEqualTo(Constants.VERSION_2_0); + } + private static class VolumeControlFeatureCallback extends IHdmiCecVolumeControlFeatureListener.Stub { diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java index d8f5c4c8f58c..a8f3acf8726f 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import android.hardware.hdmi.HdmiDeviceInfo; import android.platform.test.annotations.Presubmit; import android.util.Slog; @@ -235,4 +236,366 @@ public class HdmiUtilsTest { assertThat(HdmiUtils.pathRelationship(0x1234, 0x1234)) .isEqualTo(Constants.PATH_RELATIONSHIP_SAME); } + + @Test + public void getTypeFromAddress() { + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_TV)).containsExactly( + HdmiDeviceInfo.DEVICE_TV); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_RECORDER_1)).containsExactly( + HdmiDeviceInfo.DEVICE_RECORDER); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_RECORDER_2)).containsExactly( + HdmiDeviceInfo.DEVICE_RECORDER); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_TUNER_1)).containsExactly( + HdmiDeviceInfo.DEVICE_TUNER); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_PLAYBACK_1)).containsExactly( + HdmiDeviceInfo.DEVICE_PLAYBACK); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_AUDIO_SYSTEM)).containsExactly( + HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_TUNER_2)).containsExactly( + HdmiDeviceInfo.DEVICE_TUNER); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_TUNER_3)).containsExactly( + HdmiDeviceInfo.DEVICE_TUNER); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_PLAYBACK_2)).containsExactly( + HdmiDeviceInfo.DEVICE_PLAYBACK); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_RECORDER_3)).containsExactly( + HdmiDeviceInfo.DEVICE_RECORDER); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_TUNER_4)).containsExactly( + HdmiDeviceInfo.DEVICE_TUNER); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_PLAYBACK_3)).containsExactly( + HdmiDeviceInfo.DEVICE_PLAYBACK); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_BACKUP_1)).containsExactly( + HdmiDeviceInfo.DEVICE_PLAYBACK, HdmiDeviceInfo.DEVICE_RECORDER, + HdmiDeviceInfo.DEVICE_TUNER, HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_BACKUP_2)).containsExactly( + HdmiDeviceInfo.DEVICE_PLAYBACK, HdmiDeviceInfo.DEVICE_RECORDER, + HdmiDeviceInfo.DEVICE_TUNER, HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR); + assertThat(HdmiUtils.getTypeFromAddress(Constants.ADDR_SPECIFIC_USE)).containsExactly( + HdmiDeviceInfo.DEVICE_TV); + } + + @Test + public void isEligibleAddressForDevice() { + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_TV)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_TV)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_TV)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_TV)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_TV)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_TV)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_TV)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_TV)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_RECORDER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_RECORDER_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_RECORDER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_RECORDER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_RECORDER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_RECORDER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_RECORDER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_RECORDER_1)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_RECORDER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_RECORDER_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_RECORDER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_RECORDER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_RECORDER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_RECORDER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_RECORDER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_RECORDER_2)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_TUNER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_TUNER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_TUNER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_TUNER_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_TUNER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_TUNER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_TUNER_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_TUNER_1)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_PLAYBACK_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_PLAYBACK_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_PLAYBACK_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_PLAYBACK_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_PLAYBACK_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_PLAYBACK_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_PLAYBACK_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_PLAYBACK_1)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_AUDIO_SYSTEM)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_AUDIO_SYSTEM)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_AUDIO_SYSTEM)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_AUDIO_SYSTEM)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_AUDIO_SYSTEM)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_AUDIO_SYSTEM)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_AUDIO_SYSTEM)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_AUDIO_SYSTEM)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_TUNER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_TUNER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_TUNER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_TUNER_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_TUNER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_TUNER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_TUNER_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_TUNER_2)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_TUNER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_TUNER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_TUNER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_TUNER_3)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_TUNER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_TUNER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_TUNER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_TUNER_3)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_PLAYBACK_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_PLAYBACK_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_PLAYBACK_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_PLAYBACK_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_PLAYBACK_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_PLAYBACK_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_PLAYBACK_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_PLAYBACK_2)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_RECORDER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_RECORDER_3)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_RECORDER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_RECORDER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_RECORDER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_RECORDER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_RECORDER_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_RECORDER_3)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_TUNER_4)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_TUNER_4)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_TUNER_4)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_TUNER_4)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_TUNER_4)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_TUNER_4)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_TUNER_4)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_TUNER_4)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_PLAYBACK_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_PLAYBACK_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_PLAYBACK_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_PLAYBACK_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_PLAYBACK_3)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_PLAYBACK_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_PLAYBACK_3)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_PLAYBACK_3)).isFalse(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_BACKUP_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_BACKUP_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_BACKUP_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_BACKUP_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_BACKUP_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_BACKUP_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_BACKUP_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_BACKUP_1)).isTrue(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_BACKUP_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_BACKUP_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_BACKUP_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_BACKUP_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_BACKUP_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_BACKUP_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_BACKUP_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_BACKUP_2)).isTrue(); + + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TV, + Constants.ADDR_SPECIFIC_USE)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RECORDER, + Constants.ADDR_SPECIFIC_USE)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_RESERVED, + Constants.ADDR_SPECIFIC_USE)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_TUNER, + Constants.ADDR_SPECIFIC_USE)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PLAYBACK, + Constants.ADDR_SPECIFIC_USE)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, + Constants.ADDR_SPECIFIC_USE)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, + Constants.ADDR_SPECIFIC_USE)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForDevice(HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR, + Constants.ADDR_SPECIFIC_USE)).isFalse(); + } + + @Test + public void isEligibleAddressForCecVersion_1_4() { + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_TV)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_RECORDER_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_RECORDER_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_TUNER_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_PLAYBACK_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_AUDIO_SYSTEM)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_TUNER_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_TUNER_3)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_PLAYBACK_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_RECORDER_3)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_TUNER_4)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_PLAYBACK_3)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_BACKUP_1)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_BACKUP_2)).isFalse(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_1_4, + Constants.ADDR_SPECIFIC_USE)).isTrue(); + } + + @Test + public void isEligibleAddressForCecVersion_2_0() { + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_TV)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_RECORDER_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_RECORDER_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_TUNER_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_PLAYBACK_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_AUDIO_SYSTEM)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_TUNER_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_TUNER_3)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_PLAYBACK_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_RECORDER_3)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_TUNER_4)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_PLAYBACK_3)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_BACKUP_1)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_BACKUP_2)).isTrue(); + assertThat(HdmiUtils.isEligibleAddressForCecVersion(Constants.VERSION_2_0, + Constants.ADDR_SPECIFIC_USE)).isTrue(); + } } diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java index 72afca0300cd..9b25d0dc9c77 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java @@ -45,6 +45,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.TestPackageParser2; +import com.android.server.pm.parsing.pkg.AndroidPackage; import org.junit.Before; import org.junit.Test; @@ -288,6 +289,31 @@ public class ApexManagerTest { assertThat(mApexManager.isApkInApexInstallSuccess(activeApex.apexModuleName)).isFalse(); } + /** + * registerApkInApex method checks if the prefix of base apk path contains the apex package + * name. When an apex package name is a prefix of another apex package name, e.g, + * com.android.media and com.android.mediaprovider, then we need to ensure apk inside apex + * mediaprovider does not get registered under apex media. + */ + @Test + public void testRegisterApkInApexDoesNotRegisterSimilarPrefix() throws RemoteException { + when(mApexService.getActivePackages()).thenReturn(createApexInfo(true, true)); + final ApexManager.ActiveApexInfo activeApex = mApexManager.getActiveApexInfos().get(0); + assertThat(activeApex.apexModuleName).isEqualTo(TEST_APEX_PKG); + + AndroidPackage fakeApkInApex = mock(AndroidPackage.class); + when(fakeApkInApex.getBaseApkPath()).thenReturn("/apex/" + TEST_APEX_PKG + "randomSuffix"); + when(fakeApkInApex.getPackageName()).thenReturn("randomPackageName"); + + when(mApexService.getAllPackages()).thenReturn(createApexInfo(true, true)); + mApexManager.scanApexPackagesTraced(mPackageParser2, + ParallelPackageParser.makeExecutorService()); + + assertThat(mApexManager.getApksInApex(activeApex.apexModuleName)).isEmpty(); + mApexManager.registerApkInApex(fakeApkInApex); + assertThat(mApexManager.getApksInApex(activeApex.apexModuleName)).isEmpty(); + } + private ApexInfo[] createApexInfo(boolean isActive, boolean isFactory) { File apexFile = extractResource(TEST_APEX_PKG, TEST_APEX_FILE_NAME); ApexInfo apexInfo = new ApexInfo(); diff --git a/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java b/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java index 86758f18a407..40d959d9793d 100644 --- a/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java @@ -222,4 +222,18 @@ public class IncrementalStatesTest { assertTrue(mFullyLoadedCalled.block(WAIT_TIMEOUT_MILLIS)); assertFalse(mIncrementalStates.isLoading()); } + + /** + * Test startability transitions if app crashes or anrs + */ + @Test + public void testStartableTransition_AppCrashOrAnr() { + mIncrementalStates.onCrashOrAnr(); + assertFalse(mIncrementalStates.isStartable()); + mIncrementalStates.setProgress(1.0f); + assertTrue(mIncrementalStates.isStartable()); + mIncrementalStates.onCrashOrAnr(); + // Test that if fully loaded, app remains startable even if it has crashed + assertTrue(mIncrementalStates.isStartable()); + } } diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java index 0c6d6388b458..c43050386dcf 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java @@ -45,6 +45,11 @@ import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; +import static com.android.server.usage.AppStandbyController.DEFAULT_ELAPSED_TIME_THRESHOLDS; +import static com.android.server.usage.AppStandbyController.DEFAULT_SCREEN_TIME_THRESHOLDS; +import static com.android.server.usage.AppStandbyController.MINIMUM_ELAPSED_TIME_THRESHOLDS; +import static com.android.server.usage.AppStandbyController.MINIMUM_SCREEN_TIME_THRESHOLDS; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; @@ -73,6 +78,7 @@ import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; +import android.provider.DeviceConfig; import android.util.ArraySet; import android.view.Display; @@ -184,6 +190,19 @@ public class AppStandbyControllerTests { int[] mRunningUsers = new int[] {USER_ID}; List<UserHandle> mCrossProfileTargets = Collections.emptyList(); boolean mDeviceIdleMode = false; + DeviceConfig.Properties.Builder mSettingsBuilder = + new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_APP_STANDBY) + .setLong("screen_threshold_active", 0) + .setLong("screen_threshold_working_set", 0) + .setLong("screen_threshold_frequent", 0) + .setLong("screen_threshold_rare", HOUR_MS) + // screen_threshold_restricted intentionally skipped + .setLong("elapsed_threshold_active", 0) + .setLong("elapsed_threshold_working_set", WORKING_SET_THRESHOLD) + .setLong("elapsed_threshold_frequent", FREQUENT_THRESHOLD) + .setLong("elapsed_threshold_rare", RARE_THRESHOLD) + .setLong("elapsed_threshold_restricted", RESTRICTED_THRESHOLD); + DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener; MyInjector(Context context, Looper looper) { super(context, looper); @@ -285,10 +304,9 @@ public class AppStandbyControllerTests { } @Override - String getAppIdleSettings() { - return "screen_thresholds=0/0/0/" + HOUR_MS + ",elapsed_thresholds=0/" - + WORKING_SET_THRESHOLD + "/" + FREQUENT_THRESHOLD + "/" + RARE_THRESHOLD - + "/" + RESTRICTED_THRESHOLD; + @NonNull + DeviceConfig.Properties getDeviceConfigProperties(String... keys) { + return mSettingsBuilder.build(); } @Override @@ -301,6 +319,12 @@ public class AppStandbyControllerTests { return mCrossProfileTargets; } + @Override + public void registerDeviceConfigPropertiesChangedListener( + @NonNull DeviceConfig.OnPropertiesChangedListener listener) { + mPropertiesChangedListener = listener; + } + // Internal methods void setDisplayOn(boolean on) { @@ -867,6 +891,25 @@ public class AppStandbyControllerTests { assertBucket(STANDBY_BUCKET_RARE); } + /** Test that timeouts still work properly even if invalid configuration values are set. */ + @Test + public void testTimeout_InvalidThresholds() throws Exception { + mInjector.mSettingsBuilder + .setLong("screen_threshold_active", -1) + .setLong("screen_threshold_working_set", -1) + .setLong("screen_threshold_frequent", -1) + .setLong("screen_threshold_rare", -1) + .setLong("screen_threshold_restricted", -1) + .setLong("elapsed_threshold_active", -1) + .setLong("elapsed_threshold_working_set", -1) + .setLong("elapsed_threshold_frequent", -1) + .setLong("elapsed_threshold_rare", -1) + .setLong("elapsed_threshold_restricted", -1); + mInjector.mPropertiesChangedListener + .onPropertiesChanged(mInjector.getDeviceConfigProperties()); + testTimeout(); + } + /** * Test that setAppStandbyBucket to RESTRICTED doesn't change the bucket until the usage * timeout has passed. @@ -1554,6 +1597,132 @@ public class AppStandbyControllerTests { assertBucket(STANDBY_BUCKET_RARE, PACKAGE_1); } + @Test + public void testChangingSettings_ElapsedThreshold_Invalid() { + mInjector.mSettingsBuilder + .setLong("elapsed_threshold_active", -1) + .setLong("elapsed_threshold_working_set", -1) + .setLong("elapsed_threshold_frequent", -1) + .setLong("elapsed_threshold_rare", -1) + .setLong("elapsed_threshold_restricted", -1); + mInjector.mPropertiesChangedListener + .onPropertiesChanged(mInjector.getDeviceConfigProperties()); + for (int i = 0; i < MINIMUM_ELAPSED_TIME_THRESHOLDS.length; ++i) { + assertEquals(MINIMUM_ELAPSED_TIME_THRESHOLDS[i], + mController.mAppStandbyElapsedThresholds[i]); + } + } + + @Test + public void testChangingSettings_ElapsedThreshold_Valid() { + // Effectively clear values + mInjector.mSettingsBuilder + .setString("elapsed_threshold_active", null) + .setString("elapsed_threshold_working_set", null) + .setString("elapsed_threshold_frequent", null) + .setString("elapsed_threshold_rare", null) + .setString("elapsed_threshold_restricted", null); + mInjector.mPropertiesChangedListener + .onPropertiesChanged(mInjector.getDeviceConfigProperties()); + for (int i = 0; i < DEFAULT_ELAPSED_TIME_THRESHOLDS.length; ++i) { + assertEquals(DEFAULT_ELAPSED_TIME_THRESHOLDS[i], + mController.mAppStandbyElapsedThresholds[i]); + } + + // Set really high thresholds + mInjector.mSettingsBuilder + .setLong("elapsed_threshold_active", 90 * DAY_MS) + .setLong("elapsed_threshold_working_set", 91 * DAY_MS) + .setLong("elapsed_threshold_frequent", 92 * DAY_MS) + .setLong("elapsed_threshold_rare", 93 * DAY_MS) + .setLong("elapsed_threshold_restricted", 94 * DAY_MS); + mInjector.mPropertiesChangedListener + .onPropertiesChanged(mInjector.getDeviceConfigProperties()); + for (int i = 0; i < mController.mAppStandbyElapsedThresholds.length; ++i) { + assertEquals((90 + i) * DAY_MS, mController.mAppStandbyElapsedThresholds[i]); + } + + // Only set a few values + mInjector.mSettingsBuilder + .setString("elapsed_threshold_active", null) + .setLong("elapsed_threshold_working_set", 31 * DAY_MS) + .setLong("elapsed_threshold_frequent", 62 * DAY_MS) + .setString("elapsed_threshold_rare", null) + .setLong("elapsed_threshold_restricted", 93 * DAY_MS); + mInjector.mPropertiesChangedListener + .onPropertiesChanged(mInjector.getDeviceConfigProperties()); + + assertEquals(DEFAULT_ELAPSED_TIME_THRESHOLDS[0], + mController.mAppStandbyElapsedThresholds[0]); + assertEquals(31 * DAY_MS, mController.mAppStandbyElapsedThresholds[1]); + assertEquals(62 * DAY_MS, mController.mAppStandbyElapsedThresholds[2]); + assertEquals(DEFAULT_ELAPSED_TIME_THRESHOLDS[3], + mController.mAppStandbyElapsedThresholds[3]); + assertEquals(93 * DAY_MS, mController.mAppStandbyElapsedThresholds[4]); + } + + @Test + public void testChangingSettings_ScreenThreshold_Invalid() { + mInjector.mSettingsBuilder + .setLong("screen_threshold_active", -1) + .setLong("screen_threshold_working_set", -1) + .setLong("screen_threshold_frequent", -1) + .setLong("screen_threshold_rare", -1) + .setLong("screen_threshold_restricted", -1); + mInjector.mPropertiesChangedListener + .onPropertiesChanged(mInjector.getDeviceConfigProperties()); + for (int i = 0; i < MINIMUM_SCREEN_TIME_THRESHOLDS.length; ++i) { + assertEquals(MINIMUM_SCREEN_TIME_THRESHOLDS[i], + mController.mAppStandbyScreenThresholds[i]); + } + } + + @Test + public void testChangingSettings_ScreenThreshold_Valid() { + // Effectively clear values + mInjector.mSettingsBuilder + .setString("screen_threshold_active", null) + .setString("screen_threshold_working_set", null) + .setString("screen_threshold_frequent", null) + .setString("screen_threshold_rare", null) + .setString("screen_threshold_restricted", null); + mInjector.mPropertiesChangedListener + .onPropertiesChanged(mInjector.getDeviceConfigProperties()); + for (int i = 0; i < DEFAULT_SCREEN_TIME_THRESHOLDS.length; ++i) { + assertEquals(DEFAULT_SCREEN_TIME_THRESHOLDS[i], + mController.mAppStandbyScreenThresholds[i]); + } + + // Set really high thresholds + mInjector.mSettingsBuilder + .setLong("screen_threshold_active", 90 * DAY_MS) + .setLong("screen_threshold_working_set", 91 * DAY_MS) + .setLong("screen_threshold_frequent", 92 * DAY_MS) + .setLong("screen_threshold_rare", 93 * DAY_MS) + .setLong("screen_threshold_restricted", 94 * DAY_MS); + mInjector.mPropertiesChangedListener + .onPropertiesChanged(mInjector.getDeviceConfigProperties()); + for (int i = 0; i < mController.mAppStandbyScreenThresholds.length; ++i) { + assertEquals((90 + i) * DAY_MS, mController.mAppStandbyScreenThresholds[i]); + } + + // Only set a few values + mInjector.mSettingsBuilder + .setString("screen_threshold_active", null) + .setLong("screen_threshold_working_set", 31 * DAY_MS) + .setLong("screen_threshold_frequent", 62 * DAY_MS) + .setString("screen_threshold_rare", null) + .setLong("screen_threshold_restricted", 93 * DAY_MS); + mInjector.mPropertiesChangedListener + .onPropertiesChanged(mInjector.getDeviceConfigProperties()); + + assertEquals(DEFAULT_SCREEN_TIME_THRESHOLDS[0], mController.mAppStandbyScreenThresholds[0]); + assertEquals(31 * DAY_MS, mController.mAppStandbyScreenThresholds[1]); + assertEquals(62 * DAY_MS, mController.mAppStandbyScreenThresholds[2]); + assertEquals(DEFAULT_SCREEN_TIME_THRESHOLDS[3], mController.mAppStandbyScreenThresholds[3]); + assertEquals(93 * DAY_MS, mController.mAppStandbyScreenThresholds[4]); + } + private String getAdminAppsStr(int userId) { return getAdminAppsStr(userId, mController.getActiveAdminAppsForTest(userId)); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java index b77f8c5eb8cd..fdc089ee2f7e 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java @@ -120,7 +120,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase { assertEquals(canBubble(i), ranking.canBubble()); assertEquals(visuallyInterruptive(i), ranking.visuallyInterruptive()); assertEquals(isConversation(i), ranking.isConversation()); - assertEquals(getShortcutInfo(i).getId(), ranking.getShortcutInfo().getId()); + assertEquals(getShortcutInfo(i).getId(), ranking.getConversationShortcutInfo().getId()); assertEquals(getRankingAdjustment(i), ranking.getRankingAdjustment()); } } @@ -191,7 +191,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase { tweak.canBubble(), tweak.visuallyInterruptive(), tweak.isConversation(), - tweak.getShortcutInfo(), + tweak.getConversationShortcutInfo(), tweak.getRankingAdjustment(), tweak.isBubble() ); @@ -440,7 +440,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase { assertEquals(comment, a.getSmartReplies(), b.getSmartReplies()); assertEquals(comment, a.canBubble(), b.canBubble()); assertEquals(comment, a.isConversation(), b.isConversation()); - assertEquals(comment, a.getShortcutInfo().getId(), b.getShortcutInfo().getId()); + assertEquals(comment, a.getConversationShortcutInfo().getId(), b.getConversationShortcutInfo().getId()); assertActionsEqual(a.getSmartActions(), b.getSmartActions()); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 3e779a9b2435..bf742b7f96dc 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -218,6 +218,22 @@ public class PreferencesHelperTest extends UiServiceTestCase { return null; }).when(mTestIContentProvider).canonicalizeAsync(any(), any(), any(), any()); doAnswer(invocation -> { + String callingPkg = invocation.getArgument(0); + String featureId = invocation.getArgument(1); + Uri uri = invocation.getArgument(2); + RemoteCallback cb = invocation.getArgument(3); + IContentProvider mock = (IContentProvider) (invocation.getMock()); + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + final Bundle bundle = new Bundle(); + try { + bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, + mock.uncanonicalize(callingPkg, featureId, uri)); + } catch (RemoteException e) { /* consume */ } + cb.sendResult(bundle); + }); + return null; + }).when(mTestIContentProvider).uncanonicalizeAsync(any(), any(), any(), any()); + doAnswer(invocation -> { Uri uri = invocation.getArgument(0); RemoteCallback cb = invocation.getArgument(1); IContentProvider mock = (IContentProvider) (invocation.getMock()); diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml index 9099272a0fd6..7f4f3dd58812 100644 --- a/services/tests/wmtests/AndroidManifest.xml +++ b/services/tests/wmtests/AndroidManifest.xml @@ -24,7 +24,7 @@ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> - <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> <uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" /> <uses-permission android:name="android.permission.MANAGE_USERS" /> <uses-permission android:name="android.permission.STORAGE_INTERNAL" /> diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index caf8a720e26c..b6323313dd27 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -245,9 +245,8 @@ public class ActivityStackTests extends WindowTestsBase { .setStack(rootHomeTask) .setCreateTask(true) .build(); - final Task secondaryStack = (Task) WindowContainer.fromBinder( - mAtm.mTaskOrganizerController.createRootTask(rootHomeTask.getDisplayId(), - WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token.asBinder()); + final Task secondaryStack = mAtm.mTaskOrganizerController.createRootTask( + rootHomeTask.getDisplayContent(), WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null); rootHomeTask.reparent(secondaryStack, POSITION_TOP); assertEquals(secondaryStack, rootHomeTask.getParent()); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index e47881917b2c..3720e520b1b9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -1022,7 +1022,7 @@ public class ActivityStarterTests extends WindowTestsBase { assertThat(outActivity[0].inSplitScreenWindowingMode()).isFalse(); // Move activity to split-screen-primary stack and make sure it has the focus. - TestSplitOrganizer splitOrg = new TestSplitOrganizer(mAtm, top.getDisplayId()); + TestSplitOrganizer splitOrg = new TestSplitOrganizer(mAtm, top.getDisplayContent()); top.getRootTask().reparent(splitOrg.mPrimary, POSITION_BOTTOM); top.getRootTask().moveToFront("testWindowingModeOptionsLaunchAdjacent"); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java index 54b2b3b4a009..3220d1d6a990 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java @@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,6 +32,7 @@ import android.os.Binder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.view.SurfaceControl; +import android.window.DisplayAreaAppearedInfo; import android.window.DisplayAreaInfo; import android.window.IDisplayAreaOrganizer; @@ -41,6 +43,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.List; + /** * Build/Install/Run: * atest WmTests:DisplayAreaOrganizerTest @@ -89,27 +93,39 @@ public class DisplayAreaOrganizerTest extends WindowTestsBase { } @Test + public void testRegisterOrganizer() throws RemoteException { + IDisplayAreaOrganizer organizer = createMockOrganizer(new Binder()); + List<DisplayAreaAppearedInfo> infos = mWm.mAtmService.mWindowOrganizerController + .mDisplayAreaOrganizerController + .registerOrganizer(organizer, FEATURE_VENDOR_FIRST).getList(); + + // Return a list contains the DA, and no onDisplayAreaAppeared triggered. + assertThat(infos).hasSize(1); + assertThat(infos.get(0).getDisplayAreaInfo().token) + .isEqualTo(mTestDisplayArea.getDisplayAreaInfo().token); + verify(organizer, never()).onDisplayAreaAppeared(any(DisplayAreaInfo.class), + any(SurfaceControl.class)); + } + + @Test public void testAppearedVanished() throws RemoteException { IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); - verify(organizer) - .onDisplayAreaAppeared(any(DisplayAreaInfo.class), any(SurfaceControl.class)); - unregisterMockOrganizer(organizer); + verify(organizer).onDisplayAreaVanished(any()); } @Test public void testChanged() throws RemoteException { IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); - verify(organizer) - .onDisplayAreaAppeared(any(DisplayAreaInfo.class), any(SurfaceControl.class)); - mDisplayContent.setBounds(new Rect(0, 0, 1000, 1000)); + verify(organizer).onDisplayAreaInfoChanged(any()); Configuration tmpConfiguration = new Configuration(); tmpConfiguration.setTo(mDisplayContent.getRequestedOverrideConfiguration()); mDisplayContent.onRequestedOverrideConfigurationChanged(tmpConfiguration); + // Ensure it was still only called once if the bounds didn't change verify(organizer).onDisplayAreaInfoChanged(any()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index c9e56fde0fb9..f52f98389872 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -36,6 +36,7 @@ import static android.view.Surface.ROTATION_90; import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; +import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; @@ -1606,6 +1607,29 @@ public class DisplayContentTests extends WindowTestsBase { verifySizes(dc, forcedWidth, forcedHeight, forcedDensity); } + @UseTestDisplay(addWindows = { W_ACTIVITY, W_INPUT_METHOD }) + @Test + public void testComputeImeTarget_shouldNotCheckOutdatedImeTargetLayerWhenRemoved() { + final WindowState child1 = createWindow(mAppWindow, FIRST_SUB_WINDOW, "child1"); + final WindowState nextImeTargetApp = createWindow(null /* parent */, + TYPE_BASE_APPLICATION, "nextImeTargetApp"); + spyOn(child1); + doReturn(true).when(child1).inSplitScreenWindowingMode(); + mDisplayContent.mInputMethodTarget = child1; + + spyOn(nextImeTargetApp); + spyOn(mAppWindow); + doReturn(true).when(nextImeTargetApp).canBeImeTarget(); + doReturn(true).when(nextImeTargetApp).isActivityTypeHome(); + doReturn(false).when(mAppWindow).canBeImeTarget(); + + child1.removeImmediately(); + + verify(mDisplayContent).computeImeTarget(true); + assertNull(mDisplayContent.mInputMethodInputTarget); + verify(child1, never()).needsRelativeLayeringToIme(); + } + private boolean isOptionsPanelAtRight(int displayId) { return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT; } diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java index 64a05bb361e9..823aef095831 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java @@ -19,13 +19,14 @@ 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.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY; +import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT; +import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK; import static android.view.DragEvent.ACTION_DRAG_STARTED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; @@ -33,7 +34,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.verify; import android.app.PendingIntent; @@ -82,6 +82,8 @@ import java.util.concurrent.TimeUnit; @RunWith(WindowTestRunner.class) public class DragDropControllerTests extends WindowTestsBase { private static final int TIMEOUT_MS = 3000; + private static final int TEST_UID = 12345; + private TestDragDropController mTarget; private WindowState mWindow; private IBinder mToken; @@ -195,8 +197,7 @@ public class DragDropControllerTests extends WindowTestsBase { attrs.privateFlags |= PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; policy.validateAddingWindowLw(attrs, Binder.getCallingPid(), Binder.getCallingUid()); - verify(mWm.mContext).enforcePermission( - eq(android.Manifest.permission.MANAGE_ACTIVITY_STACKS), anyInt(), anyInt(), any()); + verify(mWm.mAtmService).enforceTaskPermission(any()); } @Test @@ -278,6 +279,42 @@ public class DragDropControllerTests extends WindowTestsBase { return clipData; } + @Test + public void testValidateAppShortcutArguments() { + final Session session = new Session(mWm, new IWindowSessionCallback.Stub() { + @Override + public void onAnimatorScaleChanged(float scale) {} + }); + try { + final ClipData clipData = new ClipData( + new ClipDescription("drag", new String[] { MIMETYPE_APPLICATION_SHORTCUT }), + new ClipData.Item(new Intent())); + + session.validateAndResolveDragMimeTypeExtras(clipData, TEST_UID); + fail("Expected failure without shortcut id"); + } catch (IllegalArgumentException e) { + // Expected failure + } + } + + @Test + public void testValidateAppTaskArguments() { + final Session session = new Session(mWm, new IWindowSessionCallback.Stub() { + @Override + public void onAnimatorScaleChanged(float scale) {} + }); + try { + final ClipData clipData = new ClipData( + new ClipDescription("drag", new String[] { MIMETYPE_APPLICATION_TASK }), + new ClipData.Item(new Intent())); + + session.validateAndResolveDragMimeTypeExtras(clipData, TEST_UID); + fail("Expected failure without task id"); + } catch (IllegalArgumentException e) { + // Expected failure + } + } + private void doDragAndDrop(int flags, ClipData data, float dropX, float dropY) { startDrag(flags, data, () -> { mTarget.handleMotionEvent(false, dropX, dropY); diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index 2985796d005f..8094c9767b39 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -394,6 +394,21 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { // The rotation transform should be cleared after updating orientation with display. assertFalse(activity.hasFixedRotationTransform()); assertFalse(mDefaultDisplay.hasTopFixedRotationLaunchingApp()); + + // Simulate swiping up recents (home) in different rotation. + final ActivityRecord home = mDefaultDisplay.getDefaultTaskDisplayArea().getHomeActivity(); + mDefaultDisplay.setFixedRotationLaunchingApp(home, (mDefaultDisplay.getRotation() + 1) % 4); + mController = new RecentsAnimationController(mWm, mMockRunner, mAnimationCallbacks, + mDefaultDisplay.getDisplayId()); + initializeRecentsAnimationController(mController, home); + assertTrue(home.hasFixedRotationTransform()); + + // Assume recents activity becomes invisible for some reason (e.g. screen off). + home.setVisible(false); + mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); + // Although there won't be a transition finish callback, the fixed rotation must be cleared. + assertFalse(home.hasFixedRotationTransform()); + assertFalse(mDefaultDisplay.hasTopFixedRotationLaunchingApp()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index cc37e2bf94ca..d68dde5734ca 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -750,17 +750,15 @@ public class SizeCompatTests extends WindowTestsBase { final Rect taskBounds = mTask.getBounds(); final Rect newActivityBounds = newActivity.getBounds(); - // Task bounds should be 700x1400 with the ratio as the display. + // Task bounds should be (1400 / 1.3 = 1076)x1400 with the app requested ratio. assertTrue(mTask.isTaskLetterboxed()); assertEquals(displayBounds.height(), taskBounds.height()); - assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(), + assertEquals((long) Math.rint(taskBounds.height() / newActivity.info.maxAspectRatio), taskBounds.width()); - // App bounds should be 700x(710 x 1.3 = 910) + // App bounds should be fullscreen in Task bounds. assertFalse(newActivity.inSizeCompatMode()); - assertEquals(taskBounds.width(), newActivityBounds.width()); - assertEquals((long) Math.rint(taskBounds.width() * newActivity.info.maxAspectRatio), - newActivityBounds.height()); + assertEquals(taskBounds, newActivityBounds); } private static WindowState addWindowToActivity(ActivityRecord activity) { diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java index ace0400bc293..91e55ed7ab6a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java @@ -23,6 +23,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -194,4 +195,29 @@ public class TaskTests extends WindowTestsBase { assertEquals(1, rootTask.getChildCount()); assertEquals(leafTask1, childTask.getTopChild()); } + + @Test + public void testEnsureActivitiesVisible() { + final Task rootTask = createTaskStackOnDisplay(mDisplayContent); + final Task leafTask1 = createTaskInStack(rootTask, 0 /* userId */); + final Task leafTask2 = createTaskInStack(rootTask, 0 /* userId */); + final ActivityRecord activity1 = createActivityRecordInTask(mDisplayContent, leafTask1); + final ActivityRecord activity2 = createActivityRecordInTask(mDisplayContent, leafTask2); + + // Check visibility of occluded tasks + doReturn(false).when(leafTask1).shouldBeVisible(any()); + doReturn(true).when(leafTask2).shouldBeVisible(any()); + rootTask.ensureActivitiesVisible( + null /* starting */ , 0 /* configChanges */, false /* preserveWindows */); + assertFalse(activity1.isVisible()); + assertTrue(activity2.isVisible()); + + // Check visibility of not occluded tasks + doReturn(true).when(leafTask1).shouldBeVisible(any()); + doReturn(true).when(leafTask2).shouldBeVisible(any()); + rootTask.ensureActivitiesVisible( + null /* starting */ , 0 /* configChanges */, false /* preserveWindows */); + assertTrue(activity1.isVisible()); + assertTrue(activity2.isVisible()); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 7a1f65a3b62c..b4480aea3ce4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -479,21 +479,22 @@ public class WindowOrganizerTests extends WindowTestsBase { @Test public void testCreateDeleteRootTasks() { - RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask( - Display.DEFAULT_DISPLAY, - WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + DisplayContent dc = mWm.mRoot.getDisplayContent(Display.DEFAULT_DISPLAY); + + Task task1 = mWm.mAtmService.mTaskOrganizerController.createRootTask( + dc, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null); + RunningTaskInfo info1 = task1.getTaskInfo(); assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, info1.configuration.windowConfiguration.getWindowingMode()); assertEquals(ACTIVITY_TYPE_UNDEFINED, info1.topActivityType); - RunningTaskInfo info2 = mWm.mAtmService.mTaskOrganizerController.createRootTask( - Display.DEFAULT_DISPLAY, - WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); + Task task2 = mWm.mAtmService.mTaskOrganizerController.createRootTask( + dc, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null); + RunningTaskInfo info2 = task2.getTaskInfo(); assertEquals(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, info2.configuration.windowConfiguration.getWindowingMode()); assertEquals(ACTIVITY_TYPE_UNDEFINED, info2.topActivityType); - DisplayContent dc = mWm.mRoot.getDisplayContent(Display.DEFAULT_DISPLAY); List<Task> infos = getTasksCreatedByOrganizer(dc); assertEquals(2, infos.size()); @@ -521,8 +522,9 @@ public class WindowOrganizerTests extends WindowTestsBase { } }; mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener); - RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask( - mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); + Task task = mWm.mAtmService.mTaskOrganizerController.createRootTask( + mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null); + RunningTaskInfo info1 = task.getTaskInfo(); final Task stack = createTaskStackOnDisplay( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent); @@ -579,8 +581,9 @@ public class WindowOrganizerTests extends WindowTestsBase { } }; mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener); - RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask( - mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); + Task task = mWm.mAtmService.mTaskOrganizerController.createRootTask( + mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null); + RunningTaskInfo info1 = task.getTaskInfo(); lastReportedTiles.clear(); called[0] = false; @@ -640,10 +643,13 @@ public class WindowOrganizerTests extends WindowTestsBase { } }; mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener); - RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask( - mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); - RunningTaskInfo info2 = mWm.mAtmService.mTaskOrganizerController.createRootTask( - mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); + + Task task1 = mWm.mAtmService.mTaskOrganizerController.createRootTask( + mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null); + RunningTaskInfo info1 = task1.getTaskInfo(); + Task task2 = mWm.mAtmService.mTaskOrganizerController.createRootTask( + mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null); + RunningTaskInfo info2 = task2.getTaskInfo(); final int initialRootTaskCount = mWm.mAtmService.mTaskOrganizerController.getRootTasks( mDisplayContent.mDisplayId, null /* activityTypes */).size(); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 1eb7cbed02c8..62f04a1c830a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -973,8 +973,9 @@ class WindowTestsBase extends SystemServiceTestsBase { final int taskId = mTaskId >= 0 ? mTaskId : mTaskDisplayArea.getNextStackId(); if (mParentTask == null) { task = mTaskDisplayArea.createStackUnchecked( - mWindowingMode, mActivityType, taskId, mOnTop, mActivityInfo, - mIntent, false /* createdByOrganizer */); + mWindowingMode, mActivityType, taskId, mOnTop, mActivityInfo, mIntent, + false /* createdByOrganizer */, false /* deferTaskAppear */, + null /* launchCookie */); } else { task = new Task(mSupervisor.mService, taskId, mActivityInfo, mIntent /*intent*/, mVoiceSession, null /*_voiceInteractor*/, @@ -1016,20 +1017,17 @@ class WindowTestsBase extends SystemServiceTestsBase { // moves everything to secondary. Most tests expect this since sysui usually does it. boolean mMoveToSecondaryOnEnter = true; int mDisplayId; - TestSplitOrganizer(ActivityTaskManagerService service, int displayId) { + TestSplitOrganizer(ActivityTaskManagerService service, DisplayContent display) { mService = service; - mDisplayId = displayId; + mDisplayId = display.mDisplayId; mService.mTaskOrganizerController.registerTaskOrganizer(this); - WindowContainerToken primary = mService.mTaskOrganizerController.createRootTask( - displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token; - mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask(); - WindowContainerToken secondary = mService.mTaskOrganizerController.createRootTask( - displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token; - mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask(); + mPrimary = mService.mTaskOrganizerController.createRootTask( + display, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null); + mSecondary = mService.mTaskOrganizerController.createRootTask( + display, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);; } TestSplitOrganizer(ActivityTaskManagerService service) { - this(service, - service.mStackSupervisor.mRootWindowContainer.getDefaultDisplay().mDisplayId); + this(service, service.mStackSupervisor.mRootWindowContainer.getDefaultDisplay()); } public void setMoveToSecondaryOnEnter(boolean move) { mMoveToSecondaryOnEnter = move; diff --git a/telecomm/java/android/telecom/CallerInfo.java b/telecomm/java/android/telecom/CallerInfo.java index aff2f0183a3b..2983e6339d4b 100644 --- a/telecomm/java/android/telecom/CallerInfo.java +++ b/telecomm/java/android/telecom/CallerInfo.java @@ -27,6 +27,7 @@ import android.graphics.drawable.Drawable; import android.location.Country; import android.location.CountryDetector; import android.net.Uri; +import android.os.Build; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Data; @@ -186,7 +187,7 @@ public class CallerInfo { private boolean mIsVoiceMail; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CallerInfo() { // TODO: Move all the basic initialization here? mIsEmergency = false; @@ -347,7 +348,7 @@ public class CallerInfo { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static CallerInfo getCallerInfo(Context context, Uri contactRef) { CallerInfo info = null; ContentResolver cr = CallerInfoAsyncQuery.getCurrentProfileContentResolver(context); @@ -374,7 +375,7 @@ public class CallerInfo { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static CallerInfo getCallerInfo(Context context, String number) { if (VDBG) Log.v(TAG, "getCallerInfo() based on number..."); @@ -395,7 +396,7 @@ public class CallerInfo { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static CallerInfo getCallerInfo(Context context, String number, int subId) { if (TextUtils.isEmpty(number)) { diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java index a90d0532b721..2a4fdcb1475d 100644 --- a/telecomm/java/android/telecom/Log.java +++ b/telecomm/java/android/telecom/Log.java @@ -102,7 +102,7 @@ public class Log { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void i(String prefix, String format, Object... args) { if (INFO) { android.util.Slog.i(TAG, buildMessage(prefix, format, args)); @@ -133,7 +133,7 @@ public class Log { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void w(String prefix, String format, Object... args) { if (WARN) { android.util.Slog.w(TAG, buildMessage(prefix, format, args)); diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 82da4475c1b9..ae485d502a1e 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -32,6 +32,7 @@ import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; @@ -1605,6 +1606,30 @@ public class TelecomManager { } /** + * Returns whether the caller has {@link InCallService} access for companion apps. + * + * A companion app is an app associated with a physical wearable device via the + * {@link android.companion.CompanionDeviceManager} API. + * + * @return {@code true} if the caller has {@link InCallService} access for + * companion app; {@code false} otherwise. + */ + public boolean hasCompanionInCallServiceAccess() { + try { + if (isServiceConnected()) { + return getTelecomService().hasCompanionInCallServiceAccess( + mContext.getOpPackageName()); + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException calling hasCompanionInCallServiceAccess().", e); + if (!isSystemProcess()) { + e.rethrowAsRuntimeException(); + } + } + return false; + } + + /** * Returns whether there is an ongoing call originating from a managed * {@link ConnectionService}. An ongoing call can be in dialing, ringing, active or holding * states. @@ -2416,6 +2441,10 @@ public class TelecomManager { } } + private boolean isSystemProcess() { + return Process.myUid() == Process.SYSTEM_UID; + } + private ITelecomService getTelecomService() { if (mTelecomServiceOverride != null) { return mTelecomServiceOverride; diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index 7c6f1df972f3..6dc096daf4ea 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -179,6 +179,11 @@ interface ITelecomService { boolean isInCall(String callingPackage, String callingFeatureId); /** + * @see TelecomServiceImpl#hasCompanionInCallServiceAccess + */ + boolean hasCompanionInCallServiceAccess(String callingPackage); + + /** * @see TelecomServiceImpl#isInManagedCall */ boolean isInManagedCall(String callingPackage, String callingFeatureId); @@ -191,7 +196,7 @@ interface ITelecomService { /** * @see TelecomServiceImpl#getCallState */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int getCallState(); /** diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt deleted file mode 100644 index 63e0e5a36a26..000000000000 --- a/telephony/api/system-current.txt +++ /dev/null @@ -1,2097 +0,0 @@ -// Signature format: 2.0 -package android.telephony { - - public final class AccessNetworkConstants { - field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff - } - - public static final class AccessNetworkConstants.NgranBands { - method public static int getFrequencyRangeGroup(int); - field public static final int FREQUENCY_RANGE_GROUP_1 = 1; // 0x1 - field public static final int FREQUENCY_RANGE_GROUP_2 = 2; // 0x2 - field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0 - } - - public final class BarringInfo implements android.os.Parcelable { - ctor public BarringInfo(); - method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy(); - } - - public final class CallAttributes implements android.os.Parcelable { - ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality); - method public int describeContents(); - method @NonNull public android.telephony.CallQuality getCallQuality(); - method public int getNetworkType(); - method @NonNull public android.telephony.PreciseCallState getPreciseCallState(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR; - } - - public final class CallForwardingInfo implements android.os.Parcelable { - ctor public CallForwardingInfo(boolean, int, @Nullable String, int); - method public int describeContents(); - method @Nullable public String getNumber(); - method public int getReason(); - method public int getTimeoutSeconds(); - method public boolean isEnabled(); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallForwardingInfo> CREATOR; - field public static final int REASON_ALL = 4; // 0x4 - field public static final int REASON_ALL_CONDITIONAL = 5; // 0x5 - field public static final int REASON_BUSY = 1; // 0x1 - field public static final int REASON_NOT_REACHABLE = 3; // 0x3 - field public static final int REASON_NO_REPLY = 2; // 0x2 - field public static final int REASON_UNCONDITIONAL = 0; // 0x0 - } - - public final class CallQuality implements android.os.Parcelable { - ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int); - ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean); - method public int describeContents(); - method public int getAverageRelativeJitter(); - method public int getAverageRoundTripTime(); - method public int getCallDuration(); - method public int getCodecType(); - method public int getDownlinkCallQualityLevel(); - method public int getMaxRelativeJitter(); - method public int getNumRtpPacketsNotReceived(); - method public int getNumRtpPacketsReceived(); - method public int getNumRtpPacketsTransmitted(); - method public int getNumRtpPacketsTransmittedLost(); - method public int getUplinkCallQualityLevel(); - method public boolean isIncomingSilenceDetectedAtCallSetup(); - method public boolean isOutgoingSilenceDetectedAtCallSetup(); - method public boolean isRtpInactivityDetected(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CALL_QUALITY_BAD = 4; // 0x4 - field public static final int CALL_QUALITY_EXCELLENT = 0; // 0x0 - field public static final int CALL_QUALITY_FAIR = 2; // 0x2 - field public static final int CALL_QUALITY_GOOD = 1; // 0x1 - field public static final int CALL_QUALITY_NOT_AVAILABLE = 5; // 0x5 - field public static final int CALL_QUALITY_POOR = 3; // 0x3 - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR; - } - - public class CarrierConfigManager { - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName(); - method @NonNull public static android.os.PersistableBundle getDefaultConfig(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void updateConfigForPhoneId(int, String); - field public static final String KEY_CARRIER_SETUP_APP_STRING = "carrier_setup_app_string"; - field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool"; - } - - public static final class CarrierConfigManager.Wifi { - field public static final String KEY_HOTSPOT_MAX_CLIENT_COUNT = "wifi.hotspot_maximum_client_count"; - field public static final String KEY_PREFIX = "wifi."; - } - - public final class CarrierRestrictionRules implements android.os.Parcelable { - method @NonNull public java.util.List<java.lang.Boolean> areCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); - method public int describeContents(); - method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(); - method public int getDefaultCarrierRestriction(); - method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getExcludedCarriers(); - method public int getMultiSimPolicy(); - method public boolean isAllCarriersAllowed(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1; // 0x1 - field public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0; // 0x0 - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CarrierRestrictionRules> CREATOR; - field public static final int MULTISIM_POLICY_NONE = 0; // 0x0 - field public static final int MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT = 1; // 0x1 - } - - public static final class CarrierRestrictionRules.Builder { - ctor public CarrierRestrictionRules.Builder(); - method @NonNull public android.telephony.CarrierRestrictionRules build(); - method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed(); - method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); - method @NonNull public android.telephony.CarrierRestrictionRules.Builder setDefaultCarrierRestriction(int); - method @NonNull public android.telephony.CarrierRestrictionRules.Builder setExcludedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); - method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int); - } - - public class CbGeoUtils { - } - - public static class CbGeoUtils.Circle implements android.telephony.CbGeoUtils.Geometry { - ctor public CbGeoUtils.Circle(@NonNull android.telephony.CbGeoUtils.LatLng, double); - method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng); - method @NonNull public android.telephony.CbGeoUtils.LatLng getCenter(); - method public double getRadius(); - } - - public static interface CbGeoUtils.Geometry { - method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng); - } - - public static class CbGeoUtils.LatLng { - ctor public CbGeoUtils.LatLng(double, double); - method public double distance(@NonNull android.telephony.CbGeoUtils.LatLng); - method @NonNull public android.telephony.CbGeoUtils.LatLng subtract(@NonNull android.telephony.CbGeoUtils.LatLng); - field public final double lat; - field public final double lng; - } - - public static class CbGeoUtils.Polygon implements android.telephony.CbGeoUtils.Geometry { - ctor public CbGeoUtils.Polygon(@NonNull java.util.List<android.telephony.CbGeoUtils.LatLng>); - method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng); - method @NonNull public java.util.List<android.telephony.CbGeoUtils.LatLng> getVertices(); - } - - public abstract class CellBroadcastService extends android.app.Service { - ctor public CellBroadcastService(); - method @NonNull @WorkerThread public abstract CharSequence getCellBroadcastAreaInfo(int); - method public android.os.IBinder onBind(@Nullable android.content.Intent); - method public abstract void onCdmaCellBroadcastSms(int, @NonNull byte[], int); - method public abstract void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>); - method public abstract void onGsmCellBroadcastSms(int, @NonNull byte[]); - field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService"; - } - - public abstract class CellIdentity implements android.os.Parcelable { - method @NonNull public abstract android.telephony.CellLocation asCellLocation(); - method @NonNull public abstract android.telephony.CellIdentity sanitizeLocationInfo(); - } - - public final class CellIdentityCdma extends android.telephony.CellIdentity { - method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation(); - method @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo(); - } - - public final class CellIdentityGsm extends android.telephony.CellIdentity { - method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); - method @NonNull public android.telephony.CellIdentityGsm sanitizeLocationInfo(); - } - - public final class CellIdentityLte extends android.telephony.CellIdentity { - method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); - method @NonNull public android.telephony.CellIdentityLte sanitizeLocationInfo(); - } - - public final class CellIdentityNr extends android.telephony.CellIdentity { - method @NonNull public android.telephony.CellLocation asCellLocation(); - method @NonNull public android.telephony.CellIdentityNr sanitizeLocationInfo(); - } - - public final class CellIdentityTdscdma extends android.telephony.CellIdentity { - method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); - method @NonNull public android.telephony.CellIdentityTdscdma sanitizeLocationInfo(); - } - - public final class CellIdentityWcdma extends android.telephony.CellIdentity { - method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); - method @NonNull public android.telephony.CellIdentityWcdma sanitizeLocationInfo(); - } - - public final class DataFailCause { - field @Deprecated public static final int VSNCP_APN_UNATHORIZED = 2238; // 0x8be - } - - public final class DataSpecificRegistrationInfo implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR; - } - - public final class ImsiEncryptionInfo implements android.os.Parcelable { - method public int describeContents(); - method @Nullable public String getKeyIdentifier(); - method @Nullable public java.security.PublicKey getPublicKey(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ImsiEncryptionInfo> CREATOR; - } - - public final class LteVopsSupportInfo implements android.os.Parcelable { - ctor public LteVopsSupportInfo(int, int); - method public int describeContents(); - method public int getEmcBearerSupport(); - method public int getVopsSupport(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR; - field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1 - field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3 - field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2 - } - - public class MbmsDownloadSession implements java.lang.AutoCloseable { - field public static final String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload"; - } - - public class MbmsGroupCallSession implements java.lang.AutoCloseable { - field public static final String MBMS_GROUP_CALL_SERVICE_ACTION = "android.telephony.action.EmbmsGroupCall"; - } - - public class MbmsStreamingSession implements java.lang.AutoCloseable { - field public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming"; - } - - public final class ModemActivityInfo implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public android.telephony.ModemActivityInfo getDelta(@NonNull android.telephony.ModemActivityInfo); - method public long getIdleTimeMillis(); - method public static int getNumTxPowerLevels(); - method public long getReceiveTimeMillis(); - method public long getSleepTimeMillis(); - method public long getTimestampMillis(); - method public long getTransmitDurationMillisAtPowerLevel(int); - method @NonNull public android.util.Range<java.lang.Integer> getTransmitPowerRange(int); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR; - field public static final int TX_POWER_LEVEL_0 = 0; // 0x0 - field public static final int TX_POWER_LEVEL_1 = 1; // 0x1 - field public static final int TX_POWER_LEVEL_2 = 2; // 0x2 - field public static final int TX_POWER_LEVEL_3 = 3; // 0x3 - field public static final int TX_POWER_LEVEL_4 = 4; // 0x4 - } - - public final class NetworkRegistrationInfo implements android.os.Parcelable { - method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); - method public int getRegistrationState(); - method public int getRejectCause(); - method public int getRoamingType(); - method public boolean isEmergencyEnabled(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3 - field public static final int REGISTRATION_STATE_HOME = 1; // 0x1 - field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0 - field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2 - field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5 - field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4 - } - - public static final class NetworkRegistrationInfo.Builder { - ctor public NetworkRegistrationInfo.Builder(); - method @NonNull public android.telephony.NetworkRegistrationInfo build(); - method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int); - method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List<java.lang.Integer>); - method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity); - method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int); - method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean); - method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String); - method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int); - method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int); - method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int); - } - - public abstract class NetworkService extends android.app.Service { - ctor public NetworkService(); - method public android.os.IBinder onBind(android.content.Intent); - method @Nullable public abstract android.telephony.NetworkService.NetworkServiceProvider onCreateNetworkServiceProvider(int); - field public static final String SERVICE_INTERFACE = "android.telephony.NetworkService"; - } - - public abstract class NetworkService.NetworkServiceProvider implements java.lang.AutoCloseable { - ctor public NetworkService.NetworkServiceProvider(int); - method public abstract void close(); - method public final int getSlotIndex(); - method public final void notifyNetworkRegistrationInfoChanged(); - method public void requestNetworkRegistrationInfo(int, @NonNull android.telephony.NetworkServiceCallback); - } - - public class NetworkServiceCallback { - method public void onRequestNetworkRegistrationInfoComplete(int, @Nullable android.telephony.NetworkRegistrationInfo); - field public static final int RESULT_ERROR_BUSY = 3; // 0x3 - field public static final int RESULT_ERROR_FAILED = 5; // 0x5 - field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4 - field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2 - field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1 - field public static final int RESULT_SUCCESS = 0; // 0x0 - } - - public interface NumberVerificationCallback { - method public default void onCallReceived(@NonNull String); - method public default void onVerificationFailed(int); - field public static final int REASON_CONCURRENT_REQUESTS = 4; // 0x4 - field public static final int REASON_IN_ECBM = 5; // 0x5 - field public static final int REASON_IN_EMERGENCY_CALL = 6; // 0x6 - field public static final int REASON_NETWORK_NOT_AVAILABLE = 2; // 0x2 - field public static final int REASON_TIMED_OUT = 1; // 0x1 - field public static final int REASON_TOO_MANY_CALLS = 3; // 0x3 - field public static final int REASON_UNSPECIFIED = 0; // 0x0 - } - - public final class PhoneNumberRange implements android.os.Parcelable { - ctor public PhoneNumberRange(@NonNull String, @NonNull String, @NonNull String, @NonNull String); - method public int describeContents(); - method public boolean matches(@NonNull String); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR; - } - - public class PhoneNumberUtils { - method @NonNull public static String getUsernameFromUriNumber(@NonNull String); - method public static boolean isUriNumber(@Nullable String); - method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String); - } - - public final class PhysicalChannelConfig implements android.os.Parcelable { - method public int describeContents(); - method public int getCellBandwidthDownlink(); - method public int getChannelNumber(); - method public int getConnectionStatus(); - method public int getNetworkType(); - method @IntRange(from=0, to=1007) public int getPhysicalCellId(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field public static final int CHANNEL_NUMBER_UNKNOWN = -1; // 0xffffffff - field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1 - field public static final int CONNECTION_SECONDARY_SERVING = 2; // 0x2 - field public static final int CONNECTION_UNKNOWN = -1; // 0xffffffff - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhysicalChannelConfig> CREATOR; - field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff - } - - public final class PreciseCallState implements android.os.Parcelable { - ctor public PreciseCallState(int, int, int, int, int); - method public int describeContents(); - method public int getBackgroundCallState(); - method public int getForegroundCallState(); - method public int getRingingCallState(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseCallState> CREATOR; - field public static final int PRECISE_CALL_STATE_ACTIVE = 1; // 0x1 - field public static final int PRECISE_CALL_STATE_ALERTING = 4; // 0x4 - field public static final int PRECISE_CALL_STATE_DIALING = 3; // 0x3 - field public static final int PRECISE_CALL_STATE_DISCONNECTED = 7; // 0x7 - field public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; // 0x8 - field public static final int PRECISE_CALL_STATE_HOLDING = 2; // 0x2 - field public static final int PRECISE_CALL_STATE_IDLE = 0; // 0x0 - field public static final int PRECISE_CALL_STATE_INCOMING = 5; // 0x5 - field public static final int PRECISE_CALL_STATE_NOT_VALID = -1; // 0xffffffff - field public static final int PRECISE_CALL_STATE_WAITING = 6; // 0x6 - } - - public final class PreciseDataConnectionState implements android.os.Parcelable { - method @Deprecated @NonNull public String getDataConnectionApn(); - method @Deprecated public int getDataConnectionApnTypeBitMask(); - method @Deprecated public int getDataConnectionFailCause(); - method @Deprecated public int getDataConnectionState(); - method public int getId(); - } - - public final class PreciseDisconnectCause { - field public static final int ACCESS_CLASS_BLOCKED = 260; // 0x104 - field public static final int ACCESS_INFORMATION_DISCARDED = 43; // 0x2b - field public static final int ACM_LIMIT_EXCEEDED = 68; // 0x44 - field public static final int BEARER_CAPABILITY_NOT_AUTHORIZED = 57; // 0x39 - field public static final int BEARER_NOT_AVAIL = 58; // 0x3a - field public static final int BEARER_SERVICE_NOT_IMPLEMENTED = 65; // 0x41 - field public static final int BUSY = 17; // 0x11 - field public static final int CALL_BARRED = 240; // 0xf0 - field public static final int CALL_REJECTED = 21; // 0x15 - field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1 - field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee - field public static final int CDMA_DROP = 1001; // 0x3e9 - field public static final int CDMA_INTERCEPT = 1002; // 0x3ea - field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8 - field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0 - field public static final int CDMA_PREEMPTED = 1007; // 0x3ef - field public static final int CDMA_REORDER = 1003; // 0x3eb - field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed - field public static final int CDMA_SO_REJECT = 1004; // 0x3ec - field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c - field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6 - field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64 - field public static final int DESTINATION_OUT_OF_ORDER = 27; // 0x1b - field public static final int ERROR_UNSPECIFIED = 65535; // 0xffff - field public static final int FACILITY_REJECTED = 29; // 0x1d - field public static final int FDN_BLOCKED = 241; // 0xf1 - field public static final int IMEI_NOT_ACCEPTED = 243; // 0xf3 - field public static final int IMSI_UNKNOWN_IN_VLR = 242; // 0xf2 - field public static final int INCOMING_CALLS_BARRED_WITHIN_CUG = 55; // 0x37 - field public static final int INCOMPATIBLE_DESTINATION = 88; // 0x58 - field public static final int INFORMATION_ELEMENT_NON_EXISTENT = 99; // 0x63 - field public static final int INTERWORKING_UNSPECIFIED = 127; // 0x7f - field public static final int INVALID_MANDATORY_INFORMATION = 96; // 0x60 - field public static final int INVALID_NUMBER_FORMAT = 28; // 0x1c - field public static final int INVALID_TRANSACTION_IDENTIFIER = 81; // 0x51 - field public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101; // 0x65 - field public static final int MESSAGE_TYPE_NON_IMPLEMENTED = 97; // 0x61 - field public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98; // 0x62 - field public static final int NETWORK_DETACH = 261; // 0x105 - field public static final int NETWORK_OUT_OF_ORDER = 38; // 0x26 - field public static final int NETWORK_REJECT = 252; // 0xfc - field public static final int NETWORK_RESP_TIMEOUT = 251; // 0xfb - field public static final int NORMAL = 16; // 0x10 - field public static final int NORMAL_UNSPECIFIED = 31; // 0x1f - field public static final int NOT_VALID = -1; // 0xffffffff - field public static final int NO_ANSWER_FROM_USER = 19; // 0x13 - field public static final int NO_CIRCUIT_AVAIL = 34; // 0x22 - field public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0; // 0x0 - field public static final int NO_ROUTE_TO_DESTINATION = 3; // 0x3 - field public static final int NO_USER_RESPONDING = 18; // 0x12 - field public static final int NO_VALID_SIM = 249; // 0xf9 - field public static final int NUMBER_CHANGED = 22; // 0x16 - field public static final int OEM_CAUSE_1 = 61441; // 0xf001 - field public static final int OEM_CAUSE_10 = 61450; // 0xf00a - field public static final int OEM_CAUSE_11 = 61451; // 0xf00b - field public static final int OEM_CAUSE_12 = 61452; // 0xf00c - field public static final int OEM_CAUSE_13 = 61453; // 0xf00d - field public static final int OEM_CAUSE_14 = 61454; // 0xf00e - field public static final int OEM_CAUSE_15 = 61455; // 0xf00f - field public static final int OEM_CAUSE_2 = 61442; // 0xf002 - field public static final int OEM_CAUSE_3 = 61443; // 0xf003 - field public static final int OEM_CAUSE_4 = 61444; // 0xf004 - field public static final int OEM_CAUSE_5 = 61445; // 0xf005 - field public static final int OEM_CAUSE_6 = 61446; // 0xf006 - field public static final int OEM_CAUSE_7 = 61447; // 0xf007 - field public static final int OEM_CAUSE_8 = 61448; // 0xf008 - field public static final int OEM_CAUSE_9 = 61449; // 0xf009 - field public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70; // 0x46 - field public static final int OPERATOR_DETERMINED_BARRING = 8; // 0x8 - field public static final int OUT_OF_SRV = 248; // 0xf8 - field public static final int PREEMPTION = 25; // 0x19 - field public static final int PROTOCOL_ERROR_UNSPECIFIED = 111; // 0x6f - field public static final int QOS_NOT_AVAIL = 49; // 0x31 - field public static final int RADIO_ACCESS_FAILURE = 253; // 0xfd - field public static final int RADIO_INTERNAL_ERROR = 250; // 0xfa - field public static final int RADIO_LINK_FAILURE = 254; // 0xfe - field public static final int RADIO_LINK_LOST = 255; // 0xff - field public static final int RADIO_OFF = 247; // 0xf7 - field public static final int RADIO_RELEASE_ABNORMAL = 259; // 0x103 - field public static final int RADIO_RELEASE_NORMAL = 258; // 0x102 - field public static final int RADIO_SETUP_FAILURE = 257; // 0x101 - field public static final int RADIO_UPLINK_FAILURE = 256; // 0x100 - field public static final int RECOVERY_ON_TIMER_EXPIRED = 102; // 0x66 - field public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED = 69; // 0x45 - field public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED = 50; // 0x32 - field public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47; // 0x2f - field public static final int SEMANTICALLY_INCORRECT_MESSAGE = 95; // 0x5f - field public static final int SERVICE_OPTION_NOT_AVAILABLE = 63; // 0x3f - field public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79; // 0x4f - field public static final int STATUS_ENQUIRY = 30; // 0x1e - field public static final int SWITCHING_CONGESTION = 42; // 0x2a - field public static final int TEMPORARY_FAILURE = 41; // 0x29 - field public static final int UNOBTAINABLE_NUMBER = 1; // 0x1 - field public static final int USER_NOT_MEMBER_OF_CUG = 87; // 0x57 - } - - public class ServiceState implements android.os.Parcelable { - method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int); - method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int); - method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int); - field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2 - field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3 - field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0 - field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1 - } - - public final class SmsCbCmasInfo implements android.os.Parcelable { - ctor public SmsCbCmasInfo(int, int, int, int, int, int); - method public int describeContents(); - method public int getCategory(); - method public int getCertainty(); - method public int getMessageClass(); - method public int getResponseType(); - method public int getSeverity(); - method public int getUrgency(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CMAS_CATEGORY_CBRNE = 10; // 0xa - field public static final int CMAS_CATEGORY_ENV = 7; // 0x7 - field public static final int CMAS_CATEGORY_FIRE = 5; // 0x5 - field public static final int CMAS_CATEGORY_GEO = 0; // 0x0 - field public static final int CMAS_CATEGORY_HEALTH = 6; // 0x6 - field public static final int CMAS_CATEGORY_INFRA = 9; // 0x9 - field public static final int CMAS_CATEGORY_MET = 1; // 0x1 - field public static final int CMAS_CATEGORY_OTHER = 11; // 0xb - field public static final int CMAS_CATEGORY_RESCUE = 4; // 0x4 - field public static final int CMAS_CATEGORY_SAFETY = 2; // 0x2 - field public static final int CMAS_CATEGORY_SECURITY = 3; // 0x3 - field public static final int CMAS_CATEGORY_TRANSPORT = 8; // 0x8 - field public static final int CMAS_CATEGORY_UNKNOWN = -1; // 0xffffffff - field public static final int CMAS_CERTAINTY_LIKELY = 1; // 0x1 - field public static final int CMAS_CERTAINTY_OBSERVED = 0; // 0x0 - field public static final int CMAS_CERTAINTY_UNKNOWN = -1; // 0xffffffff - field public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 3; // 0x3 - field public static final int CMAS_CLASS_CMAS_EXERCISE = 5; // 0x5 - field public static final int CMAS_CLASS_EXTREME_THREAT = 1; // 0x1 - field public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 6; // 0x6 - field public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0; // 0x0 - field public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 4; // 0x4 - field public static final int CMAS_CLASS_SEVERE_THREAT = 2; // 0x2 - field public static final int CMAS_CLASS_UNKNOWN = -1; // 0xffffffff - field public static final int CMAS_RESPONSE_TYPE_ASSESS = 6; // 0x6 - field public static final int CMAS_RESPONSE_TYPE_AVOID = 5; // 0x5 - field public static final int CMAS_RESPONSE_TYPE_EVACUATE = 1; // 0x1 - field public static final int CMAS_RESPONSE_TYPE_EXECUTE = 3; // 0x3 - field public static final int CMAS_RESPONSE_TYPE_MONITOR = 4; // 0x4 - field public static final int CMAS_RESPONSE_TYPE_NONE = 7; // 0x7 - field public static final int CMAS_RESPONSE_TYPE_PREPARE = 2; // 0x2 - field public static final int CMAS_RESPONSE_TYPE_SHELTER = 0; // 0x0 - field public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1; // 0xffffffff - field public static final int CMAS_SEVERITY_EXTREME = 0; // 0x0 - field public static final int CMAS_SEVERITY_SEVERE = 1; // 0x1 - field public static final int CMAS_SEVERITY_UNKNOWN = -1; // 0xffffffff - field public static final int CMAS_URGENCY_EXPECTED = 1; // 0x1 - field public static final int CMAS_URGENCY_IMMEDIATE = 0; // 0x0 - field public static final int CMAS_URGENCY_UNKNOWN = -1; // 0xffffffff - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbCmasInfo> CREATOR; - } - - public final class SmsCbEtwsInfo implements android.os.Parcelable { - ctor public SmsCbEtwsInfo(int, boolean, boolean, boolean, @Nullable byte[]); - method public int describeContents(); - method @Nullable public byte[] getPrimaryNotificationSignature(); - method public long getPrimaryNotificationTimestamp(); - method public int getWarningType(); - method public boolean isEmergencyUserAlert(); - method public boolean isPopupAlert(); - method public boolean isPrimary(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbEtwsInfo> CREATOR; - field public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0; // 0x0 - field public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 2; // 0x2 - field public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 4; // 0x4 - field public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 3; // 0x3 - field public static final int ETWS_WARNING_TYPE_TSUNAMI = 1; // 0x1 - field public static final int ETWS_WARNING_TYPE_UNKNOWN = -1; // 0xffffffff - } - - public final class SmsCbLocation implements android.os.Parcelable { - ctor public SmsCbLocation(@NonNull String, int, int); - method public int describeContents(); - method public int getCid(); - method public int getLac(); - method @NonNull public String getPlmn(); - method public boolean isInLocationArea(@NonNull android.telephony.SmsCbLocation); - method public boolean isInLocationArea(@Nullable String, int, int); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbLocation> CREATOR; - } - - public final class SmsCbMessage implements android.os.Parcelable { - ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, int, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int, @Nullable java.util.List<android.telephony.CbGeoUtils.Geometry>, long, int, int); - method @NonNull public static android.telephony.SmsCbMessage createFromCursor(@NonNull android.database.Cursor); - method public int describeContents(); - method @Nullable public android.telephony.SmsCbCmasInfo getCmasWarningInfo(); - method @NonNull public android.content.ContentValues getContentValues(); - method public int getDataCodingScheme(); - method @Nullable public android.telephony.SmsCbEtwsInfo getEtwsWarningInfo(); - method public int getGeographicalScope(); - method @NonNull public java.util.List<android.telephony.CbGeoUtils.Geometry> getGeometries(); - method @Nullable public String getLanguageCode(); - method @NonNull public android.telephony.SmsCbLocation getLocation(); - method public int getMaximumWaitingDuration(); - method @Nullable public String getMessageBody(); - method public int getMessageFormat(); - method public int getMessagePriority(); - method public long getReceivedTime(); - method public int getSerialNumber(); - method public int getServiceCategory(); - method public int getSlotIndex(); - method public int getSubscriptionId(); - method public boolean isCmasMessage(); - method public boolean isEmergencyMessage(); - method public boolean isEtwsMessage(); - method public boolean needGeoFencingCheck(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbMessage> CREATOR; - field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3; // 0x3 - field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; // 0x0 - field public static final int GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2; // 0x2 - field public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; // 0x1 - field public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; // 0xff - field public static final int MESSAGE_FORMAT_3GPP = 1; // 0x1 - field public static final int MESSAGE_FORMAT_3GPP2 = 2; // 0x2 - field public static final int MESSAGE_PRIORITY_EMERGENCY = 3; // 0x3 - field public static final int MESSAGE_PRIORITY_INTERACTIVE = 1; // 0x1 - field public static final int MESSAGE_PRIORITY_NORMAL = 0; // 0x0 - field public static final int MESSAGE_PRIORITY_URGENT = 2; // 0x2 - } - - public final class SmsManager { - method public boolean disableCellBroadcastRange(int, int, int); - method public boolean enableCellBroadcastRange(int, int, int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int); - field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3 - field public static final int PREMIUM_SMS_CONSENT_ASK_USER = 1; // 0x1 - field public static final int PREMIUM_SMS_CONSENT_NEVER_ALLOW = 2; // 0x2 - field public static final int PREMIUM_SMS_CONSENT_UNKNOWN = 0; // 0x0 - } - - public class SmsMessage { - method @Nullable public static android.telephony.SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[], boolean); - method @Nullable public static android.telephony.SmsMessage.SubmitPdu getSmsPdu(int, int, @Nullable String, @NonNull String, @NonNull String, long); - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static byte[] getSubmitPduEncodedMessage(boolean, @NonNull String, @NonNull String, int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0, to=255) int, @IntRange(from=1, to=255) int, @IntRange(from=1, to=255) int); - } - - public class SubscriptionInfo implements android.os.Parcelable { - method public boolean areUiccApplicationsEnabled(); - method @Nullable public java.util.List<android.telephony.UiccAccessRule> getAccessRules(); - method public int getProfileClass(); - method public boolean isGroupDisabled(); - } - - public class SubscriptionManager { - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean canDisablePhysicalSubscription(); - method public boolean canManageSubscription(@NonNull android.telephony.SubscriptionInfo, @NonNull String); - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int[] getActiveSubscriptionIdList(); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String); - method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList(); - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int[] getCompleteActiveSubscriptionIdList(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEnabledSubscriptionId(int); - method @NonNull public static android.content.res.Resources getResourcesForSubId(@NonNull android.content.Context, int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSubscriptionEnabled(int); - method public void requestEmbeddedSubscriptionInfoListRefresh(); - method public void requestEmbeddedSubscriptionInfoListRefresh(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(int, boolean); - field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED"; - field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI; - field @Deprecated public static final int PROFILE_CLASS_DEFAULT; - field public static final int PROFILE_CLASS_OPERATIONAL; - field public static final int PROFILE_CLASS_PROVISIONING; - field public static final int PROFILE_CLASS_TESTING; - field public static final int PROFILE_CLASS_UNSET; - field @NonNull public static final android.net.Uri VT_ENABLED_CONTENT_URI; - field @NonNull public static final android.net.Uri WFC_ENABLED_CONTENT_URI; - field @NonNull public static final android.net.Uri WFC_MODE_CONTENT_URI; - field @NonNull public static final android.net.Uri WFC_ROAMING_ENABLED_CONTENT_URI; - field @NonNull public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI; - } - - public final class TelephonyHistogram implements android.os.Parcelable { - ctor public TelephonyHistogram(int, int, int); - ctor public TelephonyHistogram(android.telephony.TelephonyHistogram); - ctor public TelephonyHistogram(android.os.Parcel); - method public void addTimeTaken(int); - method public int describeContents(); - method public int getAverageTime(); - method public int getBucketCount(); - method public int[] getBucketCounters(); - method public int[] getBucketEndPoints(); - method public int getCategory(); - method public int getId(); - method public int getMaxTime(); - method public int getMinTime(); - method public int getSampleCount(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.TelephonyHistogram> CREATOR; - field public static final int TELEPHONY_CATEGORY_RIL = 1; // 0x1 - } - - public class TelephonyManager { - method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String); - method public int checkCarrierPrivilegesForPackage(String); - method public int checkCarrierPrivilegesForPackageAnyPhone(String); - method public void dial(String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean disableDataConnectivity(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableDataConnectivity(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableModemForSlot(int, boolean); - method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int); - method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes(); - method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallForwarding(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CallForwardingInfoCallback); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallWaitingStatus(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int); - method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent); - method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCarrierPrivilegeStatus(int); - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPrivilegedPackagesForAllActiveSubscriptions(); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaEnhancedRoamingIndicatorIconIndex(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int); - method public String getCdmaPrlVersion(); - method public int getCurrentPhoneType(); - method public int getCurrentPhoneType(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState(); - method @Deprecated public boolean getDataEnabled(); - method @Deprecated public boolean getDataEnabled(int); - method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getDefaultRespondViaMessageApplication(); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); - method public int getMaxNumberOfSimultaneouslyActiveSims(); - method public static long getMaxNumberVerificationTimeoutMillis(); - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String[] getMergedImsisFromGroup(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask(); - method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState(); - method public int getSimApplicationState(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimApplicationState(int); - method public int getSimCardState(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimCardState(int); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Locale getSimLocale(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getSupportedRadioAccessFamily(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.UiccSlotInfo[] getUiccSlotsInfo(); - method @Nullable public android.os.Bundle getVisualVoicemailSettings(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String); - method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int); - method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); - method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApnMetered(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int); - method public boolean isDataConnectivityPossible(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean isIccLockEnabled(); - method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMobileDataPolicyEnabled(int); - method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String); - method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn(); - method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isTetheringApnRequired(); - method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled(); - method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean matchesCurrentSimOperator(@NonNull String, int, @Nullable String); - method public boolean needsOtaServiceProvisioning(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean); - method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestModemActivityInfo(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.ModemActivityInfo,android.telephony.TelephonyManager.ModemActivityInfoException>); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int); - method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig(); - method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings(); - method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCallForwarding(@NonNull android.telephony.CallForwardingInfo, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCallWaitingEnabled(boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>); - method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int); - method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabledStatus(int, boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRadioEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadioPower(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerState(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerStateForSlot(int, int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>); - method @Deprecated public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios(); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff(); - method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor); - method public void updateServiceLocation(); - field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED"; - field public static final String ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED"; - field public static final String ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED"; - field public static final String ACTION_EMERGENCY_ASSISTANCE = "android.telephony.action.EMERGENCY_ASSISTANCE"; - field public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED"; - field public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED = "android.intent.action.EMERGENCY_CALL_STATE_CHANGED"; - field public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE = "com.android.omadm.service.CONFIGURATION_UPDATE"; - field public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS = "android.telephony.action.SHOW_NOTICE_ECM_BLOCK_OTHERS"; - field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED"; - field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED"; - field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED"; - field public static final int CALL_WAITING_STATUS_DISABLED = 2; // 0x2 - field public static final int CALL_WAITING_STATUS_ENABLED = 1; // 0x1 - field public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; // 0x4 - field public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; // 0x3 - field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe - field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1 - field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0 - field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff - field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION"; - field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID"; - field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE"; - field public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = "android.telephony.extra.PHONE_IN_EMERGENCY_CALL"; - field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE"; - field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL"; - field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING"; - field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff - field public static final int KEY_TYPE_EPDG = 1; // 0x1 - field public static final int KEY_TYPE_WLAN = 2; // 0x2 - field public static final int MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL = 1; // 0x1 - field public static final int MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED = 2; // 0x2 - field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L - field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L - field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L - field public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L - field public static final long NETWORK_TYPE_BITMASK_EVDO_0 = 16L; // 0x10L - field public static final long NETWORK_TYPE_BITMASK_EVDO_A = 32L; // 0x20L - field public static final long NETWORK_TYPE_BITMASK_EVDO_B = 2048L; // 0x800L - field public static final long NETWORK_TYPE_BITMASK_GPRS = 1L; // 0x1L - field public static final long NETWORK_TYPE_BITMASK_GSM = 32768L; // 0x8000L - field public static final long NETWORK_TYPE_BITMASK_HSDPA = 128L; // 0x80L - field public static final long NETWORK_TYPE_BITMASK_HSPA = 512L; // 0x200L - field public static final long NETWORK_TYPE_BITMASK_HSPAP = 16384L; // 0x4000L - field public static final long NETWORK_TYPE_BITMASK_HSUPA = 256L; // 0x100L - field public static final long NETWORK_TYPE_BITMASK_IWLAN = 131072L; // 0x20000L - field public static final long NETWORK_TYPE_BITMASK_LTE = 4096L; // 0x1000L - field public static final long NETWORK_TYPE_BITMASK_LTE_CA = 262144L; // 0x40000L - field public static final long NETWORK_TYPE_BITMASK_NR = 524288L; // 0x80000L - field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L - field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L - field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L - field public static final int RADIO_POWER_OFF = 0; // 0x0 - field public static final int RADIO_POWER_ON = 1; // 0x1 - field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2 - field public static final int SET_CARRIER_RESTRICTION_ERROR = 2; // 0x2 - field public static final int SET_CARRIER_RESTRICTION_NOT_SUPPORTED = 1; // 0x1 - field public static final int SET_CARRIER_RESTRICTION_SUCCESS = 0; // 0x0 - field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2 - field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1 - field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3 - field public static final int SIM_ACTIVATION_STATE_RESTRICTED = 4; // 0x4 - field public static final int SIM_ACTIVATION_STATE_UNKNOWN = 0; // 0x0 - field public static final int SIM_STATE_LOADED = 10; // 0xa - field public static final int SIM_STATE_PRESENT = 11; // 0xb - field public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; // 0x3 - field public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; // 0x1 - field public static final int SRVCC_STATE_HANDOVER_FAILED = 2; // 0x2 - field public static final int SRVCC_STATE_HANDOVER_NONE = -1; // 0xffffffff - field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0 - } - - public static interface TelephonyManager.CallForwardingInfoCallback { - method public void onCallForwardingInfoAvailable(@NonNull android.telephony.CallForwardingInfo); - method public void onError(int); - field public static final int RESULT_ERROR_FDN_CHECK_FAILURE = 2; // 0x2 - field public static final int RESULT_ERROR_NOT_SUPPORTED = 3; // 0x3 - field public static final int RESULT_ERROR_UNKNOWN = 1; // 0x1 - field public static final int RESULT_SUCCESS = 0; // 0x0 - } - - public static class TelephonyManager.ModemActivityInfoException extends java.lang.Exception { - method public int getErrorCode(); - field public static final int ERROR_INVALID_INFO_RECEIVED = 2; // 0x2 - field public static final int ERROR_MODEM_RESPONSE_ERROR = 3; // 0x3 - field public static final int ERROR_PHONE_NOT_AVAILABLE = 1; // 0x1 - field public static final int ERROR_UNKNOWN = 0; // 0x0 - } - - public final class UiccAccessRule implements android.os.Parcelable { - ctor public UiccAccessRule(byte[], @Nullable String, long); - method public int describeContents(); - method public int getCarrierPrivilegeStatus(android.content.pm.PackageInfo); - method public int getCarrierPrivilegeStatus(android.content.pm.Signature, String); - method public String getCertificateHexString(); - method @Nullable public String getPackageName(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR; - } - - public class UiccSlotInfo implements android.os.Parcelable { - ctor @Deprecated public UiccSlotInfo(boolean, boolean, String, int, int, boolean); - method public int describeContents(); - method public String getCardId(); - method public int getCardStateInfo(); - method public boolean getIsActive(); - method public boolean getIsEuicc(); - method public boolean getIsExtendedApduSupported(); - method public int getLogicalSlotIdx(); - method public boolean isRemovable(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CARD_STATE_INFO_ABSENT = 1; // 0x1 - field public static final int CARD_STATE_INFO_ERROR = 3; // 0x3 - field public static final int CARD_STATE_INFO_PRESENT = 2; // 0x2 - field public static final int CARD_STATE_INFO_RESTRICTED = 4; // 0x4 - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccSlotInfo> CREATOR; - } - - public abstract class VisualVoicemailService extends android.app.Service { - method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, String, short, String, android.app.PendingIntent); - method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings); - } - -} - -package android.telephony.cdma { - - public final class CdmaSmsCbProgramData implements android.os.Parcelable { - method public int describeContents(); - method public int getCategory(); - method public int getOperation(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003 - field public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001 - field public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff - field public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000 - field public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002 - field public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004 - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR; - field public static final int OPERATION_ADD_CATEGORY = 1; // 0x1 - field public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2 - field public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0 - } - -} - -package android.telephony.data { - - public final class DataCallResponse implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public java.util.List<android.net.LinkAddress> getAddresses(); - method public int getCause(); - method @NonNull public java.util.List<java.net.InetAddress> getDnsAddresses(); - method @NonNull public java.util.List<java.net.InetAddress> getGatewayAddresses(); - method public int getHandoverFailureMode(); - method public int getId(); - method @NonNull public String getInterfaceName(); - method public int getLinkStatus(); - method @Deprecated public int getMtu(); - method public int getMtuV4(); - method public int getMtuV6(); - method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses(); - method public int getProtocolType(); - method public int getSuggestedRetryTime(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR; - field public static final int HANDOVER_FAILURE_MODE_DO_FALLBACK = 1; // 0x1 - field public static final int HANDOVER_FAILURE_MODE_LEGACY = 0; // 0x0 - field public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER = 2; // 0x2 - field public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL = 3; // 0x3 - field public static final int HANDOVER_FAILURE_MODE_UNKNOWN = -1; // 0xffffffff - field public static final int LINK_STATUS_ACTIVE = 2; // 0x2 - field public static final int LINK_STATUS_DORMANT = 1; // 0x1 - field public static final int LINK_STATUS_INACTIVE = 0; // 0x0 - field public static final int LINK_STATUS_UNKNOWN = -1; // 0xffffffff - } - - public static final class DataCallResponse.Builder { - ctor public DataCallResponse.Builder(); - method @NonNull public android.telephony.data.DataCallResponse build(); - method @NonNull public android.telephony.data.DataCallResponse.Builder setAddresses(@NonNull java.util.List<android.net.LinkAddress>); - method @NonNull public android.telephony.data.DataCallResponse.Builder setCause(int); - method @NonNull public android.telephony.data.DataCallResponse.Builder setDnsAddresses(@NonNull java.util.List<java.net.InetAddress>); - method @NonNull public android.telephony.data.DataCallResponse.Builder setGatewayAddresses(@NonNull java.util.List<java.net.InetAddress>); - method @NonNull public android.telephony.data.DataCallResponse.Builder setHandoverFailureMode(int); - method @NonNull public android.telephony.data.DataCallResponse.Builder setId(int); - method @NonNull public android.telephony.data.DataCallResponse.Builder setInterfaceName(@NonNull String); - method @NonNull public android.telephony.data.DataCallResponse.Builder setLinkStatus(int); - method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int); - method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV4(int); - method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int); - method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>); - method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int); - method @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int); - } - - public final class DataProfile implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public String getApn(); - method public int getAuthType(); - method public int getBearerBitmask(); - method @Deprecated public int getMtu(); - method public int getMtuV4(); - method public int getMtuV6(); - method @Nullable public String getPassword(); - method public int getProfileId(); - method public int getProtocolType(); - method public int getRoamingProtocolType(); - method public int getSupportedApnTypesBitmask(); - method public int getType(); - method @Nullable public String getUserName(); - method public boolean isEnabled(); - method public boolean isPersistent(); - method public boolean isPreferred(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataProfile> CREATOR; - field public static final int TYPE_3GPP = 1; // 0x1 - field public static final int TYPE_3GPP2 = 2; // 0x2 - field public static final int TYPE_COMMON = 0; // 0x0 - } - - public static final class DataProfile.Builder { - ctor public DataProfile.Builder(); - method @NonNull public android.telephony.data.DataProfile build(); - method @NonNull public android.telephony.data.DataProfile.Builder enable(boolean); - method @NonNull public android.telephony.data.DataProfile.Builder setApn(@NonNull String); - method @NonNull public android.telephony.data.DataProfile.Builder setAuthType(int); - method @NonNull public android.telephony.data.DataProfile.Builder setBearerBitmask(int); - method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setMtu(int); - method @NonNull public android.telephony.data.DataProfile.Builder setMtuV4(int); - method @NonNull public android.telephony.data.DataProfile.Builder setMtuV6(int); - method @NonNull public android.telephony.data.DataProfile.Builder setPassword(@NonNull String); - method @NonNull public android.telephony.data.DataProfile.Builder setPersistent(boolean); - method @NonNull public android.telephony.data.DataProfile.Builder setPreferred(boolean); - method @NonNull public android.telephony.data.DataProfile.Builder setProfileId(int); - method @NonNull public android.telephony.data.DataProfile.Builder setProtocolType(int); - method @NonNull public android.telephony.data.DataProfile.Builder setRoamingProtocolType(int); - method @NonNull public android.telephony.data.DataProfile.Builder setSupportedApnTypesBitmask(int); - method @NonNull public android.telephony.data.DataProfile.Builder setType(int); - method @NonNull public android.telephony.data.DataProfile.Builder setUserName(@NonNull String); - } - - public abstract class DataService extends android.app.Service { - ctor public DataService(); - method public android.os.IBinder onBind(android.content.Intent); - method @Nullable public abstract android.telephony.data.DataService.DataServiceProvider onCreateDataServiceProvider(int); - field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3 - field public static final int REQUEST_REASON_NORMAL = 1; // 0x1 - field public static final int REQUEST_REASON_SHUTDOWN = 2; // 0x2 - field public static final int REQUEST_REASON_UNKNOWN = 0; // 0x0 - field public static final String SERVICE_INTERFACE = "android.telephony.data.DataService"; - } - - public abstract class DataService.DataServiceProvider implements java.lang.AutoCloseable { - ctor public DataService.DataServiceProvider(int); - method public abstract void close(); - method public void deactivateDataCall(int, int, @Nullable android.telephony.data.DataServiceCallback); - method public final int getSlotIndex(); - method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>); - method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback); - method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback); - method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback); - method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback); - } - - public class DataServiceCallback { - method public void onDataCallListChanged(@NonNull java.util.List<android.telephony.data.DataCallResponse>); - method public void onDeactivateDataCallComplete(int); - method public void onRequestDataCallListComplete(int, @NonNull java.util.List<android.telephony.data.DataCallResponse>); - method public void onSetDataProfileComplete(int); - method public void onSetInitialAttachApnComplete(int); - method public void onSetupDataCallComplete(int, @Nullable android.telephony.data.DataCallResponse); - field public static final int RESULT_ERROR_BUSY = 3; // 0x3 - field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4 - field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2 - field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1 - field public static final int RESULT_SUCCESS = 0; // 0x0 - } - - public abstract class QualifiedNetworksService extends android.app.Service { - ctor public QualifiedNetworksService(); - method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int); - field public static final String QUALIFIED_NETWORKS_SERVICE_INTERFACE = "android.telephony.data.QualifiedNetworksService"; - } - - public abstract class QualifiedNetworksService.NetworkAvailabilityProvider implements java.lang.AutoCloseable { - ctor public QualifiedNetworksService.NetworkAvailabilityProvider(int); - method public abstract void close(); - method public final int getSlotIndex(); - method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>); - } - -} - -package android.telephony.euicc { - - public final class DownloadableSubscription implements android.os.Parcelable { - method public java.util.List<android.telephony.UiccAccessRule> getAccessRules(); - method @Nullable public String getCarrierName(); - } - - public static final class DownloadableSubscription.Builder { - ctor public DownloadableSubscription.Builder(); - ctor public DownloadableSubscription.Builder(android.telephony.euicc.DownloadableSubscription); - method public android.telephony.euicc.DownloadableSubscription build(); - method public android.telephony.euicc.DownloadableSubscription.Builder setAccessRules(java.util.List<android.telephony.UiccAccessRule>); - method public android.telephony.euicc.DownloadableSubscription.Builder setCarrierName(String); - method public android.telephony.euicc.DownloadableSubscription.Builder setConfirmationCode(String); - method public android.telephony.euicc.DownloadableSubscription.Builder setEncodedActivationCode(String); - } - - public class EuiccCardManager { - method public void authenticateServer(String, String, byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); - method public void cancelSession(String, byte[], @android.telephony.euicc.EuiccCardManager.CancelReason int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); - method public void deleteProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); - method public void disableProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); - method public void listNotifications(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>); - method public void loadBoundProfilePackage(String, byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); - method public void prepareDownload(String, @Nullable byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); - method public void removeNotificationFromList(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); - method public void requestAllProfiles(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo[]>); - method public void requestDefaultSmdpAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>); - method public void requestEuiccChallenge(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); - method public void requestEuiccInfo1(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); - method public void requestEuiccInfo2(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); - method public void requestProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>); - method public void requestRulesAuthTable(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccRulesAuthTable>); - method public void requestSmdsAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>); - method public void resetMemory(String, @android.telephony.euicc.EuiccCardManager.ResetOption int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); - method public void retrieveNotification(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification>); - method public void retrieveNotificationList(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>); - method public void setDefaultSmdpAddress(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); - method public void setNickname(String, String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); - method public void switchToProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>); - field public static final int CANCEL_REASON_END_USER_REJECTED = 0; // 0x0 - field public static final int CANCEL_REASON_POSTPONED = 1; // 0x1 - field public static final int CANCEL_REASON_PPR_NOT_ALLOWED = 3; // 0x3 - field public static final int CANCEL_REASON_TIMEOUT = 2; // 0x2 - field public static final int RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 2; // 0x2 - field public static final int RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1; // 0x1 - field public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 4; // 0x4 - field public static final int RESULT_CALLER_NOT_ALLOWED = -3; // 0xfffffffd - field public static final int RESULT_EUICC_NOT_FOUND = -2; // 0xfffffffe - field public static final int RESULT_OK = 0; // 0x0 - field public static final int RESULT_UNKNOWN_ERROR = -1; // 0xffffffff - } - - @IntDef(prefix={"CANCEL_REASON_"}, value={android.telephony.euicc.EuiccCardManager.CANCEL_REASON_END_USER_REJECTED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_POSTPONED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_TIMEOUT, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_PPR_NOT_ALLOWED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.CancelReason { - } - - @IntDef(flag=true, prefix={"RESET_OPTION_"}, value={android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.ResetOption { - } - - public static interface EuiccCardManager.ResultCallback<T> { - method public void onComplete(int, T); - } - - public class EuiccManager { - method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void continueOperation(android.content.Intent, android.os.Bundle); - method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@NonNull android.app.PendingIntent); - method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@android.telephony.euicc.EuiccCardManager.ResetOption int, @NonNull android.app.PendingIntent); - method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDefaultDownloadableSubscriptionList(android.app.PendingIntent); - method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDownloadableSubscriptionMetadata(android.telephony.euicc.DownloadableSubscription, android.app.PendingIntent); - method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public int getOtaStatus(); - method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getSupportedCountries(); - method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getUnsupportedCountries(); - method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public boolean isSupportedCountry(@NonNull String); - method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setSupportedCountries(@NonNull java.util.List<java.lang.String>); - method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setUnsupportedCountries(@NonNull java.util.List<java.lang.String>); - field public static final String ACTION_DELETE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED"; - field @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public static final String ACTION_OTA_STATUS_CHANGED = "android.telephony.euicc.action.OTA_STATUS_CHANGED"; - field public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION"; - field public static final String ACTION_RENAME_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED"; - field public static final String ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED"; - field public static final int EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED = 4; // 0x4 - field public static final int EUICC_ACTIVATION_TYPE_BACKUP = 2; // 0x2 - field public static final int EUICC_ACTIVATION_TYPE_DEFAULT = 1; // 0x1 - field public static final int EUICC_ACTIVATION_TYPE_TRANSFER = 3; // 0x3 - field public static final int EUICC_OTA_FAILED = 2; // 0x2 - field public static final int EUICC_OTA_IN_PROGRESS = 1; // 0x1 - field public static final int EUICC_OTA_NOT_NEEDED = 4; // 0x4 - field public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; // 0x5 - field public static final int EUICC_OTA_SUCCEEDED = 3; // 0x3 - field public static final String EXTRA_ACTIVATION_TYPE = "android.telephony.euicc.extra.ACTIVATION_TYPE"; - field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS"; - field public static final String EXTRA_ENABLE_SUBSCRIPTION = "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION"; - field public static final String EXTRA_FORCE_PROVISION = "android.telephony.euicc.extra.FORCE_PROVISION"; - field public static final String EXTRA_FROM_SUBSCRIPTION_ID = "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID"; - field public static final String EXTRA_PHYSICAL_SLOT_ID = "android.telephony.euicc.extra.PHYSICAL_SLOT_ID"; - field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.euicc.extra.SUBSCRIPTION_ID"; - field public static final String EXTRA_SUBSCRIPTION_NICKNAME = "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME"; - } - - @IntDef(prefix={"EUICC_OTA_"}, value={android.telephony.euicc.EuiccManager.EUICC_OTA_IN_PROGRESS, android.telephony.euicc.EuiccManager.EUICC_OTA_FAILED, android.telephony.euicc.EuiccManager.EUICC_OTA_SUCCEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_NOT_NEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccManager.OtaStatus { - } - - public final class EuiccNotification implements android.os.Parcelable { - ctor public EuiccNotification(int, String, @android.telephony.euicc.EuiccNotification.Event int, @Nullable byte[]); - method public int describeContents(); - method @Nullable public byte[] getData(); - method @android.telephony.euicc.EuiccNotification.Event public int getEvent(); - method public int getSeq(); - method public String getTargetAddr(); - method public void writeToParcel(android.os.Parcel, int); - field @android.telephony.euicc.EuiccNotification.Event public static final int ALL_EVENTS = 15; // 0xf - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccNotification> CREATOR; - field public static final int EVENT_DELETE = 8; // 0x8 - field public static final int EVENT_DISABLE = 4; // 0x4 - field public static final int EVENT_ENABLE = 2; // 0x2 - field public static final int EVENT_INSTALL = 1; // 0x1 - } - - @IntDef(flag=true, prefix={"EVENT_"}, value={android.telephony.euicc.EuiccNotification.EVENT_INSTALL, android.telephony.euicc.EuiccNotification.EVENT_ENABLE, android.telephony.euicc.EuiccNotification.EVENT_DISABLE, android.telephony.euicc.EuiccNotification.EVENT_DELETE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccNotification.Event { - } - - public final class EuiccRulesAuthTable implements android.os.Parcelable { - method public int describeContents(); - method public int findIndex(@android.service.euicc.EuiccProfileInfo.PolicyRule int, android.service.carrier.CarrierIdentifier); - method public boolean hasPolicyRuleFlag(int, @android.telephony.euicc.EuiccRulesAuthTable.PolicyRuleFlag int); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccRulesAuthTable> CREATOR; - field public static final int POLICY_RULE_FLAG_CONSENT_REQUIRED = 1; // 0x1 - } - - public static final class EuiccRulesAuthTable.Builder { - ctor public EuiccRulesAuthTable.Builder(int); - method public android.telephony.euicc.EuiccRulesAuthTable.Builder add(int, java.util.List<android.service.carrier.CarrierIdentifier>, int); - method public android.telephony.euicc.EuiccRulesAuthTable build(); - } - - @IntDef(flag=true, prefix={"POLICY_RULE_FLAG_"}, value={android.telephony.euicc.EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccRulesAuthTable.PolicyRuleFlag { - } - -} - -package android.telephony.ims { - - public final class ImsCallForwardInfo implements android.os.Parcelable { - ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int); - method public int describeContents(); - method public int getCondition(); - method public String getNumber(); - method public int getServiceClass(); - method public int getStatus(); - method public int getTimeSeconds(); - method public int getToA(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CDIV_CF_REASON_ALL = 4; // 0x4 - field public static final int CDIV_CF_REASON_ALL_CONDITIONAL = 5; // 0x5 - field public static final int CDIV_CF_REASON_BUSY = 1; // 0x1 - field public static final int CDIV_CF_REASON_NOT_LOGGED_IN = 6; // 0x6 - field public static final int CDIV_CF_REASON_NOT_REACHABLE = 3; // 0x3 - field public static final int CDIV_CF_REASON_NO_REPLY = 2; // 0x2 - field public static final int CDIV_CF_REASON_UNCONDITIONAL = 0; // 0x0 - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallForwardInfo> CREATOR; - field public static final int STATUS_ACTIVE = 1; // 0x1 - field public static final int STATUS_NOT_ACTIVE = 0; // 0x0 - field public static final int TYPE_OF_ADDRESS_INTERNATIONAL = 145; // 0x91 - field public static final int TYPE_OF_ADDRESS_UNKNOWN = 129; // 0x81 - } - - public final class ImsCallProfile implements android.os.Parcelable { - ctor public ImsCallProfile(); - ctor public ImsCallProfile(int, int); - ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile); - method public int describeContents(); - method public String getCallExtra(String); - method public String getCallExtra(String, String); - method public boolean getCallExtraBoolean(String); - method public boolean getCallExtraBoolean(String, boolean); - method public int getCallExtraInt(String); - method public int getCallExtraInt(String, int); - method public android.os.Bundle getCallExtras(); - method public int getCallType(); - method public static int getCallTypeFromVideoState(int); - method public int getCallerNumberVerificationStatus(); - method public int getEmergencyCallRouting(); - method public int getEmergencyServiceCategories(); - method @NonNull public java.util.List<java.lang.String> getEmergencyUrns(); - method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile(); - method @NonNull public android.os.Bundle getProprietaryCallExtras(); - method public int getRestrictCause(); - method public int getServiceType(); - method public static int getVideoStateFromCallType(int); - method public static int getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile); - method public boolean hasKnownUserIntentEmergency(); - method public boolean isEmergencyCallTesting(); - method public boolean isVideoCall(); - method public boolean isVideoPaused(); - method public static int presentationToOir(int); - method public void setCallExtra(String, String); - method public void setCallExtraBoolean(String, boolean); - method public void setCallExtraInt(String, int); - method public void setCallRestrictCause(int); - method public void setCallerNumberVerificationStatus(int); - method public void setEmergencyCallRouting(int); - method public void setEmergencyCallTesting(boolean); - method public void setEmergencyServiceCategories(int); - method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>); - method public void setHasKnownUserIntentEmergency(boolean); - method public void updateCallExtras(android.telephony.ims.ImsCallProfile); - method public void updateCallType(android.telephony.ims.ImsCallProfile); - method public void updateMediaProfile(android.telephony.ims.ImsCallProfile); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; // 0x2 - field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3 - field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0 - field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1 - field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3 - field public static final int CALL_TYPE_VOICE = 2; // 0x2 - field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1 - field public static final int CALL_TYPE_VS = 8; // 0x8 - field public static final int CALL_TYPE_VS_RX = 10; // 0xa - field public static final int CALL_TYPE_VS_TX = 9; // 0x9 - field public static final int CALL_TYPE_VT = 4; // 0x4 - field public static final int CALL_TYPE_VT_NODIR = 7; // 0x7 - field public static final int CALL_TYPE_VT_RX = 6; // 0x6 - field public static final int CALL_TYPE_VT_TX = 5; // 0x5 - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallProfile> CREATOR; - field public static final int DIALSTRING_NORMAL = 0; // 0x0 - field public static final int DIALSTRING_SS_CONF = 1; // 0x1 - field public static final int DIALSTRING_USSD = 2; // 0x2 - field public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo"; - field public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS"; - field public static final String EXTRA_CALL_DISCONNECT_CAUSE = "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE"; - field public static final String EXTRA_CALL_NETWORK_TYPE = "android.telephony.ims.extra.CALL_NETWORK_TYPE"; - field @Deprecated public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech"; - field public static final String EXTRA_CHILD_NUMBER = "ChildNum"; - field public static final String EXTRA_CNA = "cna"; - field public static final String EXTRA_CNAP = "cnap"; - field public static final String EXTRA_CODEC = "Codec"; - field public static final String EXTRA_DIALSTRING = "dialstring"; - field public static final String EXTRA_DISPLAY_TEXT = "DisplayText"; - field public static final String EXTRA_EMERGENCY_CALL = "e_call"; - field public static final String EXTRA_FORWARDED_NUMBER = "android.telephony.ims.extra.FORWARDED_NUMBER"; - field public static final String EXTRA_IS_CALL_PULL = "CallPull"; - field public static final String EXTRA_OI = "oi"; - field public static final String EXTRA_OIR = "oir"; - field public static final String EXTRA_REMOTE_URI = "remote_uri"; - field public static final String EXTRA_USSD = "ussd"; - field public static final int OIR_DEFAULT = 0; // 0x0 - field public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; // 0x2 - field public static final int OIR_PRESENTATION_PAYPHONE = 4; // 0x4 - field public static final int OIR_PRESENTATION_RESTRICTED = 1; // 0x1 - field public static final int OIR_PRESENTATION_UNKNOWN = 3; // 0x3 - field public static final int SERVICE_TYPE_EMERGENCY = 2; // 0x2 - field public static final int SERVICE_TYPE_NONE = 0; // 0x0 - field public static final int SERVICE_TYPE_NORMAL = 1; // 0x1 - field public static final int VERIFICATION_STATUS_FAILED = 2; // 0x2 - field public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0; // 0x0 - field public static final int VERIFICATION_STATUS_PASSED = 1; // 0x1 - } - - public class ImsCallSessionListener { - method public void callQualityChanged(@NonNull android.telephony.CallQuality); - method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo); - method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile); - method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile); - method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState); - method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo); - method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo); - method public void callSessionHeld(android.telephony.ims.ImsCallProfile); - method public void callSessionHoldFailed(android.telephony.ims.ImsReasonInfo); - method public void callSessionHoldReceived(android.telephony.ims.ImsCallProfile); - method public void callSessionInitiated(android.telephony.ims.ImsCallProfile); - method public void callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo); - method public void callSessionInviteParticipantsRequestDelivered(); - method public void callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo); - method @Deprecated public void callSessionMayHandover(int, int); - method public void callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase); - method public void callSessionMergeFailed(android.telephony.ims.ImsReasonInfo); - method public void callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile); - method public void callSessionMultipartyStateChanged(boolean); - method public void callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile); - method public void callSessionRemoveParticipantsRequestDelivered(); - method public void callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo); - method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo); - method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile); - method public void callSessionResumed(android.telephony.ims.ImsCallProfile); - method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile); - method public void callSessionRttMessageReceived(String); - method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile); - method public void callSessionRttModifyResponseReceived(int); - method public void callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification); - method public void callSessionTerminated(android.telephony.ims.ImsReasonInfo); - method public void callSessionTtyModeReceived(int); - method public void callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo); - method public void callSessionUpdateReceived(android.telephony.ims.ImsCallProfile); - method public void callSessionUpdated(android.telephony.ims.ImsCallProfile); - method public void callSessionUssdMessageReceived(int, String); - method public void onHandover(int, int, @Nullable android.telephony.ims.ImsReasonInfo); - method public void onHandoverFailed(int, int, @NonNull android.telephony.ims.ImsReasonInfo); - method public void onMayHandover(int, int); - } - - public final class ImsConferenceState implements android.os.Parcelable { - method public int describeContents(); - method public static int getConnectionStateForStatus(String); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsConferenceState> CREATOR; - field public static final String DISPLAY_TEXT = "display-text"; - field public static final String ENDPOINT = "endpoint"; - field public static final String SIP_STATUS_CODE = "sipstatuscode"; - field public static final String STATUS = "status"; - field public static final String STATUS_ALERTING = "alerting"; - field public static final String STATUS_CONNECTED = "connected"; - field public static final String STATUS_CONNECT_FAIL = "connect-fail"; - field public static final String STATUS_DIALING_IN = "dialing-in"; - field public static final String STATUS_DIALING_OUT = "dialing-out"; - field public static final String STATUS_DISCONNECTED = "disconnected"; - field public static final String STATUS_DISCONNECTING = "disconnecting"; - field public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus"; - field public static final String STATUS_ON_HOLD = "on-hold"; - field public static final String STATUS_PENDING = "pending"; - field public static final String STATUS_SEND_ONLY = "sendonly"; - field public static final String STATUS_SEND_RECV = "sendrecv"; - field public static final String USER = "user"; - field public final java.util.HashMap<java.lang.String,android.os.Bundle> mParticipants; - } - - public final class ImsException extends java.lang.Exception { - ctor public ImsException(@Nullable String); - ctor public ImsException(@Nullable String, int); - ctor public ImsException(@Nullable String, int, @Nullable Throwable); - } - - public final class ImsExternalCallState implements android.os.Parcelable { - ctor public ImsExternalCallState(@NonNull String, @NonNull android.net.Uri, @Nullable android.net.Uri, boolean, int, int, boolean); - method public int describeContents(); - method @NonNull public android.net.Uri getAddress(); - method public int getCallId(); - method public int getCallState(); - method public int getCallType(); - method @Nullable public android.net.Uri getLocalAddress(); - method public boolean isCallHeld(); - method public boolean isCallPullable(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CALL_STATE_CONFIRMED = 1; // 0x1 - field public static final int CALL_STATE_TERMINATED = 2; // 0x2 - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsExternalCallState> CREATOR; - } - - public class ImsManager { - method @NonNull public android.telephony.ims.SipDelegateManager getSipDelegateManager(int); - } - - public class ImsMmTelManager implements android.telephony.ims.RegistrationManager { - method @Deprecated @NonNull @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException; - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAvailable(int, int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isCapable(int, int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void isSupported(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>) throws android.telephony.ims.ImsException; - method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException; - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiModeSetting(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiNonPersistent(boolean, int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingModeSetting(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingSettingEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean); - method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback); - } - - @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback { - ctor @Deprecated public ImsMmTelManager.RegistrationCallback(); - } - - public final class ImsReasonInfo implements android.os.Parcelable { - field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service"; - } - - public class ImsService extends android.app.Service { - ctor public ImsService(); - method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int); - method public android.telephony.ims.feature.RcsFeature createRcsFeature(int); - method public void disableIms(int); - method public void enableIms(int); - method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int); - method public long getImsServiceCapabilities(); - method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int); - method @Nullable public android.telephony.ims.stub.SipTransportImplBase getSipTransport(int); - method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException; - method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures(); - method public void readyForFeatureCreation(); - field public static final long CAPABILITY_SIP_DELEGATE_CREATION = 2L; // 0x2L - } - - public final class ImsSsData implements android.os.Parcelable { - ctor public ImsSsData(int, int, int, int, int); - method public int describeContents(); - method @Nullable public java.util.List<android.telephony.ims.ImsCallForwardInfo> getCallForwardInfo(); - method public int getRequestType(); - method public int getResult(); - method public int getServiceClass(); - method public int getServiceType(); - method @NonNull public java.util.List<android.telephony.ims.ImsSsInfo> getSuppServiceInfo(); - method public int getTeleserviceType(); - method public boolean isTypeBarring(); - method public boolean isTypeCf(); - method public boolean isTypeClip(); - method public boolean isTypeClir(); - method public boolean isTypeColp(); - method public boolean isTypeColr(); - method public boolean isTypeCw(); - method public boolean isTypeIcb(); - method public boolean isTypeInterrogation(); - method public boolean isTypeUnConditional(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsData> CREATOR; - field public static final int RESULT_SUCCESS = 0; // 0x0 - field public static final int SERVICE_CLASS_DATA = 2; // 0x2 - field public static final int SERVICE_CLASS_DATA_CIRCUIT_ASYNC = 32; // 0x20 - field public static final int SERVICE_CLASS_DATA_CIRCUIT_SYNC = 16; // 0x10 - field public static final int SERVICE_CLASS_DATA_PACKET_ACCESS = 64; // 0x40 - field public static final int SERVICE_CLASS_DATA_PAD = 128; // 0x80 - field public static final int SERVICE_CLASS_FAX = 4; // 0x4 - field public static final int SERVICE_CLASS_NONE = 0; // 0x0 - field public static final int SERVICE_CLASS_SMS = 8; // 0x8 - field public static final int SERVICE_CLASS_VOICE = 1; // 0x1 - field public static final int SS_ACTIVATION = 0; // 0x0 - field public static final int SS_ALL_BARRING = 18; // 0x12 - field public static final int SS_ALL_DATA_TELESERVICES = 3; // 0x3 - field public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; // 0x5 - field public static final int SS_ALL_TELESEVICES = 1; // 0x1 - field public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; // 0x0 - field public static final int SS_BAIC = 16; // 0x10 - field public static final int SS_BAIC_ROAMING = 17; // 0x11 - field public static final int SS_BAOC = 13; // 0xd - field public static final int SS_BAOIC = 14; // 0xe - field public static final int SS_BAOIC_EXC_HOME = 15; // 0xf - field public static final int SS_CFU = 0; // 0x0 - field public static final int SS_CFUT = 6; // 0x6 - field public static final int SS_CF_ALL = 4; // 0x4 - field public static final int SS_CF_ALL_CONDITIONAL = 5; // 0x5 - field public static final int SS_CF_BUSY = 1; // 0x1 - field public static final int SS_CF_NOT_REACHABLE = 3; // 0x3 - field public static final int SS_CF_NO_REPLY = 2; // 0x2 - field public static final int SS_CLIP = 7; // 0x7 - field public static final int SS_CLIR = 8; // 0x8 - field public static final int SS_CNAP = 11; // 0xb - field public static final int SS_COLP = 9; // 0x9 - field public static final int SS_COLR = 10; // 0xa - field public static final int SS_DEACTIVATION = 1; // 0x1 - field public static final int SS_ERASURE = 4; // 0x4 - field public static final int SS_INCOMING_BARRING = 20; // 0x14 - field public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; // 0x16 - field public static final int SS_INCOMING_BARRING_DN = 21; // 0x15 - field public static final int SS_INTERROGATION = 2; // 0x2 - field public static final int SS_OUTGOING_BARRING = 19; // 0x13 - field public static final int SS_REGISTRATION = 3; // 0x3 - field public static final int SS_SMS_SERVICES = 4; // 0x4 - field public static final int SS_TELEPHONY = 2; // 0x2 - field public static final int SS_WAIT = 12; // 0xc - } - - public static final class ImsSsData.Builder { - ctor public ImsSsData.Builder(int, int, int, int, int); - method @NonNull public android.telephony.ims.ImsSsData build(); - method @NonNull public android.telephony.ims.ImsSsData.Builder setCallForwardingInfo(@NonNull java.util.List<android.telephony.ims.ImsCallForwardInfo>); - method @NonNull public android.telephony.ims.ImsSsData.Builder setSuppServiceInfo(@NonNull java.util.List<android.telephony.ims.ImsSsInfo>); - } - - public final class ImsSsInfo implements android.os.Parcelable { - ctor @Deprecated public ImsSsInfo(int, @Nullable String); - method public int describeContents(); - method public int getClirInterrogationStatus(); - method public int getClirOutgoingState(); - method @Deprecated public String getIcbNum(); - method @Nullable public String getIncomingCommunicationBarringNumber(); - method public int getProvisionStatus(); - method public int getStatus(); - method public void writeToParcel(android.os.Parcel, int); - field public static final int CLIR_OUTGOING_DEFAULT = 0; // 0x0 - field public static final int CLIR_OUTGOING_INVOCATION = 1; // 0x1 - field public static final int CLIR_OUTGOING_SUPPRESSION = 2; // 0x2 - field public static final int CLIR_STATUS_NOT_PROVISIONED = 0; // 0x0 - field public static final int CLIR_STATUS_PROVISIONED_PERMANENT = 1; // 0x1 - field public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4; // 0x4 - field public static final int CLIR_STATUS_TEMPORARILY_RESTRICTED = 3; // 0x3 - field public static final int CLIR_STATUS_UNKNOWN = 2; // 0x2 - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsInfo> CREATOR; - field public static final int DISABLED = 0; // 0x0 - field public static final int ENABLED = 1; // 0x1 - field public static final int NOT_REGISTERED = -1; // 0xffffffff - field public static final int SERVICE_NOT_PROVISIONED = 0; // 0x0 - field public static final int SERVICE_PROVISIONED = 1; // 0x1 - field public static final int SERVICE_PROVISIONING_UNKNOWN = -1; // 0xffffffff - } - - public static final class ImsSsInfo.Builder { - ctor public ImsSsInfo.Builder(int); - method @NonNull public android.telephony.ims.ImsSsInfo build(); - method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirInterrogationStatus(int); - method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirOutgoingState(int); - method @NonNull public android.telephony.ims.ImsSsInfo.Builder setIncomingCommunicationBarringNumber(@NonNull String); - method @NonNull public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int); - } - - public final class ImsStreamMediaProfile implements android.os.Parcelable { - ctor public ImsStreamMediaProfile(int, int, int, int, int); - method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile); - method public int describeContents(); - method public int getAudioDirection(); - method public int getAudioQuality(); - method public int getRttMode(); - method public int getVideoDirection(); - method public int getVideoQuality(); - method public boolean isReceivingRttAudio(); - method public boolean isRttCall(); - method public void setReceivingRttAudio(boolean); - method public void setRttMode(int); - method public void writeToParcel(android.os.Parcel, int); - field public static final int AUDIO_QUALITY_AMR = 1; // 0x1 - field public static final int AUDIO_QUALITY_AMR_WB = 2; // 0x2 - field public static final int AUDIO_QUALITY_EVRC = 4; // 0x4 - field public static final int AUDIO_QUALITY_EVRC_B = 5; // 0x5 - field public static final int AUDIO_QUALITY_EVRC_NW = 7; // 0x7 - field public static final int AUDIO_QUALITY_EVRC_WB = 6; // 0x6 - field public static final int AUDIO_QUALITY_EVS_FB = 20; // 0x14 - field public static final int AUDIO_QUALITY_EVS_NB = 17; // 0x11 - field public static final int AUDIO_QUALITY_EVS_SWB = 19; // 0x13 - field public static final int AUDIO_QUALITY_EVS_WB = 18; // 0x12 - field public static final int AUDIO_QUALITY_G711A = 13; // 0xd - field public static final int AUDIO_QUALITY_G711AB = 15; // 0xf - field public static final int AUDIO_QUALITY_G711U = 11; // 0xb - field public static final int AUDIO_QUALITY_G722 = 14; // 0xe - field public static final int AUDIO_QUALITY_G723 = 12; // 0xc - field public static final int AUDIO_QUALITY_G729 = 16; // 0x10 - field public static final int AUDIO_QUALITY_GSM_EFR = 8; // 0x8 - field public static final int AUDIO_QUALITY_GSM_FR = 9; // 0x9 - field public static final int AUDIO_QUALITY_GSM_HR = 10; // 0xa - field public static final int AUDIO_QUALITY_NONE = 0; // 0x0 - field public static final int AUDIO_QUALITY_QCELP13K = 3; // 0x3 - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsStreamMediaProfile> CREATOR; - field public static final int DIRECTION_INACTIVE = 0; // 0x0 - field public static final int DIRECTION_INVALID = -1; // 0xffffffff - field public static final int DIRECTION_RECEIVE = 1; // 0x1 - field public static final int DIRECTION_SEND = 2; // 0x2 - field public static final int DIRECTION_SEND_RECEIVE = 3; // 0x3 - field public static final int RTT_MODE_DISABLED = 0; // 0x0 - field public static final int RTT_MODE_FULL = 1; // 0x1 - field public static final int VIDEO_QUALITY_NONE = 0; // 0x0 - field public static final int VIDEO_QUALITY_QCIF = 1; // 0x1 - field public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = 2; // 0x2 - field public static final int VIDEO_QUALITY_QVGA_PORTRAIT = 4; // 0x4 - field public static final int VIDEO_QUALITY_VGA_LANDSCAPE = 8; // 0x8 - field public static final int VIDEO_QUALITY_VGA_PORTRAIT = 16; // 0x10 - } - - public final class ImsSuppServiceNotification implements android.os.Parcelable { - ctor public ImsSuppServiceNotification(int, int, int, int, String, String[]); - method public int describeContents(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSuppServiceNotification> CREATOR; - field public final int code; - field public final String[] history; - field public final int index; - field public final int notificationType; - field public final String number; - field public final int type; - } - - public class ImsUtListener { - method public void onLineIdentificationSupplementaryServiceResponse(int, @NonNull android.telephony.ims.ImsSsInfo); - method public void onSupplementaryServiceIndication(android.telephony.ims.ImsSsData); - method public void onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]); - method public void onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]); - method public void onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]); - method @Deprecated public void onUtConfigurationQueried(int, android.os.Bundle); - method public void onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo); - method public void onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo); - method public void onUtConfigurationUpdated(int); - field @Deprecated public static final String BUNDLE_KEY_CLIR = "queryClir"; - field @Deprecated public static final String BUNDLE_KEY_SSINFO = "imsSsInfo"; - } - - public abstract class ImsVideoCallProvider { - ctor public ImsVideoCallProvider(); - method public void changeCallDataUsage(long); - method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities); - method public void changePeerDimensions(int, int); - method public void changeVideoQuality(int); - method public void handleCallSessionEvent(int); - method public abstract void onRequestCallDataUsage(); - method public abstract void onRequestCameraCapabilities(); - method public abstract void onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile); - method public abstract void onSendSessionModifyResponse(android.telecom.VideoProfile); - method public abstract void onSetCamera(String); - method public void onSetCamera(String, int); - method public abstract void onSetDeviceOrientation(int); - method public abstract void onSetDisplaySurface(android.view.Surface); - method public abstract void onSetPauseImage(android.net.Uri); - method public abstract void onSetPreviewSurface(android.view.Surface); - method public abstract void onSetZoom(float); - method public void receiveSessionModifyRequest(android.telecom.VideoProfile); - method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile); - } - - public class ProvisioningManager { - method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getProvisioningIntValue(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getProvisioningStatusForCapability(int, int); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getRcsProvisioningStatusForCapability(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException; - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(int, int, boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback); - field public static final int KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID = 67; // 0x43 - field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b - field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a - field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0 - field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1 - field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC"; - field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY"; - } - - public static class ProvisioningManager.Callback { - ctor public ProvisioningManager.Callback(); - method public void onProvisioningIntChanged(int, int); - method public void onProvisioningStringChanged(int, @NonNull String); - } - - public class RcsUceAdapter { - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException; - } - - public class SipDelegateManager { - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSupported() throws android.telephony.ims.ImsException; - } - -} - -package android.telephony.ims.feature { - - public final class CapabilityChangeRequest implements android.os.Parcelable { - method public void addCapabilitiesToDisableForTech(int, int); - method public void addCapabilitiesToEnableForTech(int, int); - method public int describeContents(); - method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToDisable(); - method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToEnable(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.feature.CapabilityChangeRequest> CREATOR; - } - - public static class CapabilityChangeRequest.CapabilityPair { - ctor public CapabilityChangeRequest.CapabilityPair(int, int); - method public int getCapability(); - method public int getRadioTech(); - } - - public abstract class ImsFeature { - ctor public ImsFeature(); - method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); - method public int getFeatureState(); - method public final int getSlotIndex(); - method public abstract void onFeatureReady(); - method public abstract void onFeatureRemoved(); - method public final void setFeatureState(int); - field public static final int CAPABILITY_ERROR_GENERIC = -1; // 0xffffffff - field public static final int CAPABILITY_SUCCESS = 0; // 0x0 - field public static final int FEATURE_EMERGENCY_MMTEL = 0; // 0x0 - field public static final int FEATURE_MMTEL = 1; // 0x1 - field public static final int FEATURE_RCS = 2; // 0x2 - field public static final int STATE_INITIALIZING = 1; // 0x1 - field public static final int STATE_READY = 2; // 0x2 - field public static final int STATE_UNAVAILABLE = 0; // 0x0 - } - - @Deprecated public static class ImsFeature.Capabilities { - field @Deprecated protected int mCapabilities; - } - - protected static class ImsFeature.CapabilityCallbackProxy { - method public void onChangeCapabilityConfigurationError(int, int, int); - } - - public class MmTelFeature extends android.telephony.ims.feature.ImsFeature { - ctor public MmTelFeature(); - method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); - method @Nullable public android.telephony.ims.ImsCallProfile createCallProfile(int, int); - method @Nullable public android.telephony.ims.stub.ImsCallSessionImplBase createCallSession(@NonNull android.telephony.ims.ImsCallProfile); - method @NonNull public android.telephony.ims.stub.ImsEcbmImplBase getEcbm(); - method @NonNull public android.telephony.ims.stub.ImsMultiEndpointImplBase getMultiEndpoint(); - method @NonNull public android.telephony.ims.stub.ImsSmsImplBase getSmsImplementation(); - method @NonNull public android.telephony.ims.stub.ImsUtImplBase getUt(); - method public final void notifyCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities); - method public final void notifyIncomingCall(@NonNull android.telephony.ims.stub.ImsCallSessionImplBase, @NonNull android.os.Bundle); - method public final void notifyRejectedCall(@NonNull android.telephony.ims.ImsCallProfile, @NonNull android.telephony.ims.ImsReasonInfo); - method public final void notifyVoiceMessageCountUpdate(int); - method public void onFeatureReady(); - method public void onFeatureRemoved(); - method public boolean queryCapabilityConfiguration(int, int); - method @NonNull public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus(); - method public void setUiTtyMode(int, @Nullable android.os.Message); - method public int shouldProcessCall(@NonNull String[]); - field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL"; - field public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD"; - field public static final int PROCESS_CALL_CSFB = 1; // 0x1 - field public static final int PROCESS_CALL_IMS = 0; // 0x0 - } - - public static class MmTelFeature.MmTelCapabilities extends android.telephony.ims.feature.ImsFeature.Capabilities { - ctor public MmTelFeature.MmTelCapabilities(); - ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities); - ctor public MmTelFeature.MmTelCapabilities(int); - method public final void addCapabilities(int); - method public final void removeCapabilities(int); - } - - public class RcsFeature extends android.telephony.ims.feature.ImsFeature { - ctor public RcsFeature(); - method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); - method public void onFeatureReady(); - method public void onFeatureRemoved(); - } - -} - -package android.telephony.ims.stub { - - public class ImsCallSessionImplBase implements java.lang.AutoCloseable { - ctor public ImsCallSessionImplBase(); - method public void accept(int, android.telephony.ims.ImsStreamMediaProfile); - method public void close(); - method public void deflect(String); - method public void extendToConference(String[]); - method public String getCallId(); - method public android.telephony.ims.ImsCallProfile getCallProfile(); - method public android.telephony.ims.ImsVideoCallProvider getImsVideoCallProvider(); - method public android.telephony.ims.ImsCallProfile getLocalCallProfile(); - method public String getProperty(String); - method public android.telephony.ims.ImsCallProfile getRemoteCallProfile(); - method public int getState(); - method public void hold(android.telephony.ims.ImsStreamMediaProfile); - method public void inviteParticipants(String[]); - method public boolean isInCall(); - method public boolean isMultiparty(); - method public void merge(); - method public void reject(int); - method public void removeParticipants(String[]); - method public void resume(android.telephony.ims.ImsStreamMediaProfile); - method public void sendDtmf(char, android.os.Message); - method public void sendRttMessage(String); - method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile); - method public void sendRttModifyResponse(boolean); - method public void sendUssd(String); - method public void setListener(android.telephony.ims.ImsCallSessionListener); - method public void setMute(boolean); - method public void start(String, android.telephony.ims.ImsCallProfile); - method public void startConference(String[], android.telephony.ims.ImsCallProfile); - method public void startDtmf(char); - method public void stopDtmf(); - method public void terminate(int); - method public void update(int, android.telephony.ims.ImsStreamMediaProfile); - field public static final int USSD_MODE_NOTIFY = 0; // 0x0 - field public static final int USSD_MODE_REQUEST = 1; // 0x1 - } - - public static class ImsCallSessionImplBase.State { - method public static String toString(int); - field public static final int ESTABLISHED = 4; // 0x4 - field public static final int ESTABLISHING = 3; // 0x3 - field public static final int IDLE = 0; // 0x0 - field public static final int INITIATED = 1; // 0x1 - field public static final int INVALID = -1; // 0xffffffff - field public static final int NEGOTIATING = 2; // 0x2 - field public static final int REESTABLISHING = 6; // 0x6 - field public static final int RENEGOTIATING = 5; // 0x5 - field public static final int TERMINATED = 8; // 0x8 - field public static final int TERMINATING = 7; // 0x7 - } - - public class ImsConfigImplBase { - ctor public ImsConfigImplBase(); - method public int getConfigInt(int); - method public String getConfigString(int); - method public final void notifyProvisionedValueChanged(int, int); - method public final void notifyProvisionedValueChanged(int, String); - method public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean); - method public int setConfig(int, int); - method public int setConfig(int, String); - field public static final int CONFIG_RESULT_FAILED = 1; // 0x1 - field public static final int CONFIG_RESULT_SUCCESS = 0; // 0x0 - field public static final int CONFIG_RESULT_UNKNOWN = -1; // 0xffffffff - } - - public class ImsEcbmImplBase { - ctor public ImsEcbmImplBase(); - method public final void enteredEcbm(); - method public void exitEmergencyCallbackMode(); - method public final void exitedEcbm(); - } - - public final class ImsFeatureConfiguration implements android.os.Parcelable { - method public int describeContents(); - method public java.util.Set<android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair> getServiceFeatures(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.stub.ImsFeatureConfiguration> CREATOR; - } - - public static class ImsFeatureConfiguration.Builder { - ctor public ImsFeatureConfiguration.Builder(); - method public android.telephony.ims.stub.ImsFeatureConfiguration.Builder addFeature(int, int); - method public android.telephony.ims.stub.ImsFeatureConfiguration build(); - } - - public static final class ImsFeatureConfiguration.FeatureSlotPair { - ctor public ImsFeatureConfiguration.FeatureSlotPair(int, int); - field public final int featureType; - field public final int slotId; - } - - public class ImsMultiEndpointImplBase { - ctor public ImsMultiEndpointImplBase(); - method public final void onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>); - method public void requestImsExternalCallStateInfo(); - } - - public class ImsRegistrationImplBase { - ctor public ImsRegistrationImplBase(); - method public final void onDeregistered(android.telephony.ims.ImsReasonInfo); - method public final void onRegistered(int); - method public final void onRegistering(int); - method public final void onSubscriberAssociatedUriChanged(android.net.Uri[]); - method public final void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo); - field public static final int REGISTRATION_TECH_IWLAN = 1; // 0x1 - field public static final int REGISTRATION_TECH_LTE = 0; // 0x0 - field public static final int REGISTRATION_TECH_NONE = -1; // 0xffffffff - } - - public class ImsSmsImplBase { - ctor public ImsSmsImplBase(); - method public void acknowledgeSms(int, @IntRange(from=0, to=65535) int, int); - method public void acknowledgeSmsReport(int, @IntRange(from=0, to=65535) int, int); - method public String getSmsFormat(); - method public void onReady(); - method @Deprecated public final void onSendSmsResult(int, @IntRange(from=0, to=65535) int, int, int) throws java.lang.RuntimeException; - method public final void onSendSmsResultError(int, @IntRange(from=0, to=65535) int, int, int, int) throws java.lang.RuntimeException; - method public final void onSendSmsResultSuccess(int, @IntRange(from=0, to=65535) int) throws java.lang.RuntimeException; - method public final void onSmsReceived(int, String, byte[]) throws java.lang.RuntimeException; - method @Deprecated public final void onSmsStatusReportReceived(int, @IntRange(from=0, to=65535) int, String, byte[]) throws java.lang.RuntimeException; - method public final void onSmsStatusReportReceived(int, String, byte[]) throws java.lang.RuntimeException; - method public void sendSms(int, @IntRange(from=0, to=65535) int, String, String, boolean, byte[]); - field public static final int DELIVER_STATUS_ERROR_GENERIC = 2; // 0x2 - field public static final int DELIVER_STATUS_ERROR_NO_MEMORY = 3; // 0x3 - field public static final int DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED = 4; // 0x4 - field public static final int DELIVER_STATUS_OK = 1; // 0x1 - field public static final int RESULT_NO_NETWORK_ERROR = -1; // 0xffffffff - field public static final int SEND_STATUS_ERROR = 2; // 0x2 - field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4 - field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3 - field public static final int SEND_STATUS_OK = 1; // 0x1 - field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2 - field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1 - } - - public class ImsUtImplBase { - ctor public ImsUtImplBase(); - method public void close(); - method public int queryCallBarring(int); - method public int queryCallBarringForServiceClass(int, int); - method public int queryCallForward(int, String); - method public int queryCallWaiting(); - method public int queryClip(); - method public int queryClir(); - method public int queryColp(); - method public int queryColr(); - method public void setListener(android.telephony.ims.ImsUtListener); - method public int transact(android.os.Bundle); - method public int updateCallBarring(int, int, String[]); - method public int updateCallBarringForServiceClass(int, int, String[], int); - method public int updateCallForward(int, int, String, int, int); - method public int updateCallWaiting(boolean, int); - method public int updateClip(boolean); - method public int updateClir(int); - method public int updateColp(boolean); - method public int updateColr(int); - } - - public class SipTransportImplBase { - ctor public SipTransportImplBase(@NonNull java.util.concurrent.Executor); - } - -} - -package android.telephony.mbms { - - public static class DownloadRequest.Builder { - method public android.telephony.mbms.DownloadRequest.Builder setServiceId(String); - } - - public final class FileInfo implements android.os.Parcelable { - ctor public FileInfo(android.net.Uri, String); - } - - public final class FileServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable { - ctor public FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>); - } - - public class MbmsDownloadReceiver extends android.content.BroadcastReceiver { - field public static final int RESULT_APP_NOTIFICATION_ERROR = 6; // 0x6 - field public static final int RESULT_BAD_TEMP_FILE_ROOT = 3; // 0x3 - field public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4; // 0x4 - field public static final int RESULT_INVALID_ACTION = 1; // 0x1 - field public static final int RESULT_MALFORMED_INTENT = 2; // 0x2 - field public static final int RESULT_OK = 0; // 0x0 - field public static final int RESULT_TEMP_FILE_GENERATION_ERROR = 5; // 0x5 - } - - public final class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable { - ctor public StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date); - } - - public final class UriPathPair implements android.os.Parcelable { - method public int describeContents(); - method public android.net.Uri getContentUri(); - method public android.net.Uri getFilePathUri(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.mbms.UriPathPair> CREATOR; - } - -} - -package android.telephony.mbms.vendor { - - public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface { - ctor public MbmsDownloadServiceBase(); - method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException; - method public int addServiceAnnouncement(int, @NonNull byte[]); - method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException; - method public android.os.IBinder asBinder(); - method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException; - method public void dispose(int) throws android.os.RemoteException; - method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException; - method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException; - method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException; - method public void onAppCallbackDied(int, int); - method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException; - method public int removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException; - method public int removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException; - method public int requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException; - method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException; - method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException; - method public int setTempFileRootDirectory(int, String) throws android.os.RemoteException; - } - - public class MbmsGroupCallServiceBase extends android.app.Service { - ctor public MbmsGroupCallServiceBase(); - method public void dispose(int) throws android.os.RemoteException; - method public int initialize(@NonNull android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException; - method public void onAppCallbackDied(int, int); - method public android.os.IBinder onBind(android.content.Intent); - method public int startGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>, @NonNull android.telephony.mbms.GroupCallCallback); - method public void stopGroupCall(int, long); - method public void updateGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>); - } - - public class MbmsStreamingServiceBase extends android.os.Binder implements android.os.IInterface { - ctor public MbmsStreamingServiceBase(); - method public android.os.IBinder asBinder(); - method public void dispose(int) throws android.os.RemoteException; - method @Nullable public android.net.Uri getPlaybackUri(int, String) throws android.os.RemoteException; - method public int initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) throws android.os.RemoteException; - method public void onAppCallbackDied(int, int); - method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException; - method public int requestUpdateStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException; - method public int startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) throws android.os.RemoteException; - method public void stopStreaming(int, String) throws android.os.RemoteException; - } - - public class VendorUtils { - ctor public VendorUtils(); - method public static android.content.ComponentName getAppReceiverFromPackageName(android.content.Context, String); - field public static final String ACTION_CLEANUP = "android.telephony.mbms.action.CLEANUP"; - field public static final String ACTION_DOWNLOAD_RESULT_INTERNAL = "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL"; - field public static final String ACTION_FILE_DESCRIPTOR_REQUEST = "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST"; - field public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT"; - field public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI"; - field public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST"; - field public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST"; - field public static final String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST"; - field public static final String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID"; - field public static final String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE"; - field public static final String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT"; - field public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST"; - } - -} - diff --git a/telephony/api/system-removed.txt b/telephony/api/system-removed.txt deleted file mode 100644 index ae46075c4829..000000000000 --- a/telephony/api/system-removed.txt +++ /dev/null @@ -1,19 +0,0 @@ -// Signature format: 2.0 -package android.telephony { - - public class TelephonyManager { - method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall(); - method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall(); - method @Deprecated public void silenceRinger(); - } - -} - -package android.telephony.data { - - public final class DataCallResponse implements android.os.Parcelable { - ctor public DataCallResponse(int, int, int, int, int, @Nullable String, @Nullable java.util.List<android.net.LinkAddress>, @Nullable java.util.List<java.net.InetAddress>, @Nullable java.util.List<java.net.InetAddress>, @Nullable java.util.List<java.net.InetAddress>, int); - } - -} - diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java index c3cd01738b96..96996a1ae8ac 100644 --- a/telephony/common/com/android/internal/telephony/SmsApplication.java +++ b/telephony/common/com/android/internal/telephony/SmsApplication.java @@ -35,6 +35,7 @@ import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; +import android.os.Build; import android.os.Process; import android.os.UserHandle; import android.provider.Telephony; @@ -89,7 +90,7 @@ public final class SmsApplication { /** * Name of this SMS app for display. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String mApplicationName; /** @@ -580,7 +581,7 @@ public final class SmsApplication { * Sets the specified package as the default SMS/MMS application. The caller of this method * needs to have permission to set AppOps and write to secure settings. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void setDefaultApplication(String packageName, Context context) { setDefaultApplicationAsUser(packageName, context, getIncomingUserId(context)); } @@ -849,7 +850,7 @@ public final class SmsApplication { sSmsPackageMonitor.register(context, context.getMainLooper(), UserHandle.ALL); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static void configurePreferredActivity(PackageManager packageManager, ComponentName componentName) { // Add the four activity preferences we want to direct to this app. @@ -887,7 +888,7 @@ public final class SmsApplication { * Returns SmsApplicationData for this package if this package is capable of being set as the * default SMS application. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static SmsApplicationData getSmsApplicationData(String packageName, Context context) { Collection<SmsApplicationData> applications = getApplicationCollection(context); return getApplicationForPackage(applications, packageName); @@ -959,7 +960,7 @@ public final class SmsApplication { * @param updateIfNeeded update the default app if there is no valid default app configured. * @return component name of the app and class to direct Respond Via Message intent to */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static ComponentName getDefaultRespondViaMessageApplication(Context context, boolean updateIfNeeded) { int userId = getIncomingUserId(context); @@ -1060,7 +1061,7 @@ public final class SmsApplication { * <p> * Caller must pass in the correct user context if calling from a singleton service. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean shouldWriteMessageForPackage(String packageName, Context context) { return !isDefaultSmsApplication(context, packageName); } diff --git a/telephony/common/com/google/android/mms/ContentType.java b/telephony/common/com/google/android/mms/ContentType.java index 4a971dd34c8f..2aec86fe67e4 100644 --- a/telephony/common/com/google/android/mms/ContentType.java +++ b/telephony/common/com/google/android/mms/ContentType.java @@ -18,6 +18,7 @@ package com.google.android.mms; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.util.ArrayList; @@ -176,17 +177,17 @@ public class ContentType { return (null != contentType) && sSupportedContentTypes.contains(contentType); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isSupportedImageType(String contentType) { return isImageType(contentType) && isSupportedType(contentType); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isSupportedAudioType(String contentType) { return isAudioType(contentType) && isSupportedType(contentType); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isSupportedVideoType(String contentType) { return isVideoType(contentType) && isSupportedType(contentType); } diff --git a/telephony/common/com/google/android/mms/MmsException.java b/telephony/common/com/google/android/mms/MmsException.java index 24bceb37f590..db6d1d1e3d8a 100644 --- a/telephony/common/com/google/android/mms/MmsException.java +++ b/telephony/common/com/google/android/mms/MmsException.java @@ -18,6 +18,7 @@ package com.google.android.mms; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; /** * A generic exception that is thrown by the Mms client. @@ -59,7 +60,7 @@ public class MmsException extends Exception { * @param message the detail message. * @param cause the cause. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public MmsException(String message, Throwable cause) { super(message, cause); } diff --git a/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java b/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java index 8693385bb032..3eda60bfbf1f 100644 --- a/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java +++ b/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java @@ -18,6 +18,7 @@ package com.google.android.mms.pdu; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import com.google.android.mms.InvalidHeaderValueException; @@ -68,7 +69,7 @@ public class AcknowledgeInd extends GenericPdu { * @param value the value * @throws InvalidHeaderValueException if the value is invalid. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setReportAllowed(int value) throws InvalidHeaderValueException { mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED); } diff --git a/telephony/common/com/google/android/mms/pdu/DeliveryInd.java b/telephony/common/com/google/android/mms/pdu/DeliveryInd.java index 8fb6a7545abf..ca1f2ebeb044 100644 --- a/telephony/common/com/google/android/mms/pdu/DeliveryInd.java +++ b/telephony/common/com/google/android/mms/pdu/DeliveryInd.java @@ -18,6 +18,7 @@ package com.google.android.mms.pdu; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import com.google.android.mms.InvalidHeaderValueException; @@ -53,7 +54,7 @@ public class DeliveryInd extends GenericPdu { * * @return the value */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long getDate() { return mPduHeaders.getLongInteger(PduHeaders.DATE); } diff --git a/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java b/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java index 8c0380f77cdd..8b01cb3c4405 100644 --- a/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java +++ b/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java @@ -18,6 +18,7 @@ package com.google.android.mms.pdu; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.util.Log; import java.io.ByteArrayOutputStream; @@ -237,7 +238,7 @@ public class EncodedStringValue implements Cloneable { /** * Extract an EncodedStringValue[] from a given String. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static EncodedStringValue[] extract(String src) { String[] values = src.split(";"); diff --git a/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java b/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java index 42a89c69e873..45ba4819aa24 100644 --- a/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java +++ b/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java @@ -18,6 +18,7 @@ package com.google.android.mms.pdu; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import com.google.android.mms.InvalidHeaderValueException; @@ -116,7 +117,7 @@ public class MultimediaMessagePdu extends GenericPdu{ * @param value the value * @throws NullPointerException if the value is null. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addTo(EncodedStringValue value) { mPduHeaders.appendEncodedStringValue(value, PduHeaders.TO); } @@ -137,7 +138,7 @@ public class MultimediaMessagePdu extends GenericPdu{ * @param value the value * @throws InvalidHeaderValueException if the value is invalid. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setPriority(int value) throws InvalidHeaderValueException { mPduHeaders.setOctet(value, PduHeaders.PRIORITY); } @@ -157,7 +158,7 @@ public class MultimediaMessagePdu extends GenericPdu{ * * @param value the value */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDate(long value) { mPduHeaders.setLongInteger(value, PduHeaders.DATE); } diff --git a/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java b/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java index ebd81afc0173..16d83953e723 100644 --- a/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java +++ b/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java @@ -18,6 +18,7 @@ package com.google.android.mms.pdu; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import com.google.android.mms.InvalidHeaderValueException; @@ -72,7 +73,7 @@ public class NotifyRespInd extends GenericPdu { * @throws InvalidHeaderValueException if the value is invalid. * RuntimeException if an undeclared error occurs. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setReportAllowed(int value) throws InvalidHeaderValueException { mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED); } diff --git a/telephony/common/com/google/android/mms/pdu/PduBody.java b/telephony/common/com/google/android/mms/pdu/PduBody.java index f7f285f653b9..e76738b5a42f 100644 --- a/telephony/common/com/google/android/mms/pdu/PduBody.java +++ b/telephony/common/com/google/android/mms/pdu/PduBody.java @@ -18,6 +18,7 @@ package com.google.android.mms.pdu; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import java.util.HashMap; import java.util.Map; @@ -113,7 +114,7 @@ public class PduBody { * @param index index of the part to return * @return part at the specified index */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public PduPart removePart(int index) { return mParts.remove(index); } @@ -142,7 +143,7 @@ public class PduBody { * @param part the part object * @return index the index of the first occurrence of the part in this body */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getPartIndex(PduPart part) { return mParts.indexOf(part); } diff --git a/telephony/common/com/google/android/mms/pdu/PduPart.java b/telephony/common/com/google/android/mms/pdu/PduPart.java index 8dd976b2569f..aead141634e8 100644 --- a/telephony/common/com/google/android/mms/pdu/PduPart.java +++ b/telephony/common/com/google/android/mms/pdu/PduPart.java @@ -19,6 +19,7 @@ package com.google.android.mms.pdu; import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; +import android.os.Build; import java.util.HashMap; import java.util.Map; @@ -164,7 +165,7 @@ public class PduPart { /** * @return The length of the data, if this object have data, else 0. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getDataLength() { if(mPartData != null){ return mPartData.length; diff --git a/telephony/common/com/google/android/mms/pdu/SendReq.java b/telephony/common/com/google/android/mms/pdu/SendReq.java index 6e2f2da01791..8b5a61701377 100644 --- a/telephony/common/com/google/android/mms/pdu/SendReq.java +++ b/telephony/common/com/google/android/mms/pdu/SendReq.java @@ -18,6 +18,7 @@ package com.google.android.mms.pdu; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.util.Log; import com.google.android.mms.InvalidHeaderValueException; @@ -150,7 +151,7 @@ public class SendReq extends MultimediaMessagePdu { * @param value the value * @throws NullPointerException if the value is null. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCc(EncodedStringValue[] value) { mPduHeaders.setEncodedStringValues(value, PduHeaders.CC); } diff --git a/telephony/common/com/google/android/mms/util/AbstractCache.java b/telephony/common/com/google/android/mms/util/AbstractCache.java index 25862e73581e..8b9ee43b0981 100644 --- a/telephony/common/com/google/android/mms/util/AbstractCache.java +++ b/telephony/common/com/google/android/mms/util/AbstractCache.java @@ -18,6 +18,7 @@ package com.google.android.mms.util; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.util.Log; import java.util.HashMap; @@ -64,7 +65,7 @@ public abstract class AbstractCache<K, V> { return false; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public V get(K key) { if (LOCAL_LOGV) { Log.v(TAG, "Trying to get " + key + " from cache."); diff --git a/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java b/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java index 0f9390daa725..d0e33984e094 100644 --- a/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java +++ b/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java @@ -20,6 +20,7 @@ package com.google.android.mms.util; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.drm.DrmManagerClient; +import android.os.Build; import android.util.Log; public class DownloadDrmHelper { @@ -73,7 +74,7 @@ public class DownloadDrmHelper { * Modifies the file extension for a DRM Forward Lock file NOTE: This * function shouldn't be called if the file shouldn't be DRM converted */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String modifyDrmFwLockFileExtension(String filename) { if (filename != null) { int extensionIndex; diff --git a/telephony/common/com/google/android/mms/util/SqliteWrapper.java b/telephony/common/com/google/android/mms/util/SqliteWrapper.java index 31fe4d7683d6..e2d62f868d52 100644 --- a/telephony/common/com/google/android/mms/util/SqliteWrapper.java +++ b/telephony/common/com/google/android/mms/util/SqliteWrapper.java @@ -25,6 +25,7 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.net.Uri; +import android.os.Build; import android.util.Log; import android.widget.Toast; @@ -79,7 +80,7 @@ public final class SqliteWrapper { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean requery(Context context, Cursor cursor) { try { return cursor.requery(); diff --git a/telephony/framework-telephony-jarjar-rules.txt b/telephony/framework-telephony-jarjar-rules.txt deleted file mode 100644 index e1bb90194f69..000000000000 --- a/telephony/framework-telephony-jarjar-rules.txt +++ /dev/null @@ -1,10 +0,0 @@ -rule android.telephony.Annotation* android.telephony.framework.Annotation@1 -rule android.util.RecurrenceRule* android.telephony.RecurrenceRule@1 -rule com.android.i18n.phonenumbers.** com.android.telephony.framework.phonenumbers.@1 -rule com.android.internal.os.SomeArgs* android.telephony.SomeArgs@1 -rule com.android.internal.util.BitwiseInputStream* android.telephony.BitwiseInputStream@1 -rule com.android.internal.util.BitwiseOutputStream* android.telephony.BitwiseOutputStream@1 -rule com.android.internal.util.FunctionalUtils* android.telephony.FunctionalUtils@1 -rule com.android.internal.util.Preconditions* android.telephony.Preconditions@1 -rule com.android.internal.util.IndentingPrintWriter* android.telephony.IndentingPrintWriter@1 -rule com.android.internal.util.HexDump* android.telephony.HexDump@1 diff --git a/telephony/java/android/service/euicc/EuiccProfileInfo.java b/telephony/java/android/service/euicc/EuiccProfileInfo.java index 92e419707970..8ec500b4d49d 100644 --- a/telephony/java/android/service/euicc/EuiccProfileInfo.java +++ b/telephony/java/android/service/euicc/EuiccProfileInfo.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.service.carrier.CarrierIdentifier; @@ -146,7 +147,7 @@ public final class EuiccProfileInfo implements Parcelable { * @deprecated - Do not use. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public EuiccProfileInfo(String iccid, @Nullable UiccAccessRule[] accessRules, @Nullable String nickname) { if (!TextUtils.isDigitsOnly(iccid)) { diff --git a/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java b/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java index 2382f657c9ee..58e1d08a2009 100644 --- a/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java +++ b/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java @@ -18,6 +18,7 @@ package android.service.euicc; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.telephony.euicc.DownloadableSubscription; @@ -50,7 +51,7 @@ public final class GetDefaultDownloadableSubscriptionListResult implements Parce * @deprecated - Do no use. Use getResult() instead. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int result; @Nullable diff --git a/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java b/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java index d0fb51180c1d..6417c0dfcf05 100644 --- a/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java +++ b/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java @@ -18,6 +18,7 @@ package android.service.euicc; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.telephony.euicc.DownloadableSubscription; @@ -47,7 +48,7 @@ public final class GetDownloadableSubscriptionMetadataResult implements Parcelab * @deprecated - Do no use. Use getResult() instead. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final int result; @Nullable diff --git a/telephony/java/android/service/euicc/IDeleteSubscriptionCallback.aidl b/telephony/java/android/service/euicc/IDeleteSubscriptionCallback.aidl index aff8f1b7b346..a55f019bec23 100644 --- a/telephony/java/android/service/euicc/IDeleteSubscriptionCallback.aidl +++ b/telephony/java/android/service/euicc/IDeleteSubscriptionCallback.aidl @@ -18,6 +18,6 @@ package android.service.euicc; /** @hide */ oneway interface IDeleteSubscriptionCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onComplete(int result); }
\ No newline at end of file diff --git a/telephony/java/android/service/euicc/IEraseSubscriptionsCallback.aidl b/telephony/java/android/service/euicc/IEraseSubscriptionsCallback.aidl index 34b53cc71dfb..da26045be3ac 100644 --- a/telephony/java/android/service/euicc/IEraseSubscriptionsCallback.aidl +++ b/telephony/java/android/service/euicc/IEraseSubscriptionsCallback.aidl @@ -18,6 +18,6 @@ package android.service.euicc; /** @hide */ oneway interface IEraseSubscriptionsCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onComplete(int result); }
\ No newline at end of file diff --git a/telephony/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl b/telephony/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl index ad69ef132428..db73f8e0f0f4 100644 --- a/telephony/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl +++ b/telephony/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl @@ -20,6 +20,6 @@ import android.service.euicc.GetDefaultDownloadableSubscriptionListResult; /** @hide */ oneway interface IGetDefaultDownloadableSubscriptionListCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onComplete(in GetDefaultDownloadableSubscriptionListResult result); }
\ No newline at end of file diff --git a/telephony/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl b/telephony/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl index 01f187ed11e2..102ee3096c34 100644 --- a/telephony/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl +++ b/telephony/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl @@ -20,6 +20,6 @@ import android.service.euicc.GetDownloadableSubscriptionMetadataResult; /** @hide */ oneway interface IGetDownloadableSubscriptionMetadataCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onComplete(in GetDownloadableSubscriptionMetadataResult result); }
\ No newline at end of file diff --git a/telephony/java/android/service/euicc/IGetEidCallback.aidl b/telephony/java/android/service/euicc/IGetEidCallback.aidl index e405a981c85a..c47cf13f75c6 100644 --- a/telephony/java/android/service/euicc/IGetEidCallback.aidl +++ b/telephony/java/android/service/euicc/IGetEidCallback.aidl @@ -18,6 +18,6 @@ package android.service.euicc; /** @hide */ oneway interface IGetEidCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onSuccess(String eid); }
\ No newline at end of file diff --git a/telephony/java/android/service/euicc/IGetEuiccInfoCallback.aidl b/telephony/java/android/service/euicc/IGetEuiccInfoCallback.aidl index c0611825ff0f..291c058dfd2e 100644 --- a/telephony/java/android/service/euicc/IGetEuiccInfoCallback.aidl +++ b/telephony/java/android/service/euicc/IGetEuiccInfoCallback.aidl @@ -20,6 +20,6 @@ import android.telephony.euicc.EuiccInfo; /** @hide */ oneway interface IGetEuiccInfoCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onSuccess(in EuiccInfo euiccInfo); }
\ No newline at end of file diff --git a/telephony/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl b/telephony/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl index 0485f7be29d3..eadddb1193e8 100644 --- a/telephony/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl +++ b/telephony/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl @@ -20,6 +20,6 @@ import android.service.euicc.GetEuiccProfileInfoListResult; /** @hide */ oneway interface IGetEuiccProfileInfoListCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onComplete(in GetEuiccProfileInfoListResult result); }
\ No newline at end of file diff --git a/telephony/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl b/telephony/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl index 340401fe89cb..ade1ccdb6b06 100644 --- a/telephony/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl +++ b/telephony/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl @@ -18,6 +18,6 @@ package android.service.euicc; /** @hide */ oneway interface IRetainSubscriptionsForFactoryResetCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onComplete(int result); }
\ No newline at end of file diff --git a/telephony/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl b/telephony/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl index b8f984d1c28b..1b4b658f6211 100644 --- a/telephony/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl +++ b/telephony/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl @@ -18,6 +18,6 @@ package android.service.euicc; /** @hide */ oneway interface ISwitchToSubscriptionCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onComplete(int result); }
\ No newline at end of file diff --git a/telephony/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl b/telephony/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl index 0aa66978bb91..fda73497674c 100644 --- a/telephony/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl +++ b/telephony/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl @@ -18,6 +18,6 @@ package android.service.euicc; /** @hide */ oneway interface IUpdateSubscriptionNicknameCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onComplete(int result); }
\ No newline at end of file diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 157609130c1b..b806313e32f8 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -26,6 +26,7 @@ import android.annotation.SystemService; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; +import android.os.Build; import android.os.PersistableBundle; import android.os.RemoteException; import android.service.carrier.CarrierService; @@ -2723,7 +2724,7 @@ public class CarrierConfigManager { * Key identifying if voice call barring notification is required to be shown to the user. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL = "disable_voice_barring_notification_bool"; diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java index cfb9099a1c42..a3bec339794b 100644 --- a/telephony/java/android/telephony/CellIdentityGsm.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -21,6 +21,7 @@ import static android.text.TextUtils.formatSimple; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; @@ -58,7 +59,7 @@ public final class CellIdentityGsm extends CellIdentity { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CellIdentityGsm() { super(TAG, CellInfo.TYPE_GSM, null, null, null, null); mLac = CellInfo.UNAVAILABLE; diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index bbfab433be39..bd92d00a0321 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -67,7 +67,7 @@ public final class CellIdentityLte extends CellIdentity { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CellIdentityLte() { super(TAG, CellInfo.TYPE_LTE, null, null, null, null); mCi = CellInfo.UNAVAILABLE; diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java index 1bef681619ed..3ce99facfdb1 100644 --- a/telephony/java/android/telephony/CellInfoCdma.java +++ b/telephony/java/android/telephony/CellInfoCdma.java @@ -36,7 +36,7 @@ public final class CellInfoCdma extends CellInfo implements Parcelable { private CellSignalStrengthCdma mCellSignalStrengthCdma; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CellInfoCdma() { super(); mCellIdentityCdma = new CellIdentityCdma(); diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java index c19521fdfa99..e296e613362a 100644 --- a/telephony/java/android/telephony/CellInfoGsm.java +++ b/telephony/java/android/telephony/CellInfoGsm.java @@ -18,6 +18,7 @@ package android.telephony; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -35,7 +36,7 @@ public final class CellInfoGsm extends CellInfo implements Parcelable { private CellSignalStrengthGsm mCellSignalStrengthGsm; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CellInfoGsm() { super(); mCellIdentityGsm = new CellIdentityGsm(); diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java index 320925ea63ae..6f812341756b 100644 --- a/telephony/java/android/telephony/CellInfoLte.java +++ b/telephony/java/android/telephony/CellInfoLte.java @@ -39,7 +39,7 @@ public final class CellInfoLte extends CellInfo implements Parcelable { private CellConfigLte mCellConfig; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CellInfoLte() { super(); mCellIdentityLte = new CellIdentityLte(); diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java index 9d55f109f751..3ff859b55bdd 100644 --- a/telephony/java/android/telephony/CellSignalStrengthGsm.java +++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java @@ -53,7 +53,7 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P private int mLevel; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CellSignalStrengthGsm() { setDefaultValues(); } diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java index c26936e4bdd0..47a8f72a2337 100644 --- a/telephony/java/android/telephony/CellSignalStrengthLte.java +++ b/telephony/java/android/telephony/CellSignalStrengthLte.java @@ -18,6 +18,7 @@ package android.telephony; import android.annotation.IntRange; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; @@ -107,7 +108,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P private int mParametersUseForLevel; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public CellSignalStrengthLte() { setDefaultValues(); } diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index 92238420fd32..f8a200a5f8d3 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -369,7 +369,6 @@ public final class NetworkRegistrationInfo implements Parcelable { * Get the 5G NR connection state. * * @return the 5G NR connection state. - * @hide */ public @NRState int getNrState() { return mNrState; diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java index d4ed860cdafd..24dfbd028d03 100644 --- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java +++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java @@ -17,6 +17,7 @@ package android.telephony; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.text.Editable; import android.text.Selection; import android.text.TextWatcher; @@ -50,7 +51,7 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher { */ private boolean mStopFormatting; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private AsYouTypeFormatter mFormatter; /** diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 58e368bcc444..ed09d538a3b1 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -27,6 +27,7 @@ import android.content.Intent; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; +import android.os.Build; import android.os.PersistableBundle; import android.provider.Contacts; import android.provider.ContactsContract; @@ -1832,7 +1833,7 @@ public class PhoneNumberUtils { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Deprecated public static boolean isPotentialEmergencyNumber(int subId, String number) { // Check against the emergency numbers listed by the RIL / SIM, @@ -2108,7 +2109,7 @@ public class PhoneNumberUtils { * @hide */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isPotentialLocalEmergencyNumber(Context context, String number) { return isPotentialLocalEmergencyNumber(context, getDefaultVoiceSubId(), number); } @@ -2138,7 +2139,7 @@ public class PhoneNumberUtils { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Deprecated public static boolean isPotentialLocalEmergencyNumber(Context context, int subId, String number) { diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index fd9f46011c7e..9ea624b60988 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -73,7 +73,7 @@ public final class PreciseDataConnectionState implements Parcelable { */ @TestApi @Deprecated - @UnsupportedAppUsage // (maxTargetSdk = Build.VERSION_CODES.Q) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) // (maxTargetSdk = Build.VERSION_CODES.Q) // FIXME: figure out how to remove the UnsupportedAppUsage and delete this constructor public PreciseDataConnectionState(@DataState int state, @NetworkType int networkType, diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java index 90ddf2cd4730..f1e90118a559 100644 --- a/telephony/java/android/telephony/RadioAccessFamily.java +++ b/telephony/java/android/telephony/RadioAccessFamily.java @@ -92,7 +92,7 @@ public class RadioAccessFamily implements Parcelable { * {@link TelephonyManager.NetworkTypeBitMask}. It's a bit mask value to represent the support * type. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public RadioAccessFamily(int phoneId, int radioAccessFamily) { mPhoneId = phoneId; mRadioAccessFamily = radioAccessFamily; @@ -103,7 +103,7 @@ public class RadioAccessFamily implements Parcelable { * * @return phone ID */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getPhoneId() { return mPhoneId; } @@ -113,7 +113,7 @@ public class RadioAccessFamily implements Parcelable { * * @return radio access family */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @TelephonyManager.NetworkTypeBitMask int getRadioAccessFamily() { return mRadioAccessFamily; } @@ -168,7 +168,7 @@ public class RadioAccessFamily implements Parcelable { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TelephonyManager.NetworkTypeBitMask public static int getRafFromNetworkType(@PrefNetworkMode int type) { switch (type) { diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 3e7464739f9f..41b3ee672f46 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -956,7 +956,7 @@ public class ServiceState implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String rilRadioTechnologyToString(int rt) { String rtString; @@ -1167,7 +1167,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setVoiceRegState(int state) { mVoiceRegState = state; if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setVoiceRegState=" + mVoiceRegState); @@ -1198,7 +1198,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setVoiceRoaming(boolean roaming) { setVoiceRoamingType(roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING); } @@ -1219,7 +1219,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDataRoaming(boolean dataRoaming) { setDataRoamingType(dataRoaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING); } @@ -1291,7 +1291,7 @@ public class ServiceState implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setOperatorAlphaLong(@Nullable String longName) { mOperatorAlphaLong = longName; } @@ -1476,7 +1476,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getRilVoiceRadioTechnology() { NetworkRegistrationInfo wwanRegInfo = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); @@ -1486,7 +1486,7 @@ public class ServiceState implements Parcelable { return RIL_RADIO_TECHNOLOGY_UNKNOWN; } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getRilDataRadioTechnology() { return networkTypeToRilRadioTechnology(getDataNetworkType()); } @@ -1763,7 +1763,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean bitmaskHasTech(int bearerBitmask, int radioTech) { if (bearerBitmask == 0) { return true; @@ -1849,7 +1849,7 @@ public class ServiceState implements Parcelable { * voice SS. The voice SS is only used if it is IN_SERVICE (otherwise the base SS is returned). * @hide * */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static ServiceState mergeServiceStates(ServiceState baseSs, ServiceState voiceSs) { if (voiceSs.mVoiceRegState != STATE_IN_SERVICE) { return baseSs; diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 2b17de64dae9..964cf76d17f6 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -591,7 +591,7 @@ public final class SmsManager { * @throws IllegalArgumentException if destinationAddress or text are empty * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void sendTextMessage( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index 717a9b155cbf..cfb29f124b43 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -29,6 +29,7 @@ import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.os.Binder; +import android.os.Build; import android.text.TextUtils; import com.android.internal.telephony.GsmAlphabet; @@ -133,7 +134,7 @@ public class SmsMessage { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mSubId = 0; /** set Subscription information @@ -1054,7 +1055,7 @@ public class SmsMessage { * * @return true if Cdma format should be used for MO SMS, false otherwise. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static boolean useCdmaFormatForMoSms(int subId) { SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId); if (!smsManager.isImsSmsSupported()) { diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index 2547392d2c1f..6441565d731b 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -32,6 +32,7 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.Typeface; +import android.os.Build; import android.os.Parcel; import android.os.ParcelUuid; import android.os.Parcelable; @@ -356,7 +357,7 @@ public class SubscriptionInfo implements Parcelable { * Sets the name displayed to the user that identifies this subscription * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDisplayName(CharSequence name) { this.mDisplayName = name; } @@ -381,7 +382,7 @@ public class SubscriptionInfo implements Parcelable { * NAME_SOURCE_USER_INPUT. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getNameSource() { return this.mNameSource; } @@ -448,7 +449,7 @@ public class SubscriptionInfo implements Parcelable { * Sets the color displayed to the user that identifies this subscription * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setIconTint(int iconTint) { this.mIconTint = iconTint; } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 2e51ef16baf1..7f87019dbbe2 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -127,7 +127,7 @@ public class SubscriptionManager { public static final int MAX_SUBSCRIPTION_ID_VALUE = DEFAULT_SUBSCRIPTION_ID - 1; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Uri CONTENT_URI = SimInfo.CONTENT_URI; /** @hide */ @@ -1826,7 +1826,7 @@ public class SubscriptionManager { * @return the number of records updated * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int setDisplayNumber(String number, int subId) { if (number == null) { logd("[setDisplayNumber]- fail"); @@ -1844,7 +1844,7 @@ public class SubscriptionManager { * @return the number of records updated * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int setDataRoaming(int roaming, int subId) { if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId); return setSubscriptionPropertyHelper(subId, "setDataRoaming", @@ -1989,13 +1989,13 @@ public class SubscriptionManager { * @return the SubscriptionInfo for the default voice subscription. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public SubscriptionInfo getDefaultVoiceSubscriptionInfo() { return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId()); } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int getDefaultVoicePhoneId() { return getPhoneId(getDefaultVoiceSubscriptionId()); } @@ -2047,7 +2047,7 @@ public class SubscriptionManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getDefaultSmsPhoneId() { return getPhoneId(getDefaultSmsSubscriptionId()); } @@ -2181,7 +2181,7 @@ public class SubscriptionManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean isValidPhoneId(int phoneId) { return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount(); } @@ -2200,7 +2200,7 @@ public class SubscriptionManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) { if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId); intent.putExtra(EXTRA_SLOT_INDEX, phoneId); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 20eeb1da0d99..556e0b2b4096 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -2807,7 +2807,7 @@ public class TelephonyManager { /** Current network is IWLAN */ public static final int NETWORK_TYPE_IWLAN = TelephonyProtoEnums.NETWORK_TYPE_IWLAN; // = 18. /** Current network is LTE_CA {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int NETWORK_TYPE_LTE_CA = TelephonyProtoEnums.NETWORK_TYPE_LTE_CA; // = 19. /** * Current network is NR (New Radio) 5G. @@ -6772,7 +6772,7 @@ public class TelephonyManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean nvResetConfig(int resetType) { try { ITelephony telephony = getITelephony(); @@ -7041,7 +7041,7 @@ public class TelephonyManager { * @return The value at the given index of settings. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int getIntAtIndex(android.content.ContentResolver cr, String name, int index) throws android.provider.Settings.SettingNotFoundException { @@ -7074,7 +7074,7 @@ public class TelephonyManager { * @return true if the value was set, false on database errors * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static boolean putIntAtIndex(android.content.ContentResolver cr, String name, int index, int value) { String data = ""; @@ -7146,7 +7146,7 @@ public class TelephonyManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static String getTelephonyProperty(String property, String defaultVal) { String propVal = SystemProperties.get(property); return TextUtils.isEmpty(propVal) ? defaultVal : propVal; @@ -7445,7 +7445,7 @@ public class TelephonyManager { * Corresponds to features defined in ImsFeature. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable IImsRegistration getImsRegistration(int slotIndex, int feature) { try { ITelephony telephony = getITelephony(); @@ -7465,7 +7465,7 @@ public class TelephonyManager { * Corresponds to features defined in ImsFeature. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @Nullable IImsConfig getImsConfig(int slotIndex, int feature) { try { ITelephony telephony = getITelephony(); @@ -7484,7 +7484,7 @@ public class TelephonyManager { * @param Registration state * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setImsRegistrationState(boolean registered) { try { ITelephony telephony = getITelephony(); @@ -8151,7 +8151,7 @@ public class TelephonyManager { * @deprecated Use {@link #setPreferredNetworkTypeBitmask} instead. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean setPreferredNetworkType(int subId, @PrefNetworkMode int networkType) { try { ITelephony telephony = getITelephony(); @@ -8525,7 +8525,7 @@ public class TelephonyManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList) { @@ -9815,7 +9815,7 @@ public class TelephonyManager { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setSimOperatorNumericForPhone(int phoneId, String numeric) { if (SubscriptionManager.isValidPhoneId(phoneId)) { List<String> newList = updateTelephonyProperty( @@ -10187,7 +10187,7 @@ public class TelephonyManager { * @param name the alphabetic name of current registered operator. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setNetworkOperatorNameForPhone(int phoneId, String name) { if (SubscriptionManager.isValidPhoneId(phoneId)) { List<String> newList = updateTelephonyProperty( @@ -10212,7 +10212,7 @@ public class TelephonyManager { * @param operator the numeric name (MCC+MNC) of current registered operator * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setNetworkOperatorNumericForPhone(int phoneId, String numeric) { if (SubscriptionManager.isValidPhoneId(phoneId)) { List<String> newList = updateTelephonyProperty( @@ -10237,7 +10237,7 @@ public class TelephonyManager { * @param isRoaming is network in romaing state or not * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setNetworkRoamingForPhone(int phoneId, boolean isRoaming) { if (SubscriptionManager.isValidPhoneId(phoneId)) { List<Boolean> newList = updateTelephonyProperty( @@ -10266,7 +10266,7 @@ public class TelephonyManager { * @param type the network type currently in use on the device for data transmission * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setDataNetworkTypeForPhone(int phoneId, int type) { if (SubscriptionManager.isValidPhoneId(phoneId)) { List<String> newList = updateTelephonyProperty( @@ -10571,6 +10571,9 @@ public class TelephonyManager { * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()} * + * If you want continuous updates of service state info, register a {@link PhoneStateListener} + * via {@link #listen} with the {@link PhoneStateListener#LISTEN_SERVICE_STATE} event. + * * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}) * and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. @@ -13672,6 +13675,149 @@ public class TelephonyManager { } } + /** + * No error. Operation succeeded. + * @hide + */ + @SystemApi + public static final int ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS = 0; + + /** + * NR Dual connectivity enablement is not supported. + * @hide + */ + @SystemApi + public static final int ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED = 1; + + /** + * Radio is not available. + * @hide + */ + @SystemApi + public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE = 2; + + /** + * Internal Radio error. + * @hide + */ + @SystemApi + public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR = 3; + + /** + * Currently in invalid state. Not able to process the request. + * @hide + */ + @SystemApi + public static final int ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE = 4; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"ENABLE_NR_DUAL_CONNECTIVITY"}, value = { + ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS, + ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED, + ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE, + ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE, + ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR}) + public @interface EnableNrDualConnectivityResult {} + + /** + * Enable NR dual connectivity. Enabled state does not mean dual connectivity + * is active. It means device is allowed to connect to both primary and secondary. + * + * @hide + */ + @SystemApi + public static final int NR_DUAL_CONNECTIVITY_ENABLE = 1; + + /** + * Disable NR dual connectivity. Disabled state does not mean the secondary cell is released. + * Modem will release it only if the current bearer is released to avoid radio link failure. + * @hide + */ + @SystemApi + public static final int NR_DUAL_CONNECTIVITY_DISABLE = 2; + + /** + * Disable NR dual connectivity and force the secondary cell to be released if dual connectivity + * was active. This will result in radio link failure. + * @hide + */ + @SystemApi + public static final int NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE = 3; + + /** + * @hide + */ + @IntDef(prefix = { "NR_DUAL_CONNECTIVITY_" }, value = { + NR_DUAL_CONNECTIVITY_ENABLE, + NR_DUAL_CONNECTIVITY_DISABLE, + NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NrDualConnectivityState { + } + + /** + * Enable/Disable E-UTRA-NR Dual Connectivity. + * + * @param nrDualConnectivityState expected NR dual connectivity state + * This can be passed following states + * <ol> + * <li>Enable NR dual connectivity {@link #NR_DUAL_CONNECTIVITY_ENABLE} + * <li>Disable NR dual connectivity {@link #NR_DUAL_CONNECTIVITY_DISABLE} + * <li>Disable NR dual connectivity and force secondary cell to be released + * {@link #NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE} + * </ol> + * @return operation result. + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * @throws IllegalStateException if the Telephony process is not currently available. + * @hide + */ + @SystemApi + public @EnableNrDualConnectivityResult int setNrDualConnectivityState( + @NrDualConnectivityState int nrDualConnectivityState) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.setNrDualConnectivityState(getSubId(), nrDualConnectivityState); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "setNrDualConnectivityState RemoteException", ex); + ex.rethrowFromSystemServer(); + } + + return ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE; + } + + /** + * Is E-UTRA-NR Dual Connectivity enabled. + * @return true if dual connectivity is enabled else false. Enabled state does not mean dual + * connectivity is active. It means the device is allowed to connect to both primary and + * secondary cell. + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} + * @throws IllegalStateException if the Telephony process is not currently available. + * @hide + */ + @SystemApi + public boolean isNrDualConnectivityEnabled() { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.isNrDualConnectivityEnabled(getSubId()); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "isNRDualConnectivityEnabled RemoteException", ex); + ex.rethrowFromSystemServer(); + } + return false; + } + private static class DeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 41381c59482b..3e2a6eec37c4 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -109,8 +109,14 @@ public final class DataCallResponse implements Parcelable { */ public static final int HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL = 3; + /** + * Indicates that data retry interval is not specified. Platform can determine when to + * perform data setup appropriately. + */ + public static final int RETRY_INTERVAL_UNDEFINED = -1; + private final @DataFailureCause int mCause; - private final int mSuggestedRetryTime; + private final long mSuggestedRetryTime; private final int mId; private final @LinkStatus int mLinkStatus; private final @ProtocolType int mProtocolType; @@ -172,7 +178,7 @@ public final class DataCallResponse implements Parcelable { mHandoverFailureMode = HANDOVER_FAILURE_MODE_LEGACY; } - private DataCallResponse(@DataFailureCause int cause, int suggestedRetryTime, int id, + private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id, @LinkStatus int linkStatus, @ProtocolType int protocolType, @Nullable String interfaceName, @Nullable List<LinkAddress> addresses, @Nullable List<InetAddress> dnsAddresses, @Nullable List<InetAddress> gatewayAddresses, @@ -202,7 +208,7 @@ public final class DataCallResponse implements Parcelable { @VisibleForTesting public DataCallResponse(Parcel source) { mCause = source.readInt(); - mSuggestedRetryTime = source.readInt(); + mSuggestedRetryTime = source.readLong(); mId = source.readInt(); mLinkStatus = source.readInt(); mProtocolType = source.readInt(); @@ -229,8 +235,22 @@ public final class DataCallResponse implements Parcelable { /** * @return The suggested data retry time in milliseconds. + * + * @deprecated Use {@link #getRetryIntervalMillis()} instead. + */ + @Deprecated + public int getSuggestedRetryTime() { + return (int) mSuggestedRetryTime; + } + + /** + * @return The network suggested data retry interval in milliseconds. {@code Long.MAX_VALUE} + * indicates data retry should not occur. {@link #RETRY_INTERVAL_UNDEFINED} indicates network + * did not suggest any retry interval. */ - public int getSuggestedRetryTime() { return mSuggestedRetryTime; } + public long getRetryIntervalMillis() { + return mSuggestedRetryTime; + } /** * @return The unique id of the data connection. @@ -382,7 +402,7 @@ public final class DataCallResponse implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mCause); - dest.writeInt(mSuggestedRetryTime); + dest.writeLong(mSuggestedRetryTime); dest.writeInt(mId); dest.writeInt(mLinkStatus); dest.writeInt(mProtocolType); @@ -446,7 +466,7 @@ public final class DataCallResponse implements Parcelable { public static final class Builder { private @DataFailureCause int mCause; - private int mSuggestedRetryTime; + private long mSuggestedRetryTime = RETRY_INTERVAL_UNDEFINED; private int mId; @@ -494,9 +514,23 @@ public final class DataCallResponse implements Parcelable { * * @param suggestedRetryTime The suggested data retry time in milliseconds. * @return The same instance of the builder. + * + * @deprecated Use {@link #setRetryIntervalMillis(long)} instead. */ + @Deprecated public @NonNull Builder setSuggestedRetryTime(int suggestedRetryTime) { - mSuggestedRetryTime = suggestedRetryTime; + mSuggestedRetryTime = (long) suggestedRetryTime; + return this; + } + + /** + * Set the network suggested data retry interval. + * + * @param retryIntervalMillis The suggested data retry interval in milliseconds. + * @return The same instance of the builder. + */ + public @NonNull Builder setRetryIntervalMillis(long retryIntervalMillis) { + mSuggestedRetryTime = retryIntervalMillis; return this; } diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.java b/telephony/java/android/telephony/euicc/DownloadableSubscription.java index 23d46ba09599..52b31d7f9611 100644 --- a/telephony/java/android/telephony/euicc/DownloadableSubscription.java +++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.java @@ -19,6 +19,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.PendingIntent; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.telephony.UiccAccessRule; @@ -61,7 +62,7 @@ public final class DownloadableSubscription implements Parcelable { */ @Nullable @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final String encodedActivationCode; @Nullable private String confirmationCode; @@ -191,7 +192,7 @@ public final class DownloadableSubscription implements Parcelable { * @deprecated - Do not use. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setCarrierName(String carrierName) { this.carrierName = carrierName; } @@ -238,7 +239,7 @@ public final class DownloadableSubscription implements Parcelable { * @deprecated - Do not use. */ @Deprecated - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setAccessRules(UiccAccessRule[] accessRules) { this.accessRules = Arrays.asList(accessRules); } diff --git a/telephony/java/android/telephony/euicc/EuiccInfo.java b/telephony/java/android/telephony/euicc/EuiccInfo.java index 467d2689cd3c..08de2051975e 100644 --- a/telephony/java/android/telephony/euicc/EuiccInfo.java +++ b/telephony/java/android/telephony/euicc/EuiccInfo.java @@ -17,6 +17,7 @@ package android.telephony.euicc; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -44,7 +45,7 @@ public final class EuiccInfo implements Parcelable { }; @Nullable - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final String osVersion; /** diff --git a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java index 3f9c8d26ca91..1c2cac27eb37 100644 --- a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java +++ b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -128,26 +129,26 @@ public final class ImsCallForwardInfo implements Parcelable { public @interface TypeOfAddress{} /**@hide*/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @CallForwardReasons int mCondition; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @CallForwardStatus int mStatus; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @TypeOfAddress int mToA; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @ImsSsData.ServiceClassFlags int mServiceClass; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String mNumber; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mTimeSeconds; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ImsCallForwardInfo() { } diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index 47a0ab61f970..5b54719afbfb 100644 --- a/telephony/java/android/telephony/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -356,10 +357,10 @@ public final class ImsCallProfile implements Parcelable { /** @hide */ public int mServiceType; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mCallType; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public @CallRestrictCause int mRestrictCause = CALL_RESTRICT_CAUSE_NONE; /** @@ -467,10 +468,10 @@ public final class ImsCallProfile implements Parcelable { * a {@link android.os.Binder}. */ /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Bundle mCallExtras; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ImsStreamMediaProfile mMediaProfile; /** @hide */ @@ -823,7 +824,7 @@ public final class ImsCallProfile implements Parcelable { * See {@link #presentationToOir(int)}. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int presentationToOIR(int presentation) { switch (presentation) { case PhoneConstants.PRESENTATION_RESTRICTED: diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java index 30389a290368..184477af0b46 100644 --- a/telephony/java/android/telephony/ims/ImsReasonInfo.java +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -1353,7 +1353,7 @@ public final class ImsReasonInfo implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ImsReasonInfo(int code, int extraCode) { mCode = code; mExtraCode = extraCode; diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java index 27b56b8c5b47..bc53b628131e 100644 --- a/telephony/java/android/telephony/ims/ImsSsInfo.java +++ b/telephony/java/android/telephony/ims/ImsSsInfo.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -155,10 +156,10 @@ public final class ImsSsInfo implements Parcelable { // 0: disabled, 1: enabled /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mStatus; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String mIcbNum; /** @hide */ public int mProvisionStatus = SERVICE_PROVISIONING_UNKNOWN; @@ -166,7 +167,7 @@ public final class ImsSsInfo implements Parcelable { private int mClirOutgoingState = CLIR_OUTGOING_DEFAULT; /**@hide*/ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ImsSsInfo() { } diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java index 131cb1a505fb..2792f790e13b 100644 --- a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java +++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java @@ -19,6 +19,7 @@ package android.telephony.ims; import android.annotation.NonNull; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -84,16 +85,16 @@ public final class ImsStreamMediaProfile implements Parcelable { // Audio related information /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mAudioQuality; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mAudioDirection; // Video related information /** @hide */ public int mVideoQuality; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mVideoDirection; // Rtt related information /** @hide */ @@ -164,7 +165,7 @@ public final class ImsStreamMediaProfile implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ImsStreamMediaProfile() { mAudioQuality = AUDIO_QUALITY_NONE; mAudioDirection = DIRECTION_SEND_RECEIVE; diff --git a/telephony/java/android/telephony/ims/ImsVideoCallProvider.java b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java index 2fca4096f447..64bdcbba265a 100644 --- a/telephony/java/android/telephony/ims/ImsVideoCallProvider.java +++ b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java @@ -19,6 +19,7 @@ package android.telephony.ims; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.net.Uri; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -179,7 +180,7 @@ public abstract class ImsVideoCallProvider { * Returns binder object which can be used across IPC methods. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final IImsVideoCallProvider getInterface() { return mBinder; } diff --git a/telephony/java/android/telephony/ims/compat/ImsService.java b/telephony/java/android/telephony/ims/compat/ImsService.java index 41d1d726b3f4..303ba183c12e 100644 --- a/telephony/java/android/telephony/ims/compat/ImsService.java +++ b/telephony/java/android/telephony/ims/compat/ImsService.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.app.Service; import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; +import android.os.Build; import android.os.IBinder; import android.telephony.CarrierConfigManager; import android.telephony.ims.compat.feature.ImsFeature; @@ -86,7 +87,7 @@ public class ImsService extends Service { /** * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected final IBinder mImsServiceController = new IImsServiceController.Stub() { @Override @@ -122,7 +123,7 @@ public class ImsService extends Service { } }; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ImsService() { } diff --git a/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java b/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java index 5a9e8e2dafc4..6038a18a28b1 100644 --- a/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java @@ -19,6 +19,7 @@ package android.telephony.ims.compat.feature; import android.annotation.IntDef; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.IInterface; import android.os.RemoteException; import android.telephony.SubscriptionManager; @@ -78,12 +79,12 @@ public abstract class ImsFeature { mSlotId = slotId; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getFeatureState() { return mState; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected final void setFeatureState(@ImsState int state) { if (mState != state) { mState = state; diff --git a/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java index b52c37106049..d32e9b7f5122 100644 --- a/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java +++ b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java @@ -18,6 +18,7 @@ package android.telephony.ims.compat.feature; import android.app.PendingIntent; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Message; import android.os.RemoteException; import android.telephony.ims.ImsCallProfile; @@ -48,7 +49,7 @@ public class MMTelFeature extends ImsFeature { // Lock for feature synchronization private final Object mLock = new Object(); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public MMTelFeature() { } diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java index 06aa6428b1b2..4b8f39817f88 100755 --- a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java @@ -19,6 +19,7 @@ package android.telephony.ims.compat.stub; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Message; import android.os.RemoteException; import android.telephony.CallQuality; @@ -45,7 +46,7 @@ import com.android.ims.internal.IImsVideoCallProvider; public class ImsCallSessionImplBase extends IImsCallSession.Stub { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ImsCallSessionImplBase() { } diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java index 0c7264697cd3..a8278ae0d734 100644 --- a/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java @@ -19,6 +19,7 @@ package android.telephony.ims.compat.stub; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; +import android.os.Build; import android.os.RemoteException; import android.util.Log; @@ -59,7 +60,7 @@ public class ImsConfigImplBase { ImsConfigStub mImsConfigStub; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ImsConfigImplBase(Context context) { mImsConfigStub = new ImsConfigStub(this, context); } @@ -164,7 +165,7 @@ public class ImsConfigImplBase { public void setVideoQuality(int quality, ImsConfigListener listener) throws RemoteException { } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public IImsConfig getIImsConfig() { return mImsConfigStub; } /** diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java index ce291d4d14c6..c689460a5cec 100644 --- a/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java @@ -17,6 +17,7 @@ package android.telephony.ims.compat.stub; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Bundle; import android.os.RemoteException; import android.telephony.ims.ImsCallForwardInfo; @@ -40,7 +41,7 @@ import com.android.ims.internal.IImsUtListener; public class ImsUtListenerImplBase extends IImsUtListener.Stub { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ImsUtListenerImplBase() { } diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl index c140127237d4..a4abfac74177 100755 --- a/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl +++ b/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl @@ -26,17 +26,17 @@ import android.telephony.mbms.StreamingServiceInfo; */ interface IMbmsStreamingService { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int initialize(IMbmsStreamingSessionCallback callback, int subId); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int requestUpdateStreamingServices(int subId, in List<String> serviceClasses); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) int startStreaming(int subId, String serviceId, IStreamingServiceCallback callback); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Uri getPlaybackUri(int subId, String serviceId); void stopStreaming(int subId, String serviceId); diff --git a/telephony/java/com/android/ims/ImsConfigListener.aidl b/telephony/java/com/android/ims/ImsConfigListener.aidl index 4f229df252a6..df8144c15d77 100644 --- a/telephony/java/com/android/ims/ImsConfigListener.aidl +++ b/telephony/java/com/android/ims/ImsConfigListener.aidl @@ -47,7 +47,7 @@ oneway interface ImsConfigListener { * * @return void. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void onSetFeatureResponse(int feature, int network, int value, int status); /** diff --git a/telephony/java/com/android/ims/ImsUtInterface.java b/telephony/java/com/android/ims/ImsUtInterface.java index 4a5380e4551b..5dfbce3dd65f 100644 --- a/telephony/java/com/android/ims/ImsUtInterface.java +++ b/telephony/java/com/android/ims/ImsUtInterface.java @@ -17,6 +17,7 @@ package com.android.ims; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Handler; import android.os.Message; import android.telephony.ims.ImsCallForwardInfo; @@ -124,7 +125,7 @@ public interface ImsUtInterface { * Retrieves the configuration of the call forward. * The return value of ((AsyncResult)result.obj) is an array of {@link ImsCallForwardInfo}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void queryCallForward(int condition, String number, Message result); /** diff --git a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl index 1c62cc48093c..8afd85633322 100644 --- a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl @@ -34,47 +34,47 @@ oneway interface IImsCallSessionListener { /** * Notifies the result of the basic session operation (setup / terminate). */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionProgressing(in IImsCallSession session, in ImsStreamMediaProfile profile); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionStarted(in IImsCallSession session, in ImsCallProfile profile); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionStartFailed(in IImsCallSession session, in ImsReasonInfo reasonInfo); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionTerminated(in IImsCallSession session, in ImsReasonInfo reasonInfo); /** * Notifies the result of the call hold/resume operation. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionHeld(in IImsCallSession session, in ImsCallProfile profile); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionHoldFailed(in IImsCallSession session, in ImsReasonInfo reasonInfo); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionHoldReceived(in IImsCallSession session, in ImsCallProfile profile); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionResumed(in IImsCallSession session, in ImsCallProfile profile); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionResumeFailed(in IImsCallSession session, in ImsReasonInfo reasonInfo); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionResumeReceived(in IImsCallSession session, in ImsCallProfile profile); /** * Notifies the result of call merge operation. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionMergeStarted(in IImsCallSession session, in IImsCallSession newSession, in ImsCallProfile profile); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionMergeComplete(in IImsCallSession session); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionMergeFailed(in IImsCallSession session, in ImsReasonInfo reasonInfo); /** * Notifies the result of call upgrade / downgrade or any other call updates. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionUpdated(in IImsCallSession session, in ImsCallProfile profile); void callSessionUpdateFailed(in IImsCallSession session, @@ -95,9 +95,9 @@ oneway interface IImsCallSessionListener { /** * Notifies the result of the participant invitation / removal to/from the conference session. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionInviteParticipantsRequestDelivered(in IImsCallSession session); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionInviteParticipantsRequestFailed(in IImsCallSession session, in ImsReasonInfo reasonInfo); void callSessionRemoveParticipantsRequestDelivered(in IImsCallSession session); @@ -107,7 +107,7 @@ oneway interface IImsCallSessionListener { /** * Notifies the changes of the conference info. in the conference session. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionConferenceStateUpdated(in IImsCallSession session, in ImsConferenceState state); @@ -120,10 +120,10 @@ oneway interface IImsCallSessionListener { /** * Notifies of handover information for this call */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionHandover(in IImsCallSession session, in int srcAccessTech, in int targetAccessTech, in ImsReasonInfo reasonInfo); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionHandoverFailed(in IImsCallSession session, in int srcAccessTech, in int targetAccessTech, in ImsReasonInfo reasonInfo); void callSessionMayHandover(in IImsCallSession session, @@ -137,7 +137,7 @@ oneway interface IImsCallSessionListener { * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionTtyModeReceived(in IImsCallSession session, in int mode); /** @@ -146,13 +146,13 @@ oneway interface IImsCallSessionListener { * @param session The call session. * @param isMultiParty {@code true} if the session became multiparty, {@code false} otherwise. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionMultipartyStateChanged(in IImsCallSession session, in boolean isMultiParty); /** * Notifies the supplementary service information for the current session. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void callSessionSuppServiceReceived(in IImsCallSession session, in ImsSuppServiceNotification suppSrvNotification); diff --git a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl index a7a62a625478..216b45c37458 100644 --- a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl @@ -32,7 +32,7 @@ oneway interface IImsRegistrationListener { * * @deprecated see {@link registrationConnectedWithRadioTech} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void registrationConnected(); /** @@ -48,7 +48,7 @@ oneway interface IImsRegistrationListener { * @param imsRadioTech the radio access technology. Valid values are {@code * RIL_RADIO_TECHNOLOGY_*} defined in {@link ServiceState}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void registrationConnectedWithRadioTech(int imsRadioTech); /** @@ -57,14 +57,14 @@ oneway interface IImsRegistrationListener { * @param imsRadioTech the radio access technology. Valid values are {@code * RIL_RADIO_TECHNOLOGY_*} defined in {@link ServiceState}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void registrationProgressingWithRadioTech(int imsRadioTech); /** * Notifies the application when the device is disconnected from the IMS network. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void registrationDisconnected(in ImsReasonInfo imsReasonInfo); /** @@ -98,7 +98,7 @@ oneway interface IImsRegistrationListener { * @param enabledFeatures features enabled as defined in com.android.ims.ImsConfig#FeatureConstants. * @param disabledFeatures features disabled as defined in com.android.ims.ImsConfig#FeatureConstants. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void registrationFeatureCapabilityChanged(int serviceClass, in int[] enabledFeatures, in int[] disabledFeatures); @@ -106,13 +106,13 @@ oneway interface IImsRegistrationListener { * Updates the application with the waiting voice message count. * @param count The number of waiting voice messages. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void voiceMessageCountUpdate(int count); /** * Notifies the application when the list of URIs associated with IMS client is updated. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void registrationAssociatedUriChanged(in Uri[] uris); /** @@ -123,6 +123,6 @@ oneway interface IImsRegistrationListener { * attempted. * @param imsReasonInfo Reason for the failure. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void registrationChangeFailed(in int targetAccessTech, in ImsReasonInfo imsReasonInfo); } diff --git a/telephony/java/com/android/ims/internal/IImsUtListener.aidl b/telephony/java/com/android/ims/internal/IImsUtListener.aidl index 9a12ceee5212..604adf84817b 100644 --- a/telephony/java/com/android/ims/internal/IImsUtListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsUtListener.aidl @@ -31,38 +31,38 @@ oneway interface IImsUtListener { /** * Notifies the result of the supplementary service configuration udpate. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void utConfigurationUpdated(in IImsUt ut, int id); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void utConfigurationUpdateFailed(in IImsUt ut, int id, in ImsReasonInfo error); /** * Notifies the result of the supplementary service configuration query. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void utConfigurationQueried(in IImsUt ut, int id, in Bundle ssInfo); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void utConfigurationQueryFailed(in IImsUt ut, int id, in ImsReasonInfo error); void lineIdentificationSupplementaryServiceResponse(int id, in ImsSsInfo config); /** * Notifies the status of the call barring supplementary service. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void utConfigurationCallBarringQueried(in IImsUt ut, int id, in ImsSsInfo[] cbInfo); /** * Notifies the status of the call forwarding supplementary service. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void utConfigurationCallForwardQueried(in IImsUt ut, int id, in ImsCallForwardInfo[] cfInfo); /** * Notifies the status of the call waiting supplementary service. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void utConfigurationCallWaitingQueried(in IImsUt ut, int id, in ImsSsInfo[] cwInfo); diff --git a/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl b/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl index cf8d63794546..5d575abda979 100644 --- a/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl +++ b/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl @@ -31,25 +31,25 @@ import android.telecom.VideoProfile; * {@hide} */ oneway interface IImsVideoCallCallback { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void receiveSessionModifyRequest(in VideoProfile videoProfile); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void receiveSessionModifyResponse(int status, in VideoProfile requestedProfile, in VideoProfile responseProfile); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void handleCallSessionEvent(int event); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void changePeerDimensions(int width, int height); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void changeCallDataUsage(long dataUsage); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void changeCameraCapabilities(in VideoProfile.CameraCapabilities cameraCapabilities); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void changeVideoQuality(int videoQuality); } diff --git a/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl b/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl index 4d20bd675628..44d83897390a 100644 --- a/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl +++ b/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl @@ -41,7 +41,7 @@ import com.android.ims.internal.IImsVideoCallCallback; * @hide */ oneway interface IImsVideoCallProvider { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void setCallback(IImsVideoCallCallback callback); void setCamera(String cameraId, int uid); diff --git a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl index 76ebc0f3ac2f..89620eaaf609 100644 --- a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl +++ b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl @@ -24,7 +24,7 @@ import android.os.PersistableBundle; interface ICarrierConfigLoader { /** @deprecated Use {@link #getConfigForSubIdWithFeature(int, String, String) instead */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) PersistableBundle getConfigForSubId(int subId, String callingPackage); PersistableBundle getConfigForSubIdWithFeature(int subId, String callingPackage, diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl index 28ef235bf398..09f9b4212c03 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl @@ -25,7 +25,7 @@ import android.telephony.ImsiEncryptionInfo; interface IPhoneSubInfo { /** @deprecated Use {@link #getDeviceIdWithFeature(String, String) instead */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String getDeviceId(String callingPackage); /** diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 0d8351d1ff12..a38d5b6f2141 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -96,7 +96,7 @@ interface ITelephony { void call(String callingPackage, String number); /** @deprecated Use {@link #isRadioOnWithFeature(String, String) instead */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isRadioOn(String callingPackage); /** @@ -110,7 +110,7 @@ interface ITelephony { /** * @deprecated Use {@link #isRadioOnForSubscriberWithFeature(int, String, String) instead */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean isRadioOnForSubscriber(int subId, String callingPackage); /** @@ -190,7 +190,7 @@ interface ITelephony { * @param subId user preferred subId. * @return true if MMI command is executed. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean handlePinMmiForSubscriber(int subId, String dialString); /** @@ -614,7 +614,7 @@ interface ITelephony { * successful iccOpenLogicalChannel. * @return true if the channel was closed successfully. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) boolean iccCloseLogicalChannel(int subId, int channel); /** @@ -656,7 +656,7 @@ interface ITelephony { * @return The APDU response from the ICC card with the status appended at * the end. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) String iccTransmitApduLogicalChannel(int subId, int channel, int cla, int instruction, int p1, int p2, int p3, String data); @@ -2216,4 +2216,20 @@ interface ITelephony { * does not exist on the SIM card. */ List<String> getEquivalentHomePlmns(int subId, String callingPackage, String callingFeatureId); + + /** + * Enable/Disable E-UTRA-NR Dual Connectivity + * @return operation result. See TelephonyManager.EnableNrDualConnectivityResult for + * details + * @param subId the id of the subscription + * @param enable enable/disable dual connectivity + */ + int setNrDualConnectivityState(int subId, int nrDualConnectivityState); + + /** + * Is E-UTRA-NR Dual Connectivity enabled + * @param subId the id of the subscription + * @return true if dual connectivity is enabled else false + */ + boolean isNrDualConnectivityEnabled(int subId); } diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java index 2ca459811e04..a6f0f667d0cd 100644 --- a/telephony/java/com/android/internal/telephony/OperatorInfo.java +++ b/telephony/java/com/android/internal/telephony/OperatorInfo.java @@ -35,37 +35,37 @@ public class OperatorInfo implements Parcelable { FORBIDDEN; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String mOperatorAlphaLong; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String mOperatorAlphaShort; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String mOperatorNumeric; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private State mState = State.UNKNOWN; private int mRan = AccessNetworkType.UNKNOWN; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getOperatorAlphaLong() { return mOperatorAlphaLong; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getOperatorAlphaShort() { return mOperatorAlphaShort; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String getOperatorNumeric() { return mOperatorNumeric; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public State getState() { return mState; @@ -75,7 +75,7 @@ public class OperatorInfo implements Parcelable { return mRan; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) OperatorInfo(String operatorAlphaLong, String operatorAlphaShort, String operatorNumeric, @@ -97,7 +97,7 @@ public class OperatorInfo implements Parcelable { mRan = ran; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public OperatorInfo(String operatorAlphaLong, String operatorAlphaShort, String operatorNumeric, @@ -124,7 +124,7 @@ public class OperatorInfo implements Parcelable { /** * See state strings defined in ril.h RIL_REQUEST_QUERY_AVAILABLE_NETWORKS */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static State rilStateToState(String s) { if (s.equals("unknown")) { return State.UNKNOWN; @@ -180,7 +180,7 @@ public class OperatorInfo implements Parcelable { * Implement the Parcelable interface * Method to deserialize a OperatorInfo object, or an array thereof. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final Creator<OperatorInfo> CREATOR = new Creator<OperatorInfo>() { @Override diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index d524299d7ede..953a2924dc44 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -494,6 +494,8 @@ public interface RILConstants { int RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS = 210; int RIL_REQUEST_GET_BARRING_INFO = 211; int RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION = 212; + int RIL_REQUEST_ENABLE_NR_DUAL_CONNECTIVITY = 213; + int RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED = 214; /* Responses begin */ int RIL_RESPONSE_ACKNOWLEDGEMENT = 800; diff --git a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java index f8ab87d042eb..2109c6a4739c 100644 --- a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java +++ b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java @@ -19,6 +19,7 @@ package com.android.internal.telephony; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.XmlResourceParser; +import android.os.Build; import android.util.SparseIntArray; import com.android.internal.telephony.cdma.sms.UserData; @@ -28,15 +29,15 @@ import com.android.telephony.Rlog; public class Sms7BitEncodingTranslator { private static final String TAG = "Sms7BitEncodingTranslator"; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static final boolean DBG = TelephonyUtils.IS_DEBUGGABLE; private static boolean mIs7BitTranslationTableLoaded = false; private static SparseIntArray mTranslationTable = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static SparseIntArray mTranslationTableCommon = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static SparseIntArray mTranslationTableGSM = null; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static SparseIntArray mTranslationTableCDMA = null; // Parser variables diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java index 084882b10c9b..6d46ed3b8416 100644 --- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java +++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java @@ -39,18 +39,18 @@ public abstract class SmsMessageBase { Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*"); /** {@hide} The address of the SMSC. May be null */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected String mScAddress; /** {@hide} The address of the sender */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected SmsAddress mOriginatingAddress; /** {@hide} The address of the receiver */ protected SmsAddress mRecipientAddress; /** {@hide} The message body as a string. May be null if the message isn't text */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected String mMessageBody; /** {@hide} */ @@ -76,21 +76,21 @@ public abstract class SmsMessageBase { protected byte[] mUserData; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected SmsHeader mUserDataHeader; // "Message Waiting Indication Group" // 23.038 Section 4 /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected boolean mIsMwi; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected boolean mMwiSense; /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected boolean mMwiDontStore; /** @@ -104,7 +104,7 @@ public abstract class SmsMessageBase { protected int mIndexOnIcc = -1; /** TP-Message-Reference - Message Reference of sent message. @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mMessageRef; @UnsupportedAppUsage diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index a34e474e666e..f636276f11b8 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -233,7 +233,7 @@ public class SmsMessage extends SmsMessageBase { * null on encode error. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message, boolean statusReportRequested, SmsHeader smsHeader, int priority) { @@ -316,7 +316,7 @@ public class SmsMessage extends SmsMessageBase { * @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns * null on encode error. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static SubmitPdu getSubmitPdu(String destAddr, UserData userData, boolean statusReportRequested, int priority) { return privateGetSubmitPdu(destAddr, statusReportRequested, userData, priority); diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java index d186fcf63cfe..851bc020a1da 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java @@ -18,6 +18,7 @@ package com.android.internal.telephony.cdma.sms; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; +import android.os.Build; import android.telephony.SmsCbCmasInfo; import android.telephony.cdma.CdmaSmsCbProgramData; import android.telephony.cdma.CdmaSmsCbProgramResults; @@ -1919,7 +1920,7 @@ public final class BearerData { * @return the number of bits to read from the stream * @throws CodingException if the specified encoding is not supported */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static int getBitsForNumFields(int msgEncoding, int numFields) throws CodingException { switch (msgEncoding) { diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java index d1903450261b..7e2cc6af4182 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java @@ -17,6 +17,7 @@ package com.android.internal.telephony.gsm; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.telephony.SmsCbCmasInfo; import android.telephony.SmsCbEtwsInfo; @@ -111,7 +112,7 @@ public class SmsCbHeader { private final int mSerialNumber; /** The Message Identifier in 3GPP is the same as the Service Category in CDMA. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final int mMessageIdentifier; private final int mDataCodingScheme; @@ -130,7 +131,7 @@ public class SmsCbHeader { /** CMAS warning notification info. */ private final SmsCbCmasInfo mCmasInfo; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public SmsCbHeader(byte[] pdu) throws IllegalArgumentException { if (pdu == null || pdu.length < PDU_HEADER_LENGTH) { throw new IllegalArgumentException("Illegal PDU"); @@ -228,17 +229,17 @@ public class SmsCbHeader { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getGeographicalScope() { return mGeographicalScope; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getSerialNumber() { return mSerialNumber; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getServiceCategory() { return mMessageIdentifier; } @@ -251,12 +252,12 @@ public class SmsCbHeader { return mDataCodingSchemeStructedData; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getPageIndex() { return mPageIndex; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getNumberOfPages() { return mNrOfPages; } diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index e3df903b7f4f..b51e8d3d3c5d 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -266,7 +266,7 @@ public class SmsMessage extends SmsMessageBase { * encoded message. Returns null on encode error. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static SubmitPdu getSubmitPdu(String scAddress, String destinationAddress, String message, boolean statusReportRequested, byte[] header, int encoding, @@ -292,7 +292,7 @@ public class SmsMessage extends SmsMessageBase { * encoded message. Returns null on encode error. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static SubmitPdu getSubmitPdu(String scAddress, String destinationAddress, String message, boolean statusReportRequested, byte[] header, int encoding, @@ -491,7 +491,7 @@ public class SmsMessage extends SmsMessageBase { * @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the * encoded message. Returns null on encode error. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static SubmitPdu getSubmitPdu(String scAddress, String destinationAddress, String message, boolean statusReportRequested, int validityPeriod) { @@ -774,9 +774,9 @@ public class SmsMessage extends SmsMessageBase { } private static class PduParser { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) byte mPdu[]; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int mCur; SmsHeader mUserDataHeader; byte[] mUserData; @@ -1168,14 +1168,14 @@ public class SmsMessage extends SmsMessageBase { } /** {@inheritDoc} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Override public int getStatus() { return mStatus; } /** {@inheritDoc} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Override public boolean isStatusReportMessage() { return mIsStatusReportMessage; diff --git a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java index 1d136924aa2c..d79225fe5369 100644 --- a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java +++ b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java @@ -21,6 +21,7 @@ import android.content.res.Resources; import android.content.res.Resources.NotFoundException; import android.graphics.Bitmap; import android.graphics.Color; +import android.os.Build; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.GsmAlphabet; @@ -385,7 +386,7 @@ public class IccUtils { return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length, defaultCharset.trim()); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static int hexCharToInt(char c) { if (c >= '0' && c <= '9') return (c - '0'); diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java index a5c254f1aca2..5b9f67efd95d 100644 --- a/test-mock/src/android/test/mock/MockContentProvider.java +++ b/test-mock/src/android/test/mock/MockContentProvider.java @@ -169,6 +169,12 @@ public class MockContentProvider extends ContentProvider { } @Override + public void uncanonicalizeAsync(String callingPkg, String featureId, Uri uri, + RemoteCallback callback) { + MockContentProvider.this.uncanonicalizeAsync(uri, callback); + } + + @Override public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle args, ICancellationSignal cancellationSignal) throws RemoteException { return MockContentProvider.this.refresh(url, args); @@ -311,6 +317,18 @@ public class MockContentProvider extends ContentProvider { /** * @hide */ + @SuppressWarnings("deprecation") + public void uncanonicalizeAsync(Uri uri, RemoteCallback callback) { + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + final Bundle bundle = new Bundle(); + bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, uncanonicalize(uri)); + callback.sendResult(bundle); + }); + } + + /** + * @hide + */ public boolean refresh(Uri url, Bundle args) { throw new UnsupportedOperationException("unimplemented mock method call"); } diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java index 223bcc59039d..82a1cf7d1796 100644 --- a/test-mock/src/android/test/mock/MockIContentProvider.java +++ b/test-mock/src/android/test/mock/MockIContentProvider.java @@ -162,12 +162,23 @@ public class MockIContentProvider implements IContentProvider { } @Override - public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri) - throws RemoteException { + public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri) { throw new UnsupportedOperationException("unimplemented mock method"); } @Override + @SuppressWarnings("deprecation") + public void uncanonicalizeAsync(String callingPkg, String featureId, Uri uri, + RemoteCallback remoteCallback) { + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + final Bundle bundle = new Bundle(); + bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, + uncanonicalize(callingPkg, featureId, uri)); + remoteCallback.sendResult(bundle); + }); + } + + @Override public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle args, ICancellationSignal cancellationSignal) throws RemoteException { throw new UnsupportedOperationException("unimplemented mock method"); diff --git a/tests/ActivityViewTest/AndroidManifest.xml b/tests/ActivityViewTest/AndroidManifest.xml index c84b7d904f0a..7563a25424ad 100644 --- a/tests/ActivityViewTest/AndroidManifest.xml +++ b/tests/ActivityViewTest/AndroidManifest.xml @@ -17,7 +17,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.test.activityview"> <uses-permission android:name="android.permission.INJECT_EVENTS"/> - <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"/> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/> <uses-permission android:name="android.permission.ACTIVITY_EMBEDDING"/> <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/> diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java index 66e44e123c7e..1adbc2dc182c 100644 --- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java +++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java @@ -32,7 +32,7 @@ public class HierrarchicalDataClassBase implements Parcelable { - // Code below generated by codegen v1.0.16. + // Code below generated by codegen v1.0.18. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -51,7 +51,7 @@ public class HierrarchicalDataClassBase implements Parcelable { } @DataClass.Generated.Member - public HierrarchicalDataClassBase setBaseData( int value) { + public @android.annotation.NonNull HierrarchicalDataClassBase setBaseData( int value) { mBaseData = value; return this; } @@ -98,8 +98,8 @@ public class HierrarchicalDataClassBase implements Parcelable { }; @DataClass.Generated( - time = 1601950882280L, - codegenVersion = "1.0.16", + time = 1603836848866L, + codegenVersion = "1.0.18", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java", inputSignatures = "private int mBaseData\nclass HierrarchicalDataClassBase extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genSetters=true)") @Deprecated diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java index 643abd8650d0..a4fdcd18aa3d 100644 --- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java +++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java @@ -46,7 +46,7 @@ public class HierrarchicalDataClassChild extends HierrarchicalDataClassBase { - // Code below generated by codegen v1.0.16. + // Code below generated by codegen v1.0.18. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -65,7 +65,7 @@ public class HierrarchicalDataClassChild extends HierrarchicalDataClassBase { } @DataClass.Generated.Member - public HierrarchicalDataClassChild setChildData(@NonNull String value) { + public @NonNull HierrarchicalDataClassChild setChildData(@NonNull String value) { mChildData = value; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mChildData); @@ -120,8 +120,8 @@ public class HierrarchicalDataClassChild extends HierrarchicalDataClassBase { }; @DataClass.Generated( - time = 1601950883222L, - codegenVersion = "1.0.16", + time = 1603836849753L, + codegenVersion = "1.0.18", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java", inputSignatures = "private @android.annotation.NonNull java.lang.String mChildData\nclass HierrarchicalDataClassChild extends com.android.codegentest.HierrarchicalDataClassBase implements []\n@com.android.internal.util.DataClass(genParcelable=true, genConstructor=false, genSetters=true)") @Deprecated diff --git a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java index 5e33a338f098..f0d728e2f604 100644 --- a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java +++ b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java @@ -54,7 +54,7 @@ public class ParcelAllTheThingsDataClass implements Parcelable { - // Code below generated by codegen v1.0.16. + // Code below generated by codegen v1.0.18. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -412,8 +412,8 @@ public class ParcelAllTheThingsDataClass implements Parcelable { } @DataClass.Generated( - time = 1601950881327L, - codegenVersion = "1.0.16", + time = 1603836847927L, + codegenVersion = "1.0.18", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java", inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\n @java.lang.SuppressWarnings({\"WeakerAccess\"}) @android.annotation.Nullable java.lang.Boolean mNullableBoolean\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)") @Deprecated diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java index 9e5b1a974030..a3f458beebcc 100644 --- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java +++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java @@ -23,6 +23,7 @@ import android.annotation.Size; import android.annotation.StringDef; import android.annotation.StringRes; import android.annotation.UserIdInt; +import android.content.pm.PackageManager; import android.net.LinkAddress; import android.os.Parcel; import android.os.Parcelable; @@ -86,9 +87,10 @@ public final class SampleDataClass implements Parcelable { * @see #toString() * @see State */ - public static final int STATE_UNDEFINED = -1; public static final int STATE_ON = 1; public static final int STATE_OFF = 0; + public static final int STATE_UNDEFINED + = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; /** * {@link IntDef}s with values specified in hex("0x...") are considered to be @@ -342,7 +344,7 @@ public final class SampleDataClass implements Parcelable { - // Code below generated by codegen v1.0.16. + // Code below generated by codegen v1.0.18. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -356,9 +358,9 @@ public final class SampleDataClass implements Parcelable { @IntDef(prefix = "STATE_", value = { - STATE_UNDEFINED, STATE_ON, - STATE_OFF + STATE_OFF, + STATE_UNDEFINED }) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @DataClass.Generated.Member @@ -367,12 +369,12 @@ public final class SampleDataClass implements Parcelable { @DataClass.Generated.Member public static String stateToString(@State int value) { switch (value) { - case STATE_UNDEFINED: - return "STATE_UNDEFINED"; case STATE_ON: return "STATE_ON"; case STATE_OFF: return "STATE_OFF"; + case STATE_UNDEFINED: + return "STATE_UNDEFINED"; default: return Integer.toHexString(value); } } @@ -560,14 +562,14 @@ public final class SampleDataClass implements Parcelable { | FLAG_AUGMENTED_REQUEST); this.mState = state; - if (!(mState == STATE_UNDEFINED) - && !(mState == STATE_ON) - && !(mState == STATE_OFF)) { + if (!(mState == STATE_ON) + && !(mState == STATE_OFF) + && !(mState == STATE_UNDEFINED)) { throw new java.lang.IllegalArgumentException( "state was " + mState + " but must be one of: " - + "STATE_UNDEFINED(" + STATE_UNDEFINED + "), " + "STATE_ON(" + STATE_ON + "), " - + "STATE_OFF(" + STATE_OFF + ")"); + + "STATE_OFF(" + STATE_OFF + "), " + + "STATE_UNDEFINED(" + STATE_UNDEFINED + ")"); } this.charSeq = charSeq; @@ -820,7 +822,7 @@ public final class SampleDataClass implements Parcelable { * pieces in multiple places for each field. */ @DataClass.Generated.Member - public SampleDataClass setNum( int value) { + public @NonNull SampleDataClass setNum( int value) { mNum = value; return this; } @@ -832,7 +834,7 @@ public final class SampleDataClass implements Parcelable { * @see #mNum2 ..and so should blocks at the bottom, e.g. {@code @see} blocks. */ @DataClass.Generated.Member - public SampleDataClass setNum2( int value) { + public @NonNull SampleDataClass setNum2( int value) { mNum2 = value; return this; } @@ -846,7 +848,7 @@ public final class SampleDataClass implements Parcelable { * @hide */ @DataClass.Generated.Member - public SampleDataClass setNum4( int value) { + public @NonNull SampleDataClass setNum4( int value) { mNum4 = value; return this; } @@ -855,7 +857,7 @@ public final class SampleDataClass implements Parcelable { * {@link Nullable} or {@link NonNull} annotation is required on all non-primitive fields. */ @DataClass.Generated.Member - public SampleDataClass setName(@NonNull String value) { + public @NonNull SampleDataClass setName(@NonNull String value) { mName = value; return this; } @@ -868,7 +870,7 @@ public final class SampleDataClass implements Parcelable { * while mandatory fields are passed via {@link Builder#Builder constructor}. */ @DataClass.Generated.Member - public SampleDataClass setName2(@NonNull String value) { + public @NonNull SampleDataClass setName2(@NonNull String value) { mName2 = value; AnnotationValidations.validate( NonNull.class, null, mName2); @@ -880,7 +882,7 @@ public final class SampleDataClass implements Parcelable { * {@link #defaultName4 defaultFieldName()} can be defined to compute the default value. */ @DataClass.Generated.Member - public SampleDataClass setName4(@NonNull String value) { + public @NonNull SampleDataClass setName4(@NonNull String value) { mName4 = value; AnnotationValidations.validate( NonNull.class, null, mName4); @@ -892,7 +894,7 @@ public final class SampleDataClass implements Parcelable { * E.g. {@link Parcelable} subclasses, {@link String}, {@link int}, {@link boolean}, etc. */ @DataClass.Generated.Member - public SampleDataClass setOtherParcelable(@NonNull AccessibilityNodeInfo value) { + public @NonNull SampleDataClass setOtherParcelable(@NonNull AccessibilityNodeInfo value) { mOtherParcelable = value; return this; } @@ -904,7 +906,7 @@ public final class SampleDataClass implements Parcelable { * @see MyDateParcelling an example {@link Parcelling} implementation */ @DataClass.Generated.Member - public SampleDataClass setDate(@NonNull Date value) { + public @NonNull SampleDataClass setDate(@NonNull Date value) { mDate = value; AnnotationValidations.validate( NonNull.class, null, mDate); @@ -916,7 +918,7 @@ public final class SampleDataClass implements Parcelable { * to encourage its reuse. */ @DataClass.Generated.Member - public SampleDataClass setPattern(@NonNull Pattern value) { + public @NonNull SampleDataClass setPattern(@NonNull Pattern value) { mPattern = value; AnnotationValidations.validate( NonNull.class, null, mPattern); @@ -929,7 +931,7 @@ public final class SampleDataClass implements Parcelable { * {@link Builder#addLinkAddresses2(LinkAddress) add} method is generated for convenience. */ @DataClass.Generated.Member - public SampleDataClass setLinkAddresses2(@NonNull List<LinkAddress> value) { + public @NonNull SampleDataClass setLinkAddresses2(@NonNull List<LinkAddress> value) { mLinkAddresses2 = value; AnnotationValidations.validate( NonNull.class, null, mLinkAddresses2); @@ -943,7 +945,7 @@ public final class SampleDataClass implements Parcelable { * @see Builder#addLinkAddress(LinkAddress) */ @DataClass.Generated.Member - public SampleDataClass setLinkAddresses(@NonNull ArrayList<LinkAddress> value) { + public @NonNull SampleDataClass setLinkAddresses(@NonNull ArrayList<LinkAddress> value) { mLinkAddresses = value; AnnotationValidations.validate( NonNull.class, null, mLinkAddresses); @@ -957,7 +959,7 @@ public final class SampleDataClass implements Parcelable { * @see Builder#setLinkAddresses4(LinkAddress...) */ @DataClass.Generated.Member - public SampleDataClass setLinkAddresses4(@NonNull LinkAddress... value) { + public @NonNull SampleDataClass setLinkAddresses4(@NonNull LinkAddress... value) { mLinkAddresses4 = value; return this; } @@ -970,7 +972,7 @@ public final class SampleDataClass implements Parcelable { * @see Builder#setStateName */ @DataClass.Generated.Member - public SampleDataClass setStateName(@StateName @NonNull String value) { + public @NonNull SampleDataClass setStateName(@StateName @NonNull String value) { mStateName = value; if (!(Objects.equals(mStateName, STATE_NAME_UNDEFINED)) @@ -992,7 +994,7 @@ public final class SampleDataClass implements Parcelable { * Fields annotated with {@link IntDef} annotations also get a proper {@link #toString()} value. */ @DataClass.Generated.Member - public SampleDataClass setFlags(@RequestFlags int value) { + public @NonNull SampleDataClass setFlags(@RequestFlags int value) { mFlags = value; Preconditions.checkFlagsArgument( @@ -1007,17 +1009,17 @@ public final class SampleDataClass implements Parcelable { * Above is true for both {@link IntDef#flag flags} and enum-like {@link IntDef}s */ @DataClass.Generated.Member - public SampleDataClass setState(@State int value) { + public @NonNull SampleDataClass setState(@State int value) { mState = value; - if (!(mState == STATE_UNDEFINED) - && !(mState == STATE_ON) - && !(mState == STATE_OFF)) { + if (!(mState == STATE_ON) + && !(mState == STATE_OFF) + && !(mState == STATE_UNDEFINED)) { throw new java.lang.IllegalArgumentException( "state was " + mState + " but must be one of: " - + "STATE_UNDEFINED(" + STATE_UNDEFINED + "), " + "STATE_ON(" + STATE_ON + "), " - + "STATE_OFF(" + STATE_OFF + ")"); + + "STATE_OFF(" + STATE_OFF + "), " + + "STATE_UNDEFINED(" + STATE_UNDEFINED + ")"); } return this; @@ -1036,7 +1038,7 @@ public final class SampleDataClass implements Parcelable { * @see #SampleDataClass */ @DataClass.Generated.Member - public SampleDataClass setStringRes(@StringRes int value) { + public @NonNull SampleDataClass setStringRes(@StringRes int value) { mStringRes = value; AnnotationValidations.validate( StringRes.class, null, mStringRes); @@ -1051,7 +1053,7 @@ public final class SampleDataClass implements Parcelable { * @see AnnotationValidations#validate(Class, Size, int, String, int, String, int) */ @DataClass.Generated.Member - public SampleDataClass setDayOfWeek(@android.annotation.IntRange(from = 0, to = 6) int value) { + public @NonNull SampleDataClass setDayOfWeek(@android.annotation.IntRange(from = 0, to = 6) int value) { mDayOfWeek = value; AnnotationValidations.validate( android.annotation.IntRange.class, null, mDayOfWeek, @@ -1070,7 +1072,7 @@ public final class SampleDataClass implements Parcelable { * @see AnnotationValidations#validate(Class, Size, int, String, int) */ @DataClass.Generated.Member - public SampleDataClass setCoords(@Size(2) @NonNull @FloatRange(from = 0f) float... value) { + public @NonNull SampleDataClass setCoords(@Size(2) @NonNull @FloatRange(from = 0f) float... value) { mCoords = value; AnnotationValidations.validate( Size.class, null, mCoords.length, @@ -1372,14 +1374,14 @@ public final class SampleDataClass implements Parcelable { | FLAG_AUGMENTED_REQUEST); this.mState = state; - if (!(mState == STATE_UNDEFINED) - && !(mState == STATE_ON) - && !(mState == STATE_OFF)) { + if (!(mState == STATE_ON) + && !(mState == STATE_OFF) + && !(mState == STATE_UNDEFINED)) { throw new java.lang.IllegalArgumentException( "state was " + mState + " but must be one of: " - + "STATE_UNDEFINED(" + STATE_UNDEFINED + "), " + "STATE_ON(" + STATE_ON + "), " - + "STATE_OFF(" + STATE_OFF + ")"); + + "STATE_OFF(" + STATE_OFF + "), " + + "STATE_UNDEFINED(" + STATE_UNDEFINED + ")"); } this.charSeq = _charSeq; @@ -1872,10 +1874,10 @@ public final class SampleDataClass implements Parcelable { } @DataClass.Generated( - time = 1601950879293L, - codegenVersion = "1.0.16", + time = 1603836845952L, + codegenVersion = "1.0.18", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java", - inputSignatures = "public static final java.lang.String STATE_NAME_UNDEFINED\npublic static final java.lang.String STATE_NAME_ON\npublic static final java.lang.String STATE_NAME_OFF\npublic static final int STATE_UNDEFINED\npublic static final int STATE_ON\npublic static final int STATE_OFF\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate int mNum\nprivate int mNum2\nprivate int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient android.net.LinkAddress[] mLinkAddresses6\ntransient int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static java.lang.String defaultName4()\nprivate int[] lazyInitTmpStorage()\npublic android.net.LinkAddress[] getLinkAddresses4()\nprivate boolean patternEquals(java.util.regex.Pattern)\nprivate int patternHashCode()\nprivate void onConstructed()\npublic void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)") + inputSignatures = "public static final java.lang.String STATE_NAME_UNDEFINED\npublic static final java.lang.String STATE_NAME_ON\npublic static final java.lang.String STATE_NAME_OFF\npublic static final int STATE_ON\npublic static final int STATE_OFF\npublic static final int STATE_UNDEFINED\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate int mNum\nprivate int mNum2\nprivate int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient android.net.LinkAddress[] mLinkAddresses6\ntransient int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static java.lang.String defaultName4()\nprivate int[] lazyInitTmpStorage()\npublic android.net.LinkAddress[] getLinkAddresses4()\nprivate boolean patternEquals(java.util.regex.Pattern)\nprivate int patternHashCode()\nprivate void onConstructed()\npublic void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)") @Deprecated private void __metadata() {} diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java index 735f7047af9f..e3567044d361 100644 --- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java +++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java @@ -85,7 +85,7 @@ public class SampleWithCustomBuilder implements Parcelable { - // Code below generated by codegen v1.0.16. + // Code below generated by codegen v1.0.18. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -253,8 +253,8 @@ public class SampleWithCustomBuilder implements Parcelable { } @DataClass.Generated( - time = 1601950880290L, - codegenVersion = "1.0.16", + time = 1603836846970L, + codegenVersion = "1.0.18", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java", inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nprivate static java.util.concurrent.TimeUnit unparcelDelayUnit(android.os.Parcel)\nprivate void parcelDelayUnit(android.os.Parcel,int)\nclass SampleWithCustomBuilder extends java.lang.Object implements [android.os.Parcelable]\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []") @Deprecated diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java index 51601213acce..07ec31ddc5e6 100644 --- a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java +++ b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java @@ -36,7 +36,7 @@ public class SampleWithNestedDataClasses { - // Code below generated by codegen v1.0.16. + // Code below generated by codegen v1.0.18. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -135,8 +135,8 @@ public class SampleWithNestedDataClasses { }; @DataClass.Generated( - time = 1601950885147L, - codegenVersion = "1.0.16", + time = 1603836851627L, + codegenVersion = "1.0.18", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java", inputSignatures = " @android.annotation.NonNull java.lang.String mBar\nclass NestedDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)") @Deprecated @@ -160,7 +160,7 @@ public class SampleWithNestedDataClasses { - // Code below generated by codegen v1.0.16. + // Code below generated by codegen v1.0.18. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -259,8 +259,8 @@ public class SampleWithNestedDataClasses { }; @DataClass.Generated( - time = 1601950885156L, - codegenVersion = "1.0.16", + time = 1603836851635L, + codegenVersion = "1.0.18", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java", inputSignatures = " @android.annotation.NonNull long mBaz2\nclass NestedDataClass3 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)") @Deprecated @@ -274,7 +274,7 @@ public class SampleWithNestedDataClasses { - // Code below generated by codegen v1.0.16. + // Code below generated by codegen v1.0.18. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -373,8 +373,8 @@ public class SampleWithNestedDataClasses { }; @DataClass.Generated( - time = 1601950885161L, - codegenVersion = "1.0.16", + time = 1603836851640L, + codegenVersion = "1.0.18", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java", inputSignatures = " @android.annotation.NonNull java.lang.String mBaz\nclass NestedDataClass2 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)") @Deprecated diff --git a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java index 5417c11c8fca..5cbc6b30d1fc 100644 --- a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java +++ b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java @@ -59,7 +59,7 @@ public class StaleDataclassDetectorFalsePositivesTest { - // Code below generated by codegen v1.0.16. + // Code below generated by codegen v1.0.18. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -78,14 +78,14 @@ public class StaleDataclassDetectorFalsePositivesTest { } @DataClass.Generated.Member - public StaleDataclassDetectorFalsePositivesTest setUsesWildcards(@NonNull List<Set<?>> value) { + public @NonNull StaleDataclassDetectorFalsePositivesTest setUsesWildcards(@NonNull List<Set<?>> value) { mUsesWildcards = value; return this; } @DataClass.Generated( - time = 1601950884160L, - codegenVersion = "1.0.16", + time = 1603836850677L, + codegenVersion = "1.0.18", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java", inputSignatures = "private @android.annotation.Nullable java.util.List<java.util.Set<?>> mUsesWildcards\npublic @android.annotation.NonNull java.lang.String someMethod(int)\nclass StaleDataclassDetectorFalsePositivesTest extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false)") @Deprecated diff --git a/tests/Input/AndroidManifest.xml b/tests/Input/AndroidManifest.xml index 4195df72864c..20f564e80b3d 100644 --- a/tests/Input/AndroidManifest.xml +++ b/tests/Input/AndroidManifest.xml @@ -27,7 +27,6 @@ android:process=":externalProcess"> </activity> - </application> <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" android:targetPackage="com.android.test.input" diff --git a/tests/TaskOrganizerTest/AndroidManifest.xml b/tests/TaskOrganizerTest/AndroidManifest.xml index f0ba71a47d7e..451a55f13d8f 100644 --- a/tests/TaskOrganizerTest/AndroidManifest.xml +++ b/tests/TaskOrganizerTest/AndroidManifest.xml @@ -14,7 +14,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.test.taskembed"> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/> - <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"/> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/> <application> <service android:name=".TaskOrganizerPipTest" diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml index 009f817af407..6bed5a80d129 100644 --- a/tests/net/AndroidManifest.xml +++ b/tests/net/AndroidManifest.xml @@ -42,7 +42,7 @@ <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" /> <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" /> - <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> <uses-permission android:name="android.permission.INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.NETWORK_STACK" /> <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" /> diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java index e1693129892f..11a83ebf6dd7 100644 --- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java +++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java @@ -30,6 +30,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; +import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; @@ -359,6 +360,33 @@ public class NetworkCapabilitiesTest { } @Test + public void testOemPrivate() { + NetworkCapabilities nc = new NetworkCapabilities(); + // By default OEM_PRIVATE is neither in the unwanted or required lists and the network is + // not restricted. + assertFalse(nc.hasUnwantedCapability(NET_CAPABILITY_OEM_PRIVATE)); + assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PRIVATE)); + nc.maybeMarkCapabilitiesRestricted(); + assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); + + // Adding OEM_PRIVATE to capability list should make network restricted. + nc.addCapability(NET_CAPABILITY_OEM_PRIVATE); + nc.addCapability(NET_CAPABILITY_INTERNET); // Combine with unrestricted capability. + nc.maybeMarkCapabilitiesRestricted(); + assertTrue(nc.hasCapability(NET_CAPABILITY_OEM_PRIVATE)); + assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); + + // Now let's make request for OEM_PRIVATE network. + NetworkCapabilities nr = new NetworkCapabilities(); + nr.addCapability(NET_CAPABILITY_OEM_PRIVATE); + nr.maybeMarkCapabilitiesRestricted(); + assertTrue(nr.satisfiedByNetworkCapabilities(nc)); + + // Request fails for network with the default capabilities. + assertFalse(nr.satisfiedByNetworkCapabilities(new NetworkCapabilities())); + } + + @Test public void testUnwantedCapabilities() { NetworkCapabilities network = new NetworkCapabilities(); diff --git a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java b/tests/net/java/android/net/ipmemorystore/ParcelableTests.java index 02f5286506a8..603c87519532 100644 --- a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java +++ b/tests/net/java/android/net/ipmemorystore/ParcelableTests.java @@ -19,6 +19,8 @@ package android.net.ipmemorystore; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import android.net.networkstack.aidl.quirks.IPv6ProvisioningLossQuirk; +import android.net.networkstack.aidl.quirks.IPv6ProvisioningLossQuirkParcelable; import android.os.Parcel; import android.os.Parcelable; @@ -46,7 +48,7 @@ public class ParcelableTests { builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4")); // lease will expire in two hours builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000); - // groupHint stays null this time around + // cluster stays null this time around builder.setDnsAddresses(Collections.emptyList()); builder.setMtu(18); in = builder.build(); @@ -69,7 +71,7 @@ public class ParcelableTests { // Verify that this test does not miss any new field added later. // If any field is added to NetworkAttributes it must be tested here for parceling // roundtrip. - assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields()) + assertEquals(6, Arrays.stream(NetworkAttributes.class.getDeclaredFields()) .filter(f -> !Modifier.isStatic(f.getModifiers())).count()); } @@ -104,6 +106,22 @@ public class ParcelableTests { assertEquals(in.confidence, out.confidence, 0.01f /* delta */); } + @Test + public void testIPv6ProvisioningLossQuirkParceling() throws Exception { + final NetworkAttributes.Builder builder = new NetworkAttributes.Builder(); + final IPv6ProvisioningLossQuirkParcelable parcelable = + new IPv6ProvisioningLossQuirkParcelable(); + final long expiry = System.currentTimeMillis() + 7_200_000; + + parcelable.detectionCount = 3; + parcelable.quirkExpiry = expiry; // quirk info will expire in two hours + builder.setIpv6ProvLossQuirk(IPv6ProvisioningLossQuirk.fromStableParcelable(parcelable)); + final NetworkAttributes in = builder.build(); + + final NetworkAttributes out = new NetworkAttributes(parcelingRoundTrip(in.toParcelable())); + assertEquals(out.ipv6ProvisioningLossQuirk, in.ipv6ProvisioningLossQuirk); + } + private <T extends Parcelable> T parcelingRoundTrip(final T in) throws Exception { final Parcel p = Parcel.obtain(); in.writeToParcel(p, /* flags */ 0); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 4081346f62f9..2a0c99c3bc52 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -6023,23 +6023,23 @@ public class ConnectivityServiceTest { mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); mCellNetworkAgent.connect(true); trustedCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - verify(mNetworkManagementService).setDefaultNetId(eq(mCellNetworkAgent.getNetwork().netId)); - reset(mNetworkManagementService); + verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); + reset(mMockNetd); mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(true); trustedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - verify(mNetworkManagementService).setDefaultNetId(eq(mWiFiNetworkAgent.getNetwork().netId)); - reset(mNetworkManagementService); + verify(mMockNetd).networkSetDefault(eq(mWiFiNetworkAgent.getNetwork().netId)); + reset(mMockNetd); mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_TRUSTED); trustedCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - verify(mNetworkManagementService).setDefaultNetId(eq(mCellNetworkAgent.getNetwork().netId)); - reset(mNetworkManagementService); + verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); + reset(mMockNetd); mCellNetworkAgent.removeCapability(NET_CAPABILITY_TRUSTED); trustedCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - verify(mNetworkManagementService).clearDefaultNetId(); + verify(mMockNetd).networkClearDefault(); mCm.unregisterNetworkCallback(trustedCallback); } @@ -6143,6 +6143,7 @@ public class ConnectivityServiceTest { verify(mMockNetd, times(1)).networkCreatePhysical(eq(cellNetId), anyInt()); assertRoutesAdded(cellNetId, ipv6Subnet, defaultRoute); verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId)); + verify(mMockNetd, times(1)).networkAddInterface(cellNetId, MOBILE_IFNAME); verify(mBatteryStatsService).noteNetworkInterfaceType(cellLp.getInterfaceName(), TYPE_MOBILE); @@ -6199,7 +6200,7 @@ public class ConnectivityServiceTest { .getStackedLinks(); assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0)); assertRoutesAdded(cellNetId, stackedDefault); - + verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); // Change trivial linkproperties and see if stacked link is preserved. cellLp.addDnsServer(InetAddress.getByName("8.8.8.8")); mCellNetworkAgent.sendLinkProperties(cellLp); @@ -6230,6 +6231,7 @@ public class ConnectivityServiceTest { (lp) -> lp.getStackedLinks().size() == 0); verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); assertRoutesRemoved(cellNetId, stackedDefault); + verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kOtherNat64Prefix.toString()); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, @@ -6238,6 +6240,7 @@ public class ConnectivityServiceTest { networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getStackedLinks().size() == 1); assertRoutesAdded(cellNetId, stackedDefault); + verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); reset(mMockNetd); // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked @@ -6262,7 +6265,7 @@ public class ConnectivityServiceTest { // The interface removed callback happens but has no effect after stop is called. clat.interfaceRemoved(CLAT_PREFIX + MOBILE_IFNAME); networkCallback.assertNoCallback(); - + verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); verifyNoMoreInteractions(mMockNetd); verifyNoMoreInteractions(mMockDnsResolver); reset(mNetworkManagementService); @@ -6295,6 +6298,7 @@ public class ConnectivityServiceTest { networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getStackedLinks().size() == 1 && lp.getNat64Prefix() != null); assertRoutesAdded(cellNetId, stackedDefault); + verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); // NAT64 prefix is removed. Expect that clat is stopped. mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, @@ -6307,8 +6311,8 @@ public class ConnectivityServiceTest { verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, (lp) -> lp.getStackedLinks().size() == 0); + verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); verifyNoMoreInteractions(mMockNetd); - // Clean up. mCellNetworkAgent.disconnect(); networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); diff --git a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java index fb84611cb662..ebbc0ef62548 100644 --- a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java +++ b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java @@ -19,6 +19,7 @@ package com.android.server.net.ipmemorystore; import static org.junit.Assert.assertEquals; import android.net.ipmemorystore.NetworkAttributes; +import android.net.networkstack.aidl.quirks.IPv6ProvisioningLossQuirk; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -52,6 +53,8 @@ public class NetworkAttributesTest { } assertEquals(sum, NetworkAttributes.TOTAL_WEIGHT, EPSILON); + final IPv6ProvisioningLossQuirk ipv6ProvisioningLossQuirk = + new IPv6ProvisioningLossQuirk(3, System.currentTimeMillis() + 7_200_000); // Use directly the constructor with all attributes, and make sure that when compared // to itself the score is a clean 1.0f. final NetworkAttributes na = @@ -61,7 +64,7 @@ public class NetworkAttributesTest { "some hint", Arrays.asList(Inet4Address.getByAddress(new byte[] {5, 6, 7, 8}), Inet4Address.getByAddress(new byte[] {9, 0, 1, 2})), - 98); + 98, ipv6ProvisioningLossQuirk); assertEquals(1.0f, na.getNetworkGroupSamenessConfidence(na), EPSILON); } } diff --git a/tools/codegen/src/com/android/codegen/Debug.kt b/tools/codegen/src/com/android/codegen/Debug.kt new file mode 100644 index 000000000000..de3184468540 --- /dev/null +++ b/tools/codegen/src/com/android/codegen/Debug.kt @@ -0,0 +1,39 @@ +/* + * 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.codegen + +import com.github.javaparser.ast.Node + +fun Node.dump(indent: String = ""): String { + return buildString { + append(indent) + appendln(dumpOneLineNoChildren()) + childNodes.forEach { child -> + append(child.dump(indent + " ")) + } + } +} + +private fun Node.dumpOneLineNoChildren(): String { + val node = this + return buildString { + append(node::class.java.simpleName) + if (childNodes.isEmpty()) { + append(": ").append(node.toString()) + } + } +} diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt index 6e1ab5944eb6..6c6d011cfede 100644 --- a/tools/codegen/src/com/android/codegen/Generators.kt +++ b/tools/codegen/src/com/android/codegen/Generators.kt @@ -16,10 +16,7 @@ import java.io.File fun ClassPrinter.generateConstDefs() { val consts = classAst.fields.filter { it.isStatic && it.isFinal && it.variables.all { variable -> - val initializer = variable.initializer.orElse(null) - val isLiteral = initializer is LiteralExpr - || (initializer is UnaryExpr && initializer.expression is LiteralExpr) - isLiteral && variable.type.asString() in listOf("int", "String") + variable.type.asString() in listOf("int", "String") } && it.annotations.none { it.nameAsString == DataClassSuppressConstDefs } }.flatMap { field -> field.variables.map { it to field } } val intConsts = consts.filter { it.first.type.asString() == "int" } diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt index 785aa9107f90..ca658a972209 100644 --- a/tools/codegen/src/com/android/codegen/SharedConstants.kt +++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt @@ -1,7 +1,7 @@ package com.android.codegen const val CODEGEN_NAME = "codegen" -const val CODEGEN_VERSION = "1.0.17" +const val CODEGEN_VERSION = "1.0.18" const val CANONICAL_BUILDER_CLASS = "Builder" const val BASE_BUILDER_CLASS = "BaseBuilder" diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py index e4b96b1d4f5f..28ff606d0381 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists.py +++ b/tools/hiddenapi/generate_hiddenapi_lists.py @@ -188,11 +188,10 @@ class FlagsDict: def _check_entries_set(self, keys_subset, source): assert isinstance(keys_subset, set) assert keys_subset.issubset(self._dict_keyset), ( - "Error processing: {}\n" - "The following entries were unexpected:\n" + "Error: {} specifies signatures not present in code:\n" "{}" "Please visit go/hiddenapi for more information.").format( - source, "".join(map(lambda x: " " + str(x), keys_subset - self._dict_keyset))) + source, "".join(map(lambda x: " " + str(x) + "\n", keys_subset - self._dict_keyset))) def _check_flags_set(self, flags_subset, source): assert isinstance(flags_subset, set) diff --git a/tools/validatekeymaps/Android.bp b/tools/validatekeymaps/Android.bp index 61ce44c3b5b9..2759e29d1620 100644 --- a/tools/validatekeymaps/Android.bp +++ b/tools/validatekeymaps/Android.bp @@ -16,6 +16,7 @@ cc_binary_host { static_libs: [ "libbase", + "libbinder", "libinput", "libutils", "libcutils", diff --git a/wifi/Android.bp b/wifi/Android.bp index 3040041038cb..52e3840c126e 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -75,25 +75,34 @@ test_access_hidden_api_whitelist = [ "//external/sl4a:__subpackages__", ] -// wifi-service needs pre-jarjared version of framework-wifi so it can reference copied utility -// classes before they are renamed. -java_library { - name: "framework-wifi-pre-jarjar", +// defaults shared between `framework-wifi` & `framework-wifi-pre-jarjar` +// java_sdk_library `framework-wifi` needs sources to generate stubs, so it cannot reuse +// `framework-wifi-pre-jarjar` +java_defaults { + name: "framework-wifi-defaults", defaults: ["wifi-module-sdk-version-defaults"], - sdk_version: "module_current", static_libs: [ "framework-wifi-util-lib", "android.hardware.wifi-V1.0-java-constants", + "modules-utils-build", ], libs: [ - "framework-annotations-lib", "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage ], srcs: [ ":framework-wifi-updatable-sources", ":framework-wifi-util-lib-aidls", ], - // java_api_finder must accompany `srcs` +} + +// wifi-service needs pre-jarjared version of framework-wifi so it can reference copied utility +// classes before they are renamed. +java_library { + name: "framework-wifi-pre-jarjar", + defaults: ["framework-wifi-defaults"], + sdk_version: "module_current", + libs: ["framework-annotations-lib"], + // java_api_finder must accompany `srcs` (`srcs` defined in `framework-wifi-defaults`) plugins: ["java_api_finder"], installable: false, visibility: [ @@ -107,18 +116,7 @@ java_sdk_library { name: "framework-wifi", defaults: [ "framework-module-defaults", - "wifi-module-sdk-version-defaults", - ], - static_libs: [ - "framework-wifi-util-lib", - "android.hardware.wifi-V1.0-java-constants", - ], - libs: [ - "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage - ], - srcs: [ - ":framework-wifi-updatable-sources", - ":framework-wifi-util-lib-aidls", + "framework-wifi-defaults", ], jarjar_rules: ":wifi-jarjar-rules", diff --git a/wifi/aidl-export/android/net/wifi/aware/AwareResources.aidl b/wifi/aidl-export/android/net/wifi/aware/AwareResources.aidl new file mode 100644 index 000000000000..d0bd2dda5722 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/aware/AwareResources.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.aware; + +parcelable AwareResources;
\ No newline at end of file diff --git a/wifi/api/current.txt b/wifi/api/current.txt index 0bc1ff22b704..d5ef703253cb 100644 --- a/wifi/api/current.txt +++ b/wifi/api/current.txt @@ -561,6 +561,15 @@ package android.net.wifi.aware { method public void onAttached(android.net.wifi.aware.WifiAwareSession); } + public final class AwareResources implements android.os.Parcelable { + method public int describeContents(); + method public int getNumOfAvailableDataPaths(); + method public int getNumOfAvailablePublishSessions(); + method public int getNumOfAvailableSubscribeSessions(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.AwareResources> CREATOR; + } + public final class Characteristics implements android.os.Parcelable { method public int describeContents(); method public int getMaxMatchFilterLength(); @@ -663,7 +672,8 @@ package android.net.wifi.aware { public class WifiAwareManager { method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @Nullable android.os.Handler); method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler); - method public android.net.wifi.aware.Characteristics getCharacteristics(); + method @Nullable public android.net.wifi.aware.AwareResources getAvailableAwareResources(); + method @Nullable public android.net.wifi.aware.Characteristics getCharacteristics(); method public boolean isAvailable(); method public boolean isDeviceAttached(); method public boolean isInstantCommunicationModeEnabled(); diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt index da5888b6adee..5dc5dfc02bce 100644 --- a/wifi/api/system-current.txt +++ b/wifi/api/system-current.txt @@ -252,8 +252,10 @@ package android.net.wifi { public final class SoftApConfiguration implements android.os.Parcelable { method @NonNull public java.util.List<android.net.MacAddress> getAllowedClientList(); method public int getBand(); + method @NonNull public int[] getBands(); method @NonNull public java.util.List<android.net.MacAddress> getBlockedClientList(); method public int getChannel(); + method @NonNull public android.util.SparseIntArray getChannels(); method public int getMacRandomizationSetting(); method public int getMaxNumberOfClients(); method public long getShutdownTimeoutMillis(); @@ -275,9 +277,11 @@ package android.net.wifi { method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAllowedClientList(@NonNull java.util.List<android.net.MacAddress>); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAutoShutdownEnabled(boolean); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBand(int); + method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBands(@NonNull int[]); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBlockedClientList(@NonNull java.util.List<android.net.MacAddress>); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBssid(@Nullable android.net.MacAddress); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannel(int, int); + method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannels(@NonNull android.util.SparseIntArray); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setClientControlByUserEnabled(boolean); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setHiddenSsid(boolean); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setMacRandomizationSetting(int); diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index eef08b54f570..b0ff4bb27e70 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -36,6 +36,7 @@ rule android.net.ipmemorystore.IOnStatusListener* com.android.wifi.x.@0 rule android.net.ipmemorystore.NetworkAttributesParcelable* com.android.wifi.x.@0 rule android.net.ipmemorystore.SameL3NetworkResponseParcelable* com.android.wifi.x.@0 rule android.net.ipmemorystore.StatusParcelable* com.android.wifi.x.@0 +rule android.net.networkstack.aidl.quirks.IPv6ProvisioningLossQuirk* com.android.wifi.x.@0 # Net utils (includes Network Stack helper classes). rule android.net.DhcpResults* com.android.wifi.x.@0 @@ -123,3 +124,4 @@ rule com.android.internal.util.Preconditions* com.android.wifi.x.@0 rule com.android.internal.util.Protocol* com.android.wifi.x.@0 rule com.android.net.module.util.** com.android.wifi.x.@0 +rule com.android.modules.utils.** com.android.wifi.x.@0 diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index b3ed8ac09034..7329c16d68d0 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -187,7 +187,7 @@ interface IWifiManager void factoryReset(String packageName); - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Network getCurrentNetwork(); byte[] retrieveBackupData(); diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 329ca37407de..4c23286258d8 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -22,6 +22,7 @@ import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.net.wifi.WifiAnnotations.ChannelWidth; import android.net.wifi.WifiAnnotations.WifiStandard; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -381,7 +382,7 @@ public final class ScanResult implements Parcelable { * @deprecated use is80211mcResponder() instead * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean is80211McRTTResponder; /** @@ -772,47 +773,47 @@ public final class ScanResult implements Parcelable { */ public static class InformationElement { /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_SSID = 0; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_SUPPORTED_RATES = 1; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_TIM = 5; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_BSS_LOAD = 11; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_ERP = 42; /** @hide */ public static final int EID_HT_CAPABILITIES = 45; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_RSN = 48; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_EXTENDED_SUPPORTED_RATES = 50; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_HT_OPERATION = 61; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_INTERWORKING = 107; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_ROAMING_CONSORTIUM = 111; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_EXTENDED_CAPS = 127; /** @hide */ public static final int EID_VHT_CAPABILITIES = 191; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_VHT_OPERATION = 192; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int EID_VSA = 221; /** @hide */ public static final int EID_EXTENSION_PRESENT = 255; diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java index cf54f26fc5e4..6bd4211d8214 100644 --- a/wifi/java/android/net/wifi/SoftApCapability.java +++ b/wifi/java/android/net/wifi/SoftApCapability.java @@ -21,10 +21,11 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.wifi.SoftApConfiguration.BandType; -import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; import android.os.Parcelable; +import com.android.modules.utils.build.SdkLevel; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; @@ -176,7 +177,7 @@ public final class SoftApCapability implements Parcelable { */ @NonNull public int[] getSupportedChannelList(@BandType int band) { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } switch (band) { diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 2649b66c703f..2c53daaf55a7 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -22,14 +22,15 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.MacAddress; -import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; +import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; +import com.android.modules.utils.build.SdkLevel; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -167,16 +168,12 @@ public final class SoftApConfiguration implements Parcelable { private final boolean mHiddenSsid; /** - * The operating band of the AP. - * One or combination of the following band type: - * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, {@link #BAND_6GHZ}. - */ - private final @BandType int mBand; - - /** - * The operating channel of the AP. + * The operating channels of the dual APs. + * + * The SparseIntArray that consists the band and the channel of matching the band. */ - private final int mChannel; + @NonNull + private final SparseIntArray mChannels; /** * The maximim allowed number of clients that can associate to the AP. @@ -280,7 +277,7 @@ public final class SoftApConfiguration implements Parcelable { /** Private constructor for Builder and Parcelable implementation. */ private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid, - @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel, + @Nullable String passphrase, boolean hiddenSsid, @NonNull SparseIntArray channels, @SecurityType int securityType, int maxNumberOfClients, boolean shutdownTimeoutEnabled, long shutdownTimeoutMillis, boolean clientControlByUser, @NonNull List<MacAddress> blockedList, @NonNull List<MacAddress> allowedList, @@ -289,8 +286,12 @@ public final class SoftApConfiguration implements Parcelable { mBssid = bssid; mPassphrase = passphrase; mHiddenSsid = hiddenSsid; - mBand = band; - mChannel = channel; + if (channels.size() != 0) { + mChannels = channels.clone(); + } else { + mChannels = new SparseIntArray(1); + mChannels.put(BAND_2GHZ, 0); + } mSecurityType = securityType; mMaxNumberOfClients = maxNumberOfClients; mAutoShutdownEnabled = shutdownTimeoutEnabled; @@ -314,8 +315,7 @@ public final class SoftApConfiguration implements Parcelable { && Objects.equals(mBssid, other.mBssid) && Objects.equals(mPassphrase, other.mPassphrase) && mHiddenSsid == other.mHiddenSsid - && mBand == other.mBand - && mChannel == other.mChannel + && mChannels.toString().equals(other.mChannels.toString()) && mSecurityType == other.mSecurityType && mMaxNumberOfClients == other.mMaxNumberOfClients && mAutoShutdownEnabled == other.mAutoShutdownEnabled @@ -329,7 +329,7 @@ public final class SoftApConfiguration implements Parcelable { @Override public int hashCode() { return Objects.hash(mSsid, mBssid, mPassphrase, mHiddenSsid, - mBand, mChannel, mSecurityType, mMaxNumberOfClients, mAutoShutdownEnabled, + mChannels.toString(), mSecurityType, mMaxNumberOfClients, mAutoShutdownEnabled, mShutdownTimeoutMillis, mClientControlByUser, mBlockedClientList, mAllowedClientList, mMacRandomizationSetting); } @@ -337,21 +337,20 @@ public final class SoftApConfiguration implements Parcelable { @Override public String toString() { StringBuilder sbuf = new StringBuilder(); - sbuf.append("ssid=").append(mSsid); - if (mBssid != null) sbuf.append(" \n bssid=").append(mBssid.toString()); - sbuf.append(" \n Passphrase =").append( + sbuf.append("ssid = ").append(mSsid); + if (mBssid != null) sbuf.append(" \n bssid = ").append(mBssid.toString()); + sbuf.append(" \n Passphrase = ").append( TextUtils.isEmpty(mPassphrase) ? "<empty>" : "<non-empty>"); - sbuf.append(" \n HiddenSsid =").append(mHiddenSsid); - sbuf.append(" \n Band =").append(mBand); - sbuf.append(" \n Channel =").append(mChannel); - sbuf.append(" \n SecurityType=").append(getSecurityType()); - sbuf.append(" \n MaxClient=").append(mMaxNumberOfClients); - sbuf.append(" \n AutoShutdownEnabled=").append(mAutoShutdownEnabled); - sbuf.append(" \n ShutdownTimeoutMillis=").append(mShutdownTimeoutMillis); - sbuf.append(" \n ClientControlByUser=").append(mClientControlByUser); - sbuf.append(" \n BlockedClientList=").append(mBlockedClientList); - sbuf.append(" \n AllowedClientList=").append(mAllowedClientList); - sbuf.append(" \n MacRandomizationSetting=").append(mMacRandomizationSetting); + sbuf.append(" \n HiddenSsid = ").append(mHiddenSsid); + sbuf.append(" \n Channels = ").append(mChannels); + sbuf.append(" \n SecurityType = ").append(getSecurityType()); + sbuf.append(" \n MaxClient = ").append(mMaxNumberOfClients); + sbuf.append(" \n AutoShutdownEnabled = ").append(mAutoShutdownEnabled); + sbuf.append(" \n ShutdownTimeoutMillis = ").append(mShutdownTimeoutMillis); + sbuf.append(" \n ClientControlByUser = ").append(mClientControlByUser); + sbuf.append(" \n BlockedClientList = ").append(mBlockedClientList); + sbuf.append(" \n AllowedClientList= ").append(mAllowedClientList); + sbuf.append(" \n MacRandomizationSetting = ").append(mMacRandomizationSetting); return sbuf.toString(); } @@ -361,8 +360,7 @@ public final class SoftApConfiguration implements Parcelable { dest.writeParcelable(mBssid, flags); dest.writeString(mPassphrase); dest.writeBoolean(mHiddenSsid); - dest.writeInt(mBand); - dest.writeInt(mChannel); + writeSparseIntArray(dest, mChannels); dest.writeInt(mSecurityType); dest.writeInt(mMaxNumberOfClients); dest.writeBoolean(mAutoShutdownEnabled); @@ -373,6 +371,42 @@ public final class SoftApConfiguration implements Parcelable { dest.writeInt(mMacRandomizationSetting); } + /* Reference from frameworks/base/core/java/android/os/Parcel.java */ + private static void writeSparseIntArray(@NonNull Parcel dest, + @Nullable SparseIntArray val) { + if (val == null) { + dest.writeInt(-1); + return; + } + int n = val.size(); + dest.writeInt(n); + int i = 0; + while (i < n) { + dest.writeInt(val.keyAt(i)); + dest.writeInt(val.valueAt(i)); + i++; + } + } + + + /* Reference from frameworks/base/core/java/android/os/Parcel.java */ + @NonNull + private static SparseIntArray readSparseIntArray(@NonNull Parcel in) { + int n = in.readInt(); + if (n < 0) { + return new SparseIntArray(); + } + SparseIntArray sa = new SparseIntArray(n); + while (n > 0) { + int key = in.readInt(); + int value = in.readInt(); + sa.append(key, value); + n--; + } + return sa; + } + + @Override public int describeContents() { return 0; @@ -385,7 +419,7 @@ public final class SoftApConfiguration implements Parcelable { return new SoftApConfiguration( in.readString(), in.readParcelable(MacAddress.class.getClassLoader()), - in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt(), + in.readString(), in.readBoolean(), readSparseIntArray(in), in.readInt(), in.readInt(), in.readBoolean(), in.readLong(), in.readBoolean(), in.createTypedArrayList(MacAddress.CREATOR), in.createTypedArrayList(MacAddress.CREATOR), in.readInt()); @@ -399,7 +433,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Return String set to be the SSID for the AP. - * {@link Builder#setSsid(String)}. + * See also {@link Builder#setSsid(String)}. */ @Nullable public String getSsid() { @@ -408,7 +442,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns MAC address set to be BSSID for the AP. - * {@link Builder#setBssid(MacAddress)}. + * See also {@link Builder#setBssid(MacAddress)}. */ @Nullable public MacAddress getBssid() { @@ -417,7 +451,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns String set to be passphrase for current AP. - * {@link Builder#setPassphrase(String, int)}. + * See also {@link Builder#setPassphrase(String, int)}. */ @Nullable public String getPassphrase() { @@ -427,7 +461,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns Boolean set to be indicate hidden (true: doesn't broadcast its SSID) or * not (false: broadcasts its SSID) for the AP. - * {@link Builder#setHiddenSsid(boolean)}. + * See also {@link Builder#setHiddenSsid(boolean)}. */ public boolean isHiddenSsid() { return mHiddenSsid; @@ -436,27 +470,75 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns band type set to be the band for the AP. * - * One or combination of the following band type: - * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, {@link #BAND_6GHZ}. + * One or combination of {@code BAND_}, for instance + * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, or {@code BAND_2GHZ | BAND_5GHZ}. + * + * Note: Returns the lowest band when more than one band is set. + * Use {@link #getBands()} to get dual bands setting. * - * {@link Builder#setBand(int)}. + * See also {@link Builder#setBand(int)}. * * @hide */ @SystemApi public @BandType int getBand() { - return mBand; + return mChannels.keyAt(0); + } + + /** + * Returns a sorted array in ascending order that consists of the configured band types + * for the APs. + * + * The band type is one or combination of {@code BAND_}, for instance + * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, or {@code BAND_2GHZ | BAND_5GHZ}. + * + * Note: return array may only include one band when current setting is single AP mode. + * See also {@link Builder#setBands(int[])}. + * + * @hide + */ + @SystemApi + public @NonNull int[] getBands() { + if (!SdkLevel.isAtLeastS()) { + throw new UnsupportedOperationException(); + } + int[] bands = new int[mChannels.size()]; + for (int i = 0; i < bands.length; i++) { + bands[i] = mChannels.keyAt(i); + } + return bands; } /** * Returns Integer set to be the channel for the AP. - * {@link Builder#setChannel(int)}. + * + * Note: Returns the channel which associated to the lowest band if more than one channel + * is set. Use {@link Builder#getChannels()} to get dual channel setting. + * See also {@link Builder#setChannel(int, int)}. * * @hide */ @SystemApi public int getChannel() { - return mChannel; + return mChannels.valueAt(0); + } + + + /** + * Returns SparseIntArray (key: {@code BandType} , value: channel) that consists of + * the configured bands and channels for the AP(s). + * + * Note: return array may only include one channel when current setting is single AP mode. + * See also {@link Builder#setChannels(SparseIntArray)}. + * + * @hide + */ + @SystemApi + public @NonNull SparseIntArray getChannels() { + if (!SdkLevel.isAtLeastS()) { + throw new UnsupportedOperationException(); + } + return mChannels; } /** @@ -474,7 +556,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns the maximum number of clients that can associate to the AP. - * {@link Builder#setMaxNumberOfClients(int)}. + * See also {@link Builder#setMaxNumberOfClients(int)}. * * @hide */ @@ -486,7 +568,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns whether auto shutdown is enabled or not. * The Soft AP will shutdown when there are no devices associated to it for - * the timeout duration. See {@link Builder#setAutoShutdownEnabled(boolean)}. + * the timeout duration. See also {@link Builder#setAutoShutdownEnabled(boolean)}. * * @hide */ @@ -498,7 +580,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns the shutdown timeout in milliseconds. * The Soft AP will shutdown when there are no devices associated to it for - * the timeout duration. See {@link Builder#setShutdownTimeoutMillis(long)}. + * the timeout duration. See also {@link Builder#setShutdownTimeoutMillis(long)}. * * @hide */ @@ -510,7 +592,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns a flag indicating whether clients need to be pre-approved by the user. * (true: authorization required) or not (false: not required). - * {@link Builder#setClientControlByUserEnabled(Boolean)}. + * See also {@link Builder#setClientControlByUserEnabled(Boolean)}. * * @hide */ @@ -546,14 +628,14 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns the level of MAC randomization for the AP BSSID. - * {@link Builder#setMacRandomizationSetting(int)}. + * See also {@link Builder#setMacRandomizationSetting(int)}. * * @hide */ @SystemApi @MacRandomizationSetting public int getMacRandomizationSetting() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } return mMacRandomizationSetting; @@ -578,7 +660,7 @@ public final class SoftApConfiguration implements Parcelable { wifiConfig.SSID = mSsid; wifiConfig.preSharedKey = mPassphrase; wifiConfig.hiddenSSID = mHiddenSsid; - wifiConfig.apChannel = mChannel; + wifiConfig.apChannel = getChannel(); switch (mSecurityType) { case SECURITY_TYPE_OPEN: wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); @@ -592,7 +674,7 @@ public final class SoftApConfiguration implements Parcelable { return null; } - switch (mBand) { + switch (getBand()) { case BAND_2GHZ: wifiConfig.apBand = WifiConfiguration.AP_BAND_2GHZ; break; @@ -606,7 +688,7 @@ public final class SoftApConfiguration implements Parcelable { wifiConfig.apBand = WifiConfiguration.AP_BAND_ANY; break; default: - Log.e(TAG, "Convert fail, unsupported band setting :" + mBand); + Log.e(TAG, "Convert fail, unsupported band setting :" + getBand()); return null; } return wifiConfig; @@ -627,8 +709,7 @@ public final class SoftApConfiguration implements Parcelable { private MacAddress mBssid; private String mPassphrase; private boolean mHiddenSsid; - private int mBand; - private int mChannel; + private SparseIntArray mChannels; private int mMaxNumberOfClients; private int mSecurityType; private boolean mAutoShutdownEnabled; @@ -646,8 +727,8 @@ public final class SoftApConfiguration implements Parcelable { mBssid = null; mPassphrase = null; mHiddenSsid = false; - mBand = BAND_2GHZ; - mChannel = 0; + mChannels = new SparseIntArray(1); + mChannels.put(BAND_2GHZ, 0); mMaxNumberOfClients = 0; mSecurityType = SECURITY_TYPE_OPEN; mAutoShutdownEnabled = true; // enabled by default. @@ -668,8 +749,7 @@ public final class SoftApConfiguration implements Parcelable { mBssid = other.mBssid; mPassphrase = other.mPassphrase; mHiddenSsid = other.mHiddenSsid; - mBand = other.mBand; - mChannel = other.mChannel; + mChannels = other.mChannels.clone(); mMaxNumberOfClients = other.mMaxNumberOfClients; mSecurityType = other.mSecurityType; mAutoShutdownEnabled = other.mAutoShutdownEnabled; @@ -693,7 +773,7 @@ public final class SoftApConfiguration implements Parcelable { } } return new SoftApConfiguration(mSsid, mBssid, mPassphrase, - mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients, + mHiddenSsid, mChannels, mSecurityType, mMaxNumberOfClients, mAutoShutdownEnabled, mShutdownTimeoutMillis, mClientControlByUser, mBlockedClientList, mAllowedClientList, mMacRandomizationSetting); } @@ -724,6 +804,22 @@ public final class SoftApConfiguration implements Parcelable { * Specifies a BSSID for the AP. * <p> * <li>If not set, defaults to null.</li> + * + * If multiple bands are requested via {@link #setBands(int[])} or + * {@link #setChannels(SparseIntArray)}, HAL will derive 2 MAC addresses since framework + * only sends down 1 MAC address. + * + * An example (but different implementation may perform a different mapping): + * <li>MAC address 1: copy value of MAC address, + * and set byte 1 = (0xFF - BSSID[1])</li> + * <li>MAC address 2: copy value of MAC address, + * and set byte 2 = (0xFF - BSSID[2])</li> + * + * Example BSSID argument: e2:38:60:c4:0e:b7 + * Derived MAC address 1: e2:c7:60:c4:0e:b7 + * Derived MAC address 2: e2:38:9f:c4:0e:b7 + * + * * @param bssid BSSID, or null to have the BSSID chosen by the framework. The caller is * responsible for avoiding collisions. * @return Builder for chaining. @@ -807,19 +903,48 @@ public final class SoftApConfiguration implements Parcelable { * @param band One or combination of the following band type: * {@link #BAND_2GHZ}, {@link #BAND_5GHZ}, {@link #BAND_6GHZ}. * @return Builder for chaining. + * @throws IllegalArgumentException when an invalid band type is provided. */ @NonNull public Builder setBand(@BandType int band) { if (!isBandValid(band)) { - throw new IllegalArgumentException("Invalid band type"); + throw new IllegalArgumentException("Invalid band type: " + band); } - mBand = band; - // Since band preference is specified, no specific channel is selected. - mChannel = 0; + mChannels = new SparseIntArray(1); + mChannels.put(band, 0); return this; } /** + * Specifies the bands for the APs. + * If more than 1 band is set, this will bring up concurrent APs. + * on the requested bands (if possible). + * <p> + * + * @param bands Array of the {@link #BandType}. + * @return Builder for chaining. + * @throws IllegalArgumentException when more than 2 bands are set or an invalid band type + * is provided. + */ + @NonNull + public Builder setBands(@NonNull int[] bands) { + if (bands.length == 0 || bands.length > 2) { + throw new IllegalArgumentException("Unsupported number of bands(" + + bands.length + ") configured"); + } + SparseIntArray channels = new SparseIntArray(bands.length); + for (int val : bands) { + if (!isBandValid(val)) { + throw new IllegalArgumentException("Invalid band type: " + val); + } + channels.put(val, 0); + } + mChannels = channels; + return this; + } + + + /** * Specifies the channel and associated band for the AP. * * The channel which AP resides on. Valid channels are country dependent. @@ -827,36 +952,86 @@ public final class SoftApConfiguration implements Parcelable { * valid channels. * * <p> - * The default for the channel is a the special value 0 to have the framework - * auto-select a valid channel from the band configured with + * If not set, the default for the channel is the special value 0 which has the + * framework auto-select a valid channel from the band configured with * {@link #setBand(int)}. * - * The channel auto selection will offload to driver when + * The channel auto selection will be offloaded to driver when * {@link SoftApCapability#areFeaturesSupported( * SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)} - * return true. Driver will auto select best channel which based on environment - * interference to get best performance. Check {@link SoftApCapability} to get more detail. + * returns true. The driver will auto select the best channel (e.g. best performance) + * based on environment interference. Check {@link SoftApCapability} for more detail. * - * Note, since 6GHz band use the same channel numbering of 2.4GHz and 5GHZ bands, - * the caller needs to pass the band containing the selected channel. + * The API contains (band, channel) input since the 6GHz band uses the same channel + * numbering scheme as is used in the 2.4GHz and 5GHz band. Therefore, both are needed to + * uniquely identify individual channels. * * <p> - * <li>If not set, defaults to 0.</li> * @param channel operating channel of the AP. * @param band containing this channel. * @return Builder for chaining. + * @throws IllegalArgumentException when the invalid channel or band type is configured. */ @NonNull public Builder setChannel(int channel, @BandType int band) { if (!isChannelBandPairValid(channel, band)) { - throw new IllegalArgumentException("Invalid band type"); + throw new IllegalArgumentException("Invalid channel(" + channel + + ") & band (" + band + ") configured"); } - mBand = band; - mChannel = channel; + mChannels = new SparseIntArray(1); + mChannels.put(band, channel); return this; } /** + * Specifies the channels and associated bands for the APs. + * + * When more than 1 channel is set, this will bring up concurrent APs on the requested + * channels and bands (if possible). + * + * Valid channels are country dependent. + * The {@link SoftApCapability#getSupportedChannelList(int)} can be used to obtain + * valid channels in each band. + * + * <p> + * If not set, the default for the channel is the special value 0 which has the framework + * auto-select a valid channel from the band configured with {@link #setBands(int[])}. + * + * The channel auto selection will be offloaded to driver when + * {@link SoftApCapability#areFeaturesSupported( + * SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)} + * returns true. The driver will auto select the best channel (e.g. best performance) + * based on environment interference. Check {@link SoftApCapability} for more detail. + * + * The API contains (band, channel) input since the 6GHz band uses the same channel + * numbering scheme as is used in the 2.4GHz and 5GHz band. Therefore, both are needed to + * uniquely identify individual channels. + * + * <p> + * @param channels SparseIntArray (key: {@code #BandType} , value: channel) consists of + * {@code BAND_} and corresponding channel. + * @return Builder for chaining. + * @throws IllegalArgumentException when more than 2 channels are set or the invalid + * channel or band type is configured. + */ + @NonNull + public Builder setChannels(@NonNull SparseIntArray channels) { + if (channels.size() == 0 || channels.size() > 2) { + throw new IllegalArgumentException("Unsupported number of channels(" + + channels.size() + ") configured"); + } + for (int i = 0; i < channels.size(); i++) { + if (!isChannelBandPairValid(channels.valueAt(i), channels.keyAt(i))) { + throw new IllegalArgumentException("Invalid channel(" + channels.valueAt(i) + + ") & band (" + channels.keyAt(i) + ") configured"); + } + } + mChannels = channels.clone(); + return this; + } + + + /** * Specifies the maximum number of clients that can associate to the AP. * * The maximum number of clients (STAs) which can associate to the AP. @@ -1044,7 +1219,7 @@ public final class SoftApConfiguration implements Parcelable { @NonNull public Builder setMacRandomizationSetting( @MacRandomizationSetting int macRandomizationSetting) { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } mMacRandomizationSetting = macRandomizationSetting; diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java index cf61f81e6d22..9a16facfec26 100644 --- a/wifi/java/android/net/wifi/SoftApInfo.java +++ b/wifi/java/android/net/wifi/SoftApInfo.java @@ -20,11 +20,11 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.MacAddress; -import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.util.Preconditions; +import com.android.modules.utils.build.SdkLevel; import java.util.Objects; @@ -141,7 +141,7 @@ public final class SoftApInfo implements Parcelable { */ @Nullable public MacAddress getBssid() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } return mBssid; @@ -180,7 +180,7 @@ public final class SoftApInfo implements Parcelable { * @return valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} */ public @WifiAnnotations.WifiStandard int getWifiStandard() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } return mWifiStandard; diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index fd4e1ddac3a2..9a8a5ad4b41f 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -906,7 +906,7 @@ public class WifiConfiguration implements Parcelable { * @hide * Number of reports indicating no Internet Access */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int numNoInternetAccessReports; /** @@ -926,7 +926,7 @@ public class WifiConfiguration implements Parcelable { * this configuration and selects "don't ask again". * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean noInternetAccessExpected; /** @@ -966,7 +966,7 @@ public class WifiConfiguration implements Parcelable { * @deprecated only kept for @UnsupportedAppUsage * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean selfAdded; /** diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 2ca2d1e39049..8ee08f1610d6 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -44,7 +44,6 @@ import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; import android.net.wifi.hotspot2.ProvisioningCallback; -import android.net.wifi.util.SdkLevelUtil; import android.os.Binder; import android.os.Build; import android.os.Handler; @@ -62,6 +61,7 @@ import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.modules.utils.build.SdkLevel; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -1055,7 +1055,7 @@ public class WifiManager { * @see #ACTION_LINK_CONFIGURATION_CHANGED * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final String LINK_CONFIGURATION_CHANGED_ACTION = "android.net.wifi.LINK_CONFIGURATION_CHANGED"; @@ -1265,7 +1265,7 @@ public class WifiManager { * change is significant enough to change the RSSI signal level. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int RSSI_LEVELS = 5; //TODO (b/146346676): This needs to be removed, not used in the code. @@ -2493,7 +2493,7 @@ public class WifiManager { * @return true if this device supports multiple STA concurrency, false otherwise. */ public boolean isMultiStaConcurrencySupported() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA); diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 0b368708d283..acae218b74e0 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -26,7 +26,6 @@ import android.annotation.SystemApi; import android.net.MacAddress; import android.net.NetworkCapabilities; import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; import android.os.Parcelable; import android.telephony.SubscriptionInfo; @@ -34,6 +33,8 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; +import com.android.modules.utils.build.SdkLevel; + import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; import java.util.List; @@ -451,7 +452,7 @@ public final class WifiNetworkSuggestion implements Parcelable { * @return Instance of {@link Builder} to enable chaining of the builder method. */ public @NonNull Builder setSubscriptionId(int subId) { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } mSubscriptionId = subId; @@ -466,7 +467,7 @@ public final class WifiNetworkSuggestion implements Parcelable { * @return Instance of {@link Builder} to enable chaining of the builder method. */ public @NonNull Builder setPriorityGroup(int priorityGroup) { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } mPriorityGroup = priorityGroup; @@ -707,7 +708,7 @@ public final class WifiNetworkSuggestion implements Parcelable { */ @SystemApi public @NonNull Builder setOemPaid(boolean isOemPaid) { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } mIsNetworkOemPaid = isOemPaid; @@ -1204,7 +1205,7 @@ public final class WifiNetworkSuggestion implements Parcelable { */ @SystemApi public boolean isOemPaid() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } return wifiConfiguration.oemPaid; @@ -1242,7 +1243,7 @@ public final class WifiNetworkSuggestion implements Parcelable { * @see Builder#setPriorityGroup(int) */ public int getPriorityGroup() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } return priorityGroup; @@ -1252,7 +1253,7 @@ public final class WifiNetworkSuggestion implements Parcelable { * @see Builder#setSubscriptionId(int) */ public int getSubscriptionId() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } return wifiConfiguration.subscriptionId; diff --git a/wifi/java/android/net/wifi/aware/AwareResources.java b/wifi/java/android/net/wifi/aware/AwareResources.java new file mode 100644 index 000000000000..cee1f40c05cd --- /dev/null +++ b/wifi/java/android/net/wifi/aware/AwareResources.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.aware; + +import android.annotation.NonNull; +import android.os.Handler; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * The resources of the Aware service. + */ +public final class AwareResources implements Parcelable { + /** + * Number of the NDPs are available. + */ + private int mNumOfAvailableNdps; + + /** + * Number of the publish sessions are available. + */ + private int mNumOfAvailablePublishSessions; + + /** + * Number of the subscribe sessions are available. + */ + private int mNumOfAvailableSubscribeSessions; + + /** + * @hide : should not be created by apps + */ + public AwareResources() { + } + + /** + * Return the number of Aware data-paths (also known as NDPs - NAN Data Paths) which an app + * could create. Please refer to the {@link WifiAwareNetworkSpecifier} to create + * a Network Specifier and request a data-path. + * <p> + * Note that these resources aren't reserved - other apps could use them by the time you + * attempt to create a data-path. + * </p> + * @return A Non-negative integer, number of data-paths that could be created. + */ + public int getNumOfAvailableDataPaths() { + return mNumOfAvailableNdps; + } + + /** + * Return the number of Aware publish sessions which an app could create. Please refer to the + * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback, Handler)} + * to create a publish session. + * <p> + * Note that these resources aren't reserved - other apps could use them by the time you + * attempt to create a publish session. + * </p> + * @return A Non-negative integer, number of publish sessions that could be created. + */ + public int getNumOfAvailablePublishSessions() { + return mNumOfAvailablePublishSessions; + } + + /** + * Return the number of Aware subscribe sessions which an app could create. Please refer to the + * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback, Handler)} + * to create a publish session. + * <p> + * Note that these resources aren't reserved - other apps could use them by the time you + * attempt to create a subscribe session. + * </p> + * @return A Non-negative integer, number of subscribe sessions that could be created. + */ + public int getNumOfAvailableSubscribeSessions() { + return mNumOfAvailableSubscribeSessions; + } + + /** + * Set the number of the available NDPs. + * @hide + * @param numOfAvailableNdps Number of available NDPs. + */ + public void setNumOfAvailableDataPaths(int numOfAvailableNdps) { + mNumOfAvailableNdps = numOfAvailableNdps; + } + + /** + * Set the number of the available publish sessions. + * @hide + * @param numOfAvailablePublishSessions Number of available publish sessions. + */ + public void setNumOfAvailablePublishSessions(int numOfAvailablePublishSessions) { + mNumOfAvailablePublishSessions = numOfAvailablePublishSessions; + } + + /** + * Set the number of the available subscribe sessions. + * @hide + * @param numOfAvailableSubscribeSessions Number of available subscribe sessions. + */ + public void setNumOfAvailableSubscribeSessions(int numOfAvailableSubscribeSessions) { + mNumOfAvailableSubscribeSessions = numOfAvailableSubscribeSessions; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mNumOfAvailableNdps); + dest.writeInt(mNumOfAvailablePublishSessions); + dest.writeInt(mNumOfAvailableSubscribeSessions); + } + + public static final @android.annotation.NonNull Creator<AwareResources> CREATOR = + new Creator<AwareResources>() { + @Override + public AwareResources createFromParcel(Parcel in) { + AwareResources awareResources = new AwareResources(); + awareResources.setNumOfAvailableDataPaths(in.readInt()); + awareResources.setNumOfAvailablePublishSessions(in.readInt()); + awareResources.setNumOfAvailableSubscribeSessions(in.readInt()); + return awareResources; + } + + @Override + public AwareResources[] newArray(int size) { + return new AwareResources[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/aware/Characteristics.java b/wifi/java/android/net/wifi/aware/Characteristics.java index 116786516b3b..9bdda7f7d323 100644 --- a/wifi/java/android/net/wifi/aware/Characteristics.java +++ b/wifi/java/android/net/wifi/aware/Characteristics.java @@ -17,11 +17,12 @@ package android.net.wifi.aware; import android.annotation.IntDef; -import android.net.wifi.util.SdkLevelUtil; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import com.android.modules.utils.build.SdkLevel; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -92,7 +93,7 @@ public final class Characteristics implements Parcelable { * @return True if supported, false otherwise. */ public boolean isInstantCommunicationModeSupported() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } return mCharacteristics.getBoolean(KEY_IS_INSTANT_COMMUNICATION_MODE_SUPPORTED); diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl index cd2ca692137d..c90c4d8a27b2 100644 --- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl +++ b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl @@ -25,6 +25,7 @@ import android.net.wifi.aware.IWifiAwareMacAddressProvider; import android.net.wifi.aware.PublishConfig; import android.net.wifi.aware.SubscribeConfig; import android.net.wifi.aware.Characteristics; +import android.net.wifi.aware.AwareResources; /** * Interface that WifiAwareService implements @@ -36,6 +37,7 @@ interface IWifiAwareManager // Aware API boolean isUsageEnabled(); Characteristics getCharacteristics(); + AwareResources getAvailableAwareResources(); boolean isDeviceAttached(); void enableInstantCommunicationMode(in String callingPackage, boolean enable); boolean isInstantCommunicationModeEnabled(); diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java index bb146e37d48c..d7cdf07a44b2 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -29,7 +29,6 @@ import android.net.ConnectivityManager; import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.wifi.util.HexEncoding; -import android.net.wifi.util.SdkLevelUtil; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -39,6 +38,8 @@ import android.os.Message; import android.os.RemoteException; import android.util.Log; +import com.android.modules.utils.build.SdkLevel; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; @@ -210,7 +211,7 @@ public class WifiAwareManager { * or not (false). */ public boolean isDeviceAttached() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } try { @@ -229,7 +230,7 @@ public class WifiAwareManager { */ @SystemApi public void enableInstantCommunicationMode(boolean enable) { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } try { @@ -246,7 +247,7 @@ public class WifiAwareManager { * @return true if it is enabled, false otherwise. */ public boolean isInstantCommunicationModeEnabled() { - if (!SdkLevelUtil.isAtLeastS()) { + if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } try { @@ -262,7 +263,7 @@ public class WifiAwareManager { * * @return An object specifying configuration limitations of Aware. */ - public Characteristics getCharacteristics() { + public @Nullable Characteristics getCharacteristics() { try { return mService.getCharacteristics(); } catch (RemoteException e) { @@ -271,6 +272,23 @@ public class WifiAwareManager { } /** + * Return the available resources of the Wi-Fi aware service: a set of parameters which specify + * limitations on service usage, e.g the number of data-paths which could be created.. + * + * @return An object specifying the currently available resource of the Wi-Fi Aware service. + */ + public @Nullable AwareResources getAvailableAwareResources() { + if (!SdkLevelUtil.isAtLeastS()) { + throw new UnsupportedOperationException(); + } + try { + return mService.getAvailableAwareResources(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Attach to the Wi-Fi Aware service - enabling the application to create discovery sessions or * create connections to peers. The device will attach to an existing cluster if it can find * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index d47989235f0b..d3a6bac2513f 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -23,6 +23,7 @@ import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.net.MacAddress; import android.net.wifi.WpsInfo; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -138,7 +139,7 @@ public class WifiP2pConfig implements Parcelable { public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int netId = WifiP2pGroup.NETWORK_ID_PERSISTENT; /** diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index 710175fee747..567637af02c7 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -19,6 +19,7 @@ package android.net.wifi.p2p; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; @@ -185,7 +186,7 @@ public class WifiP2pDevice implements Parcelable { * Note: The events formats can be looked up in the wpa_supplicant code * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public WifiP2pDevice(String string) throws IllegalArgumentException { String[] tokens = string.split("[ \n]"); Matcher match; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java index ededf67fec7f..e7866e618089 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java @@ -17,6 +17,7 @@ package android.net.wifi.p2p; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -83,7 +84,7 @@ public class WifiP2pDeviceList implements Parcelable { * @param device to be updated * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void update(WifiP2pDevice device) { updateSupplicantDetails(device); mDevices.get(device.deviceAddress).status = device.status; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index ad38c5af07fc..13ac7a0bf966 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -399,7 +399,7 @@ public class WifiP2pManager { public static final int CANCEL_CONNECT_SUCCEEDED = BASE + 12; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final int CREATE_GROUP = BASE + 13; /** @hide */ public static final int CREATE_GROUP_FAILED = BASE + 14; @@ -1105,7 +1105,7 @@ public class WifiP2pManager { } } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int putListener(Object listener) { if (listener == null) return INVALID_LISTENER_KEY; int key; @@ -1417,7 +1417,7 @@ public class WifiP2pManager { * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void startWps(Channel c, WpsInfo wps, ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(START_WPS, 0, c.putListener(listener), wps); @@ -1698,7 +1698,7 @@ public class WifiP2pManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setWFDInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo, @Nullable ActionListener listener) { diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java index 37b442baeb3f..5d018e75488e 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java @@ -170,7 +170,7 @@ public class WifiP2pServiceInfo implements Parcelable { } /** Implement the Parcelable interface {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Creator<WifiP2pServiceInfo> CREATOR = new Creator<WifiP2pServiceInfo>() { public WifiP2pServiceInfo createFromParcel(Parcel in) { diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java index 68cbb88037b0..dea0477cf09b 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java @@ -265,7 +265,7 @@ public class WifiP2pServiceRequest implements Parcelable { } /** Implement the Parcelable interface {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static final @android.annotation.NonNull Creator<WifiP2pServiceRequest> CREATOR = new Creator<WifiP2pServiceRequest>() { public WifiP2pServiceRequest createFromParcel(Parcel in) { diff --git a/wifi/java/android/net/wifi/util/SdkLevelUtil.java b/wifi/java/android/net/wifi/util/SdkLevelUtil.java deleted file mode 100644 index d08d4fd742b7..000000000000 --- a/wifi/java/android/net/wifi/util/SdkLevelUtil.java +++ /dev/null @@ -1,68 +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 android.net.wifi.util; - -import android.os.Build; - -/** - * Utility to check the SDK version of the device that the code is running on. - * - * This can be used to disable new Wifi APIs added in Mainline updates on older SDK versions. - * - * Note: if certain functionality is gated with SdkLevelUtil, its corresponding unit tests should - * also be gated by the same condition. Then, those unit tests will only be exercised on a base - * system image satisfying that condition. - * Alternatively, it can be tested via static mocking. - * - * @hide - */ -public class SdkLevelUtil { - - /** This class is not instantiable. */ - private SdkLevelUtil() {} - - /** Returns true if the Android platform SDK is at least "S", false otherwise. */ - public static boolean isAtLeastS() { - // TODO(b/167575586): after S SDK finalization, this method should just be - // `return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;` - - // at least S: return true - // this condition only evaluates to true after S SDK finalization when VERSION_CODES.S - // is set to something like "31", before SDK finalization the value is "10000" - // Note that Build.VERSION_CODES.S is inlined at compile time. If it's inlined to 10000, - // this condition never evaluates to true. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - return true; - } - - // Assume for now that S = R + 1 - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) { - return true; - } - - // R: check CODENAME - // Before S SDK finalization, SDK_INT = R = 30 i.e. remains on the previous version - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) { - // CODENAME = "REL" on R release builds - // CODENAME = "S" on S development builds - return "S".equals(Build.VERSION.CODENAME); - } - - // older than R: return false - return false; - } -} diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp index 6a39959e8cfd..b710a1492d8c 100644 --- a/wifi/tests/Android.bp +++ b/wifi/tests/Android.bp @@ -31,10 +31,11 @@ android_test { static_libs: [ "androidx.test.rules", "core-test-rules", + "frameworks-base-testutils", "guava", "mockito-target-minus-junit4", + "modules-utils-build", "net-tests-utils", - "frameworks-base-testutils", "truth-prebuilt", ], @@ -47,4 +48,8 @@ android_test { "device-tests", "mts", ], + + // static libs used by both framework-wifi & FrameworksWifiApiTests. Need to rename test usage + // to a different package name to prevent conflict with the copy in production code. + jarjar_rules: "test-jarjar-rules.txt", } diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java index 3c935058787b..702212b324f6 100644 --- a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java @@ -16,14 +16,15 @@ package android.net.wifi; -import android.net.wifi.util.SdkLevelUtil; -import android.os.Parcel; - import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeTrue; +import android.os.Parcel; + import androidx.test.filters.SmallTest; +import com.android.modules.utils.build.SdkLevel; + import org.junit.Test; /** @@ -93,7 +94,7 @@ public class SoftApCapabilityTest { @Test(expected = IllegalArgumentException.class) public void testGetSupportedChannelListWithInvalidBand() { - assumeTrue(SdkLevelUtil.isAtLeastS()); + assumeTrue(SdkLevel.isAtLeastS()); long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index 7877ea11ca1f..4a94f1f47962 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -19,16 +19,20 @@ package android.net.wifi; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import android.net.MacAddress; -import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; +import android.util.SparseIntArray; import androidx.test.filters.SmallTest; +import com.android.modules.utils.build.SdkLevel; + import org.junit.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Random; @@ -81,7 +85,7 @@ public class SoftApConfigurationTest { assertThat(original.getChannel()).isEqualTo(0); assertThat(original.isHiddenSsid()).isEqualTo(false); assertThat(original.getMaxNumberOfClients()).isEqualTo(0); - if (SdkLevelUtil.isAtLeastS()) { + if (SdkLevel.isAtLeastS()) { assertThat(original.getMacRandomizationSetting()) .isEqualTo(SoftApConfiguration.RANDOMIZATION_PERSISTENT); } @@ -137,7 +141,7 @@ public class SoftApConfigurationTest { .setClientControlByUserEnabled(true) .setBlockedClientList(testBlockedClientList) .setAllowedClientList(testAllowedClientList); - if (SdkLevelUtil.isAtLeastS()) { + if (SdkLevel.isAtLeastS()) { originalBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE); } SoftApConfiguration original = originalBuilder.build(); @@ -153,7 +157,7 @@ public class SoftApConfigurationTest { assertThat(original.isClientControlByUserEnabled()).isEqualTo(true); assertThat(original.getBlockedClientList()).isEqualTo(testBlockedClientList); assertThat(original.getAllowedClientList()).isEqualTo(testAllowedClientList); - if (SdkLevelUtil.isAtLeastS()) { + if (SdkLevel.isAtLeastS()) { assertThat(original.getMacRandomizationSetting()) .isEqualTo(SoftApConfiguration.RANDOMIZATION_NONE); } @@ -364,4 +368,135 @@ public class SoftApConfigurationTest { .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); assertThat(wifiConfig_sae_transition.preSharedKey).isEqualTo("secretsecret"); } + + @Test + public void testDualBands() { + int[] dual_bands = new int[2]; + dual_bands[0] = SoftApConfiguration.BAND_2GHZ; + dual_bands[1] = SoftApConfiguration.BAND_5GHZ; + SoftApConfiguration dual_bands_config = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setBands(dual_bands) + .build(); + assertTrue(Arrays.equals(dual_bands, dual_bands_config.getBands())); + assertThat(dual_bands_config.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); + } + + @Test + public void testDualChannels() { + int[] expected_dual_bands = new int[2]; + expected_dual_bands[0] = SoftApConfiguration.BAND_2GHZ; + expected_dual_bands[1] = SoftApConfiguration.BAND_5GHZ; + SparseIntArray dual_channels = new SparseIntArray(2); + dual_channels.put(SoftApConfiguration.BAND_5GHZ, 149); + dual_channels.put(SoftApConfiguration.BAND_2GHZ, 2); + SoftApConfiguration dual_channels_config = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setChannels(dual_channels) + .build(); + assertTrue(Arrays.equals(expected_dual_bands, dual_channels_config.getBands())); + assertThat(dual_channels_config.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); + assertTrue(dual_channels.toString().equals(dual_channels_config.getChannels().toString())); + assertThat(dual_channels_config.getChannel()).isEqualTo(2); + } + + @Test + public void testInvalidBandWhenSetBands() { + boolean isIllegalArgumentExceptionHappened = false; + int[] dual_bands = new int[2]; + dual_bands[0] = SoftApConfiguration.BAND_2GHZ; + dual_bands[1] = -1; + try { + SoftApConfiguration dual_channels_config = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setBands(dual_bands) + .build(); + isIllegalArgumentExceptionHappened = false; + } catch (IllegalArgumentException iae) { + isIllegalArgumentExceptionHappened = true; + } + assertTrue(isIllegalArgumentExceptionHappened); + + try { + SoftApConfiguration dual_channels_config = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setBands(new int[0]) + .build(); + isIllegalArgumentExceptionHappened = false; + } catch (IllegalArgumentException iae) { + isIllegalArgumentExceptionHappened = true; + } + assertTrue(isIllegalArgumentExceptionHappened); + + try { + SoftApConfiguration dual_channels_config = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setBands(new int[3]) + .build(); + isIllegalArgumentExceptionHappened = false; + } catch (IllegalArgumentException iae) { + isIllegalArgumentExceptionHappened = true; + } + assertTrue(isIllegalArgumentExceptionHappened); + } + + @Test + public void testInvalidConfigWhenSetChannels() { + boolean isIllegalArgumentExceptionHappened = false; + SparseIntArray invalid_channels = new SparseIntArray(); + try { + SoftApConfiguration zero_channels_config = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setChannels(invalid_channels) + .build(); + isIllegalArgumentExceptionHappened = false; + } catch (IllegalArgumentException iae) { + isIllegalArgumentExceptionHappened = true; + } + assertTrue(isIllegalArgumentExceptionHappened); + + try { + invalid_channels.clear(); + invalid_channels.put(SoftApConfiguration.BAND_2GHZ, 2); + invalid_channels.put(SoftApConfiguration.BAND_5GHZ, 11); + SoftApConfiguration invalid_band_channels_config = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setChannels(invalid_channels) + .build(); + isIllegalArgumentExceptionHappened = false; + } catch (IllegalArgumentException iae) { + isIllegalArgumentExceptionHappened = true; + } + assertTrue(isIllegalArgumentExceptionHappened); + + try { + invalid_channels.clear(); + invalid_channels.put(SoftApConfiguration.BAND_2GHZ, 2); + invalid_channels.put(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ, + 149); + SoftApConfiguration invalid_dual_channels_config = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setChannels(invalid_channels) + .build(); + isIllegalArgumentExceptionHappened = false; + } catch (IllegalArgumentException iae) { + isIllegalArgumentExceptionHappened = true; + } + assertTrue(isIllegalArgumentExceptionHappened); + + try { + invalid_channels.clear(); + invalid_channels.put(SoftApConfiguration.BAND_2GHZ, 2); + invalid_channels.put(SoftApConfiguration.BAND_5GHZ, 149); + invalid_channels.put(SoftApConfiguration.BAND_6GHZ, 2); + SoftApConfiguration three_channels_config = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setChannels(invalid_channels) + .build(); + isIllegalArgumentExceptionHappened = false; + } catch (IllegalArgumentException iae) { + isIllegalArgumentExceptionHappened = true; + } + assertTrue(isIllegalArgumentExceptionHappened); + } } diff --git a/wifi/tests/src/android/net/wifi/SoftApInfoTest.java b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java index 2821c35f9347..28758432119c 100644 --- a/wifi/tests/src/android/net/wifi/SoftApInfoTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java @@ -16,14 +16,15 @@ package android.net.wifi; +import static org.junit.Assert.assertEquals; + import android.net.MacAddress; -import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; -import static org.junit.Assert.assertEquals; - import androidx.test.filters.SmallTest; +import com.android.modules.utils.build.SdkLevel; + import org.junit.Test; /** @@ -84,7 +85,7 @@ public class SoftApInfoTest { SoftApInfo info = new SoftApInfo(); assertEquals(info.getFrequency(), 0); assertEquals(info.getBandwidth(), SoftApInfo.CHANNEL_WIDTH_INVALID); - if (SdkLevelUtil.isAtLeastS()) { + if (SdkLevel.isAtLeastS()) { assertEquals(info.getBssid(), null); assertEquals(info.getWifiStandard(), ScanResult.WIFI_STANDARD_UNKNOWN); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index bda776db733c..7340b145e8b2 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -86,7 +86,6 @@ import android.net.wifi.WifiManager.SoftApCallback; import android.net.wifi.WifiManager.SuggestionConnectionStatusListener; import android.net.wifi.WifiManager.TrafficStateCallback; import android.net.wifi.WifiManager.WifiConnectedNetworkScorer; -import android.net.wifi.util.SdkLevelUtil; import android.os.Build; import android.os.Handler; import android.os.HandlerExecutor; @@ -98,6 +97,8 @@ import android.util.SparseArray; import androidx.test.filters.SmallTest; +import com.android.modules.utils.build.SdkLevel; + import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -1729,7 +1730,7 @@ public class WifiManagerTest { */ @Test public void testIsMultiStaConcurrencyOpenSupported() throws Exception { - assumeTrue(SdkLevelUtil.isAtLeastS()); + assumeTrue(SdkLevel.isAtLeastS()); when(mWifiService.getSupportedFeatures()) .thenReturn(new Long(WIFI_FEATURE_ADDITIONAL_STA)); diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index bb84120da6ed..56e79983817f 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -27,11 +27,12 @@ import static org.junit.Assume.assumeTrue; import android.net.MacAddress; import android.net.wifi.hotspot2.PasspointConfiguration; import android.net.wifi.hotspot2.PasspointTestUtils; -import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; import androidx.test.filters.SmallTest; +import com.android.modules.utils.build.SdkLevel; + import org.junit.Test; import java.security.cert.X509Certificate; @@ -198,7 +199,7 @@ public class WifiNetworkSuggestionTest { */ @Test public void testWifiNetworkSuggestionBuilderForOemPaidEnhancedOpenNetworkWithBssid() { - assumeTrue(SdkLevelUtil.isAtLeastS()); + assumeTrue(SdkLevel.isAtLeastS()); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) @@ -953,7 +954,7 @@ public class WifiNetworkSuggestionTest { */ @Test public void testSimCredentialNetworkWithSubId() { - assumeTrue(SdkLevelUtil.isAtLeastS()); + assumeTrue(SdkLevel.isAtLeastS()); WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE); @@ -1254,7 +1255,7 @@ public class WifiNetworkSuggestionTest { */ @Test public void testSetIsNetworkAsOemPaid() { - assumeTrue(SdkLevelUtil.isAtLeastS()); + assumeTrue(SdkLevel.isAtLeastS()); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) @@ -1272,7 +1273,7 @@ public class WifiNetworkSuggestionTest { */ @Test public void testSetIsNetworkAsOemPaidOnPasspointNetwork() { - assumeTrue(SdkLevelUtil.isAtLeastS()); + assumeTrue(SdkLevel.isAtLeastS()); PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() @@ -1307,7 +1308,7 @@ public class WifiNetworkSuggestionTest { */ @Test(expected = IllegalStateException.class) public void testSetCredentialSharedWithUserWithSetIsNetworkAsOemPaid() { - assumeTrue(SdkLevelUtil.isAtLeastS()); + assumeTrue(SdkLevel.isAtLeastS()); new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java index 2cf7f2c1b8cf..f5e9aaf111d3 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java @@ -39,7 +39,6 @@ import android.content.pm.PackageManager; import android.net.MacAddress; import android.net.wifi.RttManager; import android.net.wifi.util.HexEncoding; -import android.net.wifi.util.SdkLevelUtil; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -48,6 +47,8 @@ import android.os.test.TestLooper; import androidx.test.filters.SmallTest; +import com.android.modules.utils.build.SdkLevel; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -154,6 +155,7 @@ public class WifiAwareManagerTest { */ @Test public void testIsAttached() throws Exception { + assumeTrue(SdkLevelUtil.isAtLeastS()); mDut.isDeviceAttached(); verify(mockAwareService).isDeviceAttached(); } @@ -164,13 +166,23 @@ public class WifiAwareManagerTest { */ @Test public void testEnableInstantCommunicationMode() throws Exception { - assumeTrue(SdkLevelUtil.isAtLeastS()); + assumeTrue(SdkLevel.isAtLeastS()); mDut.isInstantCommunicationModeEnabled(); verify(mockAwareService).isInstantCommunicationModeEnabled(); mDut.enableInstantCommunicationMode(true); verify(mockAwareService).enableInstantCommunicationMode(anyString(), eq(true)); } + /** + * Validate pass-through of getAvailableAwareResources() API. + */ + @Test + public void testGetAvailableAwareResource() throws Exception { + assumeTrue(SdkLevelUtil.isAtLeastS()); + mDut.getAvailableAwareResources(); + verify(mockAwareService).getAvailableAwareResources(); + } + /* * WifiAwareEventCallbackProxy Tests */ diff --git a/wifi/tests/test-jarjar-rules.txt b/wifi/tests/test-jarjar-rules.txt new file mode 100644 index 000000000000..41b97abb87b5 --- /dev/null +++ b/wifi/tests/test-jarjar-rules.txt @@ -0,0 +1 @@ +rule com.android.modules.utils.** com.android.wifi.test.x.@0 |