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 package com.android.cts.deviceandprofileowner;
17 
18 import static com.google.common.truth.Truth.assertWithMessage;
19 
20 import android.app.admin.DevicePolicyManager;
21 import android.content.BroadcastReceiver;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.net.Uri;
26 import android.util.Log;
27 
28 import com.android.bedstead.dpmwrapper.Utils;
29 
30 import java.util.Set;
31 import java.util.concurrent.Semaphore;
32 import java.util.concurrent.TimeUnit;
33 
34 /**
35  * Tests for {@link DevicePolicyManager#setApplicationHidden} and
36  * {@link DevicePolicyManager#isApplicationHidden} APIs.
37  */
38 public class ApplicationHiddenTest extends BaseDeviceAdminTest {
39 
40     private static final String PACKAGE_TO_HIDE = "com.android.cts.permissionapp";
41     private static final String NONEXISTING_PACKAGE_NAME = "a.b.c.d";
42 
43     private static final IntentFilter PACKAGE_INTENT_FILTER;
44     static {
45         PACKAGE_INTENT_FILTER = new IntentFilter();
46         PACKAGE_INTENT_FILTER.addAction(Intent.ACTION_PACKAGE_ADDED);
47         PACKAGE_INTENT_FILTER.addAction(Intent.ACTION_PACKAGE_REMOVED);
48         PACKAGE_INTENT_FILTER.addDataScheme("package");
49     }
50     private final ApplicationHiddenReceiver mReceiver = new ApplicationHiddenReceiver();
51 
52     @Override
setUp()53     protected void setUp() throws Exception {
54         super.setUp();
55 
56         mContext.registerReceiver(mReceiver, PACKAGE_INTENT_FILTER);
57     }
58 
59     @Override
tearDown()60     protected void tearDown() throws Exception {
61         mContext.unregisterReceiver(mReceiver);
62         mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT, PACKAGE_TO_HIDE, false);
63         super.tearDown();
64     }
65 
testSetApplicationHidden()66     public void testSetApplicationHidden() throws Exception {
67         assertWithMessage("setApplicationHidden(%s, %s, true)", ADMIN_RECEIVER_COMPONENT,
68                 PACKAGE_TO_HIDE)
69                         .that(mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT,
70                                 PACKAGE_TO_HIDE, true))
71                         .isTrue();
72         assertWithMessage("isApplicationHidden(%s, %s)", ADMIN_RECEIVER_COMPONENT, PACKAGE_TO_HIDE)
73                 .that(mDevicePolicyManager
74                         .isApplicationHidden(ADMIN_RECEIVER_COMPONENT, PACKAGE_TO_HIDE))
75                 .isTrue();
76         mReceiver.waitForRemovedBroadcast();
77         assertWithMessage("setApplicationHidden(%s, %s, false)", ADMIN_RECEIVER_COMPONENT,
78                 PACKAGE_TO_HIDE)
79                         .that(mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT,
80                                 PACKAGE_TO_HIDE, false))
81                         .isTrue();
82         assertWithMessage("isApplicationHidden(%s, %s)", ADMIN_RECEIVER_COMPONENT, PACKAGE_TO_HIDE)
83                 .that(mDevicePolicyManager
84                         .isApplicationHidden(ADMIN_RECEIVER_COMPONENT, PACKAGE_TO_HIDE))
85                 .isFalse();
86         mReceiver.waitForAddedBroadcast();
87     }
88 
testCannotHideActiveAdmin()89     public void testCannotHideActiveAdmin() throws Exception {
90         assertWithMessage("setApplicationHidden(%s, %s, true)", ADMIN_RECEIVER_COMPONENT,
91                 PACKAGE_NAME)
92                         .that(mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT,
93                                 PACKAGE_NAME, true))
94                         .isFalse();
95     }
96 
testCannotHideNonExistingPackage()97     public void testCannotHideNonExistingPackage() throws Exception {
98         assertWithMessage("setApplicationHidden(%s, %s, true)", ADMIN_RECEIVER_COMPONENT,
99                 NONEXISTING_PACKAGE_NAME)
100                         .that(mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT,
101                                 NONEXISTING_PACKAGE_NAME, true))
102                         .isFalse();
103     }
104 
testCannotHidePolicyExemptApps()105     public void testCannotHidePolicyExemptApps() throws Exception {
106         Set<String> policyExemptApps = mDevicePolicyManager.getPolicyExemptApps();
107         Log.v(mTag, "policyExemptApps: " + policyExemptApps);
108         if (policyExemptApps.isEmpty()) return;
109 
110         policyExemptApps.forEach((app) -> {
111             try {
112                 boolean hidden = mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT,
113                         app, true);
114 
115                 assertWithMessage("setApplicationHidden(%s, true)", app).that(hidden).isFalse();
116             } finally {
117                 maybeUnhideApp(app);
118             }
119         });
120     }
121 
maybeUnhideApp(String app)122     private void maybeUnhideApp(String app) {
123         if (mDevicePolicyManager.isApplicationHidden(ADMIN_RECEIVER_COMPONENT, app)) {
124             mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT, app, false);
125         }
126     }
127 
128     private final class ApplicationHiddenReceiver extends BroadcastReceiver {
129         private static final int TIMEOUT_SECONDS = 60;
130         private final Semaphore mAddedSemaphore = new Semaphore(0);
131         private final Semaphore mRemovedSemaphore = new Semaphore(0);
132 
133         @Override
onReceive(Context context, Intent intent)134         public void onReceive(Context context, Intent intent) {
135             Log.v(mTag, "Received intent on user " + context.getUserId() + ": "
136                     + Utils.toString(intent));
137             Uri uri = intent.getData();
138             if (uri == null) {
139                 return;
140             }
141             String pkgName = uri.getSchemeSpecificPart();
142             if (!PACKAGE_TO_HIDE.equals(pkgName)) {
143                 return;
144             }
145             String action = intent.getAction();
146             switch(action) {
147                 case Intent.ACTION_PACKAGE_ADDED:
148                     Log.d(mTag, "Received PACKAGE_ADDED broadcast");
149                     mAddedSemaphore.release();
150                     break;
151                 case Intent.ACTION_PACKAGE_REMOVED:
152                     Log.d(mTag, "Received ACTION_PACKAGE_REMOVED broadcast");
153                     mRemovedSemaphore.release();
154                     break;
155                 default:
156                     Log.w(mTag, "received invalid intent: " + action);
157             }
158         }
159 
waitForAddedBroadcast()160         public void waitForAddedBroadcast() throws Exception {
161             if (!mAddedSemaphore.tryAcquire(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
162                 failBroadcastNotReceived(Intent.ACTION_PACKAGE_ADDED);
163             }
164         }
165 
waitForRemovedBroadcast()166         public void waitForRemovedBroadcast() throws Exception {
167             if (!mRemovedSemaphore.tryAcquire(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
168                 failBroadcastNotReceived(Intent.ACTION_PACKAGE_REMOVED);
169             }
170         }
171 
failBroadcastNotReceived(String broadcast)172         private void failBroadcastNotReceived(String broadcast) {
173             fail("Did not receive " + broadcast + " broadcast on user " + mContext.getUserId()
174                     + " in " + TIMEOUT_SECONDS + "s.");
175         }
176     }
177 }
178