diff options
137 files changed, 3072 insertions, 3235 deletions
diff --git a/Android.bp b/Android.bp index 586350df36b1..e59b661410bf 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", ], } @@ -1270,23 +1267,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", @@ -1383,73 +1363,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/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/api/current.txt b/api/current.txt index b35940449f9e..26d77ef4318e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -28810,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(); @@ -46509,6 +46510,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); @@ -53778,7 +53780,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); } @@ -54356,7 +54357,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(); @@ -54551,6 +54552,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); @@ -54708,7 +54710,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); @@ -61538,7 +61540,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(); @@ -61727,7 +61728,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/system-current.txt b/api/system-current.txt index f30f756ae3f6..c932718bc55c 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6695,6 +6695,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 } diff --git a/api/test-current.txt b/api/test-current.txt index edf860665fb6..82838ea605ff 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -84,7 +84,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(); @@ -534,6 +534,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[]); @@ -542,7 +543,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 @@ -2036,7 +2037,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); 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 084959b5071a..1cfe9ee784f3 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,10 +496,11 @@ 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"]; // StatsdStats tracks platform atoms with ids upto 500. // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value. @@ -606,7 +608,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"]; @@ -10746,7 +10748,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 @@ -10765,7 +10767,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 @@ -10783,7 +10785,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 @@ -10792,7 +10794,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; @@ -10811,14 +10813,23 @@ message CarrierIdMismatchEvent { } /** - * 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; } @@ -11959,3 +11970,19 @@ 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; +} diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 250f2f0b2dc9..74da95f02c76 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -4812,13 +4812,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/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 357b26c3083d..c0e3019f4619 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -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/PendingIntent.java b/core/java/android/app/PendingIntent.java index 1f81c44e54cb..37c4c92d0635 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. */ diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index ad902a028f13..8d4de2675472 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. diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java index dedfce6f6b96..f9e6308515cf 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. * 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/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index c32d34457889..106021e81ddc 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -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/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 3fb9a9e924e7..602bd6c939ba 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; @@ -8462,15 +8463,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/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 2efec3fa2ec1..62df92e656d6 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -1180,7 +1180,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 +3164,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/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 68b9d5227746..d6cd3feafca7 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -326,6 +326,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/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index be33f4edb5d1..12ddc628f4bd 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -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. @@ -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); } } 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/provider/Settings.java b/core/java/android/provider/Settings.java index 60d1d477db53..9e1b495c5202 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -9897,6 +9897,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) * @@ -11888,21 +11895,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: * 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/view/Display.java b/core/java/android/view/Display.java index 34e8221bc971..ab76e4aea993 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. diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 43a8992aa74e..d226f6048471 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -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/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/View.java b/core/java/android/view/View.java index bda368ecb3a2..ac628e145eee 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; @@ -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. @@ -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: diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 9bc07702feee..f1005e91868e 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1758,7 +1758,6 @@ public final class ViewRootImpl implements ViewParent, destroySurface(); } } - scheduleConsumeBatchedInputImmediately(); } @@ -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(); diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 2cab32b48793..d540059f993a 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -4069,11 +4069,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/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/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/widget/TextView.java b/core/java/android/widget/TextView.java index 3fc0f4efd608..5280a48596b4 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -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; } } @@ -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/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/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/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index 16a691c9c4ec..9291a90574cd 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -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/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 8a7fa04b3cf4..46956f0f56e4 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 --> <!-- ====================================================================== --> @@ -5155,6 +5160,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/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/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/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json index a4e69de97299..bee9f4163b04 100644 --- a/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json +++ b/libs/WindowManager/Shell/res/raw/wm_shell_protolog.json @@ -169,6 +169,12 @@ "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", 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/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/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..39a96a291c86 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,19 @@ 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; @Before public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); - mSpiedPipTaskOrganizer = new PipTaskOrganizer(mContext, mMockPipBoundsState, + mComponent1 = new ComponentName(mContext, "component1"); + mPipBoundsState = new PipBoundsState(); + mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipBoundsState, mMockPipBoundsHandler, mMockPipSurfaceTransactionHelper, mMockOptionalSplitScreen, - mMockdDisplayController, mMockPipUiEventLogger, mMockShellTaskOrganizer); + mMockdDisplayController, mMockPipUiEventLogger, mMockShellTaskOrganizer)); + preparePipTaskOrg(); } @Test @@ -71,4 +90,59 @@ 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 onTaskAppeared_updatesAspectRatio() { + final Rational aspectRatio = new Rational(2, 1); + + mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo( + createPipParams(aspectRatio)), null /* leash */); + + assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); + } + + @Test + public void onTaskInfoChanged_updatesAspectRatioIfChanged() { + final Rational startAspectRatio = new Rational(2, 1); + final Rational newAspectRatio = new Rational(1, 2); + mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo( + createPipParams(startAspectRatio)), null /* leash */); + + mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(createPipParams(newAspectRatio))); + + assertEquals(newAspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); + } + + private void preparePipTaskOrg() { + final DisplayInfo info = new DisplayInfo(); + 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(PictureInPictureParams params) { + final ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo(); + info.token = mock(WindowContainerToken.class); + info.pictureInPictureParams = params; + return info; + } + + private static PictureInPictureParams createPipParams(Rational aspectRatio) { + return new PictureInPictureParams.Builder() + .setAspectRatio(aspectRatio) + .build(); + } } 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/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/non-updatable-api/current.txt b/non-updatable-api/current.txt index 8adedf5779d1..41a9057c005a 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -28571,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(); @@ -44635,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); @@ -51897,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); } @@ -52475,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(); @@ -52670,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); @@ -52827,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); @@ -59657,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(); @@ -59846,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/system-current.txt b/non-updatable-api/system-current.txt index fe40892a959b..b2d13f908b61 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -6635,6 +6635,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 } diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java index 02f4457bffdb..9aa7cc4ae29f 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java @@ -17,6 +17,7 @@ package com.android.companiondevicemanager; import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress; +import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import android.app.Activity; import android.companion.CompanionDeviceManager; @@ -57,6 +58,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); 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/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index f1d7e223c933..1a2c2c8ac2e9 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -863,9 +863,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); diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 10d2eab167e7..de4325098a7f 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -293,6 +293,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 +310,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, diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 5f018a0322a3..9cd69ccabf13 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -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/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/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/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/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/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index bc060209132b..cf2e13356cca 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -252,8 +252,7 @@ public class BubbleExpandedView extends LinearLayout { mPositioner = mBubbles.getPositioner(); - mTaskView = new TaskView(mContext, mBubbles.getTaskOrganizer(), - new HandlerExecutor(getHandler())); + mTaskView = new TaskView(mContext, mBubbles.getTaskOrganizer()); // Set ActivityView's alpha value as zero, since there is no view content to be shown. setContentVisibility(false); @@ -310,6 +309,12 @@ public class BubbleExpandedView extends LinearLayout { setLayoutDirection(LAYOUT_DIRECTION_LOCALE); } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mTaskView.setExecutor(new HandlerExecutor(getHandler())); + } + void updateDimensions() { Resources res = getResources(); mMinHeight = res.getDimensionPixelSize(R.dimen.bubble_expanded_default_height); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 0714c5eb4fa4..1201d42b1fc5 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. @@ -1479,12 +1480,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(); } @@ -2595,17 +2608,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/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/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/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/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/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index ead2fc1cd9dc..cff1c9d086ea 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -102,8 +102,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 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/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/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/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/tests/unit/Android.bp b/packages/Tethering/tests/unit/Android.bp index ef556cf92392..3589725dcf50 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", ], 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/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 51cbfcf64322..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(); @@ -8214,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, @@ -17343,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/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/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/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java index 7e3c1ab50ad5..1a2871781116 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java @@ -17,10 +17,14 @@ 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.ResultReceiver; +import android.os.ShellCallback; import android.util.IntArray; import android.util.Slog; @@ -29,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.server.SystemService; import com.android.server.policy.DeviceStatePolicyImpl; +import java.io.FileDescriptor; import java.util.Arrays; /** @@ -65,15 +70,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 +107,6 @@ public final class DeviceStateManagerService extends SystemService { * * @see #getPendingState() */ - @VisibleForTesting int getCommittedState() { synchronized (mLock) { return mCommittedState; @@ -119,13 +128,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 +192,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 +234,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; } @@ -271,6 +344,11 @@ 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); + } } } 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/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..c4dfcf5c3165 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; @@ -2024,6 +2025,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 +2066,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/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..6ff661b1637e 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -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/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index 28bd97e4843c..d4593afe18fe 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,8 +148,8 @@ 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); @@ -299,6 +299,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 +390,55 @@ 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)); + } + } } 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..b4a765e10fca 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; } /** @@ -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/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 9947ecd42e31..047f1742f2ca 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; 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 1896c9f08f83..7eb4fd968c36 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; @@ -480,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; @@ -820,6 +821,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean mPromoteSystemApps; private final PackageManagerInternal mPmInternal; + private final TestUtilityService mTestUtilityService; @GuardedBy("mLock") @@ -1193,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; @@ -2957,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; @@ -3027,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(); @@ -26366,9 +26372,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/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 6de5522ee694..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)); @@ -4682,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) { @@ -4726,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; @@ -5125,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 @@ -5718,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) { @@ -7568,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 c582e6c8cb29..6749cdf6fe7d 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -160,9 +160,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; @@ -341,6 +343,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; /** @@ -2626,8 +2634,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; } @@ -3608,7 +3643,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } /** This can be called with or without the global lock held. */ - private void enforceCallerIsRecentsOrHasPermission(String permission, String func) { + void enforceCallerIsRecentsOrHasPermission(String permission, String func) { if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) { mAmInternal.enforceCallingPermission(permission, func); } @@ -4647,7 +4682,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); + } } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 7641de5ab7b9..26c5d70a2c45 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5467,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/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/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/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/Task.java b/services/core/java/com/android/server/wm/Task.java index 27948aea380b..ef1a3be70f9d 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -5414,8 +5414,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); @@ -5469,27 +5467,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) { @@ -5786,8 +5770,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()) { @@ -5974,6 +5959,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); @@ -6020,7 +6007,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); @@ -6293,7 +6279,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(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 0585679f7fbb..0eadbf296323 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -153,6 +153,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; @@ -564,6 +565,7 @@ public class WindowManagerService extends IWindowManager.Stub final AppOpsManager mAppOps; final PackageManagerInternal mPmInternal; + private final TestUtilityService mTestUtilityService; final DisplayWindowSettings mDisplayWindowSettings; @@ -1265,6 +1267,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); @@ -6925,9 +6928,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 +8352,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/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/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/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java index 18bd6b17f340..b98021bc2cab 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 @@ -313,6 +335,18 @@ public class QuotaControllerTest { return new TimingSession(start, start + duration, count); } + private void setDeviceConfigLong(String key, long val) { + mQuotaController.prepareForUpdatedConstantsLocked(); + mDeviceConfigPropertiesBuilder.setLong(key, val); + mQcConstants.processConstantLocked(mDeviceConfigPropertiesBuilder.build(), key); + } + + private void setDeviceConfigInt(String key, int val) { + mQuotaController.prepareForUpdatedConstantsLocked(); + mDeviceConfigPropertiesBuilder.setInt(key, val); + mQcConstants.processConstantLocked(mDeviceConfigPropertiesBuilder.build(), key); + } + @Test public void testSaveTimingSession() { assertNull(mQuotaController.getTimingSessions(0, "com.android.test")); @@ -858,8 +892,7 @@ public class QuotaControllerTest { advanceElapsedClock(40 * MINUTE_IN_MILLIS); } - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 0; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, 0); mQuotaController.invalidateAllExecutionStatsLocked(); assertEquals(0, mQuotaController.getExecutionStatsLocked( @@ -871,8 +904,7 @@ public class QuotaControllerTest { assertEquals(160, mQuotaController.getExecutionStatsLocked( 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 500; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, 500); mQuotaController.invalidateAllExecutionStatsLocked(); assertEquals(0, mQuotaController.getExecutionStatsLocked( @@ -884,8 +916,7 @@ public class QuotaControllerTest { assertEquals(110, mQuotaController.getExecutionStatsLocked( 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 1000; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, 1000); mQuotaController.invalidateAllExecutionStatsLocked(); assertEquals(0, mQuotaController.getExecutionStatsLocked( @@ -897,8 +928,8 @@ public class QuotaControllerTest { assertEquals(110, mQuotaController.getExecutionStatsLocked( 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 5 * SECOND_IN_MILLIS; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + 5 * SECOND_IN_MILLIS); mQuotaController.invalidateAllExecutionStatsLocked(); assertEquals(0, mQuotaController.getExecutionStatsLocked( @@ -910,8 +941,8 @@ public class QuotaControllerTest { assertEquals(70, mQuotaController.getExecutionStatsLocked( 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = MINUTE_IN_MILLIS; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + MINUTE_IN_MILLIS); mQuotaController.invalidateAllExecutionStatsLocked(); assertEquals(0, mQuotaController.getExecutionStatsLocked( @@ -923,8 +954,8 @@ public class QuotaControllerTest { assertEquals(20, mQuotaController.getExecutionStatsLocked( 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 5 * MINUTE_IN_MILLIS; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + 5 * MINUTE_IN_MILLIS); mQuotaController.invalidateAllExecutionStatsLocked(); assertEquals(0, mQuotaController.getExecutionStatsLocked( @@ -936,8 +967,8 @@ public class QuotaControllerTest { assertEquals(10, mQuotaController.getExecutionStatsLocked( 0, "com.android.test", RARE_INDEX).sessionCountInWindow); - mQcConstants.TIMING_SESSION_COALESCING_DURATION_MS = 15 * MINUTE_IN_MILLIS; - mQcConstants.updateConstants(); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, + 15 * MINUTE_IN_MILLIS); mQuotaController.invalidateAllExecutionStatsLocked(); assertEquals(0, mQuotaController.getExecutionStatsLocked( @@ -951,8 +982,7 @@ public class QuotaControllerTest { // 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(); + setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, HOUR_IN_MILLIS); mQuotaController.invalidateAllExecutionStatsLocked(); assertEquals(0, mQuotaController.getExecutionStatsLocked( @@ -994,8 +1024,7 @@ public class QuotaControllerTest { // 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; @@ -1413,11 +1442,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", @@ -1629,8 +1657,7 @@ 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); @@ -1749,9 +1776,8 @@ 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; @@ -1790,8 +1816,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 +1827,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 +1838,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 +1849,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(); @@ -1891,27 +1923,30 @@ public class QuotaControllerTest { @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 +1955,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 +1964,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 +2009,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 +2017,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 +2055,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. */ @@ -2619,9 +2667,9 @@ 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); @@ -2671,12 +2719,12 @@ 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); 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/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/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/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java index 5a05fc6eda4c..debf20bffe28 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; @@ -71,6 +72,44 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("04:90").isEqualTo(ERROR_PARAMETER_SHORT); } + @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); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(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..382ae8218729 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -383,6 +383,41 @@ public class HdmiControlServiceTest { } + @Test + public void getCecVersion_default() { + 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 { boolean mCallbackReceived = false; 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/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java index 64a05bb361e9..747fb8999276 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java @@ -19,6 +19,8 @@ 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; @@ -82,6 +84,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; @@ -278,6 +282,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/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/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..e636b93deace 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); diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt deleted file mode 100644 index a58b6d84cbd1..000000000000 --- a/telephony/api/system-current.txt +++ /dev/null @@ -1,2107 +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 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); - 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 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); - 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 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"; - 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 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 - 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/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/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/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/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) |