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.launchertests; 17 18 import android.app.admin.DeviceAdminReceiver; 19 import android.app.admin.DevicePolicyManager; 20 import android.app.Activity; 21 import android.app.Instrumentation; 22 import android.content.BroadcastReceiver; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.IntentFilter; 27 import android.content.pm.LauncherActivityInfo; 28 import android.content.pm.LauncherApps; 29 import android.content.ServiceConnection; 30 import android.os.Bundle; 31 import android.os.Handler; 32 import android.os.IBinder; 33 import android.os.Looper; 34 import android.os.Message; 35 import android.os.Messenger; 36 import android.os.Parcel; 37 import android.os.RemoteException; 38 import android.os.ResultReceiver; 39 import android.os.UserHandle; 40 import android.os.UserManager; 41 import android.support.test.InstrumentationRegistry; 42 import android.test.AndroidTestCase; 43 import android.util.Pair; 44 45 import java.util.concurrent.Semaphore; 46 import java.util.concurrent.TimeUnit; 47 import java.util.List; 48 49 /** 50 * Tests for LauncherApps service 51 */ 52 public class LauncherAppsTests extends AndroidTestCase { 53 54 public static final String SIMPLE_APP_PACKAGE = "com.android.cts.launcherapps.simpleapp"; 55 56 public static final String USER_EXTRA = "user_extra"; 57 public static final String PACKAGE_EXTRA = "package_extra"; 58 public static final String REPLY_EXTRA = "reply_extra"; 59 60 public static final int MSG_RESULT = 0; 61 public static final int MSG_CHECK_PACKAGE_ADDED = 1; 62 public static final int MSG_CHECK_PACKAGE_REMOVED = 2; 63 public static final int MSG_CHECK_PACKAGE_CHANGED = 3; 64 public static final int MSG_CHECK_NO_PACKAGE_ADDED = 4; 65 66 public static final int RESULT_PASS = 1; 67 public static final int RESULT_FAIL = 2; 68 public static final int RESULT_TIMEOUT = 3; 69 70 private LauncherApps mLauncherApps; 71 private UserHandle mUser; 72 private Instrumentation mInstrumentation; 73 private Messenger mService; 74 private Connection mConnection; 75 private Result mResult; 76 private Messenger mResultMessenger; 77 78 @Override setUp()79 protected void setUp() throws Exception { 80 super.setUp(); 81 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 82 Bundle arguments = InstrumentationRegistry.getArguments(); 83 UserManager userManager = (UserManager) mInstrumentation.getContext().getSystemService( 84 Context.USER_SERVICE); 85 mUser = getUserHandleArgument(userManager, "testUser", arguments); 86 mLauncherApps = (LauncherApps) mInstrumentation.getContext().getSystemService( 87 Context.LAUNCHER_APPS_SERVICE); 88 89 final Intent intent = new Intent(); 90 intent.setComponent(new ComponentName("com.android.cts.launchertests.support", 91 "com.android.cts.launchertests.support.LauncherCallbackTestsService")); 92 93 mConnection = new Connection(); 94 mInstrumentation.getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 95 mConnection.waitForService(); 96 mResult = new Result(Looper.getMainLooper()); 97 mResultMessenger = new Messenger(mResult); 98 } 99 testGetActivitiesForUserFails()100 public void testGetActivitiesForUserFails() throws Exception { 101 try { 102 List<LauncherActivityInfo> activities = 103 mLauncherApps.getActivityList(null, mUser); 104 fail("getActivities for non-profile user failed to throw exception"); 105 } catch (SecurityException e) { 106 // Expected. 107 } 108 } 109 testSimpleAppInstalledForUser()110 public void testSimpleAppInstalledForUser() throws Exception { 111 List<LauncherActivityInfo> activities = 112 mLauncherApps.getActivityList(null, mUser); 113 // Check simple app is there. 114 boolean foundSimpleApp = false; 115 for (LauncherActivityInfo activity : activities) { 116 if (activity.getComponentName().getPackageName().equals( 117 SIMPLE_APP_PACKAGE)) { 118 foundSimpleApp = true; 119 } 120 assertTrue(activity.getUser().equals(mUser)); 121 } 122 assertTrue(foundSimpleApp); 123 } 124 testPackageAddedCallbackForUser()125 public void testPackageAddedCallbackForUser() throws Throwable { 126 int result = sendMessageToCallbacksService(MSG_CHECK_PACKAGE_ADDED, 127 mUser, SIMPLE_APP_PACKAGE); 128 assertEquals(RESULT_PASS, result); 129 } 130 testPackageRemovedCallbackForUser()131 public void testPackageRemovedCallbackForUser() throws Throwable { 132 int result = sendMessageToCallbacksService(MSG_CHECK_PACKAGE_REMOVED, 133 mUser, SIMPLE_APP_PACKAGE); 134 assertEquals(RESULT_PASS, result); 135 } testPackageChangedCallbackForUser()136 public void testPackageChangedCallbackForUser() throws Throwable { 137 int result = sendMessageToCallbacksService(MSG_CHECK_PACKAGE_CHANGED, 138 mUser, SIMPLE_APP_PACKAGE); 139 assertEquals(RESULT_PASS, result); 140 } 141 testNoPackageAddedCallbackForUser()142 public void testNoPackageAddedCallbackForUser() throws Throwable { 143 int result = sendMessageToCallbacksService(MSG_CHECK_NO_PACKAGE_ADDED, 144 mUser, SIMPLE_APP_PACKAGE); 145 assertEquals(RESULT_PASS, result); 146 } 147 testLaunchNonExportActivityFails()148 public void testLaunchNonExportActivityFails() throws Exception { 149 try { 150 mLauncherApps.startMainActivity(new ComponentName( 151 SIMPLE_APP_PACKAGE, 152 SIMPLE_APP_PACKAGE + ".NonExportedActivity"), 153 mUser, null, null); 154 fail("starting non-exported activity failed to throw exception"); 155 } catch (SecurityException e) { 156 // Expected. 157 } 158 } 159 testLaunchNonExportLauncherFails()160 public void testLaunchNonExportLauncherFails() throws Exception { 161 try { 162 mLauncherApps.startMainActivity(new ComponentName( 163 SIMPLE_APP_PACKAGE, 164 SIMPLE_APP_PACKAGE + ".NonLauncherActivity"), 165 mUser, null, null); 166 fail("starting non-launcher activity failed to throw exception"); 167 } catch (SecurityException e) { 168 // Expected. 169 } 170 } 171 testLaunchMainActivity()172 public void testLaunchMainActivity() throws Exception { 173 ActivityLaunchedReceiver receiver = new ActivityLaunchedReceiver(); 174 IntentFilter filter = new IntentFilter(); 175 filter.addAction(ActivityLaunchedReceiver.ACTIVITY_LAUNCHED_ACTION); 176 mInstrumentation.getContext().registerReceiver(receiver, filter); 177 mLauncherApps.startMainActivity(new ComponentName( 178 SIMPLE_APP_PACKAGE, 179 SIMPLE_APP_PACKAGE + ".SimpleActivity"), 180 mUser, null, null); 181 assertEquals(RESULT_PASS, receiver.waitForActivity()); 182 mInstrumentation.getContext().unregisterReceiver(receiver); 183 } 184 getUserHandleArgument(UserManager userManager, String key, Bundle arguments)185 private UserHandle getUserHandleArgument(UserManager userManager, String key, 186 Bundle arguments) throws Exception { 187 String serial = arguments.getString(key); 188 if (serial == null) { 189 return null; 190 } 191 int serialNo = Integer.parseInt(serial); 192 return userManager.getUserForSerialNumber(serialNo); 193 } 194 195 private class Connection implements ServiceConnection { 196 private final Semaphore mSemaphore = new Semaphore(0); 197 198 @Override onServiceConnected(ComponentName className, IBinder service)199 public void onServiceConnected(ComponentName className, IBinder service) { 200 mService = new Messenger(service); 201 mSemaphore.release(); 202 } 203 204 @Override onServiceDisconnected(ComponentName className)205 public void onServiceDisconnected(ComponentName className) { 206 mService = null; 207 } 208 waitForService()209 public void waitForService() { 210 try { 211 if (mSemaphore.tryAcquire(5, TimeUnit.SECONDS)) { 212 return; 213 } 214 } catch (InterruptedException e) { 215 } 216 fail("failed to connec to service"); 217 } 218 }; 219 220 private static class Result extends Handler { 221 222 private final Semaphore mSemaphore = new Semaphore(0); 223 public int result = 0; 224 Result(Looper looper)225 public Result(Looper looper) { 226 super(looper); 227 } 228 229 @Override handleMessage(Message msg)230 public void handleMessage(Message msg) { 231 if (msg.what == MSG_RESULT) { 232 result = msg.arg1; 233 mSemaphore.release(); 234 } else { 235 super.handleMessage(msg); 236 } 237 } 238 waitForResult()239 public int waitForResult() { 240 try { 241 if (mSemaphore.tryAcquire(120, TimeUnit.SECONDS)) { 242 return result; 243 } 244 } catch (InterruptedException e) { 245 } 246 return RESULT_TIMEOUT; 247 } 248 } 249 250 public class ActivityLaunchedReceiver extends BroadcastReceiver { 251 public static final String ACTIVITY_LAUNCHED_ACTION = 252 "com.android.cts.launchertests.LauncherAppsTests.LAUNCHED_ACTION"; 253 254 private final Semaphore mSemaphore = new Semaphore(0); 255 256 @Override onReceive(Context context, Intent intent)257 public void onReceive(Context context, Intent intent) { 258 if (intent.getAction().equals(ACTIVITY_LAUNCHED_ACTION)) { 259 mSemaphore.release(); 260 } 261 } 262 waitForActivity()263 public int waitForActivity() { 264 try { 265 if (mSemaphore.tryAcquire(5, TimeUnit.SECONDS)) { 266 return RESULT_PASS; 267 } 268 } catch (InterruptedException e) { 269 } 270 return RESULT_TIMEOUT; 271 } 272 } 273 sendMessageToCallbacksService(int msg, UserHandle user, String packageName)274 private int sendMessageToCallbacksService(int msg, UserHandle user, String packageName) 275 throws Throwable { 276 Bundle params = new Bundle(); 277 params.putParcelable(USER_EXTRA, user); 278 params.putString(PACKAGE_EXTRA, packageName); 279 280 Message message = Message.obtain(null, msg, params); 281 message.replyTo = mResultMessenger; 282 283 mService.send(message); 284 285 return mResult.waitForResult(); 286 } 287 } 288