OSDN Git Service

AAPT2: Fix regression in Manifest.java permissions
[android-x86/frameworks-base.git] / tools / aapt2 / java / ManifestClassGenerator_test.cpp
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "java/ManifestClassGenerator.h"
18
19 #include "test/Test.h"
20
21 using ::testing::HasSubstr;
22 using ::testing::Not;
23
24 namespace aapt {
25
26 static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xml::XmlResource* res,
27                                                        std::string* out_str);
28
29 TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) {
30   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
31   std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"(
32       <manifest xmlns:android="http://schemas.android.com/apk/res/android">
33         <permission android:name="android.permission.ACCESS_INTERNET" />
34         <permission android:name="android.DO_DANGEROUS_THINGS" />
35         <permission android:name="com.test.sample.permission.HUH" />
36         <permission-group android:name="foo.bar.PERMISSION" />
37       </manifest>)");
38
39   std::string actual;
40   ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
41
42   ASSERT_THAT(actual, HasSubstr("public static final class permission {"));
43   ASSERT_THAT(actual, HasSubstr("public static final class permission_group {"));
44
45   const size_t permission_start_pos = actual.find("public static final class permission {");
46   const size_t permission_group_start_pos =
47       actual.find("public static final class permission_group {");
48
49   //
50   // Make sure these permissions are in the permission class.
51   //
52   const std::string permission_class =
53       actual.substr(permission_start_pos, permission_group_start_pos - permission_start_pos);
54
55   EXPECT_THAT(
56       permission_class,
57       HasSubstr(
58           "public static final String ACCESS_INTERNET=\"android.permission.ACCESS_INTERNET\";"));
59   EXPECT_THAT(
60       permission_class,
61       HasSubstr("public static final String DO_DANGEROUS_THINGS=\"android.DO_DANGEROUS_THINGS\";"));
62   EXPECT_THAT(permission_class,
63               HasSubstr("public static final String HUH=\"com.test.sample.permission.HUH\";"));
64
65   //
66   // Make sure these permissions are in the permission_group class
67   //
68   const std::string permission_group_class = actual.substr(permission_group_start_pos);
69
70   EXPECT_THAT(permission_group_class,
71               HasSubstr("public static final String PERMISSION=\"foo.bar.PERMISSION\";"));
72 }
73
74 TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) {
75   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
76   std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"(
77       <manifest xmlns:android="http://schemas.android.com/apk/res/android">
78         <!-- Required to access the internet.
79              Added in API 1. -->
80         <permission android:name="android.permission.ACCESS_INTERNET" />
81         <!-- @deprecated This permission is for playing outside. -->
82         <permission android:name="android.permission.PLAY_OUTSIDE" />
83         <!-- This is a private permission for system only!
84              @hide
85              @SystemApi -->
86         <permission android:name="android.permission.SECRET" />
87       </manifest>)");
88
89   std::string actual;
90   ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
91
92   const char* expected_access_internet = R"(    /**
93      * Required to access the internet.
94      * Added in API 1.
95      */
96     public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)";
97   EXPECT_THAT(actual, HasSubstr(expected_access_internet));
98
99   const char* expected_play_outside = R"(    /**
100      * @deprecated This permission is for playing outside.
101      */
102     @Deprecated
103     public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)";
104   EXPECT_THAT(actual, HasSubstr(expected_play_outside));
105
106   const char* expected_secret = R"(    /**
107      * This is a private permission for system only!
108      * @hide
109      */
110     @android.annotation.SystemApi
111     public static final String SECRET="android.permission.SECRET";)";
112   EXPECT_THAT(actual, HasSubstr(expected_secret));
113 }
114
115 // This is bad but part of public API behaviour so we need to preserve it.
116 TEST(ManifestClassGeneratorTest, LastSeenPermissionWithSameLeafNameTakesPrecedence) {
117   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
118   std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"(
119       <manifest xmlns:android="http://schemas.android.com/apk/res/android">
120         <permission android:name="android.permission.ACCESS_INTERNET" />
121         <permission android:name="com.android.aapt.test.ACCESS_INTERNET" />
122       </manifest>)");
123
124   std::string actual;
125   ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual));
126   EXPECT_THAT(actual, HasSubstr("ACCESS_INTERNET=\"com.android.aapt.test.ACCESS_INTERNET\";"));
127   EXPECT_THAT(actual, Not(HasSubstr("ACCESS_INTERNET=\"android.permission.ACCESS_INTERNET\";")));
128 }
129
130 static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xml::XmlResource* res,
131                                                        std::string* out_str) {
132   std::unique_ptr<ClassDefinition> manifest_class =
133       GenerateManifestClass(context->GetDiagnostics(), res);
134   if (!manifest_class) {
135     return ::testing::AssertionFailure() << "manifest_class == nullptr";
136   }
137
138   std::stringstream out;
139   if (!manifest_class->WriteJavaFile(manifest_class.get(), "android", true, &out)) {
140     return ::testing::AssertionFailure() << "failed to write java file";
141   }
142
143   *out_str = out.str();
144   return ::testing::AssertionSuccess();
145 }
146
147 }  // namespace aapt