diff options
author | Ryan Mitchell <rtmitchell@google.com> | 2020-11-16 23:08:18 +0000 |
---|---|---|
committer | Ryan Mitchell <rtmitchell@google.com> | 2020-12-08 16:58:12 +0000 |
commit | 80094e39f90801c44cd80ab0f98df505828ea1f3 (patch) | |
tree | e70d5241691a509ce9cf774dc39ce85932fdd1d2 /libs/androidfw/tests/Theme_test.cpp | |
parent | ec7e7f5622e3444a3003db20ddfd8f5745971fa7 (diff) |
Revert^2 "libandroidfw hardening for IncFs"
55ef6167a2c235bd88c7216238b2001b46795b79
Change-Id: I02d4890d181655dfd0a14c188468db512559d27b
Merged-In: I02d4890d181655dfd0a14c188468db512559d27b
Diffstat (limited to 'libs/androidfw/tests/Theme_test.cpp')
-rw-r--r-- | libs/androidfw/tests/Theme_test.cpp | 278 |
1 files changed, 128 insertions, 150 deletions
diff --git a/libs/androidfw/tests/Theme_test.cpp b/libs/androidfw/tests/Theme_test.cpp index 16b9c75982fb..f658735da515 100644 --- a/libs/androidfw/tests/Theme_test.cpp +++ b/libs/androidfw/tests/Theme_test.cpp @@ -67,10 +67,7 @@ TEST_F(ThemeTest, EmptyTheme) { std::unique_ptr<Theme> theme = assetmanager.NewTheme(); EXPECT_EQ(0u, theme->GetChangingConfigurations()); EXPECT_EQ(&assetmanager, theme->GetAssetManager()); - - Res_value value; - uint32_t flags; - EXPECT_EQ(kInvalidCookie, theme->GetAttribute(app::R::attr::attr_one, &value, &flags)); + EXPECT_FALSE(theme->GetAttribute(app::R::attr::attr_one).has_value()); } TEST_F(ThemeTest, SingleThemeNoParent) { @@ -78,23 +75,19 @@ TEST_F(ThemeTest, SingleThemeNoParent) { assetmanager.SetApkAssets({style_assets_.get()}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); - ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleOne)); - - Res_value value; - uint32_t flags; - ApkAssetsCookie cookie; - - cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(1u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); - - cookie = theme->GetAttribute(app::R::attr::attr_two, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(2u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleOne).has_value()); + + auto value = theme->GetAttribute(app::R::attr::attr_one); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(1u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); + + value = theme->GetAttribute(app::R::attr::attr_two); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(2u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); } TEST_F(ThemeTest, SingleThemeWithParent) { @@ -102,32 +95,28 @@ TEST_F(ThemeTest, SingleThemeWithParent) { assetmanager.SetApkAssets({style_assets_.get()}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); - ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo)); - - Res_value value; - uint32_t flags; - ApkAssetsCookie cookie; - - cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(1u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); - - cookie = theme->GetAttribute(app::R::attr::attr_two, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_STRING, value.dataType); - EXPECT_EQ(0, cookie); + ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo).has_value()); + + auto value = theme->GetAttribute(app::R::attr::attr_one); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(1u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); + + value = theme->GetAttribute(app::R::attr::attr_two); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_STRING, value->type); + EXPECT_EQ(0, value->cookie); EXPECT_EQ(std::string("string"), - GetStringFromPool(assetmanager.GetStringPoolForCookie(0), value.data)); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + GetStringFromPool(assetmanager.GetStringPoolForCookie(0), value->data)); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); // This attribute should point to an attr_indirect, so the result should be 3. - cookie = theme->GetAttribute(app::R::attr::attr_three, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(3u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + value = theme->GetAttribute(app::R::attr::attr_three); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(3u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); } TEST_F(ThemeTest, TryToUseBadResourceId) { @@ -135,11 +124,8 @@ TEST_F(ThemeTest, TryToUseBadResourceId) { assetmanager.SetApkAssets({style_assets_.get()}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); - ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo)); - - Res_value value; - uint32_t flags; - ASSERT_EQ(kInvalidCookie, theme->GetAttribute(0x7f000001, &value, &flags)); + ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo).has_value()); + ASSERT_FALSE(theme->GetAttribute(0x7f000001)); } TEST_F(ThemeTest, MultipleThemesOverlaidNotForce) { @@ -147,33 +133,29 @@ TEST_F(ThemeTest, MultipleThemesOverlaidNotForce) { assetmanager.SetApkAssets({style_assets_.get()}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); - ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo)); - ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleThree)); - - Res_value value; - uint32_t flags; - ApkAssetsCookie cookie; + ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo).has_value()); + ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleThree).has_value()); // attr_one is still here from the base. - cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(1u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + auto value = theme->GetAttribute(app::R::attr::attr_one); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(1u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); // check for the new attr_six - cookie = theme->GetAttribute(app::R::attr::attr_six, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(6u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + value = theme->GetAttribute(app::R::attr::attr_six); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(6u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); // check for the old attr_five (force=true was not used). - cookie = theme->GetAttribute(app::R::attr::attr_five, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType); - EXPECT_EQ(app::R::string::string_one, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + value = theme->GetAttribute(app::R::attr::attr_five); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_REFERENCE, value->type); + EXPECT_EQ(app::R::string::string_one, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); } TEST_F(ThemeTest, MultipleThemesOverlaidForced) { @@ -181,33 +163,29 @@ TEST_F(ThemeTest, MultipleThemesOverlaidForced) { assetmanager.SetApkAssets({style_assets_.get()}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); - ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo)); - ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleThree, true /* force */)); - - Res_value value; - uint32_t flags; - ApkAssetsCookie cookie; + ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo).has_value()); + ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleThree, true /* force */).has_value()); // attr_one is still here from the base. - cookie = theme->GetAttribute(app::R::attr::attr_one, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(1u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + auto value = theme->GetAttribute(app::R::attr::attr_one); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(1u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); // check for the new attr_six - cookie = theme->GetAttribute(app::R::attr::attr_six, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(6u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + value = theme->GetAttribute(app::R::attr::attr_six); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(6u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); // check for the new attr_five (force=true was used). - cookie = theme->GetAttribute(app::R::attr::attr_five, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(5u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + value = theme->GetAttribute(app::R::attr::attr_five); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(5u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); } TEST_F(ThemeTest, ResolveDynamicAttributesAndReferencesToSharedLibrary) { @@ -216,28 +194,24 @@ TEST_F(ThemeTest, ResolveDynamicAttributesAndReferencesToSharedLibrary) { {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); - ASSERT_TRUE(theme->ApplyStyle(libclient::R::style::Theme, false /*force*/)); - - Res_value value; - uint32_t flags; - ApkAssetsCookie cookie; + ASSERT_TRUE(theme->ApplyStyle(libclient::R::style::Theme, false /*force*/).has_value()); // The attribute should be resolved to the final value. - cookie = theme->GetAttribute(libclient::R::attr::foo, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(700u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + auto value = theme->GetAttribute(libclient::R::attr::foo); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(700u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); // The reference should be resolved to a TYPE_REFERENCE. - cookie = theme->GetAttribute(libclient::R::attr::bar, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType); + value = theme->GetAttribute(libclient::R::attr::bar); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_REFERENCE, value->type); // lib_one is assigned package ID 0x03. - EXPECT_EQ(3u, get_package_id(value.data)); - EXPECT_EQ(get_type_id(lib_one::R::string::foo), get_type_id(value.data)); - EXPECT_EQ(get_entry_id(lib_one::R::string::foo), get_entry_id(value.data)); + EXPECT_EQ(3u, get_package_id(value->data)); + EXPECT_EQ(get_type_id(lib_one::R::string::foo), get_type_id(value->data)); + EXPECT_EQ(get_entry_id(lib_one::R::string::foo), get_entry_id(value->data)); } TEST_F(ThemeTest, CopyThemeSameAssetManager) { @@ -245,24 +219,20 @@ TEST_F(ThemeTest, CopyThemeSameAssetManager) { assetmanager.SetApkAssets({style_assets_.get()}); std::unique_ptr<Theme> theme_one = assetmanager.NewTheme(); - ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne)); - - Res_value value; - uint32_t flags; - ApkAssetsCookie cookie; + ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne).has_value()); // attr_one is still here from the base. - cookie = theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(1u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + auto value = theme_one->GetAttribute(app::R::attr::attr_one); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(1u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); // attr_six is not here. - EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_six, &value, &flags)); + ASSERT_FALSE(theme_one->GetAttribute(app::R::attr::attr_six).has_value()); std::unique_ptr<Theme> theme_two = assetmanager.NewTheme(); - ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleThree)); + ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleThree).has_value()); // Copy the theme to theme_one. theme_one->SetTo(*theme_two); @@ -271,14 +241,14 @@ TEST_F(ThemeTest, CopyThemeSameAssetManager) { theme_two->Clear(); // attr_one is now not here. - EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags)); + ASSERT_FALSE(theme_one->GetAttribute(app::R::attr::attr_one).has_value()); // attr_six is now here because it was copied. - cookie = theme_one->GetAttribute(app::R::attr::attr_six, &value, &flags); - ASSERT_NE(kInvalidCookie, cookie); - EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType); - EXPECT_EQ(6u, value.data); - EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); + value = theme_one->GetAttribute(app::R::attr::attr_six); + ASSERT_TRUE(value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, value->type); + EXPECT_EQ(6u, value->data); + EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value->flags); } TEST_F(ThemeTest, OnlyCopySameAssetsThemeWhenAssetManagersDiffer) { @@ -291,39 +261,43 @@ TEST_F(ThemeTest, OnlyCopySameAssetsThemeWhenAssetManagersDiffer) { style_assets_.get()}); auto theme_dst = assetmanager_dst.NewTheme(); - ASSERT_TRUE(theme_dst->ApplyStyle(app::R::style::StyleOne)); + ASSERT_TRUE(theme_dst->ApplyStyle(app::R::style::StyleOne).has_value()); auto theme_src = assetmanager_src.NewTheme(); - ASSERT_TRUE(theme_src->ApplyStyle(R::style::Theme_One)); - ASSERT_TRUE(theme_src->ApplyStyle(app::R::style::StyleTwo)); + ASSERT_TRUE(theme_src->ApplyStyle(R::style::Theme_One).has_value()); + ASSERT_TRUE(theme_src->ApplyStyle(app::R::style::StyleTwo).has_value()); ASSERT_TRUE(theme_src->ApplyStyle(fix_package_id(lib_one::R::style::Theme, 0x03), - false /*force*/)); + false /*force*/).has_value()); ASSERT_TRUE(theme_src->ApplyStyle(fix_package_id(lib_two::R::style::Theme, 0x02), - false /*force*/)); + false /*force*/).has_value()); theme_dst->SetTo(*theme_src); - Res_value value; - uint32_t flags; - // System resources (present in destination asset manager). - EXPECT_EQ(0, theme_dst->GetAttribute(R::attr::foreground, &value, &flags)); + auto value = theme_dst->GetAttribute(R::attr::foreground); + ASSERT_TRUE(value.has_value()); + EXPECT_EQ(0, value->cookie); // The cookie of the style asset is 3 in the source and 2 in the destination. // Check that the cookie has been rewritten to the destination values. - EXPECT_EQ(2, theme_dst->GetAttribute(app::R::attr::attr_one, &value, &flags)); + value = theme_dst->GetAttribute(app::R::attr::attr_one); + ASSERT_TRUE(value.has_value()); + EXPECT_EQ(2, value->cookie); // The cookie of the lib_one asset is 2 in the source and 1 in the destination. // The package id of the lib_one package is 0x03 in the source and 0x02 in the destination // Check that the cookie and packages have been rewritten to the destination values. - EXPECT_EQ(1, theme_dst->GetAttribute(fix_package_id(lib_one::R::attr::attr1, 0x02), &value, - &flags)); - EXPECT_EQ(1, theme_dst->GetAttribute(fix_package_id(lib_one::R::attr::attr2, 0x02), &value, - &flags)); + value = theme_dst->GetAttribute(fix_package_id(lib_one::R::attr::attr1, 0x02)); + ASSERT_TRUE(value.has_value()); + EXPECT_EQ(1, value->cookie); + + value = theme_dst->GetAttribute(fix_package_id(lib_one::R::attr::attr2, 0x02)); + ASSERT_TRUE(value.has_value()); + EXPECT_EQ(1, value->cookie); // attr2 references an attribute in lib_one. Check that the resolution of the attribute value is // correct after the value of attr2 had its package id rewritten to the destination package id. - EXPECT_EQ(700, value.data); + EXPECT_EQ(700, value->data); } TEST_F(ThemeTest, CopyNonReferencesWhenPackagesDiffer) { @@ -335,28 +309,32 @@ TEST_F(ThemeTest, CopyNonReferencesWhenPackagesDiffer) { auto theme_dst = assetmanager_dst.NewTheme(); auto theme_src = assetmanager_src.NewTheme(); - ASSERT_TRUE(theme_src->ApplyStyle(app::R::style::StyleSeven)); + ASSERT_TRUE(theme_src->ApplyStyle(app::R::style::StyleSeven).has_value()); theme_dst->SetTo(*theme_src); - Res_value value; - uint32_t flags; - // Allow inline resource values to be copied even if the source apk asset is not present in the // destination. - EXPECT_EQ(0, theme_dst->GetAttribute(0x0101021b /* android:versionCode */, &value, &flags)); + auto value = theme_dst->GetAttribute(0x0101021b /* android:versionCode */); + ASSERT_TRUE(value.has_value()); + EXPECT_EQ(0, value->cookie); // Do not copy strings since the data is an index into the values string pool of the source apk // asset. - EXPECT_EQ(-1, theme_dst->GetAttribute(0x01010001 /* android:label */, &value, &flags)); + EXPECT_FALSE(theme_dst->GetAttribute(0x01010001 /* android:label */).has_value()); // Do not copy values that reference another resource if the resource is not present in the // destination. - EXPECT_EQ(-1, theme_dst->GetAttribute(0x01010002 /* android:icon */, &value, &flags)); - EXPECT_EQ(-1, theme_dst->GetAttribute(0x010100d1 /* android:tag */, &value, &flags)); + EXPECT_FALSE(theme_dst->GetAttribute(0x01010002 /* android:icon */).has_value()); + EXPECT_FALSE(theme_dst->GetAttribute(0x010100d1 /* android:tag */).has_value()); // Allow @empty to and @null to be copied. - EXPECT_EQ(0, theme_dst->GetAttribute(0x010100d0 /* android:id */, &value, &flags)); - EXPECT_EQ(0, theme_dst->GetAttribute(0x01010000 /* android:theme */, &value, &flags)); + value = theme_dst->GetAttribute(0x010100d0 /* android:id */); + ASSERT_TRUE(value.has_value()); + EXPECT_EQ(0, value->cookie); + + value = theme_dst->GetAttribute(0x01010000 /* android:theme */); + ASSERT_TRUE(value.has_value()); + EXPECT_EQ(0, value->cookie); } } // namespace android |