1 /* 2 * Copyright (C) 2014 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.deviceandprofileowner; 17 18 import android.content.BroadcastReceiver; 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.IntentFilter; 22 import android.os.Bundle; 23 import android.os.Parcelable; 24 25 import java.util.concurrent.Semaphore; 26 import java.util.concurrent.TimeUnit; 27 28 /** 29 * Functionality tests for setApplicationRestrictions and getApplicationRestrictions 30 * in DevicePolicyManager. 31 * 32 * First of all, these two APIs are executed locally to assert that what you set 33 * can later be retrieved via the getter. It also fires up an external activity 34 * (which runs in com.google.android.xts.gmscore, unlike the test code itself 35 * which runs in the test target package com.google.android.gms due to 36 * instrumentation) to observe an application's view of its restrictions. 37 * The activity listens to ACTION_APPLICATION_RESTRICTIONS_CHANGED broadcast 38 * which is fired by the system whenever its restriction is modified, 39 * and relays the value back to this test for verification. 40 */ 41 public class ApplicationRestrictionsTest extends BaseDeviceAdminTest { 42 43 private static final String[] testStrings = new String[] { 44 "<bad/>", 45 ">worse!\"£$%^&*()'<", 46 "<JSON>\"{ \\\"One\\\": { \\\"OneOne\\\": \\\"11\\\", \\\"" 47 + "OneTwo\\\": \\\"12\\\" }, \\\"Two\\\": \\\"2\\\" } <JSON/>\"" 48 }; 49 50 private final Semaphore mOnRegisteredSemaphore = new Semaphore(0); 51 private final Semaphore mOnRestrictionSemaphore = new Semaphore(0); 52 private Bundle mReceivedRestrictions; 53 54 @Override setUp()55 protected void setUp() throws Exception { 56 super.setUp(); 57 IntentFilter filter = new IntentFilter(); 58 filter.addAction(ApplicationRestrictionsActivity.REGISTERED_ACTION); 59 filter.addAction(ApplicationRestrictionsActivity.RESTRICTION_ACTION); 60 mContext.registerReceiver(mReceiver, filter); 61 } 62 63 @Override tearDown()64 protected void tearDown() throws Exception { 65 mContext.unregisterReceiver(mReceiver); 66 super.tearDown(); 67 } 68 testSetApplicationRestrictions()69 public void testSetApplicationRestrictions() { 70 final String CTS_PACKAGE = PACKAGE_NAME; 71 final String OTHER_PACKAGE = CTS_PACKAGE + "dummy"; 72 73 startAndWait(); 74 75 Bundle bundle0 = createBundle0(); 76 Bundle bundle1 = createBundle1(); 77 78 // Test setting restrictions 79 mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE, 80 bundle0); 81 mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE, 82 bundle1); 83 84 // Retrieve restrictions locally and make sure they are what we put in. 85 assertBundle0(mDevicePolicyManager.getApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, 86 CTS_PACKAGE)); 87 assertBundle1(mDevicePolicyManager.getApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, 88 OTHER_PACKAGE)); 89 90 // The test activity should have received a change_restriction broadcast 91 // and relay the value back to us. 92 assertBundle0(waitForChangedRestriction()); 93 94 // Test overwriting 95 mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE, 96 bundle1); 97 assertBundle1(mDevicePolicyManager.getApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, 98 CTS_PACKAGE)); 99 assertBundle1(waitForChangedRestriction()); 100 101 // Cleanup 102 mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE, 103 new Bundle()); 104 assertTrue(mDevicePolicyManager.getApplicationRestrictions( 105 ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE).isEmpty()); 106 assertTrue(waitForChangedRestriction().isEmpty()); 107 mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE, 108 new Bundle()); 109 assertTrue(mDevicePolicyManager.getApplicationRestrictions( 110 ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE).isEmpty()); 111 112 finish(); 113 } 114 115 // Should be consistent with assertBundle0 createBundle0()116 private Bundle createBundle0() { 117 Bundle result = new Bundle(); 118 // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[] 119 // Also test for string escaping handling 120 result.putBoolean("boolean_0", false); 121 result.putBoolean("boolean_1", true); 122 result.putInt("integer", 0x7fffffff); 123 // If a null is stored, "" will be read back 124 result.putString("empty", ""); 125 result.putString("string", "text"); 126 result.putStringArray("string[]", testStrings); 127 128 // Adding a bundle, which contain 2 nested restrictions - bundle_string and bundle_int 129 Bundle bundle = new Bundle(); 130 bundle.putString("bundle_string", "bundle_string"); 131 bundle.putInt("bundle_int", 1); 132 result.putBundle("bundle", bundle); 133 134 // Adding an array of 2 bundles 135 Bundle[] bundleArray = new Bundle[2]; 136 bundleArray[0] = new Bundle(); 137 bundleArray[0].putString("bundle_array_string", "bundle_array_string"); 138 // Put bundle inside bundle 139 bundleArray[0].putBundle("bundle_array_bundle", bundle); 140 bundleArray[1] = new Bundle(); 141 bundleArray[1].putString("bundle_array_string2", "bundle_array_string2"); 142 result.putParcelableArray("bundle_array", bundleArray); 143 return result; 144 } 145 146 // Should be consistent with createBundle0 assertBundle0(Bundle bundle)147 private void assertBundle0(Bundle bundle) { 148 assertEquals(8, bundle.size()); 149 assertEquals(false, bundle.getBoolean("boolean_0")); 150 assertEquals(true, bundle.getBoolean("boolean_1")); 151 assertEquals(0x7fffffff, bundle.getInt("integer")); 152 assertEquals("", bundle.getString("empty")); 153 assertEquals("text", bundle.getString("string")); 154 155 String[] strings = bundle.getStringArray("string[]"); 156 assertTrue(strings != null && strings.length == testStrings.length); 157 for (int i = 0; i < strings.length; i++) { 158 assertEquals(strings[i], testStrings[i]); 159 } 160 161 Bundle childBundle = bundle.getBundle("bundle"); 162 assertEquals("bundle_string", childBundle.getString("bundle_string")); 163 assertEquals(1, childBundle.getInt("bundle_int")); 164 165 Parcelable[] bundleArray = bundle.getParcelableArray("bundle_array"); 166 assertEquals(2, bundleArray.length); 167 // Verifying bundle_array[0] 168 Bundle bundle1 = (Bundle) bundleArray[0]; 169 assertEquals("bundle_array_string", bundle1.getString("bundle_array_string")); 170 Bundle bundle1ChildBundle = bundle1.getBundle("bundle_array_bundle"); 171 assertNotNull(bundle1ChildBundle); 172 assertEquals("bundle_string", bundle1ChildBundle.getString("bundle_string")); 173 assertEquals(1, bundle1ChildBundle.getInt("bundle_int")); 174 // Verifying bundle_array[1] 175 Bundle bundle2 = (Bundle) bundleArray[1]; 176 assertEquals("bundle_array_string2", bundle2.getString("bundle_array_string2")); 177 } 178 179 // Should be consistent with assertBundle1 createBundle1()180 private Bundle createBundle1() { 181 Bundle result = new Bundle(); 182 result.putInt("dummy", 1); 183 return result; 184 } 185 186 // Should be consistent with createBundle1 assertBundle1(Bundle bundle)187 private void assertBundle1(Bundle bundle) { 188 assertEquals(1, bundle.size()); 189 assertEquals(1, bundle.getInt("dummy")); 190 } 191 192 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 193 @Override 194 public void onReceive(Context context, Intent intent) { 195 String action = intent.getAction(); 196 if (ApplicationRestrictionsActivity.REGISTERED_ACTION.equals(action)) { 197 mOnRegisteredSemaphore.release(); 198 } else if (ApplicationRestrictionsActivity.RESTRICTION_ACTION.equals(action)) { 199 mReceivedRestrictions = intent.getBundleExtra("value"); 200 mOnRestrictionSemaphore.release(); 201 } 202 } 203 }; 204 startTestActivity(String command)205 private void startTestActivity(String command) { 206 Intent intent = new Intent(); 207 intent.setClassName(PACKAGE_NAME, ApplicationRestrictionsActivity.class.getName()); 208 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 209 210 if (command != null) { 211 intent.putExtra(command, true); 212 } 213 mContext.startActivity(intent); 214 } 215 startAndWait()216 private void startAndWait() { 217 startTestActivity(null); 218 // Wait until the activity has registered its broadcast receiver and ready for incoming 219 // restriction changes. 220 try { 221 assertTrue(mOnRegisteredSemaphore.tryAcquire(5, TimeUnit.SECONDS)); 222 } catch (InterruptedException e) { 223 fail("Start ApplicationRestrictionActivity interrupted"); 224 } 225 } 226 waitForChangedRestriction()227 private Bundle waitForChangedRestriction() { 228 try { 229 assertTrue(mOnRestrictionSemaphore.tryAcquire(5, TimeUnit.SECONDS)); 230 } catch (InterruptedException e) { 231 fail("getRestrictionsAndWait() interrupted"); 232 } 233 234 return mReceivedRestrictions; 235 } 236 finish()237 private void finish() { 238 startTestActivity(ApplicationRestrictionsActivity.FINISH); 239 } 240 241 } 242