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