Handle hiddenapi lists which are yet unknown.
Make such APIs behave like @UnsupportedAppUsage.
Test: 822-hiddenapi-future
Bug: 172325244
Change-Id: Ic69e4d81fb64e0affb9c7c5e376bb19ab9e2d91f
diff --git a/libartbase/base/hiddenapi_flags.h b/libartbase/base/hiddenapi_flags.h
index c8b171d..375bf88 100644
--- a/libartbase/base/hiddenapi_flags.h
+++ b/libartbase/base/hiddenapi_flags.h
@@ -81,7 +81,7 @@
class ApiList {
private:
// Number of bits reserved for Value in dex flags, and the corresponding bit mask.
- static constexpr uint32_t kValueBitSize = 3;
+ static constexpr uint32_t kValueBitSize = 4;
static constexpr uint32_t kValueBitMask = helper::BitMask(kValueBitSize);
enum class Value : uint32_t {
@@ -141,6 +141,10 @@
"max-target-r",
};
+ // A magic marker used by tests to mimic a hiddenapi list which doesn't exist
+ // yet.
+ static constexpr const char* kFutureValueName = "max-target-future";
+
// Names corresponding to DomainApis.
static constexpr const char* kDomainApiNames[] {
"core-platform-api",
@@ -172,9 +176,11 @@
// Treat all ones as invalid value
if (value == helper::ToUint(Value::kInvalid)) {
return Value::kInvalid;
+ } else if (value > helper::ToUint(Value::kMax)) {
+ // For future unknown flag values, return unsupported.
+ return Value::kUnsupported;
} else {
DCHECK_GE(value, helper::ToUint(Value::kMin));
- DCHECK_LE(value, helper::ToUint(Value::kMax));
return static_cast<Value>(value);
}
}
@@ -216,6 +222,10 @@
return ApiList(helper::GetEnumAt<DomainApi>(i));
}
}
+ if (str == kFutureValueName) {
+ static_assert(helper::ToUint(Value::kMax) + 1 < helper::ToUint(Value::kInvalid));
+ return ApiList(helper::ToUint(Value::kMax) + 1);
+ }
return ApiList();
}
diff --git a/test/822-hiddenapi-future/build b/test/822-hiddenapi-future/build
new file mode 100644
index 0000000..02ce549
--- /dev/null
+++ b/test/822-hiddenapi-future/build
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+USE_HIDDENAPI=true ./default-build "$@"
diff --git a/test/822-hiddenapi-future/expected-stderr.txt b/test/822-hiddenapi-future/expected-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/822-hiddenapi-future/expected-stderr.txt
diff --git a/test/822-hiddenapi-future/expected-stdout.txt b/test/822-hiddenapi-future/expected-stdout.txt
new file mode 100644
index 0000000..6a5618e
--- /dev/null
+++ b/test/822-hiddenapi-future/expected-stdout.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/822-hiddenapi-future/hiddenapi-flags.csv b/test/822-hiddenapi-future/hiddenapi-flags.csv
new file mode 100644
index 0000000..4f95ec0
--- /dev/null
+++ b/test/822-hiddenapi-future/hiddenapi-flags.csv
@@ -0,0 +1 @@
+LMyClass;->futureHidden()I,max-target-future
diff --git a/test/822-hiddenapi-future/info.txt b/test/822-hiddenapi-future/info.txt
new file mode 100644
index 0000000..6360d9b
--- /dev/null
+++ b/test/822-hiddenapi-future/info.txt
@@ -0,0 +1 @@
+Tests that future hiddenapi flags do not crash the runtime.
diff --git a/test/822-hiddenapi-future/src-ex/MyClass.java b/test/822-hiddenapi-future/src-ex/MyClass.java
new file mode 100644
index 0000000..4a9ec9c
--- /dev/null
+++ b/test/822-hiddenapi-future/src-ex/MyClass.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class MyClass {
+ public static int futureHidden() {
+ return 42;
+ }
+}
diff --git a/test/822-hiddenapi-future/src/Main.java b/test/822-hiddenapi-future/src/Main.java
new file mode 100644
index 0000000..f90a161
--- /dev/null
+++ b/test/822-hiddenapi-future/src/Main.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[0]);
+ init();
+ appendToBootClassLoader(DEX_EXTRA, /* isCorePlatform */ false);
+
+ Class<?> klass = Object.class.getClassLoader().loadClass("MyClass");
+ Method m = klass.getDeclaredMethod("futureHidden");
+ Integer result = (Integer) m.invoke(null);
+ if (result.intValue() != 42) {
+ throw new Error("Expected 42, got " + result.intValue());
+ }
+ }
+
+ private static final String DEX_EXTRA = new File(System.getenv("DEX_LOCATION"),
+ "822-hiddenapi-future-ex.jar").getAbsolutePath();
+
+ private static native void init();
+ private static native void appendToBootClassLoader(String dexPath, boolean isCorePlatform);
+}
diff --git a/test/knownfailures.json b/test/knownfailures.json
index d4b46ff..e3f4e88 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1140,6 +1140,7 @@
"817-hiddenapi",
"820-vdex-multidex",
"821-many-args",
+ "822-hiddenapi-future",
"999-redefine-hiddenapi",
"1000-non-moving-space-stress",
"1001-app-image-regions",