diff options
| author | 2019-09-26 21:48:13 +0000 | |
|---|---|---|
| committer | 2019-09-26 21:48:13 +0000 | |
| commit | 346594121a6bbb0d38cbce6b85d80c48a75c7ff4 (patch) | |
| tree | 741d15bdb37c1b9d2f17509482e1be4bc371eff0 | |
| parent | e2415eeea0c43259bb86e34613d84d4014fc8fbe (diff) | |
| parent | 2e3942246d14a52e4ca2d421ae81b91416a90643 (diff) | |
Merge "Enable CTS verification of overlayable API"
| -rw-r--r-- | api/test-current.txt | 2 | ||||
| -rw-r--r-- | core/java/android/content/res/AssetManager.java | 15 | ||||
| -rw-r--r-- | core/jni/android_util_AssetManager.cpp | 19 | ||||
| -rw-r--r-- | libs/androidfw/AssetManager2.cpp | 58 | ||||
| -rw-r--r-- | libs/androidfw/include/androidfw/AssetManager2.h | 6 | ||||
| -rw-r--r-- | libs/androidfw/tests/AssetManager2_test.cpp | 8 |
6 files changed, 102 insertions, 6 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index 75d80bd9eeaf..9b00a42d27a9 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -786,7 +786,7 @@ package android.content.res { public final class AssetManager implements java.lang.AutoCloseable { method @NonNull public String[] getApkPaths(); - method @Nullable public java.util.Map<java.lang.String,java.lang.String> getOverlayableMap(String); + method @Nullable public String getOverlayablesToString(String); } public final class Configuration implements java.lang.Comparable<android.content.res.Configuration> android.os.Parcelable { diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 2420a6109155..567e26b4c2f6 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -1376,7 +1376,6 @@ public final class AssetManager implements AutoCloseable { /** * @hide */ - @TestApi @GuardedBy("this") public @Nullable Map<String, String> getOverlayableMap(String packageName) { synchronized (this) { @@ -1385,6 +1384,18 @@ public final class AssetManager implements AutoCloseable { } } + /** + * @hide + */ + @TestApi + @GuardedBy("this") + public @Nullable String getOverlayablesToString(String packageName) { + synchronized (this) { + ensureValidLocked(); + return nativeGetOverlayablesToString(mObject, packageName); + } + } + @GuardedBy("this") private void incRefsLocked(long id) { if (DEBUG_REFS) { @@ -1504,6 +1515,8 @@ public final class AssetManager implements AutoCloseable { private static native String[] nativeCreateIdmapsForStaticOverlaysTargetingAndroid(); private static native @Nullable Map nativeGetOverlayableMap(long ptr, @NonNull String packageName); + private static native @Nullable String nativeGetOverlayablesToString(long ptr, + @NonNull String packageName); // Global debug native methods. /** diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index bf4ffc7e42e0..daf33f61105c 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -352,7 +352,7 @@ static Guarded<AssetManager2>& AssetManagerFromLong(jlong ptr) { } static jobject NativeGetOverlayableMap(JNIEnv* env, jclass /*clazz*/, jlong ptr, - jstring package_name) { + jstring package_name) { ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr)); const ScopedUtfChars package_name_utf8(env, package_name); CHECK(package_name_utf8.c_str() != nullptr); @@ -397,6 +397,21 @@ static jobject NativeGetOverlayableMap(JNIEnv* env, jclass /*clazz*/, jlong ptr, return array_map; } +static jstring NativeGetOverlayablesToString(JNIEnv* env, jclass /*clazz*/, jlong ptr, + jstring package_name) { + ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr)); + const ScopedUtfChars package_name_utf8(env, package_name); + CHECK(package_name_utf8.c_str() != nullptr); + const std::string std_package_name(package_name_utf8.c_str()); + + std::string result; + if (!assetmanager->GetOverlayablesToString(std_package_name, &result)) { + return nullptr; + } + + return env->NewStringUTF(result.c_str()); +} + #ifdef __ANDROID__ // Layoutlib does not support parcel static jobject ReturnParcelFileDescriptor(JNIEnv* env, std::unique_ptr<Asset> asset, jlongArray out_offsets) { @@ -1608,6 +1623,8 @@ static const JNINativeMethod gAssetManagerMethods[] = { (void*)NativeCreateIdmapsForStaticOverlaysTargetingAndroid}, {"nativeGetOverlayableMap", "(JLjava/lang/String;)Ljava/util/Map;", (void*)NativeGetOverlayableMap}, + {"nativeGetOverlayablesToString", "(JLjava/lang/String;)Ljava/lang/String;", + (void*)NativeGetOverlayablesToString}, // Global management/debug methods. {"getGlobalAssetCount", "()I", (void*)NativeGetGlobalAssetCount}, diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index 01caf011f644..eec49df79630 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -224,6 +224,62 @@ const std::unordered_map<std::string, std::string>* return &loaded_package->GetOverlayableMap(); } +bool AssetManager2::GetOverlayablesToString(const android::StringPiece& package_name, + std::string* out) const { + uint8_t package_id = 0U; + for (const auto& apk_assets : apk_assets_) { + const LoadedArsc* loaded_arsc = apk_assets->GetLoadedArsc(); + if (loaded_arsc == nullptr) { + continue; + } + + const auto& loaded_packages = loaded_arsc->GetPackages(); + if (loaded_packages.empty()) { + continue; + } + + const auto& loaded_package = loaded_packages[0]; + if (loaded_package->GetPackageName() == package_name) { + package_id = GetAssignedPackageId(loaded_package.get()); + break; + } + } + + if (package_id == 0U) { + ANDROID_LOG(ERROR) << base::StringPrintf("No package with name '%s", package_name.data()); + return false; + } + + const size_t idx = package_ids_[package_id]; + if (idx == 0xff) { + return false; + } + + std::string output; + for (const ConfiguredPackage& package : package_groups_[idx].packages_) { + const LoadedPackage* loaded_package = package.loaded_package_; + for (auto it = loaded_package->begin(); it != loaded_package->end(); it++) { + const OverlayableInfo* info = loaded_package->GetOverlayableInfo(*it); + if (info != nullptr) { + ResourceName res_name; + if (!GetResourceName(*it, &res_name)) { + ANDROID_LOG(ERROR) << base::StringPrintf( + "Unable to retrieve name of overlayable resource 0x%08x", *it); + return false; + } + + const std::string name = ToFormattedResourceString(&res_name); + output.append(base::StringPrintf( + "resource='%s' overlayable='%s' actor='%s' policy='0x%08x'\n", + name.c_str(), info->name.c_str(), info->actor.c_str(), info->policy_flags)); + } + } + } + + *out = std::move(output); + return true; +} + void AssetManager2::SetConfiguration(const ResTable_config& configuration) { const int diff = configuration_.diff(configuration); configuration_ = configuration; @@ -1073,7 +1129,7 @@ void AssetManager2::InvalidateCaches(uint32_t diff) { } } -uint8_t AssetManager2::GetAssignedPackageId(const LoadedPackage* package) { +uint8_t AssetManager2::GetAssignedPackageId(const LoadedPackage* package) const { for (auto& package_group : package_groups_) { for (auto& package2 : package_group.packages_) { if (package2.loaded_package_ == package) { diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h index 1e2b36cb1703..de46081a6aa3 100644 --- a/libs/androidfw/include/androidfw/AssetManager2.h +++ b/libs/androidfw/include/androidfw/AssetManager2.h @@ -124,6 +124,10 @@ class AssetManager2 { // This may be nullptr if the APK represented by `cookie` has no resource table. const DynamicRefTable* GetDynamicRefTableForCookie(ApkAssetsCookie cookie) const; + // Returns a string representation of the overlayable API of a package. + bool GetOverlayablesToString(const android::StringPiece& package_name, + std::string* out) const; + const std::unordered_map<std::string, std::string>* GetOverlayableMapForPackage(uint32_t package_id) const; @@ -308,7 +312,7 @@ class AssetManager2 { const ResolvedBag* GetBag(uint32_t resid, std::vector<uint32_t>& child_resids); // Retrieve the assigned package id of the package if loaded into this AssetManager - uint8_t GetAssignedPackageId(const LoadedPackage* package); + uint8_t GetAssignedPackageId(const LoadedPackage* package) const; // The ordered list of ApkAssets to search. These are not owned by the AssetManager, and must // have a longer lifetime. diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp index 40c8e46e4d84..15910241518d 100644 --- a/libs/androidfw/tests/AssetManager2_test.cpp +++ b/libs/androidfw/tests/AssetManager2_test.cpp @@ -707,7 +707,7 @@ TEST_F(AssetManager2Test, GetLastPathAfterDisablingReturnsEmpty) { EXPECT_EQ("", resultDisabled); } -TEST_F(AssetManager2Test, GetOverlayableMap) { +TEST_F(AssetManager2Test, GetOverlayablesToString) { ResTable_config desired_config; memset(&desired_config, 0, sizeof(desired_config)); @@ -721,6 +721,12 @@ TEST_F(AssetManager2Test, GetOverlayableMap) { ASSERT_EQ(2, map->size()); ASSERT_EQ(map->at("OverlayableResources1"), "overlay://theme"); ASSERT_EQ(map->at("OverlayableResources2"), "overlay://com.android.overlayable"); + + std::string api; + ASSERT_TRUE(assetmanager.GetOverlayablesToString("com.android.overlayable", &api)); + ASSERT_EQ(api.find("not_overlayable"), std::string::npos); + ASSERT_NE(api.find("resource='com.android.overlayable:string/overlayable2' overlayable='OverlayableResources1' actor='overlay://theme' policy='0x0000000a'\n"), + std::string::npos); } } // namespace android |