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