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#include "test/Builders.h"
19#include "test/Context.h"
20
21#include <gtest/gtest.h>
22
23namespace aapt {
24
25static ::testing::AssertionResult getManifestClassText(IAaptContext* context, xml::XmlResource* res,
26                                                       std::string* outStr) {
27    std::unique_ptr<ClassDefinition> manifestClass = generateManifestClass(
28            context->getDiagnostics(), res);
29    if (!manifestClass) {
30        return ::testing::AssertionFailure() << "manifestClass == nullptr";
31    }
32
33    std::stringstream out;
34    if (!manifestClass->writeJavaFile(manifestClass.get(), "android", true, &out)) {
35        return ::testing::AssertionFailure() << "failed to write java file";
36    }
37
38    *outStr = out.str();
39    return ::testing::AssertionSuccess();
40}
41
42TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) {
43    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
44    std::unique_ptr<xml::XmlResource> manifest = test::buildXmlDom(R"EOF(
45        <manifest xmlns:android="http://schemas.android.com/apk/res/android">
46          <permission android:name="android.permission.ACCESS_INTERNET" />
47          <permission android:name="android.DO_DANGEROUS_THINGS" />
48          <permission android:name="com.test.sample.permission.HUH" />
49          <permission-group android:name="foo.bar.PERMISSION" />
50        </manifest>)EOF");
51
52    std::string actual;
53    ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual));
54
55    const size_t permissionClassPos = actual.find("public static final class permission {");
56    const size_t permissionGroupClassPos =
57            actual.find("public static final class permission_group {");
58    ASSERT_NE(std::string::npos, permissionClassPos);
59    ASSERT_NE(std::string::npos, permissionGroupClassPos);
60
61    //
62    // Make sure these permissions are in the permission class.
63    //
64
65    size_t pos = actual.find("public static final String ACCESS_INTERNET="
66                             "\"android.permission.ACCESS_INTERNET\";");
67    EXPECT_GT(pos, permissionClassPos);
68    EXPECT_LT(pos, permissionGroupClassPos);
69
70    pos = actual.find("public static final String DO_DANGEROUS_THINGS="
71                      "\"android.DO_DANGEROUS_THINGS\";");
72    EXPECT_GT(pos, permissionClassPos);
73    EXPECT_LT(pos, permissionGroupClassPos);
74
75    pos = actual.find("public static final String HUH=\"com.test.sample.permission.HUH\";");
76    EXPECT_GT(pos, permissionClassPos);
77    EXPECT_LT(pos, permissionGroupClassPos);
78
79    //
80    // Make sure these permissions are in the permission_group class
81    //
82
83    pos = actual.find("public static final String PERMISSION="
84                      "\"foo.bar.PERMISSION\";");
85    EXPECT_GT(pos, permissionGroupClassPos);
86    EXPECT_LT(pos, std::string::npos);
87}
88
89TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) {
90    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
91    std::unique_ptr<xml::XmlResource> manifest = test::buildXmlDom(R"EOF(
92        <manifest xmlns:android="http://schemas.android.com/apk/res/android">
93          <!-- Required to access the internet.
94               Added in API 1. -->
95          <permission android:name="android.permission.ACCESS_INTERNET" />
96          <!-- @deprecated This permission is for playing outside. -->
97          <permission android:name="android.permission.PLAY_OUTSIDE" />
98          <!-- This is a private permission for system only!
99               @hide
100               @SystemApi -->
101          <permission android:name="android.permission.SECRET" />
102        </manifest>)EOF");
103
104    std::string actual;
105    ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual));
106
107    const char* expectedAccessInternet =
108R"EOF(    /**
109     * Required to access the internet.
110     * Added in API 1.
111     */
112    public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF";
113
114    EXPECT_NE(std::string::npos, actual.find(expectedAccessInternet));
115
116    const char* expectedPlayOutside =
117R"EOF(    /**
118     * @deprecated This permission is for playing outside.
119     */
120    @Deprecated
121    public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF";
122
123    EXPECT_NE(std::string::npos, actual.find(expectedPlayOutside));
124
125    const char* expectedSecret =
126R"EOF(    /**
127     * This is a private permission for system only!
128     * @hide
129     */
130    @android.annotation.SystemApi
131    public static final String SECRET="android.permission.SECRET";)EOF";
132
133    EXPECT_NE(std::string::npos, actual.find(expectedSecret));
134}
135
136} // namespace aapt
137