Only set UI warning on hidden API dark greylist
The framework might show a toast notification on access to greylisted
hidden APIs. Only show this warning on dark greylist so as to not spam
early testers.
Bug: 64382372
Test: make
Change-Id: I8b5f7b4938e0f238c513e37d7db06856b966802f
diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h
index f476028..05e68e6 100644
--- a/runtime/hidden_api.h
+++ b/runtime/hidden_api.h
@@ -27,6 +27,7 @@
enum Action {
kAllow,
kAllowButWarn,
+ kAllowButWarnAndToast,
kDeny
};
@@ -35,8 +36,9 @@
case HiddenApiAccessFlags::kWhitelist:
return kAllow;
case HiddenApiAccessFlags::kLightGreylist:
- case HiddenApiAccessFlags::kDarkGreylist:
return kAllowButWarn;
+ case HiddenApiAccessFlags::kDarkGreylist:
+ return kAllowButWarnAndToast;
case HiddenApiAccessFlags::kBlacklist:
return kDeny;
}
@@ -70,8 +72,9 @@
std::function<bool(Thread*)> fn_caller_in_boot)
REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(member != nullptr);
+ Runtime* runtime = Runtime::Current();
- if (!Runtime::Current()->AreHiddenApiChecksEnabled()) {
+ if (!runtime->AreHiddenApiChecksEnabled()) {
// Exit early. Nothing to enforce.
return false;
}
@@ -90,20 +93,23 @@
}
// Member is hidden and we are not in the boot class path. Act accordingly.
- if (action == kAllowButWarn) {
+ if (action == kDeny) {
+ return true;
+ } else {
+ DCHECK(action == kAllowButWarn || action == kAllowButWarnAndToast);
+
// Allow access to this member but print a warning. Depending on a runtime
// flag, we might move the member into whitelist and skip the warning the
// next time the member is used.
- Runtime::Current()->SetPendingHiddenApiWarning(true);
- if (Runtime::Current()->ShouldDedupeHiddenApiWarnings()) {
+ if (runtime->ShouldDedupeHiddenApiWarnings()) {
member->SetAccessFlags(HiddenApiAccessFlags::EncodeForRuntime(
member->GetAccessFlags(), HiddenApiAccessFlags::kWhitelist));
}
WarnAboutMemberAccess(member);
+ if (action == kAllowButWarnAndToast || runtime->ShouldAlwaysSetHiddenApiWarningFlag()) {
+ Runtime::Current()->SetPendingHiddenApiWarning(true);
+ }
return false;
- } else {
- DCHECK_EQ(action, hiddenapi::kDeny);
- return true;
}
}
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index e58fd9d..648a464 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -350,6 +350,9 @@
<< "SystemServer should be forked with DISABLE_HIDDEN_API_CHECKS";
Runtime::Current()->SetHiddenApiChecksEnabled(do_hidden_api_checks);
+ // Clear the hidden API warning flag, in case it was set.
+ Runtime::Current()->SetPendingHiddenApiWarning(false);
+
if (instruction_set != nullptr && !is_system_server) {
ScopedUtfChars isa_string(env, instruction_set);
InstructionSet isa = GetInstructionSetFromString(isa_string.c_str());
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 5a3a6f0..25d83df 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -268,6 +268,7 @@
do_hidden_api_checks_(true),
pending_hidden_api_warning_(false),
dedupe_hidden_api_warnings_(true),
+ always_set_hidden_api_warning_flag_(false),
dump_native_stack_on_sig_quit_(true),
pruned_dalvik_cache_(false),
// Initially assume we perceive jank in case the process state is never updated.
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 184e4e5..7ab9be5 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -544,6 +544,14 @@
return dedupe_hidden_api_warnings_;
}
+ void AlwaysSetHiddenApiWarningFlag() {
+ always_set_hidden_api_warning_flag_ = true;
+ }
+
+ bool ShouldAlwaysSetHiddenApiWarningFlag() const {
+ return always_set_hidden_api_warning_flag_;
+ }
+
bool IsDexFileFallbackEnabled() const {
return allow_dex_file_fallback_;
}
@@ -992,6 +1000,11 @@
// This is only used for testing.
bool dedupe_hidden_api_warnings_;
+ // Hidden API can print warnings into the log and/or set a flag read by the
+ // framework to show a UI warning. If this flag is set, always set the flag
+ // when there is a warning. This is only used for testing.
+ bool always_set_hidden_api_warning_flag_;
+
// Whether threads should dump their native stack on SIGQUIT.
bool dump_native_stack_on_sig_quit_;
diff --git a/test/674-hiddenapi/hiddenapi.cc b/test/674-hiddenapi/hiddenapi.cc
index baff6f7..effa37a 100644
--- a/test/674-hiddenapi/hiddenapi.cc
+++ b/test/674-hiddenapi/hiddenapi.cc
@@ -26,8 +26,10 @@
namespace Test674HiddenApi {
extern "C" JNIEXPORT void JNICALL Java_Main_init(JNIEnv*, jclass) {
- Runtime::Current()->SetHiddenApiChecksEnabled(true);
- Runtime::Current()->SetDedupeHiddenApiWarnings(false);
+ Runtime* runtime = Runtime::Current();
+ runtime->SetHiddenApiChecksEnabled(true);
+ runtime->SetDedupeHiddenApiWarnings(false);
+ runtime->AlwaysSetHiddenApiWarningFlag();
}
extern "C" JNIEXPORT void JNICALL Java_Main_appendToBootClassLoader(