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"
18ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski#include "test/Builders.h"
19ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski#include "test/Context.h"
20ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
21ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski#include <gtest/gtest.h>
22ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
23ca5638fd85098c3d0a699492751043545f75553aAdam Lesinskinamespace aapt {
24ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
256cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinskistatic ::testing::AssertionResult getManifestClassText(IAaptContext* context, xml::XmlResource* res,
266cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski                                                       std::string* outStr) {
276cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::unique_ptr<ClassDefinition> manifestClass = generateManifestClass(
286cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski            context->getDiagnostics(), res);
296cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    if (!manifestClass) {
306cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        return ::testing::AssertionFailure() << "manifestClass == nullptr";
316cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
326cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
336cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::stringstream out;
346cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    if (!manifestClass->writeJavaFile(manifestClass.get(), "android", true, &out)) {
356cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski        return ::testing::AssertionFailure() << "failed to write java file";
366cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    }
376cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
386cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    *outStr = out.str();
396cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    return ::testing::AssertionSuccess();
406cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski}
416cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski
42ca5638fd85098c3d0a699492751043545f75553aAdam LesinskiTEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) {
43ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
44467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam 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
526cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::string actual;
536cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual));
54ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
55b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    const size_t permissionClassPos = actual.find("public static final class permission {");
56b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    const size_t permissionGroupClassPos =
57b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski            actual.find("public static final class permission_group {");
58ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    ASSERT_NE(std::string::npos, permissionClassPos);
59ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    ASSERT_NE(std::string::npos, permissionGroupClassPos);
60ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
61ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    //
62ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    // Make sure these permissions are in the permission class.
63ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    //
64ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
65ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    size_t pos = actual.find("public static final String ACCESS_INTERNET="
66ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski                             "\"android.permission.ACCESS_INTERNET\";");
67ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    EXPECT_GT(pos, permissionClassPos);
68ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    EXPECT_LT(pos, permissionGroupClassPos);
69ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
70ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    pos = actual.find("public static final String DO_DANGEROUS_THINGS="
71ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski                      "\"android.DO_DANGEROUS_THINGS\";");
72ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    EXPECT_GT(pos, permissionClassPos);
73ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    EXPECT_LT(pos, permissionGroupClassPos);
74ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
75ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    pos = actual.find("public static final String HUH=\"com.test.sample.permission.HUH\";");
76ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    EXPECT_GT(pos, permissionClassPos);
77ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    EXPECT_LT(pos, permissionGroupClassPos);
78ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
79ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    //
80ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    // Make sure these permissions are in the permission_group class
81ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    //
82ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
83ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    pos = actual.find("public static final String PERMISSION="
84ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski                      "\"foo.bar.PERMISSION\";");
85ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    EXPECT_GT(pos, permissionGroupClassPos);
86ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    EXPECT_LT(pos, std::string::npos);
87ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski}
88ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
89ca5638fd85098c3d0a699492751043545f75553aAdam LesinskiTEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) {
90ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
91467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski    std::unique_ptr<xml::XmlResource> manifest = test::buildXmlDom(R"EOF(
92ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski        <manifest xmlns:android="http://schemas.android.com/apk/res/android">
93ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski          <!-- Required to access the internet.
94ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski               Added in API 1. -->
95ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski          <permission android:name="android.permission.ACCESS_INTERNET" />
96ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski          <!-- @deprecated This permission is for playing outside. -->
97ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski          <permission android:name="android.permission.PLAY_OUTSIDE" />
98ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski          <!-- This is a private permission for system only!
99ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski               @hide
100ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski               @SystemApi -->
101ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski          <permission android:name="android.permission.SECRET" />
102ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski        </manifest>)EOF");
103ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
1046cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    std::string actual;
1056cbfb1de493e42d937158ed57495c9656864ccbaAdam Lesinski    ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual));
106ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
107803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski    const char* expectedAccessInternet =
108ca5638fd85098c3d0a699492751043545f75553aAdam LesinskiR"EOF(    /**
109ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski     * Required to access the internet.
110ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski     * Added in API 1.
111ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski     */
112803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski    public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF";
113ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
114803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski    EXPECT_NE(std::string::npos, actual.find(expectedAccessInternet));
115803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski
116803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski    const char* expectedPlayOutside =
117ca5638fd85098c3d0a699492751043545f75553aAdam LesinskiR"EOF(    /**
118ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski     * @deprecated This permission is for playing outside.
119ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski     */
120ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski    @Deprecated
121803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski    public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF";
122803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski
123803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski    EXPECT_NE(std::string::npos, actual.find(expectedPlayOutside));
124ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
125803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski    const char* expectedSecret =
126ca5638fd85098c3d0a699492751043545f75553aAdam LesinskiR"EOF(    /**
127ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski     * This is a private permission for system only!
128ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski     * @hide
129ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski     */
130b274e35abfbbd09e0fce983a215c11522c56cce2Adam Lesinski    @android.annotation.SystemApi
131803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski    public static final String SECRET="android.permission.SECRET";)EOF";
132803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski
133803c7c807969bea1f1c50f348832f5b60ad05d8eAdam Lesinski    EXPECT_NE(std::string::npos, actual.find(expectedSecret));
134ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski}
135ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski
136ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski} // namespace aapt
137