Merge "Remove framework support for audio HIDL HAL V4" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index c76be6f..8936ed5 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -19,6 +19,7 @@
":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 1b84ce7..ea59d0b 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -374,7 +374,10 @@
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 fa2be21..c733f5b 100644
--- a/api/api.go
+++ b/api/api.go
@@ -130,7 +130,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 8d8a82b..77594b7 100644
--- a/core/api/Android.bp
+++ b/core/api/Android.bp
@@ -96,3 +96,54 @@
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 d07de72..ab8fd5e 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -14,3 +14,11 @@
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 ec44100..763c79e 100644
--- a/core/java/android/service/voice/OWNERS
+++ b/core/java/android/service/voice/OWNERS
@@ -4,4 +4,4 @@
# 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 9c40a28..2a2e903 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 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 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 @@
// 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 @@
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 @@
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 @@
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 @@
* 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 9bb2499..61e6a36 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 c4530f6..cb803f7 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 d256aea..b5cf011 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.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 @@
@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 @@
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);
}
- public void setPropertyStart(String property, long start) {
+ private static long constrain(long amount, long low, long high) {
+ return amount < low ? low : (amount > high ? high : amount);
+ }
+
+ 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 5d03ef5..6766afc 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.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 @@
*/
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 @@
@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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
* 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 50322f0..dd74a2a 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.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 @@
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 @@
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 627a62e..34c3d7e 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 @@
@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 @@
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 dfeba40..1e888f5 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 @@
*/
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 8f25c0d..cd18918 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -53,6 +53,7 @@
"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 7b771af..2d065e2 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.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 @@
"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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
@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 @@
@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 @@
@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 @@
}
@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 @@
@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 d7fa124..755636a 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -70,6 +70,7 @@
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 @@
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 @@
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 @@
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;