1 /*
2  * Copyright (C) 2019 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 package com.android.cts.overlay.app;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertTrue;
20 
21 import android.content.Context;
22 import android.content.res.AssetFileDescriptor;
23 
24 import androidx.test.InstrumentationRegistry;
25 import androidx.test.runner.AndroidJUnit4;
26 
27 import java.io.InputStreamReader;
28 import java.util.concurrent.Executor;
29 import java.util.concurrent.FutureTask;
30 import java.util.concurrent.TimeUnit;
31 
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 
36 @RunWith(AndroidJUnit4.class)
37 public class OverlayableTest {
38     private static final String TARGET_PACKAGE = "com.android.cts.overlay.target";
39 
40     private static final String POLICY_ALL_PACKAGE = "com.android.cts.overlay.all";
41 
42     private static final String OVERLAID = "You have been overlaid";
43     private static final String NOT_OVERLAID = "Not overlaid";
44 
45     private static final long TIMEOUT = 30;
46 
47     private static class R {
48         class string {
49             private static final int not_overlayable = 0x7f010000;
50             private static final int policy_product = 0x7f010001;
51             private static final int policy_public = 0x7f010002;
52             private static final int policy_system = 0x7f010003;
53             private static final int policy_vendor = 0x7f010004;
54             private static final int policy_signature = 0x7f010005;
55             private static final int other_policy_public = 0x7f010006;
56         }
57     }
58 
59     private Executor mExecutor;
60 
61     @Before
setUp()62     public void setUp() throws Exception {
63         mExecutor = (command) -> new Thread(command).start();
64     }
65 
getTargetContext()66     private Context getTargetContext() throws Exception {
67         return InstrumentationRegistry.getTargetContext().createPackageContext(TARGET_PACKAGE, 0);
68     }
69 
assertOverlayEnabled(String overlayPackage)70     private void assertOverlayEnabled(String overlayPackage) throws Exception {
71         // Wait for the overlay changes to propagate
72         FutureTask<Boolean> task = new FutureTask<>(() -> {
73             while (true) {
74                 Context context = getTargetContext();
75                 for (String path : context.getAssets().getApkPaths()) {
76                     if (path.contains(overlayPackage)) {
77                         return true;
78                     }
79                 }
80             }
81         });
82 
83         mExecutor.execute(task);
84         assertTrue("Failed to load overlay " + overlayPackage, task.get(TIMEOUT, TimeUnit.SECONDS));
85     }
86 
87     @Test
testOverlayPolicyAll()88     public void testOverlayPolicyAll() throws Exception {
89         assertOverlayEnabled(POLICY_ALL_PACKAGE);
90         Context context = getTargetContext();
91 
92         String result = context.getResources().getString(R.string.not_overlayable);
93         assertEquals(NOT_OVERLAID, result);
94 
95         result = context.getResources().getString(R.string.policy_public);
96         assertEquals(OVERLAID, result);
97 
98         result = context.getResources().getString(R.string.policy_product);
99         assertEquals(NOT_OVERLAID, result);
100 
101         result = context.getResources().getString(R.string.policy_system);
102         assertEquals(NOT_OVERLAID, result);
103 
104         result = context.getResources().getString(R.string.policy_vendor);
105         assertEquals(NOT_OVERLAID, result);
106 
107         result = context.getResources().getString(R.string.policy_signature);
108         assertEquals(OVERLAID, result);
109 
110         result = context.getResources().getString(R.string.other_policy_public);
111         assertEquals(NOT_OVERLAID, result);
112     }
113 
114     @Test
testSameSignatureNoOverlayableSucceeds()115     public void testSameSignatureNoOverlayableSucceeds() throws Exception {
116         assertOverlayEnabled(POLICY_ALL_PACKAGE);
117         Context context = getTargetContext();
118 
119         String result = context.getResources().getString(R.string.not_overlayable);
120         assertEquals(OVERLAID, result);
121 
122         result = context.getResources().getString(R.string.policy_public);
123         assertEquals(OVERLAID, result);
124 
125         result = context.getResources().getString(R.string.policy_product);
126         assertEquals(OVERLAID, result);
127 
128         result = context.getResources().getString(R.string.policy_system);
129         assertEquals(OVERLAID, result);
130 
131         result = context.getResources().getString(R.string.policy_vendor);
132         assertEquals(OVERLAID, result);
133 
134         result = context.getResources().getString(R.string.policy_signature);
135         assertEquals(OVERLAID, result);
136 
137         result = context.getResources().getString(R.string.other_policy_public);
138         assertEquals(OVERLAID, result);
139     }
140 
141     @Test
testFrameworkDoesNotDefineOverlayable()142     public void testFrameworkDoesNotDefineOverlayable() throws Exception {
143         assertTrue(InstrumentationRegistry.getTargetContext().getAssets().getOverlayableMap(
144                 "android").isEmpty());
145     }
146 
147     @Test
testCannotOverlayAssets()148     public void testCannotOverlayAssets() throws Exception {
149         Context context = getTargetContext();
150         AssetFileDescriptor d = context.getAssets().openNonAssetFd("assets/asset.txt");
151         InputStreamReader inputStreamReader = new InputStreamReader(d.createInputStream());
152 
153         StringBuilder output = new StringBuilder();
154         for (int c = inputStreamReader.read(); c >= 0; c = inputStreamReader.read()) {
155             output.append((char) c);
156         }
157 
158         assertEquals(NOT_OVERLAID, output.toString());
159     }
160 }