resolved conflicts for merge of 3abcb7b7 to master
Change-Id: Ib2bec554f39e76287ea061c10852ce9028d61d17
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 89b665d..e80f4be 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -72,9 +72,12 @@
CtsHostsideNetworkTestsApp \
CtsIntentReceiverApp \
CtsIntentSenderApp \
+ CtsLauncherAppsTests \
+ CtsLauncherAppsTestsSupport \
CtsManagedProfileApp \
CtsMonkeyApp \
CtsMonkeyApp2 \
+ CtsSimpleApp \
CtsSomeAccessibilityServices \
CtsThemeDeviceApp \
TestDeviceSetup \
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
new file mode 100644
index 0000000..4517ea2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsLauncherAppsTests
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml b/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml
new file mode 100644
index 0000000..a21b8c2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.launchertests">
+
+ <uses-sdk android:minSdkVersion="21"/>
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.cts.launchertests"
+ android:label="Launcher Apps CTS Tests"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
new file mode 100644
index 0000000..3d44ecd
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.launchertests;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.test.InstrumentationTestCase;
+import android.test.InstrumentationTestRunner;
+import android.util.Pair;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.List;
+
+/**
+ * Tests for LauncherApps service
+ */
+public class LauncherAppsTests extends InstrumentationTestCase {
+
+ public static final String SIMPLE_APP_PACKAGE = "com.android.cts.launcherapps.simpleapp";
+
+ public static final String USER_EXTRA = "user_extra";
+ public static final String PACKAGE_EXTRA = "package_extra";
+ public static final String REPLY_EXTRA = "reply_extra";
+
+ public static final int MSG_RESULT = 0;
+ public static final int MSG_CHECK_PACKAGE_ADDED = 1;
+ public static final int MSG_CHECK_PACKAGE_REMOVED = 2;
+ public static final int MSG_CHECK_PACKAGE_CHANGED = 3;
+ public static final int MSG_CHECK_NO_CALLBACK = 4;
+
+ public static final int RESULT_PASS = 1;
+ public static final int RESULT_FAIL = 2;
+ public static final int RESULT_TIMEOUT = 3;
+
+ private LauncherApps mLauncherApps;
+ private UserHandle mUser;
+ private InstrumentationTestRunner mInstrumentation;
+ private Messenger mService;
+ private Connection mConnection;
+ private Result mResult;
+ private Messenger mResultMessenger;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mInstrumentation = (InstrumentationTestRunner) getInstrumentation();
+ Bundle arguments = mInstrumentation.getArguments();
+ UserManager userManager = (UserManager) mInstrumentation.getContext().getSystemService(
+ Context.USER_SERVICE);
+ mUser = getUserHandleArgument(userManager, "testUser", arguments);
+ mLauncherApps = (LauncherApps) mInstrumentation.getContext().getSystemService(
+ Context.LAUNCHER_APPS_SERVICE);
+
+ final Intent intent = new Intent();
+ intent.setComponent(new ComponentName("com.android.cts.launchertests.support",
+ "com.android.cts.launchertests.support.LauncherCallbackTestsService"));
+
+ mConnection = new Connection();
+ mInstrumentation.getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ mConnection.waitForService();
+ mResult = new Result(Looper.getMainLooper());
+ mResultMessenger = new Messenger(mResult);
+ }
+
+ public void testGetActivitiesForUserFails() throws Exception {
+ try {
+ List<LauncherActivityInfo> activities =
+ mLauncherApps.getActivityList(null, mUser);
+ fail("getActivities for non-profile user failed to throw exception");
+ } catch (SecurityException e) {
+ // Expected.
+ }
+ }
+
+ public void testSimpleAppInstalledForUser() throws Exception {
+ List<LauncherActivityInfo> activities =
+ mLauncherApps.getActivityList(null, mUser);
+ // Check simple app is there.
+ boolean foundSimpleApp = false;
+ for (LauncherActivityInfo activity : activities) {
+ if (activity.getComponentName().getPackageName().equals(
+ SIMPLE_APP_PACKAGE)) {
+ foundSimpleApp = true;
+ }
+ assertTrue(activity.getUser().equals(mUser));
+ }
+ assertTrue(foundSimpleApp);
+ }
+
+ public void testPackageAddedCallbackForUser() throws Throwable {
+ int result = sendMessageToCallbacksService(MSG_CHECK_PACKAGE_ADDED,
+ mUser, SIMPLE_APP_PACKAGE);
+ assertEquals(RESULT_PASS, result);
+ }
+
+ public void testPackageRemovedCallbackForUser() throws Throwable {
+ int result = sendMessageToCallbacksService(MSG_CHECK_PACKAGE_REMOVED,
+ mUser, SIMPLE_APP_PACKAGE);
+ assertEquals(RESULT_PASS, result);
+ }
+ public void testPackageChangedCallbackForUser() throws Throwable {
+ int result = sendMessageToCallbacksService(MSG_CHECK_PACKAGE_CHANGED,
+ mUser, SIMPLE_APP_PACKAGE);
+ assertEquals(RESULT_PASS, result);
+ }
+
+ public void testNoCallbackForUser() throws Throwable {
+ int result = sendMessageToCallbacksService(MSG_CHECK_NO_CALLBACK,
+ mUser, SIMPLE_APP_PACKAGE);
+ assertEquals(RESULT_PASS, result);
+ }
+
+ public void testLaunchNonExportActivityFails() throws Exception {
+ try {
+ mLauncherApps.startMainActivity(new ComponentName(
+ SIMPLE_APP_PACKAGE,
+ SIMPLE_APP_PACKAGE + ".NonExportedActivity"),
+ mUser, null, null);
+ fail("starting non-exported activity failed to throw exception");
+ } catch (SecurityException e) {
+ // Expected.
+ }
+ }
+
+ public void testLaunchNonExportLauncherFails() throws Exception {
+ try {
+ mLauncherApps.startMainActivity(new ComponentName(
+ SIMPLE_APP_PACKAGE,
+ SIMPLE_APP_PACKAGE + ".NonLauncherActivity"),
+ mUser, null, null);
+ fail("starting non-launcher activity failed to throw exception");
+ } catch (SecurityException e) {
+ // Expected.
+ }
+ }
+
+ public void testLaunchMainActivity() throws Exception {
+ ActivityLaunchedReceiver receiver = new ActivityLaunchedReceiver();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ActivityLaunchedReceiver.ACTIVITY_LAUNCHED_ACTION);
+ mInstrumentation.getContext().registerReceiver(receiver, filter);
+ mLauncherApps.startMainActivity(new ComponentName(
+ SIMPLE_APP_PACKAGE,
+ SIMPLE_APP_PACKAGE + ".SimpleActivity"),
+ mUser, null, null);
+ assertEquals(RESULT_PASS, receiver.waitForActivity());
+ mInstrumentation.getContext().unregisterReceiver(receiver);
+ }
+
+ private UserHandle getUserHandleArgument(UserManager userManager, String key,
+ Bundle arguments) throws Exception {
+ String serial = arguments.getString(key);
+ if (serial == null) {
+ return null;
+ }
+ int serialNo = Integer.parseInt(serial);
+ return userManager.getUserForSerialNumber(serialNo);
+ }
+
+ private class Connection implements ServiceConnection {
+ private final Semaphore mSemaphore = new Semaphore(0);
+
+ @Override
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ mService = new Messenger(service);
+ mSemaphore.release();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName className) {
+ mService = null;
+ }
+
+ public void waitForService() {
+ try {
+ if (mSemaphore.tryAcquire(5, TimeUnit.SECONDS)) {
+ return;
+ }
+ } catch (InterruptedException e) {
+ }
+ fail("failed to connec to service");
+ }
+ };
+
+ private static class Result extends Handler {
+
+ private final Semaphore mSemaphore = new Semaphore(0);
+ public int result = 0;
+
+ public Result(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_RESULT) {
+ result = msg.arg1;
+ mSemaphore.release();
+ } else {
+ super.handleMessage(msg);
+ }
+ }
+
+ public int waitForResult() {
+ try {
+ if (mSemaphore.tryAcquire(5, TimeUnit.SECONDS)) {
+ return result;
+ }
+ } catch (InterruptedException e) {
+ }
+ return RESULT_TIMEOUT;
+ }
+ }
+
+ public class ActivityLaunchedReceiver extends BroadcastReceiver {
+ public static final String ACTIVITY_LAUNCHED_ACTION =
+ "com.android.cts.launchertests.LauncherAppsTests.LAUNCHED_ACTION";
+
+ private final Semaphore mSemaphore = new Semaphore(0);
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(ACTIVITY_LAUNCHED_ACTION)) {
+ mSemaphore.release();
+ }
+ }
+
+ public int waitForActivity() {
+ try {
+ if (mSemaphore.tryAcquire(5, TimeUnit.SECONDS)) {
+ return RESULT_PASS;
+ }
+ } catch (InterruptedException e) {
+ }
+ return RESULT_TIMEOUT;
+ }
+ }
+
+ private int sendMessageToCallbacksService(int msg, UserHandle user, String packageName)
+ throws Throwable {
+ Bundle params = new Bundle();
+ params.putParcelable(USER_EXTRA, user);
+ params.putString(PACKAGE_EXTRA, packageName);
+
+ Message message = Message.obtain(null, msg, params);
+ message.replyTo = mResultMessenger;
+
+ mService.send(message);
+
+ return mResult.waitForResult();
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/TestActivity.java b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/TestActivity.java
new file mode 100644
index 0000000..5d62c8f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/TestActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.launchertests;
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity to install and launch for various users to
+ * test LauncherApps.
+ */
+public class TestActivity extends Activity {
+ public static final String USER_EXTRA = "user_extra";
+ public static final int MSG_RESULT = 0;
+ public static final int RESULT_PASS = 1;
+
+ private static final String TAG = "SimpleActivity";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.mk b/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.mk
new file mode 100644
index 0000000..2465ef3
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsLauncherAppsTestsSupport
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/LauncherTestsSupport/AndroidManifest.xml b/hostsidetests/devicepolicy/app/LauncherTestsSupport/AndroidManifest.xml
new file mode 100644
index 0000000..fbd049f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/LauncherTestsSupport/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.launchertests.support">
+
+ <uses-sdk android:minSdkVersion="21"/>
+
+ <application>
+ <service android:name=".LauncherCallbackTestsService" >
+ <intent-filter>
+ <action android:name="com.android.cts.launchertests.support.REGISTER_CALLBACK" />
+ </intent-filter>
+ </service>
+ </application>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/LauncherTestsSupport/src/com/android/cts/launchertests/support/LauncherCallbackTestsService.java b/hostsidetests/devicepolicy/app/LauncherTestsSupport/src/com/android/cts/launchertests/support/LauncherCallbackTestsService.java
new file mode 100644
index 0000000..8d61496
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/LauncherTestsSupport/src/com/android/cts/launchertests/support/LauncherCallbackTestsService.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2014 The Android Open Sour *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.launchertests.support;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Service that registers for LauncherApps callbacks.
+ *
+ * Registering in a service and different process so that
+ * device side code can launch it before running client
+ * side test code.
+ */
+public class LauncherCallbackTestsService extends Service {
+
+ public static final String USER_EXTRA = "user_extra";
+ public static final String PACKAGE_EXTRA = "package_extra";
+
+ public static final int MSG_RESULT = 0;
+ public static final int MSG_CHECK_PACKAGE_ADDED = 1;
+ public static final int MSG_CHECK_PACKAGE_REMOVED = 2;
+ public static final int MSG_CHECK_PACKAGE_CHANGED = 3;
+ public static final int MSG_CHECK_NO_CALLBACK = 4;
+
+ public static final int RESULT_PASS = 1;
+ public static final int RESULT_FAIL = 2;
+
+ private static final String TAG = "LauncherCallbackTests";
+
+ private static List<Pair<String, UserHandle>> mPackagesAdded
+ = new ArrayList<Pair<String, UserHandle>>();
+ private static List<Pair<String, UserHandle>> mPackagesRemoved
+ = new ArrayList<Pair<String, UserHandle>>();
+ private static List<Pair<String, UserHandle>> mPackagesChanged
+ = new ArrayList<Pair<String, UserHandle>>();
+ private static Object mPackagesLock = new Object();
+
+ private TestCallback mCallback;
+ private final Messenger mMessenger = new Messenger(new CheckHandler());
+
+ class CheckHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ Bundle params = null;
+ if (msg.obj instanceof Bundle) {
+ params = (Bundle) (msg.obj);
+ }
+ try {
+ switch (msg.what) {
+ case MSG_CHECK_PACKAGE_ADDED: {
+ boolean exists = eventExists(params, mPackagesAdded);
+ teardown();
+ msg.replyTo.send(Message.obtain(null, MSG_RESULT,
+ exists ? RESULT_PASS : RESULT_FAIL, 0));
+ break;
+ }
+ case MSG_CHECK_PACKAGE_REMOVED: {
+ boolean exists = eventExists(params, mPackagesRemoved);
+ teardown();
+ msg.replyTo.send(Message.obtain(null, MSG_RESULT,
+ exists ? RESULT_PASS : RESULT_FAIL, 0));
+ break;
+ }
+ case MSG_CHECK_PACKAGE_CHANGED: {
+ boolean exists = eventExists(params, mPackagesChanged);
+ teardown();
+ msg.replyTo.send(Message.obtain(null, MSG_RESULT,
+ exists ? RESULT_PASS : RESULT_FAIL, 0));
+ break;
+ }
+ case MSG_CHECK_NO_CALLBACK: {
+ boolean exists = eventExists(params, mPackagesAdded)
+ || eventExists(params, mPackagesRemoved)
+ || eventExists(params, mPackagesChanged);
+ teardown();
+ msg.replyTo.send(Message.obtain(null, MSG_RESULT,
+ exists ? RESULT_FAIL : RESULT_PASS, 0));
+ break;
+ }
+ default:
+ super.handleMessage(msg);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to report test status");
+ }
+ }
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (intent == null) {
+ return START_NOT_STICKY;
+ }
+ if ("com.android.cts.launchertests.support.REGISTER_CALLBACK".equals(intent.getAction())) {
+ setup();
+ }
+ return START_STICKY;
+ }
+
+ private void setup() {
+ LauncherApps launcherApps = (LauncherApps) getSystemService(
+ Context.LAUNCHER_APPS_SERVICE);
+ synchronized (mPackagesLock) {
+ mPackagesAdded.clear();
+ mPackagesRemoved.clear();
+ mPackagesChanged.clear();
+ if (mCallback != null) {
+ launcherApps.unregisterCallback(mCallback);
+ }
+ mCallback = new TestCallback();
+ launcherApps.registerCallback(mCallback);
+ }
+ }
+
+ private void teardown() {
+ LauncherApps launcherApps = (LauncherApps) getSystemService(
+ Context.LAUNCHER_APPS_SERVICE);
+ synchronized (mPackagesLock) {
+ if (mCallback != null) {
+ launcherApps.unregisterCallback(mCallback);
+ mCallback = null;
+ }
+ mPackagesAdded.clear();
+ mPackagesRemoved.clear();
+ mPackagesChanged.clear();
+ }
+ }
+
+ private boolean eventExists(Bundle params, List<Pair<String, UserHandle>> events) {
+ UserHandle user = params.getParcelable(USER_EXTRA);
+ String packageName = params.getString(PACKAGE_EXTRA);
+ synchronized (mPackagesLock) {
+ if (events != null) {
+ for (Pair<String, UserHandle> added : events) {
+ if (added.first.equals(packageName) && added.second.equals(user)) {
+ Log.i(TAG, "Event exists " + packageName + " for user " + user);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mMessenger.getBinder();
+ }
+
+ private class TestCallback extends LauncherApps.Callback {
+ public void onPackageRemoved(String packageName, UserHandle user) {
+ synchronized (mPackagesLock) {
+ mPackagesRemoved.add(new Pair<String, UserHandle>(packageName, user));
+ }
+ }
+
+ public void onPackageAdded(String packageName, UserHandle user) {
+ synchronized (mPackagesLock) {
+ mPackagesAdded.add(new Pair<String, UserHandle>(packageName, user));
+ }
+ }
+
+ public void onPackageChanged(String packageName, UserHandle user) {
+ synchronized (mPackagesLock) {
+ mPackagesChanged.add(new Pair<String, UserHandle>(packageName, user));
+ }
+ }
+
+ public void onPackagesAvailable(String[] packageNames, UserHandle user,
+ boolean replacing) {
+ }
+
+ public void onPackagesUnavailable(String[] packageNames, UserHandle user,
+ boolean replacing) {
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/Android.mk b/hostsidetests/devicepolicy/app/SimpleApp/Android.mk
new file mode 100644
index 0000000..eae0a4f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimpleApp/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := optional
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsSimpleApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml
new file mode 100644
index 0000000..848317c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.launcherapps.simpleapp">
+
+ <application>
+ <activity android:name=".SimpleActivity" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".NonExportedActivity">
+ android:exported="false">
+ </activity>
+ <activity android:name=".NonLauncherActivity">
+ android:exported="true">
+ </activity>
+ </application>
+
+</manifest>
+
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/NonExportedActivity.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/NonExportedActivity.java
new file mode 100644
index 0000000..4801830
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/NonExportedActivity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.launcherapps.simpleapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity that isn't exported, shouldn't be launchable
+ * by LauncherApps.
+ */
+public class NonExportedActivity extends Activity {
+
+ private static final String TAG = "NonExportedActivity";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/NonLauncherActivity.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/NonLauncherActivity.java
new file mode 100644
index 0000000..4809020
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/NonLauncherActivity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.launcherapps.simpleapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity that isn't main / category launcher, shouldn't be launchable
+ * by LauncherApps.
+ */
+public class NonLauncherActivity extends Activity {
+
+ private static final String TAG = "NonLauncherActivity";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
new file mode 100644
index 0000000..1d30335
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.launcherapps.simpleapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity to install for various users to test LauncherApps.
+ */
+public class SimpleActivity extends Activity {
+ public static String ACTIVITY_LAUNCHED_ACTION =
+ "com.android.cts.launchertests.LauncherAppsTests.LAUNCHED_ACTION";
+
+ private static final String TAG = "SimpleActivity";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
+ }
+
+ public void onStart() {
+ super.onStart();
+ Intent reply = new Intent();
+ reply.setAction(ACTIVITY_LAUNCHED_ACTION);
+ sendBroadcast(reply);
+ }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index ef7a97f..bd9c8e0 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -49,6 +49,11 @@
private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
+ protected static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
+ protected static final String MANAGED_PROFILE_APK = "CtsManagedProfileApp.apk";
+ protected static final String ADMIN_RECEIVER_TEST_CLASS =
+ MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
+
private static final String[] REQUIRED_DEVICE_FEATURES = new String[] {
"android.software.managed_users",
"android.software.device_admin" };
@@ -72,6 +77,7 @@
protected void installApp(String fileName)
throws FileNotFoundException, DeviceNotAvailableException {
+ CLog.logAndDisplay(LogLevel.INFO, "Installing app " + fileName);
String installResult = getDevice().installPackage(mCtsBuild.getTestApp(fileName), true);
assertNull(String.format("Failed to install %s, Reason: %s", fileName, installResult),
installResult);
@@ -93,12 +99,15 @@
}
/** Initializes the user with the given id. This is required so that apps can run on it. */
- protected void startUser(int userId) throws DeviceNotAvailableException {
+ protected void startUser(int userId) throws Exception {
String command = "am start-user " + userId;
+ CLog.logAndDisplay(LogLevel.INFO, "Starting command " + command);
String commandOutput = getDevice().executeShellCommand(command);
CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
assertTrue(commandOutput + " expected to start with \"Success:\"",
commandOutput.startsWith("Success:"));
+ // Wait 60 seconds for intents generated to be handled.
+ Thread.sleep(60 * 1000);
}
protected int getMaxNumberOfUsersSupported() throws DeviceNotAvailableException {
@@ -137,10 +146,13 @@
return users;
}
- protected void removeUser(int userId) throws DeviceNotAvailableException {
+ protected void removeUser(int userId) throws Exception {
String removeUserCommand = "pm remove-user " + userId;
+ CLog.logAndDisplay(LogLevel.INFO, "starting command " + removeUserCommand);
CLog.logAndDisplay(LogLevel.INFO, "Output for command " + removeUserCommand + ": "
+ getDevice().executeShellCommand(removeUserCommand));
+ // Wait 60 seconds for user to finish being removed.
+ Thread.sleep(60 * 1000);
}
/** Returns true if the specified tests passed. Tests are run as user owner. */
@@ -166,12 +178,19 @@
return runDeviceTests(pkgName, testClassName, testMethodName, userId);
}
- private boolean runDeviceTests(String pkgName, @Nullable String testClassName,
+ protected boolean runDeviceTests(String pkgName, @Nullable String testClassName,
@Nullable String testMethodName, @Nullable Integer userId)
- throws DeviceNotAvailableException {
- TestRunResult runResult = (userId == null)
+ throws DeviceNotAvailableException {
+ return runDeviceTests(pkgName, testClassName, testMethodName, userId, /*params*/ null);
+ }
+
+ protected boolean runDeviceTests(String pkgName, @Nullable String testClassName,
+ @Nullable String testMethodName, @Nullable Integer userId, @Nullable String params)
+ throws DeviceNotAvailableException {
+ TestRunResult runResult = (userId == null && params == null)
? doRunTests(pkgName, testClassName, testMethodName)
- : doRunTestsAsUser(pkgName, testClassName, testMethodName, userId);
+ : doRunTestsAsUser(pkgName, testClassName, testMethodName,
+ userId != null ? userId : 0, params != null ? params : "");
printTestResult(runResult);
return !runResult.hasFailedTests() && runResult.getNumTestsInState(TestStatus.PASSED) > 0;
}
@@ -194,7 +213,7 @@
}
private TestRunResult doRunTestsAsUser(String pkgName, @Nullable String testClassName,
- @Nullable String testMethodName, int userId)
+ @Nullable String testMethodName, int userId, String params)
throws DeviceNotAvailableException {
// TODO: move this to RemoteAndroidTestRunner once it supports users. Should be straight
// forward to add a RemoteAndroidTestRunner.setUser(userId) method. Then we can merge both
@@ -206,8 +225,8 @@
testsToRun.append("#" + testMethodName);
}
}
- String command = "am instrument --user " + userId + " -w -r " + testsToRun + " "
- + pkgName + "/" + RUNNER;
+ String command = "am instrument --user " + userId + " " + params + " -w -r "
+ + testsToRun + " " + pkgName + "/" + RUNNER;
CLog.i("Running " + command);
CollectingTestListener listener = new CollectingTestListener();
@@ -255,4 +274,62 @@
}
return true;
}
+
+ protected int createUser() throws Exception {
+ String command ="pm create-user TestUser_"+ System.currentTimeMillis();
+ CLog.logAndDisplay(LogLevel.INFO, "Starting command " + command);
+ String commandOutput = getDevice().executeShellCommand(command);
+ CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+
+ // Extract the id of the new user.
+ String[] tokens = commandOutput.split("\\s+");
+ assertTrue(tokens.length > 0);
+ assertEquals("Success:", tokens[0]);
+ // Wait 60 seconds for intents generated to be handled.
+ Thread.sleep(60 * 1000);
+ return Integer.parseInt(tokens[tokens.length-1]);
+ }
+
+ protected int createManagedProfile() throws DeviceNotAvailableException {
+ String command =
+ "pm create-user --profileOf 0 --managed TestProfile_" + System.currentTimeMillis();
+ CLog.logAndDisplay(LogLevel.INFO, "Starting command " + command);
+ String commandOutput = getDevice().executeShellCommand(command);
+ CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+
+ // Extract the id of the new user.
+ String[] tokens = commandOutput.split("\\s+");
+ assertTrue(commandOutput + " expected to have format \"Success: {USER_ID}\"",
+ tokens.length > 0);
+ assertEquals(commandOutput, "Success:", tokens[0]);
+ return Integer.parseInt(tokens[tokens.length-1]);
+ }
+
+ protected int getUserSerialNumber(int userId) throws DeviceNotAvailableException{
+ // dumpsys user return lines like "UserInfo{0:Owner:13} serialNo=0"
+ String commandOutput = getDevice().executeShellCommand("dumpsys user");
+ String[] tokens = commandOutput.split("\\n");
+ for (String token : tokens) {
+ token = token.trim();
+ if (token.contains("UserInfo{" + userId + ":")) {
+ String[] split = token.split("serialNo=");
+ assertTrue(split.length == 2);
+ int serialNumber = Integer.parseInt(split[1]);
+ CLog.logAndDisplay(LogLevel.INFO, "Serial number of user " + userId + ": "
+ + serialNumber);
+ return serialNumber;
+ }
+ }
+ fail("Couldn't find user " + userId);
+ return -1;
+ }
+
+ protected void setProfileOwner(String componentName, int userId)
+ throws DeviceNotAvailableException {
+ String command = "dpm set-profile-owner --user " + userId + " '" + componentName + "'";
+ String commandOutput = getDevice().executeShellCommand(command);
+ CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+ assertTrue(commandOutput + " expected to start with \"Success:\"",
+ commandOutput.startsWith("Success:"));
+ }
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java
new file mode 100644
index 0000000..dec8bd2
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.log.LogUtil.CLog;
+
+/**
+ * Common code for the various LauncherApps tests.
+ */
+public class BaseLauncherAppsTest extends BaseDevicePolicyTest {
+
+ protected static final String SIMPLE_APP_PKG = "com.android.cts.launcherapps.simpleapp";
+ protected static final String SIMPLE_APP_APK = "CtsSimpleApp.apk";
+ protected static final String LAUNCHER_TESTS_PKG = "com.android.cts.launchertests";
+ protected static final String LAUNCHER_TESTS_CLASS = LAUNCHER_TESTS_PKG + ".LauncherAppsTests";
+ private static final String LAUNCHER_TESTS_APK = "CtsLauncherAppsTests.apk";
+ private static final String LAUNCHER_TESTS_SUPPORT_PKG =
+ "com.android.cts.launchertests.support";
+ private static final String LAUNCHER_TESTS_SUPPORT_APK = "CtsLauncherAppsTestsSupport.apk";
+
+ protected void installTestApps() throws Exception {
+ uninstallTestApps();
+ installApp(LAUNCHER_TESTS_APK);
+ installApp(LAUNCHER_TESTS_SUPPORT_APK);
+ }
+
+ protected void uninstallTestApps() throws Exception {
+ getDevice().uninstallPackage(LAUNCHER_TESTS_PKG);
+ getDevice().uninstallPackage(LAUNCHER_TESTS_SUPPORT_PKG);
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+
+ protected void removeTestUsers() throws Exception {
+ for (int userId : listUsers()) {
+ if (userId != 0) {
+ removeUser(userId);
+ }
+ }
+ }
+
+ protected void startCallbackService() throws Exception {
+ String command = "am startservice --user 0 "
+ + "-a " + LAUNCHER_TESTS_SUPPORT_PKG + ".REGISTER_CALLBACK "
+ + LAUNCHER_TESTS_SUPPORT_PKG + "/.LauncherCallbackTestsService";
+ CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+ + getDevice().executeShellCommand(command));
+
+ }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsMultiUserTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsMultiUserTest.java
new file mode 100644
index 0000000..0af38a4
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsMultiUserTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+/**
+ * Set of tests for LauncherApps attempting to access a non-profiles
+ * apps.
+ */
+public class LauncherAppsMultiUserTest extends BaseLauncherAppsTest {
+
+ private int mSecondaryUserId;
+ private int mSecondaryUserSerialNumber;
+
+ private boolean mMultiUserSupported;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ // We need multi user to be supported in order to create a secondary user
+ // and api level 21 to support LauncherApps
+ mMultiUserSupported = getMaxNumberOfUsersSupported() > 1 && getDevice().getApiLevel() >= 21;
+
+ if (mMultiUserSupported) {
+ removeTestUsers();
+ installTestApps();
+ // Create a secondary user.
+ mSecondaryUserId = createUser();
+ mSecondaryUserSerialNumber = getUserSerialNumber(mSecondaryUserId);
+ startUser(mSecondaryUserId);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mMultiUserSupported) {
+ removeUser(mSecondaryUserId);
+ uninstallTestApps();
+ }
+ super.tearDown();
+ }
+
+ public void testGetActivitiesForNonProfileFails() throws Exception {
+ if (!mMultiUserSupported) {
+ return;
+ }
+ installApp(SIMPLE_APP_APK);
+ try {
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS,
+ "testGetActivitiesForUserFails",
+ 0, "-e testUser " + mSecondaryUserSerialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testNoLauncherCallbackPackageAddedSecondaryUser() throws Exception {
+ if (!mMultiUserSupported) {
+ return;
+ }
+ startCallbackService();
+ installApp(SIMPLE_APP_APK);
+ try {
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS,
+ "testNoCallbackForUser",
+ 0, "-e testUser " + mSecondaryUserSerialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
new file mode 100644
index 0000000..f8c2e7d
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+/**
+ * Set of tests for LauncherApps with managed profiles.
+ */
+public class LauncherAppsProfileTest extends BaseLauncherAppsTest {
+
+ private int mProfileUserId;
+ private int mProfileSerialNumber;
+ private int mMainUserSerialNumber;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // We need multi user to be supported in order to create a profile of the user owner.
+ mHasFeature = mHasFeature && (getMaxNumberOfUsersSupported() > 1);
+
+ if (mHasFeature) {
+ removeTestUsers();
+ installTestApps();
+ // Create a managed profile
+ mProfileUserId = createManagedProfile();
+ installApp(MANAGED_PROFILE_APK);
+ setProfileOwner(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mProfileUserId);
+ mProfileSerialNumber = getUserSerialNumber(mProfileUserId);
+ mMainUserSerialNumber = getUserSerialNumber(0);
+ startUser(mProfileUserId);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mHasFeature) {
+ removeUser(mProfileUserId);
+ uninstallTestApps();
+ getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
+ }
+ super.tearDown();
+ }
+
+ public void testGetActivitiesWithProfile() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ // Install app for all users.
+ installApp(SIMPLE_APP_APK);
+ try {
+ // Run tests to check SimpleApp exists in both profile and main user.
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS,
+ "testSimpleAppInstalledForUser",
+ 0, "-e testUser " + mProfileSerialNumber));
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_PKG + ".LauncherAppsTests", "testSimpleAppInstalledForUser",
+ 0, "-e testUser " + mMainUserSerialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testLauncherCallbackPackageAddedProfile() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ startCallbackService();
+ installApp(SIMPLE_APP_APK);
+ try {
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS,
+ "testPackageAddedCallbackForUser",
+ 0, "-e testUser " + mProfileSerialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testLauncherCallbackPackageRemovedProfile() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ installApp(SIMPLE_APP_APK);
+ try {
+ startCallbackService();
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS,
+ "testPackageRemovedCallbackForUser",
+ 0, "-e testUser " + mProfileSerialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testLauncherCallbackPackageChangedProfile() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ installApp(SIMPLE_APP_APK);
+ try {
+ startCallbackService();
+ installApp(SIMPLE_APP_APK);
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS,
+ "testPackageChangedCallbackForUser",
+ 0, "-e testUser " + mProfileSerialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsSingleUserTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsSingleUserTest.java
new file mode 100644
index 0000000..32be962
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsSingleUserTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.devicepolicy;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+/**
+ * Set of tests for LauncherApps with managed profiles.
+ */
+public class LauncherAppsSingleUserTest extends BaseLauncherAppsTest {
+
+ private boolean mHasLauncherApps;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mHasLauncherApps = getDevice().getApiLevel() >= 21;
+
+ if (mHasLauncherApps) {
+ installTestApps();
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mHasLauncherApps) {
+ uninstallTestApps();
+ }
+ super.tearDown();
+ }
+
+ public void testInstallAppMainUser() throws Exception {
+ if (!mHasLauncherApps) {
+ return;
+ }
+ installApp(SIMPLE_APP_APK);
+ try {
+ int serialNumber = getUserSerialNumber(0);
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS, "testSimpleAppInstalledForUser",
+ 0, "-e testUser " + serialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testLauncherCallbackPackageAddedMainUser() throws Exception {
+ if (!mHasLauncherApps) {
+ return;
+ }
+ startCallbackService();
+ installApp(SIMPLE_APP_APK);
+ try {
+ int serialNumber = getUserSerialNumber(0);
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS,
+ "testPackageAddedCallbackForUser",
+ 0, "-e testUser " + serialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testLauncherCallbackPackageRemovedMainUser() throws Exception {
+ if (!mHasLauncherApps) {
+ return;
+ }
+ installApp(SIMPLE_APP_APK);
+ try {
+ startCallbackService();
+ int serialNumber = getUserSerialNumber(0);
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS,
+ "testPackageRemovedCallbackForUser",
+ 0, "-e testUser " + serialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testLauncherCallbackPackageChangedMainUser() throws Exception {
+ if (!mHasLauncherApps) {
+ return;
+ }
+ installApp(SIMPLE_APP_APK);
+ try {
+ startCallbackService();
+ int serialNumber = getUserSerialNumber(0);
+ installApp(SIMPLE_APP_APK);
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS,
+ "testPackageChangedCallbackForUser",
+ 0, "-e testUser " + serialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testLauncherNonExportedAppFails() throws Exception {
+ if (!mHasLauncherApps) {
+ return;
+ }
+ installApp(SIMPLE_APP_APK);
+ try {
+ int serialNumber = getUserSerialNumber(0);
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS, "testLaunchNonExportActivityFails",
+ 0, "-e testUser " + serialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testLaunchNonExportActivityFails() throws Exception {
+ if (!mHasLauncherApps) {
+ return;
+ }
+ installApp(SIMPLE_APP_APK);
+ try {
+ int serialNumber = getUserSerialNumber(0);
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS, "testLaunchNonExportLauncherFails",
+ 0, "-e testUser " + serialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+
+ public void testLaunchMainActivity() throws Exception {
+ if (!mHasLauncherApps) {
+ return;
+ }
+ installApp(SIMPLE_APP_APK);
+ try {
+ int serialNumber = getUserSerialNumber(0);
+ assertTrue(runDeviceTests(LAUNCHER_TESTS_PKG,
+ LAUNCHER_TESTS_CLASS, "testLaunchMainActivity",
+ 0, "-e testUser " + serialNumber));
+ } finally {
+ getDevice().uninstallPackage(SIMPLE_APP_PKG);
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index f6e5231..fe6d592 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -248,27 +248,4 @@
"Output for command " + adbCommand + ": " + commandOutput);
return commandOutput;
}
-
- private int createManagedProfile() throws DeviceNotAvailableException {
- String command =
- "pm create-user --profileOf 0 --managed TestProfile_" + System.currentTimeMillis();
- String commandOutput = getDevice().executeShellCommand(command);
- CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
-
- // Extract the id of the new user.
- String[] tokens = commandOutput.split("\\s+");
- assertTrue(commandOutput + " expected to have format \"Success: {USER_ID}\"",
- tokens.length > 0);
- assertEquals(commandOutput, "Success:", tokens[0]);
- return Integer.parseInt(tokens[tokens.length-1]);
- }
-
- private void setProfileOwner(String componentName, int userId)
- throws DeviceNotAvailableException {
- String command = "dpm set-profile-owner --user " + userId + " '" + componentName + "'";
- String commandOutput = getDevice().executeShellCommand(command);
- CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
- assertTrue(commandOutput + " expected to start with \"Success:\"",
- commandOutput.startsWith("Success:"));
- }
}
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 5cbc938..6bad84f 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -144,6 +144,24 @@
bug: 17508787
},
{
+ description: "New tests recently added for Android Enterprise. To be moved out of CTS-staging as soon as they show that they are stable",
+ names: [
+ "com.android.cts.devicepolicy.LauncherAppsMultiUserTest#testGetActivitiesForNonProfileFails",
+ "com.android.cts.devicepolicy.LauncherAppsMultiUserTest#testNoLauncherCallbackPackageAddedSecondaryUser",
+ "com.android.cts.devicepolicy.LauncherAppsProfileTest#testGetActivitiesWithProfile",
+ "com.android.cts.devicepolicy.LauncherAppsProfileTest#testLauncherCallbackPackageAddedProfile",
+ "com.android.cts.devicepolicy.LauncherAppsProfileTest#testLauncherCallbackPackageRemovedProfile",
+ "com.android.cts.devicepolicy.LauncherAppsProfileTest#testLauncherCallbackPackageChangedProfile",
+ "com.android.cts.devicepolicy.LauncherAppsSingleUserTest#testInstallAppMainUser",
+ "com.android.cts.devicepolicy.LauncherAppsSingleUserTest#testLauncherCallbackPackageAddedMainUser",
+ "com.android.cts.devicepolicy.LauncherAppsSingleUserTest#testLauncherCallbackPackageRemovedMainUser",
+ "com.android.cts.devicepolicy.LauncherAppsSingleUserTest#testLauncherCallbackPackageChangedMainUser",
+ "com.android.cts.devicepolicy.LauncherAppsSingleUserTest#testLauncherNonExportedAppFails",
+ "com.android.cts.devicepolicy.LauncherAppsSingleUserTest#testLaunchNonExportActivityFails",
+ "com.android.cts.devicepolicy.LauncherAppsSingleUserTest#testLaunchMainActivity"
+ ]
+},
+{
description: "This test failed on devices that use effect off loading. In addition it uses hidden apis",
names: [
"android.media.cts.AudioEffectTest#test1_1ConstructorFromUuid"