diff options
17 files changed, 340 insertions, 135 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index c76be6f43372..8936ed5b92b4 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -19,6 +19,7 @@ aconfig_srcjars = [ ":android.content.res.flags-aconfig-java{.generated_srcjars}", ":android.crashrecovery.flags-aconfig-java{.generated_srcjars}", ":android.hardware.biometrics.flags-aconfig-java{.generated_srcjars}", + ":android.media.codec-aconfig-java{.generated_srcjars}", ":android.media.playback.flags-aconfig-java{.generated_srcjars}", ":android.net.vcn.flags-aconfig-java{.generated_srcjars}", ":android.nfc.flags-aconfig-java{.generated_srcjars}", diff --git a/api/Android.bp b/api/Android.bp index 1b84ce7ea5fb..ea59d0b5ccdc 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -374,7 +374,10 @@ stubs_defaults { previous_api: ":android.api.public.latest", merge_annotations_dirs: ["metalava-manual"], defaults_visibility: ["//frameworks/base/api"], - visibility: ["//frameworks/base/api"], + visibility: [ + "//frameworks/base/api", + "//frameworks/base/core/api", + ], } // We resolve dependencies on APIs in modules by depending on a prebuilt of the whole diff --git a/api/api.go b/api/api.go index fa2be21db09f..c733f5b5bffd 100644 --- a/api/api.go +++ b/api/api.go @@ -130,7 +130,7 @@ type MergedTxtDefinition struct { Scope string } -func createMergedTxt(ctx android.LoadHookContext, txt MergedTxtDefinition) { +func createMergedTxt(ctx android.LoadHookContext, txt MergedTxtDefinition, stubsTypeSuffix string, doDist bool) { metalavaCmd := "$(location metalava)" // Silence reflection warnings. See b/168689341 metalavaCmd += " -J--add-opens=java.base/java.util=ALL-UNNAMED " @@ -140,7 +140,7 @@ func createMergedTxt(ctx android.LoadHookContext, txt MergedTxtDefinition) { if txt.Scope != "public" { filename = txt.Scope + "-" + filename } - moduleName := ctx.ModuleName() + "-" + filename + moduleName := ctx.ModuleName() + stubsTypeSuffix + filename props := genruleProps{} props.Name = proptools.StringPtr(moduleName) @@ -148,17 +148,19 @@ func createMergedTxt(ctx android.LoadHookContext, txt MergedTxtDefinition) { props.Out = []string{filename} props.Cmd = proptools.StringPtr(metalavaCmd + "$(in) --out $(out)") props.Srcs = append([]string{txt.BaseTxt}, createSrcs(txt.Modules, txt.ModuleTag)...) - props.Dists = []android.Dist{ - { - Targets: []string{"droidcore"}, - Dir: proptools.StringPtr("api"), - Dest: proptools.StringPtr(filename), - }, - { - Targets: []string{"api_txt", "sdk"}, - Dir: proptools.StringPtr("apistubs/android/" + txt.Scope + "/api"), - Dest: proptools.StringPtr(txt.DistFilename), - }, + if doDist { + props.Dists = []android.Dist{ + { + Targets: []string{"droidcore"}, + Dir: proptools.StringPtr("api"), + Dest: proptools.StringPtr(filename), + }, + { + Targets: []string{"api_txt", "sdk"}, + Dir: proptools.StringPtr("apistubs/android/" + txt.Scope + "/api"), + Dest: proptools.StringPtr(txt.DistFilename), + }, + } } props.Visibility = []string{"//visibility:public"} ctx.CreateModule(genrule.GenRuleFactory, &props) @@ -343,7 +345,7 @@ func createPublicStubsSourceFilegroup(ctx android.LoadHookContext, modules []str ctx.CreateModule(android.FileGroupFactory, &props) } -func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_classpath []string) { +func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_classpath []string, baseTxtModulePrefix, stubsTypeSuffix string, doDist bool) { var textFiles []MergedTxtDefinition tagSuffix := []string{".api.txt}", ".removed-api.txt}"} @@ -352,7 +354,7 @@ func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_ textFiles = append(textFiles, MergedTxtDefinition{ TxtFilename: f, DistFilename: distFilename[i], - BaseTxt: ":non-updatable-" + f, + BaseTxt: ":" + baseTxtModulePrefix + f, Modules: bootclasspath, ModuleTag: "{.public" + tagSuffix[i], Scope: "public", @@ -360,7 +362,7 @@ func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_ textFiles = append(textFiles, MergedTxtDefinition{ TxtFilename: f, DistFilename: distFilename[i], - BaseTxt: ":non-updatable-system-" + f, + BaseTxt: ":" + baseTxtModulePrefix + "system-" + f, Modules: bootclasspath, ModuleTag: "{.system" + tagSuffix[i], Scope: "system", @@ -368,7 +370,7 @@ func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_ textFiles = append(textFiles, MergedTxtDefinition{ TxtFilename: f, DistFilename: distFilename[i], - BaseTxt: ":non-updatable-module-lib-" + f, + BaseTxt: ":" + baseTxtModulePrefix + "module-lib-" + f, Modules: bootclasspath, ModuleTag: "{.module-lib" + tagSuffix[i], Scope: "module-lib", @@ -376,14 +378,14 @@ func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_ textFiles = append(textFiles, MergedTxtDefinition{ TxtFilename: f, DistFilename: distFilename[i], - BaseTxt: ":non-updatable-system-server-" + f, + BaseTxt: ":" + baseTxtModulePrefix + "system-server-" + f, Modules: system_server_classpath, ModuleTag: "{.system-server" + tagSuffix[i], Scope: "system-server", }) } for _, txt := range textFiles { - createMergedTxt(ctx, txt) + createMergedTxt(ctx, txt, stubsTypeSuffix, doDist) } } @@ -465,7 +467,8 @@ func (a *CombinedApis) createInternalModules(ctx android.LoadHookContext) { bootclasspath = append(bootclasspath, a.properties.Conditional_bootclasspath...) sort.Strings(bootclasspath) } - createMergedTxts(ctx, bootclasspath, system_server_classpath) + createMergedTxts(ctx, bootclasspath, system_server_classpath, "non-updatable-", "-", false) + createMergedTxts(ctx, bootclasspath, system_server_classpath, "non-updatable-exportable-", "-exportable-", true) createMergedPublicStubs(ctx, bootclasspath) createMergedSystemStubs(ctx, bootclasspath) diff --git a/core/api/Android.bp b/core/api/Android.bp index 8d8a82b69b55..77594b758d19 100644 --- a/core/api/Android.bp +++ b/core/api/Android.bp @@ -96,3 +96,54 @@ filegroup { name: "non-updatable-test-lint-baseline.txt", srcs: ["test-lint-baseline.txt"], } + +// Exportable stub artifacts +filegroup { + name: "non-updatable-exportable-current.txt", + srcs: [":api-stubs-docs-non-updatable{.exportable.api.txt}"], +} + +filegroup { + name: "non-updatable-exportable-removed.txt", + srcs: [":api-stubs-docs-non-updatable{.exportable.removed-api.txt}"], +} + +filegroup { + name: "non-updatable-exportable-system-current.txt", + srcs: [":system-api-stubs-docs-non-updatable{.exportable.api.txt}"], +} + +filegroup { + name: "non-updatable-exportable-system-removed.txt", + srcs: [":system-api-stubs-docs-non-updatable{.exportable.removed-api.txt}"], +} + +filegroup { + name: "non-updatable-exportable-module-lib-current.txt", + srcs: [":module-lib-api-stubs-docs-non-updatable{.exportable.api.txt}"], +} + +filegroup { + name: "non-updatable-exportable-module-lib-removed.txt", + srcs: [":module-lib-api-stubs-docs-non-updatable{.exportable.removed-api.txt}"], +} + +filegroup { + name: "non-updatable-exportable-test-current.txt", + srcs: [":test-api-stubs-docs-non-updatable{.exportable.api.txt}"], +} + +filegroup { + name: "non-updatable-exportable-test-removed.txt", + srcs: [":test-api-stubs-docs-non-updatable{.exportable.removed-api.txt}"], +} + +filegroup { + name: "non-updatable-exportable-system-server-current.txt", + srcs: [":services-non-updatable-stubs{.exportable.api.txt}"], +} + +filegroup { + name: "non-updatable-exportable-system-server-removed.txt", + srcs: [":services-non-updatable-stubs{.exportable.removed-api.txt}"], +} diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig index d07de72d6cf5..ab8fd5e50fd5 100644 --- a/core/java/android/content/pm/flags.aconfig +++ b/core/java/android/content/pm/flags.aconfig @@ -14,3 +14,11 @@ flag { bug: "299670324" is_fixed_read_only: true } + +flag { + name: "recoverability_detection" + namespace: "package_manager_service" + description: "Feature flag to enable recoverability detection feature. It includes GMS core rollback and improvements to rescue party." + bug: "291135724" + is_fixed_read_only: true +}
\ No newline at end of file diff --git a/core/java/android/service/voice/OWNERS b/core/java/android/service/voice/OWNERS index ec4410086edf..763c79e20846 100644 --- a/core/java/android/service/voice/OWNERS +++ b/core/java/android/service/voice/OWNERS @@ -4,4 +4,4 @@ include /core/java/android/app/assist/OWNERS # The owner here should not be assist owner liangyuchen@google.com -tuanng@google.com +adudani@google.com diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 9c40a28dfd81..2a2e9038c27a 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -665,8 +665,9 @@ static void EnableKeepCapabilities(fail_fn_t fail_fn) { } } -static void DropCapabilitiesBoundingSet(fail_fn_t fail_fn) { +static void DropCapabilitiesBoundingSet(fail_fn_t fail_fn, jlong bounding_capabilities) { for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {; + if ((1LL << i) & bounding_capabilities) continue; if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) == -1) { if (errno == EINVAL) { ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify " @@ -678,6 +679,27 @@ static void DropCapabilitiesBoundingSet(fail_fn_t fail_fn) { } } +static bool MatchGid(JNIEnv* env, jintArray gids, jint gid, jint gid_to_find) { + if (gid == gid_to_find) return true; + + if (gids == nullptr) return false; + + jsize gids_num = env->GetArrayLength(gids); + ScopedIntArrayRO native_gid_proxy(env, gids); + + if (native_gid_proxy.get() == nullptr) { + RuntimeAbort(env, __LINE__, "Bad gids array"); + } + + for (int gids_index = 0; gids_index < gids_num; ++gids_index) { + if (native_gid_proxy[gids_index] == gid_to_find) { + return true; + } + } + + return false; +} + static void SetInheritable(uint64_t inheritable, fail_fn_t fail_fn) { __user_cap_header_struct capheader; memset(&capheader, 0, sizeof(capheader)); @@ -1742,9 +1764,9 @@ static void BindMountStorageDirs(JNIEnv* env, jobjectArray pkg_data_info_list, // Utility routine to specialize a zygote child process. static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, - jlong effective_capabilities, jint mount_external, - jstring managed_se_info, jstring managed_nice_name, - bool is_system_server, bool is_child_zygote, + jlong effective_capabilities, jlong bounding_capabilities, + jint mount_external, jstring managed_se_info, + jstring managed_nice_name, bool is_system_server, bool is_child_zygote, jstring managed_instruction_set, jstring managed_app_data_dir, bool is_top_app, jobjectArray pkg_data_info_list, jobjectArray allowlisted_data_info_list, bool mount_data_dirs, @@ -1758,6 +1780,9 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, auto instruction_set = extract_fn(managed_instruction_set); auto app_data_dir = extract_fn(managed_app_data_dir); + // Permit bounding capabilities + permitted_capabilities |= bounding_capabilities; + // Keep capabilities across UID change, unless we're staying root. if (uid != 0) { EnableKeepCapabilities(fail_fn); @@ -1765,7 +1790,7 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, SetInheritable(permitted_capabilities, fail_fn); - DropCapabilitiesBoundingSet(fail_fn); + DropCapabilitiesBoundingSet(fail_fn, bounding_capabilities); bool need_pre_initialize_native_bridge = !is_system_server && instruction_set.has_value() && android::NativeBridgeAvailable() && @@ -2028,6 +2053,23 @@ static uint64_t GetEffectiveCapabilityMask(JNIEnv* env) { return capdata[0].effective | (static_cast<uint64_t>(capdata[1].effective) << 32); } +static jlong CalculateBoundingCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gids) { + jlong capabilities = 0; + + /* + * Grant CAP_SYS_NICE to CapInh/CapPrm/CapBnd for processes that can spawn + * VMs. This enables processes to execve on binaries with elevated + * capabilities if its file capability bits are set. This does not grant + * capability to the parent process(that spawns the VM) as the effective + * bits are not set. + */ + if (MatchGid(env, gids, gid, AID_VIRTUALMACHINE)) { + capabilities |= (1LL << CAP_SYS_NICE); + } + + return capabilities; +} + static jlong CalculateCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gids, bool is_child_zygote) { jlong capabilities = 0; @@ -2061,26 +2103,7 @@ static jlong CalculateCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gi * Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock" */ - bool gid_wakelock_found = false; - if (gid == AID_WAKELOCK) { - gid_wakelock_found = true; - } else if (gids != nullptr) { - jsize gids_num = env->GetArrayLength(gids); - ScopedIntArrayRO native_gid_proxy(env, gids); - - if (native_gid_proxy.get() == nullptr) { - RuntimeAbort(env, __LINE__, "Bad gids array"); - } - - for (int gids_index = 0; gids_index < gids_num; ++gids_index) { - if (native_gid_proxy[gids_index] == AID_WAKELOCK) { - gid_wakelock_found = true; - break; - } - } - } - - if (gid_wakelock_found) { + if (MatchGid(env, gids, gid, AID_WAKELOCK)) { capabilities |= (1LL << CAP_BLOCK_SUSPEND); } @@ -2256,6 +2279,11 @@ pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server, const std::vector<int>& fds_to_ignore, bool is_priority_fork, bool purge) { + ATRACE_CALL(); + if (is_priority_fork) { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX); + } + SetSignalHandlers(); // Curry a failure function. @@ -2341,6 +2369,10 @@ pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server, // We blocked SIGCHLD prior to a fork, we unblock it here. UnblockSignal(SIGCHLD, fail_fn); + if (is_priority_fork && pid != 0) { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT); + } + return pid; } @@ -2357,6 +2389,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( jobjectArray pkg_data_info_list, jobjectArray allowlisted_data_info_list, jboolean mount_data_dirs, jboolean mount_storage_dirs) { jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote); + jlong bounding_capabilities = CalculateBoundingCapabilities(env, uid, gid, gids); if (UNLIKELY(managed_fds_to_close == nullptr)) { zygote::ZygoteFailure(env, "zygote", nice_name, @@ -2395,10 +2428,10 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( if (pid == 0) { SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, capabilities, capabilities, - mount_external, se_info, nice_name, false, is_child_zygote == JNI_TRUE, - instruction_set, app_data_dir, is_top_app == JNI_TRUE, pkg_data_info_list, - allowlisted_data_info_list, mount_data_dirs == JNI_TRUE, - mount_storage_dirs == JNI_TRUE); + bounding_capabilities, mount_external, se_info, nice_name, false, + is_child_zygote == JNI_TRUE, instruction_set, app_data_dir, + is_top_app == JNI_TRUE, pkg_data_info_list, allowlisted_data_info_list, + mount_data_dirs == JNI_TRUE, mount_storage_dirs == JNI_TRUE); } return pid; } @@ -2408,6 +2441,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities) { + ATRACE_CALL(); std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()), fds_to_ignore(fds_to_close); @@ -2431,7 +2465,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( // System server prcoess does not need data isolation so no need to // know pkg_data_info_list. SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, - effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true, + effective_capabilities, 0, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true, false, nullptr, nullptr, /* is_top_app= */ false, /* pkg_data_info_list */ nullptr, /* allowlisted_data_info_list */ nullptr, false, false); @@ -2483,6 +2517,7 @@ static jint com_android_internal_os_Zygote_nativeForkApp(JNIEnv* env, jintArray managed_session_socket_fds, jboolean args_known, jboolean is_priority_fork) { + ATRACE_CALL(); std::vector<int> session_socket_fds = ExtractJIntArray(env, "USAP", nullptr, managed_session_socket_fds) .value_or(std::vector<int>()); @@ -2498,6 +2533,7 @@ int zygote::forkApp(JNIEnv* env, bool args_known, bool is_priority_fork, bool purge) { + ATRACE_CALL(); std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()), fds_to_ignore(fds_to_close); @@ -2588,12 +2624,13 @@ static void com_android_internal_os_Zygote_nativeSpecializeAppProcess( jobjectArray allowlisted_data_info_list, jboolean mount_data_dirs, jboolean mount_storage_dirs) { jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote); + jlong bounding_capabilities = CalculateBoundingCapabilities(env, uid, gid, gids); SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, capabilities, capabilities, - mount_external, se_info, nice_name, false, is_child_zygote == JNI_TRUE, - instruction_set, app_data_dir, is_top_app == JNI_TRUE, pkg_data_info_list, - allowlisted_data_info_list, mount_data_dirs == JNI_TRUE, - mount_storage_dirs == JNI_TRUE); + bounding_capabilities, mount_external, se_info, nice_name, false, + is_child_zygote == JNI_TRUE, instruction_set, app_data_dir, + is_top_app == JNI_TRUE, pkg_data_info_list, allowlisted_data_info_list, + mount_data_dirs == JNI_TRUE, mount_storage_dirs == JNI_TRUE); } /** diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index 9bb249999d99..61e6a36839ff 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -127,7 +127,7 @@ <!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU: http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements, visual voicemail code for Orange: 21101 --> - <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101|20366|555|2051" /> + <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101|20366|555|2051|33033" /> <!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU: http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf, @@ -150,6 +150,9 @@ http://clients.txtnation.com/entries/209633-hungary-premium-sms-short-code-regulations --> <shortcode country="hu" pattern="[01](?:\\d{3}|\\d{9})" premium="0691227910|1784" free="116\\d{3}" /> + <!-- Honduras --> + <shortcode country="hn" pattern="\\d{4,6}" free="466453" /> + <!-- India: 1-5 digits (standard system default, not country specific) --> <shortcode country="in" pattern="\\d{1,5}" free="59336|53969" /> @@ -171,7 +174,7 @@ <shortcode country="jp" pattern="\\d{1,5}" free="8083" /> <!-- Kenya: 5 digits, known premium codes listed --> - <shortcode country="ke" pattern="\\d{5}" free="21725|21562|40520|23342|40023" /> + <shortcode country="ke" pattern="\\d{5}" free="21725|21562|40520|23342|40023|24088|23054" /> <!-- Kyrgyzstan: 4 digits, known premium codes listed --> <shortcode country="kg" pattern="\\d{4}" premium="415[2367]|444[69]" /> @@ -183,7 +186,7 @@ <shortcode country="kz" pattern="\\d{4}" premium="335[02]|4161|444[469]|77[2359]0|8444|919[3-5]|968[2-5]" /> <!-- Kuwait: 1-5 digits (standard system default, not country specific) --> - <shortcode country="kw" pattern="\\d{1,5}" free="1378|50420|94006|55991" /> + <shortcode country="kw" pattern="\\d{1,5}" free="1378|50420|94006|55991|50976" /> <!-- Lithuania: 3-5 digits, known premium codes listed, plus EU --> <shortcode country="lt" pattern="\\d{3,5}" premium="13[89]1|1394|16[34]5" free="116\\d{3}|1399|1324" /> @@ -195,9 +198,18 @@ <!-- Latvia: 4 digits, known premium codes listed, plus EU --> <shortcode country="lv" pattern="\\d{4}" premium="18(?:19|63|7[1-4])" free="116\\d{3}|1399" /> + <!-- Morocco: 1-5 digits (standard system default, not country specific) --> + <shortcode country="ma" pattern="\\d{1,5}" free="53819" /> + <!-- Macedonia: 1-6 digits (not confirmed), known premium codes listed --> <shortcode country="mk" pattern="\\d{1,6}" free="129005|122" /> + <!-- Malawi: 1-5 digits (standard system default, not country specific) --> + <shortcode country="mw" pattern="\\d{1,5}" free="4276" /> + + <!-- Mozambique: 1-5 digits (standard system default, not country specific) --> + <shortcode country="mz" pattern="\\d{1,5}" free="1714" /> + <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed --> <shortcode country="mx" pattern="\\d{4,6}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963|91101|45453|550346" /> @@ -207,6 +219,9 @@ <!-- Namibia: 1-5 digits (standard system default, not country specific) --> <shortcode country="na" pattern="\\d{1,5}" free="40005" /> + <!-- Nicaragua --> + <shortcode country="ni" pattern="\\d{4,6}" free="466453" /> + <!-- The Netherlands, 4 digits, known premium codes listed, plus EU --> <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223|1662" /> @@ -219,8 +234,8 @@ <!-- New Zealand: 3-4 digits, known premium codes listed --> <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="1737|176|2141|3067|3068|3110|3876|4006|4053|4061|4062|4202|4300|4334|4412|4575|5626|8006|8681" /> - <!-- Peru: 4-5 digits (not confirmed), known premium codes listed --> - <shortcode country="pe" pattern="\\d{4,5}" free="9963|40778" /> + <!-- Peru: 4-6 digits (not confirmed), known premium codes listed --> + <shortcode country="pe" pattern="\\d{4,6}" free="9963|40778|301303" /> <!-- Philippines --> <shortcode country="ph" pattern="\\d{1,5}" free="2147|5495|5496" /> @@ -269,6 +284,12 @@ <!-- Slovakia: 4 digits (premium), plus EU: http://www.cmtelecom.com/premium-sms/slovakia --> <shortcode country="sk" premium="\\d{4}" free="116\\d{3}|8000" /> + <!-- Senegal(SN): 1-5 digits (standard system default, not country specific) --> + <shortcode country="sn" pattern="\\d{1,5}" free="21215" /> + + <!-- El Salvador(SV): 1-5 digits (standard system default, not country specific) --> + <shortcode country="sv" pattern="\\d{4,6}" free="466453" /> + <!-- Taiwan --> <shortcode country="tw" pattern="\\d{4}" free="1922" /> @@ -278,15 +299,21 @@ <!-- Tajikistan: 4 digits, known premium codes listed --> <shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" /> + <!-- Tanzania: 1-5 digits (standard system default, not country specific) --> + <shortcode country="tz" pattern="\\d{1,5}" free="15046|15234" /> + <!-- Turkey --> <shortcode country="tr" pattern="\\d{1,5}" free="7529|5528|6493|3193" /> <!-- Ukraine: 4 digits, known premium codes listed --> <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" /> + <!-- Uganda(UG): 4 digits (standard system default, not country specific) --> + <shortcode country="ug" pattern="\\d{4}" free="8000" /> + <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm), visual voicemail code for T-Mobile: 122 --> - <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" standard="44567|244444" free="122|87902|21696|24614|28003|30356|33669|40196|41064|41270|43753|44034|46645|52413|56139|57969|61785|66975|75136|76227|81398|83952|85140|86566|86799|95737|96684|99245|611611" /> + <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" standard="44567|244444" free="122|87902|21696|24614|28003|30356|33669|40196|41064|41270|43753|44034|46645|52413|56139|57969|61785|66975|75136|76227|81398|83952|85140|86566|86799|95737|96684|99245|611611|96831" /> <!-- Vietnam: 1-5 digits (standard system default, not country specific) --> <shortcode country="vn" pattern="\\d{1,5}" free="5001|9055" /> diff --git a/data/etc/platform.xml b/data/etc/platform.xml index c4530f64a82d..cb803f7babfa 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -124,6 +124,10 @@ <group gid="security_log_writer" /> </permission> + <permission name="android.permission.MANAGE_VIRTUAL_MACHINE"> + <group gid="virtualmachine" /> + </permission> + <!-- These are permissions that were mapped to gids but we need to keep them here until an upgrade from L to the current version is to be supported. These permissions are built-in diff --git a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java index d256aead97e8..b5cf011c32a6 100644 --- a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java +++ b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java @@ -33,12 +33,12 @@ import android.os.Looper; import android.os.Process; import android.os.SystemProperties; import android.provider.DeviceConfig; +import android.sysprop.CrashRecoveryProperties; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; import android.util.LongArrayQueue; -import android.util.MathUtils; import android.util.Slog; import android.util.Xml; @@ -128,18 +128,9 @@ public class PackageWatchdog { @VisibleForTesting static final int DEFAULT_BOOT_LOOP_TRIGGER_COUNT = 5; + @VisibleForTesting static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10); - // These properties track individual system server boot events, and are reset once the boot - // threshold is met, or the boot loop trigger window is exceeded between boot events. - private static final String PROP_RESCUE_BOOT_COUNT = "sys.rescue_boot_count"; - private static final String PROP_RESCUE_BOOT_START = "sys.rescue_boot_start"; - - // These properties track multiple calls made to observers tracking boot loops. They are reset - // when the de-escalation window is exceeded between boot events. - private static final String PROP_BOOT_MITIGATION_WINDOW_START = "sys.boot_mitigation_start"; - private static final String PROP_BOOT_MITIGATION_COUNT = "sys.boot_mitigation_count"; - private long mNumberOfNativeCrashPollsRemaining; private static final int DB_VERSION = 1; @@ -1702,42 +1693,45 @@ public class PackageWatchdog { setCount(0); } - private int getCount() { - return SystemProperties.getInt(PROP_RESCUE_BOOT_COUNT, 0); + protected int getCount() { + return CrashRecoveryProperties.rescueBootCount().orElse(0); } - private void setCount(int count) { - SystemProperties.set(PROP_RESCUE_BOOT_COUNT, Integer.toString(count)); + protected void setCount(int count) { + CrashRecoveryProperties.rescueBootCount(count); } public long getStart() { - return SystemProperties.getLong(PROP_RESCUE_BOOT_START, 0); + return CrashRecoveryProperties.rescueBootStart().orElse(0L); } public int getMitigationCount() { - return SystemProperties.getInt(PROP_BOOT_MITIGATION_COUNT, 0); + return CrashRecoveryProperties.bootMitigationCount().orElse(0); } public void setStart(long start) { - setPropertyStart(PROP_RESCUE_BOOT_START, start); + CrashRecoveryProperties.rescueBootStart(getStartTime(start)); } public void setMitigationStart(long start) { - setPropertyStart(PROP_BOOT_MITIGATION_WINDOW_START, start); + CrashRecoveryProperties.bootMitigationStart(getStartTime(start)); } public long getMitigationStart() { - return SystemProperties.getLong(PROP_BOOT_MITIGATION_WINDOW_START, 0); + return CrashRecoveryProperties.bootMitigationStart().orElse(0L); } public void setMitigationCount(int count) { - SystemProperties.set(PROP_BOOT_MITIGATION_COUNT, Integer.toString(count)); + CrashRecoveryProperties.bootMitigationCount(count); + } + + private static long constrain(long amount, long low, long high) { + return amount < low ? low : (amount > high ? high : amount); } - public void setPropertyStart(String property, long start) { + public long getStartTime(long start) { final long now = mSystemClock.uptimeMillis(); - final long newStart = MathUtils.constrain(start, 0, now); - SystemProperties.set(property, Long.toString(newStart)); + return constrain(start, 0, now); } public void saveMitigationCountToMetadata() { diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java index 5d03ef578995..6766afc5e45a 100644 --- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java +++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java @@ -37,6 +37,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings; +import android.sysprop.CrashRecoveryProperties; import android.text.TextUtils; import android.util.ArraySet; import android.util.ExceptionUtils; @@ -75,12 +76,6 @@ import java.util.concurrent.TimeUnit; */ public class RescueParty { @VisibleForTesting - static final String PROP_ENABLE_RESCUE = "persist.sys.enable_rescue"; - static final String PROP_ATTEMPTING_FACTORY_RESET = "sys.attempting_factory_reset"; - static final String PROP_ATTEMPTING_REBOOT = "sys.attempting_reboot"; - static final String PROP_MAX_RESCUE_LEVEL_ATTEMPTED = "sys.max_rescue_level_attempted"; - static final String PROP_LAST_FACTORY_RESET_TIME_MS = "persist.sys.last_factory_reset"; - @VisibleForTesting static final int LEVEL_NONE = 0; @VisibleForTesting static final int LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS = 1; @@ -93,8 +88,6 @@ public class RescueParty { @VisibleForTesting static final int LEVEL_FACTORY_RESET = 5; @VisibleForTesting - static final String PROP_RESCUE_BOOT_COUNT = "sys.rescue_boot_count"; - @VisibleForTesting static final String TAG = "RescueParty"; @VisibleForTesting static final long DEFAULT_OBSERVING_DURATION_MS = TimeUnit.DAYS.toMillis(2); @@ -131,7 +124,7 @@ public class RescueParty { private static boolean isDisabled() { // Check if we're explicitly enabled for testing - if (SystemProperties.getBoolean(PROP_ENABLE_RESCUE, false)) { + if (CrashRecoveryProperties.enableRescueParty().orElse(false)) { return false; } @@ -177,11 +170,11 @@ public class RescueParty { } static boolean isFactoryResetPropertySet() { - return SystemProperties.getBoolean(PROP_ATTEMPTING_FACTORY_RESET, false); + return CrashRecoveryProperties.attemptingFactoryReset().orElse(false); } static boolean isRebootPropertySet() { - return SystemProperties.getBoolean(PROP_ATTEMPTING_REBOOT, false); + return CrashRecoveryProperties.attemptingReboot().orElse(false); } /** @@ -440,7 +433,7 @@ public class RescueParty { case LEVEL_WARM_REBOOT: // Request the reboot from a separate thread to avoid deadlock on PackageWatchdog // when device shutting down. - SystemProperties.set(PROP_ATTEMPTING_REBOOT, "true"); + CrashRecoveryProperties.attemptingReboot(true); runnable = () -> { try { PowerManager pm = context.getSystemService(PowerManager.class); @@ -462,9 +455,9 @@ public class RescueParty { if (isRebootPropertySet()) { break; } - SystemProperties.set(PROP_ATTEMPTING_FACTORY_RESET, "true"); + CrashRecoveryProperties.attemptingFactoryReset(true); long now = System.currentTimeMillis(); - SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(now)); + CrashRecoveryProperties.lastFactoryResetTimeMs(now); runnable = new Runnable() { @Override public void run() { @@ -514,10 +507,10 @@ public class RescueParty { private static void resetAllSettingsIfNecessary(Context context, int mode, int level) throws Exception { // No need to reset Settings again if they are already reset in the current level once. - if (SystemProperties.getInt(PROP_MAX_RESCUE_LEVEL_ATTEMPTED, LEVEL_NONE) >= level) { + if (CrashRecoveryProperties.maxRescueLevelAttempted().orElse(LEVEL_NONE) >= level) { return; } - SystemProperties.set(PROP_MAX_RESCUE_LEVEL_ATTEMPTED, Integer.toString(level)); + CrashRecoveryProperties.maxRescueLevelAttempted(level); // Try our best to reset all settings possible, and once finished // rethrow any exception that we encountered Exception res = null; @@ -732,7 +725,7 @@ public class RescueParty { * Will return {@code false} if a factory reset was already offered recently. */ private boolean shouldThrottleReboot() { - Long lastResetTime = SystemProperties.getLong(PROP_LAST_FACTORY_RESET_TIME_MS, 0); + Long lastResetTime = CrashRecoveryProperties.lastFactoryResetTimeMs().orElse(0L); long now = System.currentTimeMillis(); long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG, DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN); diff --git a/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java index 50322f09640f..dd74a2a978b2 100644 --- a/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java +++ b/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java @@ -34,6 +34,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.PowerManager; import android.os.SystemProperties; +import android.sysprop.CrashRecoveryProperties; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; @@ -70,7 +71,6 @@ import java.util.function.Consumer; final class RollbackPackageHealthObserver implements PackageHealthObserver { private static final String TAG = "RollbackPackageHealthObserver"; private static final String NAME = "rollback-observer"; - private static final String PROP_ATTEMPTING_REBOOT = "sys.attempting_reboot"; private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_PERSISTENT | ApplicationInfo.FLAG_SYSTEM; @@ -450,7 +450,7 @@ final class RollbackPackageHealthObserver implements PackageHealthObserver { markStagedSessionHandled(rollback.getRollbackId()); // Wait for all pending staged sessions to get handled before rebooting. if (isPendingStagedSessionsEmpty()) { - SystemProperties.set(PROP_ATTEMPTING_REBOOT, "true"); + CrashRecoveryProperties.attemptingReboot(true); mContext.getSystemService(PowerManager.class).reboot("Rollback staged install"); } } diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 627a62ee0496..34c3d7ec8433 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -246,16 +246,6 @@ public class AdbDebuggingManager { @Override public void run() { - if (mGuid.isEmpty()) { - Slog.e(TAG, "adbwifi guid was not set"); - return; - } - mPort = native_pairing_start(mGuid, mPairingCode); - if (mPort <= 0 || mPort > 65535) { - Slog.e(TAG, "Unable to start pairing server"); - return; - } - // Register the mdns service NsdServiceInfo serviceInfo = new NsdServiceInfo(); serviceInfo.setServiceName(mServiceName); @@ -288,6 +278,28 @@ public class AdbDebuggingManager { mHandler.sendMessage(message); } + @Override + public void start() { + /* + * If a user is fast enough to click cancel, native_pairing_cancel can be invoked + * while native_pairing_start is running which run the destruction of the object + * while it is being constructed. Here we start the pairing server on foreground + * Thread so native_pairing_cancel can never be called concurrently. Then we let + * the pairing server run on a background Thread. + */ + if (mGuid.isEmpty()) { + Slog.e(TAG, "adbwifi guid was not set"); + return; + } + mPort = native_pairing_start(mGuid, mPairingCode); + if (mPort <= 0) { + Slog.e(TAG, "Unable to start pairing server"); + return; + } + + super.start(); + } + public void cancelPairing() { native_pairing_cancel(); } diff --git a/services/core/java/com/android/server/wm/WindowList.java b/services/core/java/com/android/server/wm/WindowList.java index dfeba40fa45e..1e888f5823a1 100644 --- a/services/core/java/com/android/server/wm/WindowList.java +++ b/services/core/java/com/android/server/wm/WindowList.java @@ -24,7 +24,7 @@ import java.util.ArrayList; */ class WindowList<E> extends ArrayList<E> { - void addFirst(E e) { + public void addFirst(E e) { add(0, e); } diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp index 8f25c0d6b013..cd1891817915 100644 --- a/services/tests/mockingservicestests/Android.bp +++ b/services/tests/mockingservicestests/Android.bp @@ -53,6 +53,7 @@ android_test { "mockito-target-extended-minus-junit4", "platform-compat-test-rules", "platform-test-annotations", + "PlatformProperties", "service-blobstore", "service-jobscheduler", "service-permission.impl", diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java index 7b771aff0055..2d065e263a6f 100644 --- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java @@ -45,6 +45,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings; +import android.sysprop.CrashRecoveryProperties; import android.util.ArraySet; import com.android.dx.mockito.inline.extended.ExtendedMockito; @@ -95,7 +96,6 @@ public class RescuePartyTest { "persist.device_config.configuration.disable_rescue_party"; private static final String PROP_DISABLE_FACTORY_RESET_FLAG = "persist.device_config.configuration.disable_rescue_party_factory_reset"; - private static final String PROP_LAST_FACTORY_RESET_TIME_MS = "persist.sys.last_factory_reset"; private static final int THROTTLING_DURATION_MIN = 10; @@ -211,8 +211,8 @@ public class RescuePartyTest { doReturn(CURRENT_NETWORK_TIME_MILLIS).when(() -> RescueParty.getElapsedRealtime()); - SystemProperties.set(RescueParty.PROP_RESCUE_BOOT_COUNT, Integer.toString(0)); - SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true)); + CrashRecoveryProperties.rescueBootCount(0); + CrashRecoveryProperties.enableRescueParty(true); SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(false)); } @@ -255,7 +255,7 @@ public class RescuePartyTest { noteBoot(4); assertTrue(RescueParty.isRebootPropertySet()); - SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false)); + CrashRecoveryProperties.attemptingReboot(false); noteBoot(5); assertTrue(RescueParty.isFactoryResetPropertySet()); } @@ -280,7 +280,7 @@ public class RescuePartyTest { noteAppCrash(4, true); assertTrue(RescueParty.isRebootPropertySet()); - SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false)); + CrashRecoveryProperties.attemptingReboot(false); noteAppCrash(5, true); assertTrue(RescueParty.isFactoryResetPropertySet()); } @@ -438,7 +438,7 @@ public class RescuePartyTest { noteBoot(i + 1); } assertFalse(RescueParty.isFactoryResetPropertySet()); - SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false)); + CrashRecoveryProperties.attemptingReboot(false); noteBoot(LEVEL_FACTORY_RESET + 1); assertTrue(RescueParty.isAttemptingFactoryReset()); assertTrue(RescueParty.isFactoryResetPropertySet()); @@ -456,7 +456,7 @@ public class RescuePartyTest { noteBoot(mitigationCount++); assertFalse(RescueParty.isFactoryResetPropertySet()); noteBoot(mitigationCount++); - SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false)); + CrashRecoveryProperties.attemptingReboot(false); noteBoot(mitigationCount + 1); assertTrue(RescueParty.isAttemptingFactoryReset()); assertTrue(RescueParty.isFactoryResetPropertySet()); @@ -464,10 +464,10 @@ public class RescuePartyTest { @Test public void testThrottlingOnBootFailures() { - SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false)); + CrashRecoveryProperties.attemptingReboot(false); long now = System.currentTimeMillis(); long beforeTimeout = now - TimeUnit.MINUTES.toMillis(THROTTLING_DURATION_MIN - 1); - SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(beforeTimeout)); + CrashRecoveryProperties.lastFactoryResetTimeMs(beforeTimeout); for (int i = 1; i <= LEVEL_FACTORY_RESET; i++) { noteBoot(i); } @@ -476,10 +476,10 @@ public class RescuePartyTest { @Test public void testThrottlingOnAppCrash() { - SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false)); + CrashRecoveryProperties.attemptingReboot(false); long now = System.currentTimeMillis(); long beforeTimeout = now - TimeUnit.MINUTES.toMillis(THROTTLING_DURATION_MIN - 1); - SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(beforeTimeout)); + CrashRecoveryProperties.lastFactoryResetTimeMs(beforeTimeout); for (int i = 0; i <= LEVEL_FACTORY_RESET; i++) { noteAppCrash(i + 1, true); } @@ -488,10 +488,10 @@ public class RescuePartyTest { @Test public void testNotThrottlingAfterTimeoutOnBootFailures() { - SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false)); + CrashRecoveryProperties.attemptingReboot(false); long now = System.currentTimeMillis(); long afterTimeout = now - TimeUnit.MINUTES.toMillis(THROTTLING_DURATION_MIN + 1); - SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(afterTimeout)); + CrashRecoveryProperties.lastFactoryResetTimeMs(afterTimeout); for (int i = 1; i <= LEVEL_FACTORY_RESET; i++) { noteBoot(i); } @@ -499,10 +499,10 @@ public class RescuePartyTest { } @Test public void testNotThrottlingAfterTimeoutOnAppCrash() { - SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false)); + CrashRecoveryProperties.attemptingReboot(false); long now = System.currentTimeMillis(); long afterTimeout = now - TimeUnit.MINUTES.toMillis(THROTTLING_DURATION_MIN + 1); - SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(afterTimeout)); + CrashRecoveryProperties.lastFactoryResetTimeMs(afterTimeout); for (int i = 0; i <= LEVEL_FACTORY_RESET; i++) { noteAppCrash(i + 1, true); } @@ -525,26 +525,26 @@ public class RescuePartyTest { @Test public void testExplicitlyEnablingAndDisablingRescue() { - SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false)); + CrashRecoveryProperties.enableRescueParty(false); SystemProperties.set(PROP_DISABLE_RESCUE, Boolean.toString(true)); assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage, PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false); - SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true)); + CrashRecoveryProperties.enableRescueParty(true); assertTrue(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage, PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1)); } @Test public void testDisablingRescueByDeviceConfigFlag() { - SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false)); + CrashRecoveryProperties.enableRescueParty(false); SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(true)); assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage, PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false); // Restore the property value initialized in SetUp() - SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true)); + CrashRecoveryProperties.enableRescueParty(true); SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(false)); } diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index d7fa124623ce..755636aef7ed 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -70,6 +70,7 @@ import org.mockito.stubbing.Answer; import java.io.File; import java.io.FileOutputStream; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -107,10 +108,13 @@ public class PackageWatchdogTest { private ConnectivityModuleConnector mConnectivityModuleConnector; @Mock private PackageManager mMockPackageManager; + // Mock only sysprop apis + private PackageWatchdog.BootThreshold mSpyBootThreshold; @Captor private ArgumentCaptor<ConnectivityModuleHealthListener> mConnectivityModuleCallbackCaptor; private MockitoSession mSession; private HashMap<String, String> mSystemSettingsMap; + private HashMap<String, String> mCrashRecoveryPropertiesMap; private boolean retry(Supplier<Boolean> supplier) throws Exception { for (int i = 0; i < RETRY_MAX_COUNT; ++i) { @@ -1416,6 +1420,8 @@ public class PackageWatchdogTest { PackageWatchdog watchdog = new PackageWatchdog(mSpyContext, policyFile, handler, handler, controller, mConnectivityModuleConnector, mTestClock); + mockCrashRecoveryProperties(watchdog); + // Verify controller is not automatically started assertThat(controller.mIsEnabled).isFalse(); if (withPackagesReady) { @@ -1432,6 +1438,71 @@ public class PackageWatchdogTest { return watchdog; } + // Mock CrashRecoveryProperties as they cannot be accessed due to SEPolicy restrictions + private void mockCrashRecoveryProperties(PackageWatchdog watchdog) { + try { + mSpyBootThreshold = spy(watchdog.new BootThreshold( + PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, + PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS)); + mCrashRecoveryPropertiesMap = new HashMap<>(); + + doAnswer((Answer<Integer>) invocationOnMock -> { + String storedValue = mCrashRecoveryPropertiesMap + .getOrDefault("crashrecovery.rescue_boot_count", "0"); + return Integer.parseInt(storedValue); + }).when(mSpyBootThreshold).getCount(); + doAnswer((Answer<Void>) invocationOnMock -> { + int count = invocationOnMock.getArgument(0); + mCrashRecoveryPropertiesMap.put("crashrecovery.rescue_boot_count", + Integer.toString(count)); + return null; + }).when(mSpyBootThreshold).setCount(anyInt()); + + doAnswer((Answer<Integer>) invocationOnMock -> { + String storedValue = mCrashRecoveryPropertiesMap + .getOrDefault("crashrecovery.boot_mitigation_count", "0"); + return Integer.parseInt(storedValue); + }).when(mSpyBootThreshold).getMitigationCount(); + doAnswer((Answer<Void>) invocationOnMock -> { + int count = invocationOnMock.getArgument(0); + mCrashRecoveryPropertiesMap.put("crashrecovery.boot_mitigation_count", + Integer.toString(count)); + return null; + }).when(mSpyBootThreshold).setMitigationCount(anyInt()); + + doAnswer((Answer<Long>) invocationOnMock -> { + String storedValue = mCrashRecoveryPropertiesMap + .getOrDefault("crashrecovery.rescue_boot_start", "0"); + return Long.parseLong(storedValue); + }).when(mSpyBootThreshold).getStart(); + doAnswer((Answer<Void>) invocationOnMock -> { + long count = invocationOnMock.getArgument(0); + mCrashRecoveryPropertiesMap.put("crashrecovery.rescue_boot_start", + Long.toString(count)); + return null; + }).when(mSpyBootThreshold).setStart(anyLong()); + + doAnswer((Answer<Long>) invocationOnMock -> { + String storedValue = mCrashRecoveryPropertiesMap + .getOrDefault("crashrecovery.boot_mitigation_start", "0"); + return Long.parseLong(storedValue); + }).when(mSpyBootThreshold).getMitigationStart(); + doAnswer((Answer<Void>) invocationOnMock -> { + long count = invocationOnMock.getArgument(0); + mCrashRecoveryPropertiesMap.put("crashrecovery.boot_mitigation_start", + Long.toString(count)); + return null; + }).when(mSpyBootThreshold).setMitigationStart(anyLong()); + + Field mBootThresholdField = watchdog.getClass().getDeclaredField("mBootThreshold"); + mBootThresholdField.setAccessible(true); + mBootThresholdField.set(watchdog, mSpyBootThreshold); + } catch (Exception e) { + // tests will fail, just printing the error + System.out.println("Error detected while spying BootThreshold" + e.getMessage()); + } + } + private static class TestObserver implements PackageHealthObserver { private final String mName; private int mImpact; |