Merge "Fix cts test in DumpsysHostTest#testBatteryStatsOutput" into mnc-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index f743fb2..4d30dda 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -111,6 +111,7 @@
CtsVoiceInteractionService \
CtsVoiceInteractionApp \
CtsVoiceSettingsService \
+ CtsWidgetProviderApp \
$(cts_account_support_packages) \
$(cts_security_apps_list) \
$(cts_security_keysets_list)
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index e03ebdc..8e27e72 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -72,7 +72,7 @@
<action android:name="com.android.cts.managedprofile.ACTION_TEST_ALL_ACTIVITY" />
</intent-filter>
</activity>
- <activity android:name=".UserRestrictionActivity" >
+ <activity android:name=".SetPolicyActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT"/>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetPrimaryUserTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetPrimaryUserTest.java
new file mode 100644
index 0000000..bb1640b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetPrimaryUserTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.managedprofile;
+
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+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.test.AndroidTestCase;
+import android.util.Log;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This class contains tests for cross profile widget providers that are run on the primary users.
+ * The tests connect to a {@link android.appwidget.AppWidgetHost} and check whether the cross
+ * cross-profile widget can / cannot be found from the primary user.
+ * The tests cannot be run independently, but are part of one hostside test.
+ */
+public class CrossProfileWidgetPrimaryUserTest extends AndroidTestCase {
+ private static final String TAG = "CrossProfileWidgetPrimaryUserTest";
+
+ private static final int MSG_RESULT = 0;
+ private static final int MSG_PROVIDER_PRESENT = 1;
+ private static final int MSG_PROVIDER_UPDATES = 2;
+
+ private static final int RESULT_UNKNOWN = 0;
+ private static final int RESULT_PRESENT = 1;
+ private static final int RESULT_NOTPRESENT = 2;
+ private static final int RESULT_INTERRUPTED = 3;
+ private static final int RESULT_TIMEOUT = 4;
+
+ private static final String PACKAGE_EXTRA = "package-extra";
+
+ private Messenger mService;
+ private Connection mConnection;
+ private Result mResult;
+ private Messenger mResultMessenger;
+
+ @Override
+ protected void setUp() throws Exception {
+ final Intent intent = new Intent();
+ intent.setComponent(new ComponentName(CrossProfileWidgetTest.WIDGET_PROVIDER_PKG,
+ CrossProfileWidgetTest.WIDGET_PROVIDER_PKG + ".SimpleAppWidgetHostService"));
+ mConnection = new Connection();
+ getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ mConnection.waitForService();
+ mResult = new Result(Looper.getMainLooper());
+ mResultMessenger = new Messenger(mResult);
+ }
+
+ public void testHasCrossProfileWidgetProvider_false() throws Exception {
+ int result = sendMessageToCallbacksService(MSG_PROVIDER_PRESENT,
+ CrossProfileWidgetTest.WIDGET_PROVIDER_PKG);
+ assertEquals(RESULT_NOTPRESENT, result);
+ }
+
+ public void testHostReceivesWidgetUpdates_false() throws Exception {
+ int result = sendMessageToCallbacksService(MSG_PROVIDER_UPDATES,
+ CrossProfileWidgetTest.WIDGET_PROVIDER_PKG);
+ assertEquals(RESULT_NOTPRESENT, result);
+ }
+
+ public void testHasCrossProfileWidgetProvider_true() throws Exception {
+ int result = sendMessageToCallbacksService(MSG_PROVIDER_PRESENT,
+ CrossProfileWidgetTest.WIDGET_PROVIDER_PKG);
+ assertEquals(RESULT_PRESENT, result);
+ }
+
+ public void testHostReceivesWidgetUpdates_true() throws Exception {
+ int result = sendMessageToCallbacksService(MSG_PROVIDER_UPDATES,
+ CrossProfileWidgetTest.WIDGET_PROVIDER_PKG);
+ assertEquals(RESULT_PRESENT, result);
+ }
+
+ private int sendMessageToCallbacksService(int msg, String packageName)
+ throws Exception {
+ Bundle params = new Bundle();
+ params.putString(PACKAGE_EXTRA, packageName);
+
+ Message message = Message.obtain(null, msg, params);
+ message.replyTo = mResultMessenger;
+
+ mService.send(message);
+
+ return mResult.waitForResult();
+ }
+
+ 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(120, TimeUnit.SECONDS)) {
+ return result;
+ }
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Interrupted when talking to service", e);
+ }
+ return RESULT_TIMEOUT;
+ }
+ }
+
+ 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) {
+ Log.e(TAG, "Interrupted when connecting to service", e);
+ }
+ fail("failed to connect to service");
+ }
+ };
+
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetTest.java
new file mode 100644
index 0000000..085d56f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.managedprofile;
+
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This class contains tests for cross profile widget providers that are run on the managed
+ * profile. Policies are set using {@link SetPolicyActivity} and then verified in these tests.
+ * The tests cannot be run independently, but are part of one hostside test.
+ */
+public class CrossProfileWidgetTest extends BaseManagedProfileTest {
+ static final String WIDGET_PROVIDER_PKG = "com.android.cts.widgetprovider";
+
+ private AppWidgetManager mAppWidgetManager;
+
+ public void setUp() throws Exception {
+ super.setUp();
+ mAppWidgetManager = (AppWidgetManager) mContext.getSystemService(Context.APPWIDGET_SERVICE);
+ }
+
+ /**
+ * This test checks that the widget provider was successfully whitelisted and verifies that
+ * if was added successfully and can be found inside the profile.
+ */
+ public void testCrossProfileWidgetProviderAdded() {
+ List<String> providers = mDevicePolicyManager.getCrossProfileWidgetProviders(
+ ADMIN_RECEIVER_COMPONENT);
+ assertEquals(1, providers.size());
+ assertTrue(providers.contains(WIDGET_PROVIDER_PKG));
+ // check that widget can be found inside the profile
+ assertTrue(containsWidgetProviderPkg(mAppWidgetManager.getInstalledProviders()));
+ }
+
+ /**
+ * This test verifies that the widget provider was successfully removed from the whitelist.
+ */
+ public void testCrossProfileWidgetProviderRemoved() {
+ List<String> providers = mDevicePolicyManager.getCrossProfileWidgetProviders(
+ ADMIN_RECEIVER_COMPONENT);
+ assertTrue(providers.isEmpty());
+ // check that widget can still be found inside the profile
+ // This does not currently work correctly: http://b/issues/21180997
+ // assertTrue(containsWidgetProviderPkg(mAppWidgetManager.getInstalledProviders()));
+ }
+
+ private boolean containsWidgetProviderPkg(List<AppWidgetProviderInfo> widgets) {
+ for (AppWidgetProviderInfo widget : widgets) {
+ if (WIDGET_PROVIDER_PKG.equals(widget.provider.getPackageName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/UserRestrictionActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/SetPolicyActivity.java
similarity index 60%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/UserRestrictionActivity.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/SetPolicyActivity.java
index e8decf8..f59363b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/UserRestrictionActivity.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/SetPolicyActivity.java
@@ -28,15 +28,18 @@
/**
* Simple activity that adds or clears a user restriction depending on the value of the extras.
*/
-public class UserRestrictionActivity extends Activity {
+public class SetPolicyActivity extends Activity {
- private static final String TAG = UserRestrictionActivity.class.getName();
+ private static final String TAG = SetPolicyActivity.class.getName();
private static final String EXTRA_RESTRICTION_KEY = "extra-restriction-key";
+ private static final String EXTRA_PACKAGE_NAME = "extra-package-name";
private static final String EXTRA_COMMAND = "extra-command";
- private static final String ADD_COMMAND = "add-restriction";
- private static final String CLEAR_COMMAND = "clear-restriction";
+ private static final String ADD_RESTRICTION_COMMAND = "add-restriction";
+ private static final String CLEAR_RESTRICTION_COMMAND = "clear-restriction";
+ private static final String ADD_CROSS_PROFILE_WIDGET_COMMAND = "add-cross-profile-widget";
+ private static final String REMOVE_CROSS_PROFILE_WIDGET_COMMAND = "remove-cross-profile-widget";
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -62,19 +65,32 @@
private void handleIntent(Intent intent) {
DevicePolicyManager dpm = (DevicePolicyManager)
getSystemService(Context.DEVICE_POLICY_SERVICE);
- String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
String command = intent.getStringExtra(EXTRA_COMMAND);
- Log.i(TAG, "Command: \"" + command + "\". Restriction: \"" + restrictionKey + "\"");
+ Log.i(TAG, "Command: \"" + command);
- if (ADD_COMMAND.equals(command)) {
+ if (ADD_RESTRICTION_COMMAND.equals(command)) {
+ String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
dpm.addUserRestriction(BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
Log.i(TAG, "Added user restriction " + restrictionKey
+ " for user " + Process.myUserHandle());
- } else if (CLEAR_COMMAND.equals(command)) {
+ } else if (CLEAR_RESTRICTION_COMMAND.equals(command)) {
+ String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
dpm.clearUserRestriction(
BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
Log.i(TAG, "Cleared user restriction " + restrictionKey
+ " for user " + Process.myUserHandle());
+ } else if (ADD_CROSS_PROFILE_WIDGET_COMMAND.equals(command)) {
+ String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
+ dpm.addCrossProfileWidgetProvider(BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT,
+ packageName);
+ Log.i(TAG, "Added cross-profile widget provider for package:" + packageName
+ + " for user " + Process.myUserHandle());
+ } else if (REMOVE_CROSS_PROFILE_WIDGET_COMMAND.equals(command)) {
+ String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
+ dpm.removeCrossProfileWidgetProvider(BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT,
+ packageName);
+ Log.i(TAG, "Removed cross-profile widget provider for package:" + packageName
+ + " for user " + Process.myUserHandle());
} else {
Log.e(TAG, "Invalid command: " + command);
}
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/Android.mk b/hostsidetests/devicepolicy/app/WidgetProvider/Android.mk
new file mode 100644
index 0000000..c0e35fa
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/Android.mk
@@ -0,0 +1,29 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsWidgetProviderApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/AndroidManifest.xml b/hostsidetests/devicepolicy/app/WidgetProvider/AndroidManifest.xml
new file mode 100644
index 0000000..77246b5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.widgetprovider">
+
+ <uses-permission android:name="android.permission.BIND_APPWIDGET"/>
+
+ <application>
+ <receiver android:name="SimpleWidgetProvider" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+ <meta-data android:name="android.appwidget.provider"
+ android:resource="@xml/simple_widget_provider_info" />
+ </receiver>
+ <service android:name=".SimpleAppWidgetHostService" >
+ <intent-filter>
+ <action android:name="com.android.cts.widgetprovider.REGISTER_CALLBACK" />
+ </intent-filter>
+ </service>
+ </application>
+
+</manifest>
+
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/res/layout/simple_widget.xml b/hostsidetests/devicepolicy/app/WidgetProvider/res/layout/simple_widget.xml
new file mode 100644
index 0000000..338c57a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/res/layout/simple_widget.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:padding="10dip">
+
+ <ImageView
+ android:id="@+id/pkg_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"/>
+
+ <TextView
+ android:id="@+id/pkg_name"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_centerVertical="true"
+ android:paddingLeft="10dip"
+ android:layout_toRightOf="@id/pkg_icon"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/res/xml/simple_widget_provider_info.xml b/hostsidetests/devicepolicy/app/WidgetProvider/res/xml/simple_widget_provider_info.xml
new file mode 100644
index 0000000..8a002d2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/res/xml/simple_widget_provider_info.xml
@@ -0,0 +1,20 @@
+<!-- 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.
+-->
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+ android:minWidth="40dp"
+ android:minHeight="40dp"
+ android:resizeMode="horizontal|vertical"
+ android:widgetCategory="home_screen">
+</appwidget-provider>
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.java b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.java
new file mode 100644
index 0000000..b5b6003
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.java
@@ -0,0 +1,246 @@
+/*
+ * 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.widgetprovider;
+
+import android.app.Service;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Service that acts as AppWidgetHost that listens to onProvidersChanged callbacks and updates the
+ * internally stored list of profile widgets. The service reacts to messages sent from the device
+ * side tests and returns whether the expected widget provider is currently present or not.
+ */
+public class SimpleAppWidgetHostService extends Service {
+ private static final String TAG = "SimpleAppWidgetHostService";
+
+ private static final int MSG_RESULT = 0;
+ private static final int MSG_PROVIDER_PRESENT = 1;
+ private static final int MSG_PROVIDER_UPDATES = 2;
+
+ private static final int RESULT_UNKNOWN = 0;
+ private static final int RESULT_PRESENT = 1;
+ private static final int RESULT_NOT_PRESENT = 2;
+ private static final int RESULT_INTERRUPTED = 3;
+ private static final int RESULT_TIMEOUT = 4;
+
+ public static final String USER_EXTRA = "user-extra";
+ public static final String PACKAGE_EXTRA = "package-extra";
+ public static final String REPLY_EXTRA = "reply-extra";
+
+ private AppWidgetManager mAppWidgetManager;
+ private SimpleAppWidgetHost mAppWidgetHost;
+ private SimpleAppWidgetHostView mAppWidgetHostView;
+ private int mAppWidgetId;
+ private Messenger mMessenger;
+ private UserHandle mUserHandle;
+ private Semaphore mWidgetUpdateSemaphore = new Semaphore(0);
+ private RemoteViews mRemoteViews;
+
+ class CheckHandler extends Handler {
+ public CheckHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ Bundle params = null;
+ if (msg.obj instanceof Bundle) {
+ params = (Bundle) (msg.obj);
+ }
+ try {
+ switch (msg.what) {
+ case MSG_PROVIDER_PRESENT: {
+ Log.d(TAG, "MSG_PROVIDER_PRESENT");
+ int result = RESULT_UNKNOWN;
+ try {
+ AppWidgetProviderInfo info = mAppWidgetHost.getProvider(params);
+ result = (info != null) ? RESULT_PRESENT : RESULT_NOT_PRESENT;
+ if (info != null) {
+ bindAppWidget(info);
+ }
+ } catch (InterruptedException e) {
+ result = RESULT_INTERRUPTED;
+ }
+ msg.replyTo.send(Message.obtain(null, MSG_RESULT, result
+ , 0 /* not used */));
+ break;
+ }
+ case MSG_PROVIDER_UPDATES: {
+ Log.d(TAG, "MSG_PROVIDER_UPDATES");
+ int result = RESULT_UNKNOWN;
+ try {
+ updateWidgetViaWidgetId();
+ boolean update = waitForUpdate();
+ result = update ? RESULT_PRESENT : RESULT_NOT_PRESENT;
+ } catch (InterruptedException e) {
+ result = RESULT_INTERRUPTED;
+ }
+ msg.replyTo.send(Message.obtain(null, MSG_RESULT, result
+ , 0 /* not used */));
+ 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.widgetprovider.REGISTER_CALLBACK".equals(intent.getAction())) {
+ mUserHandle = getUserHandleArgument(this, USER_EXTRA, intent);
+ Log.d(TAG, "mUserHandle=" + mUserHandle);
+ setup();
+ }
+ return START_STICKY;
+ }
+
+ private void setup() {
+ HandlerThread handlerThread = new HandlerThread("Widget test callback handler");
+ handlerThread.start();
+ mMessenger = new Messenger(new CheckHandler(handlerThread.getLooper()));
+ mAppWidgetManager = (AppWidgetManager) getSystemService(Context.APPWIDGET_SERVICE);
+ mAppWidgetHost = new SimpleAppWidgetHost(this, 0);
+ mAppWidgetHost.deleteHost();
+ mAppWidgetHost.startListening();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mMessenger.getBinder();
+ }
+
+ @Override
+ public void onDestroy() {
+ mAppWidgetHost.stopListening();
+ mAppWidgetHost.deleteAppWidgetId(mAppWidgetId);
+ mAppWidgetHost.deleteHost();
+ }
+
+ private void bindAppWidget(AppWidgetProviderInfo info) {
+ mAppWidgetId = mAppWidgetHost.allocateAppWidgetId();
+ Log.d(TAG, "Registering app widget with id:" + mAppWidgetId);
+ mAppWidgetManager.bindAppWidgetIdIfAllowed(mAppWidgetId, mUserHandle, info.provider, null);
+ mAppWidgetHostView = (SimpleAppWidgetHostView) mAppWidgetHost.createView(this,
+ mAppWidgetId, info);
+ mRemoteViews = new RemoteViews(info.provider.getPackageName(), R.layout.simple_widget);
+ }
+
+ private UserHandle getUserHandleArgument(Context context, String key,
+ Intent intent) {
+ UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
+ int serial = intent.getIntExtra(key, 0);
+ Log.d(TAG, "userId=" + serial);
+ return um.getUserForSerialNumber(serial);
+ }
+
+ private void updateWidgetViaWidgetId() {
+ Log.d(TAG, "Forcing widget update via widget id");
+ mWidgetUpdateSemaphore.drainPermits();
+ // trigger a widget update
+ mAppWidgetManager.updateAppWidget(mAppWidgetId, mRemoteViews);
+ }
+
+ private boolean waitForUpdate() throws InterruptedException {
+ // wait for updateAppWidget to arrive
+ return mWidgetUpdateSemaphore.tryAcquire(20, TimeUnit.SECONDS);
+ }
+
+ private class SimpleAppWidgetHost extends AppWidgetHost {
+ private List<AppWidgetProviderInfo> mProviders;
+ private Semaphore mSemaphore = new Semaphore(0);
+ public SimpleAppWidgetHost(Context context, int hostId) {
+ super(context, hostId);
+ synchronized (this) {
+ mProviders = mAppWidgetManager.getInstalledProvidersForProfile(mUserHandle);
+ }
+ }
+
+ @Override
+ protected void onProvidersChanged() {
+ super.onProvidersChanged();
+ Log.d(TAG, "onProvidersChanged callback received");
+ synchronized (this) {
+ mProviders = mAppWidgetManager.getInstalledProvidersForProfile(mUserHandle);
+ }
+ mSemaphore.release();
+ }
+
+ @Override
+ protected AppWidgetHostView onCreateView(Context context, int id, AppWidgetProviderInfo info) {
+ return new SimpleAppWidgetHostView(context);
+ }
+
+ public AppWidgetProviderInfo getProvider(Bundle params) throws InterruptedException {
+ String packageName = params.getString(PACKAGE_EXTRA);
+ while (mSemaphore.tryAcquire(30, TimeUnit.SECONDS)) {
+ mSemaphore.drainPermits();
+ Log.d(TAG, "checking for " + packageName + " " + mUserHandle);
+ synchronized (this) {
+ for (AppWidgetProviderInfo providerInfo : mProviders) {
+ if (providerInfo.provider.getPackageName().equals(packageName)) {
+ Log.d(TAG, "Provider exists " + packageName
+ + " for user " + mUserHandle);
+ return providerInfo;
+ }
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+ private class SimpleAppWidgetHostView extends AppWidgetHostView {
+ public SimpleAppWidgetHostView(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void updateAppWidget(RemoteViews views) {
+ super.updateAppWidget(views);
+ Log.d(TAG, "Host view received widget update");
+ mWidgetUpdateSemaphore.release();
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleWidgetProvider.java b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleWidgetProvider.java
new file mode 100644
index 0000000..3bd4530
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleWidgetProvider.java
@@ -0,0 +1,24 @@
+/*
+ * 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.widgetprovider;
+
+import android.appwidget.AppWidgetProvider;
+
+/**
+ * A simple widget provider to test cross-profile widgets.
+ */
+public class SimpleWidgetProvider extends AppWidgetProvider {}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 671c3e5..650e963 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -185,9 +185,6 @@
protected boolean runDeviceTestsAsUser(
String pkgName, @Nullable String testClassName, String testMethodName, int userId)
throws DeviceNotAvailableException {
- if (testClassName.startsWith(".")) {
- testClassName = pkgName + testClassName;
- }
return runDeviceTests(pkgName, testClassName, testMethodName, userId);
}
@@ -200,6 +197,9 @@
protected boolean runDeviceTests(String pkgName, @Nullable String testClassName,
@Nullable String testMethodName, @Nullable Integer userId, @Nullable String params)
throws DeviceNotAvailableException {
+ if (testClassName != null && testClassName.startsWith(".")) {
+ testClassName = pkgName + testClassName;
+ }
TestRunResult runResult = (userId == null && params == null)
? doRunTests(pkgName, testClassName, testMethodName)
: doRunTestsAsUser(pkgName, testClassName, testMethodName,
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 93e1aff..acc5b26 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -48,6 +48,9 @@
private static final String WIFI_CONFIG_CREATOR_PKG = "com.android.cts.wificonfigcreator";
private static final String WIFI_CONFIG_CREATOR_APK = "CtsWifiConfigCreator.apk";
+ private static final String WIDGET_PROVIDER_APK = "CtsWidgetProviderApp.apk";
+ private static final String WIDGET_PROVIDER_PKG = "com.android.cts.widgetprovider";
+
private static final String ADMIN_RECEIVER_TEST_CLASS =
MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
@@ -596,6 +599,47 @@
"testNfcShareEnabled", 0));
}
+ public void testCrossProfileWidgets() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+
+ try {
+ installApp(WIDGET_PROVIDER_APK);
+ getDevice().executeShellCommand("appwidget grantbind --user 0 --package "
+ + WIDGET_PROVIDER_PKG);
+ startWidgetHostService();
+
+ String commandOutput = changeCrossProfileWidgetForUser(WIDGET_PROVIDER_PKG,
+ "add-cross-profile-widget", mUserId);
+ assertTrue("Command was expected to succeed " + commandOutput,
+ commandOutput.contains("Status: ok"));
+
+ assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetTest",
+ "testCrossProfileWidgetProviderAdded", mUserId));
+ assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetPrimaryUserTest",
+ "testHasCrossProfileWidgetProvider_true", 0));
+ assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetPrimaryUserTest",
+ "testHostReceivesWidgetUpdates_true", 0));
+
+ commandOutput = changeCrossProfileWidgetForUser(WIDGET_PROVIDER_PKG,
+ "remove-cross-profile-widget", mUserId);
+ assertTrue("Command was expected to succeed " + commandOutput,
+ commandOutput.contains("Status: ok"));
+
+ assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetTest",
+ "testCrossProfileWidgetProviderRemoved", mUserId));
+ assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetPrimaryUserTest",
+ "testHasCrossProfileWidgetProvider_false", 0));
+ assertTrue(runDeviceTests(MANAGED_PROFILE_PKG, ".CrossProfileWidgetPrimaryUserTest",
+ "testHostReceivesWidgetUpdates_false", 0));
+ } finally {
+ changeCrossProfileWidgetForUser(WIDGET_PROVIDER_PKG, "remove-cross-profile-widget",
+ mUserId);
+ getDevice().uninstallPackage(WIDGET_PROVIDER_PKG);
+ }
+ }
+
private void disableActivityForUser(String activityName, int userId)
throws DeviceNotAvailableException {
String command = "am start -W --user " + userId
@@ -612,7 +656,20 @@
+ " -c android.intent.category.DEFAULT "
+ " --es extra-command " + command
+ " --es extra-restriction-key " + key
- + " " + MANAGED_PROFILE_PKG + "/.UserRestrictionActivity";
+ + " " + MANAGED_PROFILE_PKG + "/.SetPolicyActivity";
+ String commandOutput = getDevice().executeShellCommand(adbCommand);
+ CLog.logAndDisplay(LogLevel.INFO,
+ "Output for command " + adbCommand + ": " + commandOutput);
+ return commandOutput;
+ }
+
+ private String changeCrossProfileWidgetForUser(String packageName, String command, int userId)
+ throws DeviceNotAvailableException {
+ String adbCommand = "am start -W --user " + userId
+ + " -c android.intent.category.DEFAULT "
+ + " --es extra-command " + command
+ + " --es extra-package-name " + packageName
+ + " " + MANAGED_PROFILE_PKG + "/.SetPolicyActivity";
String commandOutput = getDevice().executeShellCommand(adbCommand);
CLog.logAndDisplay(LogLevel.INFO,
"Output for command " + adbCommand + ": " + commandOutput);
@@ -627,6 +684,15 @@
+ getDevice().executeShellCommand(command));
}
+ protected void startWidgetHostService() throws Exception {
+ String command = "am startservice --user 0 "
+ + "-a " + WIDGET_PROVIDER_PKG + ".REGISTER_CALLBACK "
+ + "--ei user-extra " + getUserSerialNumber(mUserId)
+ + " " + WIDGET_PROVIDER_PKG + "/.SimpleAppWidgetHostService";
+ CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+ + getDevice().executeShellCommand(command));
+ }
+
private void assertAppLinkResult(String methodName) throws DeviceNotAvailableException {
assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".AppLinkTest", methodName, mUserId));
}
diff --git a/tests/tests/assist/AndroidManifest.xml b/tests/tests/assist/AndroidManifest.xml
index b6cd684..97bd874 100644
--- a/tests/tests/assist/AndroidManifest.xml
+++ b/tests/tests/assist/AndroidManifest.xml
@@ -29,6 +29,7 @@
<action android:name="android.intent.action.TEST_START_ACTIVITY_ASSIST_STRUCTURE" />
<action android:name="android.intent.action.TEST_START_ACTIVITY_DISABLE_CONTEXT" />
<action android:name="android.intent.action.TEST_START_ACTIVITY_FLAG_SECURE" />
+ <action android:name="android.intent.action.TEST_START_ACTIVITY_LIFECYCLE" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
diff --git a/tests/tests/assist/common/src/android/assist/common/Utils.java b/tests/tests/assist/common/src/android/assist/common/Utils.java
index bf051c0..8d555da 100644
--- a/tests/tests/assist/common/src/android/assist/common/Utils.java
+++ b/tests/tests/assist/common/src/android/assist/common/Utils.java
@@ -24,8 +24,11 @@
public class Utils {
public static final String TESTCASE_TYPE = "testcase_type";
public static final String TESTINFO = "testinfo";
- public static final String BROADCAST_INTENT = "android.intent.action.ASSIST_TESTAPP";
- public static final String BROADCAST_ASSIST_DATA_INTENT = "android.intent.action.ASSIST_DATA";
+ public static final String ACTION_PREFIX = "android.intent.action.";
+ public static final String BROADCAST_INTENT = ACTION_PREFIX + "ASSIST_TESTAPP";
+ public static final String BROADCAST_ASSIST_DATA_INTENT = ACTION_PREFIX + "ASSIST_DATA";
+ public static final String BROADCAST_INTENT_START_ASSIST = ACTION_PREFIX + "START_ASSIST";
+ public static final String ASSIST_RECEIVER_REGISTERED = ACTION_PREFIX + "ASSIST_READY";
public static final String TEST_ERROR = "Error In Test:";
public static final String ASSIST_STRUCTURE_KEY = "assist_structure";
@@ -33,12 +36,30 @@
public static final String ASSIST_BUNDLE_KEY = "assist_bundle";
public static final String ASSIST_SCREENSHOT_KEY = "assist_screenshot";
+
+ /** Lifecycle Test intent constants */
+ public static final String LIFECYCLE_PREFIX = ACTION_PREFIX + "lifecycle_";
+ public static final String LIFECYCLE_HASRESUMED = LIFECYCLE_PREFIX + "hasResumed";
+ public static final String LIFECYCLE_ONPAUSE = LIFECYCLE_PREFIX + "onpause";
+ public static final String LIFECYCLE_ONSTOP = LIFECYCLE_PREFIX + "onstop";
+ public static final String LIFECYCLE_ONDESTROY = LIFECYCLE_PREFIX + "ondestroy";
+
+ /** Flag Secure Test intent constants */
+ public static final String FLAG_SECURE_HASRESUMED = ACTION_PREFIX + "flag_secure_hasResumed";
+
+ /** Two second timeout for getting back assist context */
public static final int TIMEOUT_MS = 2 * 1000; // TODO(awlee): what is the timeout
+ public static final int ACTIVITY_ONRESUME_TIMEOUT_MS = 4000;
+ public static final String EXTRA_REGISTER_RECEIVER = "register_receiver";
/** Test name suffixes */
public static final String ASSIST_STRUCTURE = "ASSIST_STRUCTURE";
public static final String DISABLE_CONTEXT = "DISABLE_CONTEXT";
public static final String FLAG_SECURE = "FLAG_SECURE";
+ public static final String LIFECYCLE = "LIFECYCLE";
+
+ /** Session intent constants */
+ public static final String HIDE_SESSION = "android.intent.action.hide_session";
/**
* The shim activity that starts the service associated with each test.
@@ -46,10 +67,12 @@
public static final String getTestActivity(String testCaseType) {
switch (testCaseType) {
case ASSIST_STRUCTURE:
- case FLAG_SECURE:
return "service.AssistStructureActivity";
case DISABLE_CONTEXT:
return "service.DisableContextActivity";
+ case FLAG_SECURE:
+ case LIFECYCLE:
+ return "service.DelayedAssistantActivity";
default:
return "";
}
@@ -67,6 +90,9 @@
case FLAG_SECURE:
return new ComponentName(
"android.assist.testapp", "android.assist.testapp.SecureActivity");
+ case LIFECYCLE:
+ return new ComponentName(
+ "android.assist.testapp", "android.assist.testapp.LifecycleActivity");
default:
return new ComponentName("","");
}
diff --git a/tests/tests/assist/service/AndroidManifest.xml b/tests/tests/assist/service/AndroidManifest.xml
index 2c5206a..cdbeef0 100644
--- a/tests/tests/assist/service/AndroidManifest.xml
+++ b/tests/tests/assist/service/AndroidManifest.xml
@@ -34,7 +34,6 @@
<activity android:name=".AssistStructureActivity" >
<intent-filter>
<action android:name="android.intent.action.START_TEST_ASSIST_STRUCTURE" />
- <action android:name="android.intent.action.START_TEST_FLAG_SECURE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
@@ -45,6 +44,14 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
+ <activity android:name=".DelayedAssistantActivity"
+ android:label="Delay Assistant Start Activity">
+ <intent-filter>
+ <action android:name="android.intent.action.START_TEST_LIFECYCLE" />
+ <action android:name="android.intent.action.START_TEST_FLAG_SECURE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
<service android:name=".MainInteractionSessionService"
android:permission="android.permission.BIND_VOICE_INTERACTION"
android:process=":session">
diff --git a/tests/tests/assist/service/res/layout/assist_layer.xml b/tests/tests/assist/service/res/layout/assist_layer.xml
new file mode 100644
index 0000000..49f35c9
--- /dev/null
+++ b/tests/tests/assist/service/res/layout/assist_layer.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/assist_layer"
+ android:layout_width="match_parent"
+ android:background="@color/assist_layer_background"
+ android:layout_height="match_parent">
+ <TextView
+ android:layout_centerInParent="true"
+ android:text="@string/test_assistant_text"
+ android:textColor="@android:color/white"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+</RelativeLayout>
diff --git a/tests/tests/assist/service/res/values/colors.xml b/tests/tests/assist/service/res/values/colors.xml
new file mode 100644
index 0000000..4423140
--- /dev/null
+++ b/tests/tests/assist/service/res/values/colors.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <color name="assist_layer_background">#aa000000</color>
+</resources>
diff --git a/tests/tests/assist/service/res/values/strings.xml b/tests/tests/assist/service/res/values/strings.xml
new file mode 100644
index 0000000..ea959e6
--- /dev/null
+++ b/tests/tests/assist/service/res/values/strings.xml
@@ -0,0 +1,18 @@
+<!--
+ Copyright 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. -->
+
+<resources>
+ <string name="test_assistant_text">I am an Assistant</string>
+</resources>
diff --git a/tests/tests/assist/service/src/android/voiceinteraction/service/DelayedAssistantActivity.java b/tests/tests/assist/service/src/android/voiceinteraction/service/DelayedAssistantActivity.java
new file mode 100644
index 0000000..31d1694
--- /dev/null
+++ b/tests/tests/assist/service/src/android/voiceinteraction/service/DelayedAssistantActivity.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 android.assist.service;
+
+import android.app.Activity;
+import android.assist.common.Utils;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.util.Log;
+
+public class DelayedAssistantActivity extends Activity {
+ static final String TAG = "DelatyedAssistantActivity";
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(this, MainInteractionService.class));
+ intent.putExtra(Utils.EXTRA_REGISTER_RECEIVER, true);
+ finish();
+ ComponentName serviceName = startService(intent);
+ Log.i(TAG, "Started service: " + serviceName);
+ }
+}
diff --git a/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionService.java b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionService.java
index 85bd6ea..7530933 100644
--- a/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionService.java
+++ b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionService.java
@@ -16,8 +16,15 @@
package android.assist.service;
+import static android.service.voice.VoiceInteractionSession.SHOW_WITH_ASSIST;
+import static android.service.voice.VoiceInteractionSession.SHOW_WITH_SCREENSHOT;
+
+import android.assist.common.Utils;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Bundle;
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionSession;
@@ -27,6 +34,7 @@
static final String TAG = "MainInteractionService";
private Intent mIntent;
private boolean mReady = false;
+ private BroadcastReceiver mBroadcastReceiver;
@Override
public void onReady() {
@@ -36,7 +44,7 @@
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- Log.i(TAG, "onStartCommand received");
+ Log.i(TAG, "onStartCommand received - intent: " + intent);
mIntent = intent;
maybeStart();
return START_NOT_STICKY;
@@ -47,14 +55,40 @@
Log.wtf(TAG, "Can't start session because either intent is null or onReady() "
+ "has not been called yet. mIntent = " + mIntent + ", mReady = " + mReady);
} else {
- Log.i(TAG, "Yay! about to start session");
if (isActiveService(this, new ComponentName(this, getClass()))) {
- showSession(new Bundle(), VoiceInteractionSession.SHOW_WITH_ASSIST |
- VoiceInteractionSession.SHOW_WITH_SCREENSHOT);
+ if (mIntent.getBooleanExtra(Utils.EXTRA_REGISTER_RECEIVER, false)) {
+ Log.i(TAG, "Registering receiver to start session later");
+ if (mBroadcastReceiver == null) {
+ mBroadcastReceiver = new MainInteractionServiceBroadcastReceiver();
+ registerReceiver(mBroadcastReceiver,
+ new IntentFilter(Utils.BROADCAST_INTENT_START_ASSIST));
+ }
+ sendBroadcast(new Intent(Utils.ASSIST_RECEIVER_REGISTERED));
+ } else {
+ Log.i(TAG, "Yay! about to start session");
+ showSession(new Bundle(), VoiceInteractionSession.SHOW_WITH_ASSIST |
+ VoiceInteractionSession.SHOW_WITH_SCREENSHOT);
+ }
} else {
Log.wtf(TAG, "**** Not starting MainInteractionService because" +
" it is not set as the current voice interaction service");
}
}
}
+
+ private class MainInteractionServiceBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Utils.BROADCAST_INTENT_START_ASSIST)) {
+ showSession(new Bundle(), SHOW_WITH_ASSIST | SHOW_WITH_SCREENSHOT);
+ }
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ if (mBroadcastReceiver != null) {
+ unregisterReceiver(mBroadcastReceiver);
+ }
+ }
}
diff --git a/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSession.java b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSession.java
index 9a835c2..f297b3e 100644
--- a/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSession.java
+++ b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSession.java
@@ -18,13 +18,17 @@
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
+import android.assist.service.R;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.service.voice.VoiceInteractionSession;
import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
import java.io.ByteArrayOutputStream;
@@ -39,6 +43,7 @@
private boolean hasReceivedAssistData = false;
private boolean hasReceivedScreenshot = false;
+ private BroadcastReceiver mReceiver;
MainInteractionSession(Context context) {
super(context);
@@ -48,12 +53,27 @@
@Override
public void onCreate() {
super.onCreate();
+ mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(Utils.HIDE_SESSION)) {
+ hide();
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Utils.HIDE_SESSION);
+ mContext.registerReceiver(mReceiver, filter);
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy()");
super.onDestroy();
+ if (mReceiver != null) {
+ mContext.unregisterReceiver(mReceiver);
+ }
}
@Override
@@ -115,6 +135,15 @@
}
}
+ @Override
+ public View onCreateContentView() {
+ LayoutInflater f = getLayoutInflater();
+ if (f == null) {
+ Log.wtf(TAG, "layout inflater was null");
+ }
+ return f.inflate(R.layout.assist_layer,null);
+ }
+
class DoneReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
index bdf3d4a..a7e7087 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
@@ -48,7 +48,7 @@
protected BroadcastReceiver mReceiver;
protected Bundle mAssistBundle;
protected Context mContext;
- protected CountDownLatch mLatch;
+ protected CountDownLatch mLatch, mAssistantReadyLatch;
private String mTestName;
public AssistTestBase() {
@@ -58,6 +58,7 @@
@Override
protected void setUp() throws Exception {
super.setUp();
+ mAssistantReadyLatch = new CountDownLatch(1);
mContext = getInstrumentation().getTargetContext();
SystemUtil.runShellCommand(getInstrumentation(),
"settings put secure assist_structure_enabled 1");
@@ -71,6 +72,7 @@
mContext.unregisterReceiver(mReceiver);
mTestActivity.finish();
super.tearDown();
+ mContext.sendBroadcast(new Intent(Utils.HIDE_SESSION));
}
protected void startTestActivity(String testName) {
@@ -84,9 +86,32 @@
}
/**
+ * Called when waiting for Assistant's Broadcast Receiver to be setup
+ */
+ public void waitForAssistantToBeReady() throws Exception {
+ Log.i(TAG, "waiting for assistant to be ready before continuing");
+ if (!mAssistantReadyLatch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ fail("Assistant was not ready before timeout of: " + Utils.TIMEOUT_MS + "msec");
+ }
+ }
+
+ /**
+ * Send broadcast to MainInteractionService to start a session
+ */
+ protected void startSession() {
+ mContext.sendBroadcast(new Intent(Utils.BROADCAST_INTENT_START_ASSIST));
+ }
+
+ /**
* Called after startTestActivity
*/
protected boolean waitForBroadcast() throws Exception {
+ mTestActivity.start3pApp(mTestName);
+ mTestActivity.startTest(mTestName);
+ return waitForContext();
+ }
+
+ protected boolean waitForContext() throws Exception {
mLatch = new CountDownLatch(1);
if (mReceiver != null) {
mContext.unregisterReceiver(mReceiver);
@@ -95,8 +120,6 @@
mContext.registerReceiver(mReceiver,
new IntentFilter(Utils.BROADCAST_ASSIST_DATA_INTENT));
- mTestActivity.start3pApp(mTestName);
- mTestActivity.startTest(mTestName);
if (!mLatch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
fail("Failed to receive broadcast in " + Utils.TIMEOUT_MS + "msec");
return false;
@@ -188,4 +211,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/assist/src/android/assist/cts/DisableContextTest.java b/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
index 04bea77..9b29407 100644
--- a/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
+++ b/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
@@ -97,4 +97,4 @@
verifyAssistDataNullness(true, true, true, true);
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
index fc14900..40bf7a7 100644
--- a/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
+++ b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
@@ -17,8 +17,14 @@
package android.assist.cts;
import android.assist.common.Utils;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* Test we receive proper assist data (root assistStructure with no children) when the assistant is
@@ -26,10 +32,13 @@
*/
public class FlagSecureTest extends AssistTestBase {
- static final String TAG = "DisableContextTest";
+ static final String TAG = "FlagSecureTest";
private static final String TEST_CASE_TYPE = Utils.FLAG_SECURE;
+ private BroadcastReceiver mReceiver;
+ private CountDownLatch mHasResumedLatch = new CountDownLatch(1);
+
public FlagSecureTest() {
super();
}
@@ -37,13 +46,35 @@
@Override
public void setUp() throws Exception {
super.setUp();
+ setUpAndRegisterReceiver();
startTestActivity(TEST_CASE_TYPE);
- waitForBroadcast();
}
@Override
public void tearDown() throws Exception {
super.tearDown();
+ if (mReceiver != null) {
+ mContext.unregisterReceiver(mReceiver);
+ mReceiver = null;
+ }
+ }
+
+ private void setUpAndRegisterReceiver() {
+ if (mReceiver != null) {
+ mContext.unregisterReceiver(mReceiver);
+ }
+ mReceiver = new FlagSecureTestBroadcastReceiver();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Utils.FLAG_SECURE_HASRESUMED);
+ filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+ mContext.registerReceiver(mReceiver, filter);
+ }
+
+ private void waitForOnResume() throws Exception {
+ Log.i(TAG, "waiting for onResume() before continuing");
+ if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+ }
}
public void testSecureActivity() throws Exception {
@@ -52,4 +83,16 @@
// verify that we have only the root window and not its children.
verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE), true);
}
-}
\ No newline at end of file
+
+ private class FlagSecureTestBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(Utils.FLAG_SECURE_HASRESUMED)) {
+ mHasResumedLatch.countDown();
+ } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) {
+ mAssistantReadyLatch.countDown();
+ }
+ }
+ }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/LifecycleTest.java b/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
new file mode 100644
index 0000000..19a1be5
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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 android.assist.cts;
+
+import android.assist.TestStartActivity;
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.cts.util.SystemUtil;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.lang.Override;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/** Test we receive proper assist data when context is disabled or enabled */
+
+public class LifecycleTest extends AssistTestBase {
+ private static final String TAG = "LifecycleTest";
+ private static final String action_hasResumed = Utils.LIFECYCLE_HASRESUMED;
+ private static final String action_onPause = Utils.LIFECYCLE_ONPAUSE;
+ private static final String action_onStop = Utils.LIFECYCLE_ONSTOP;
+ private static final String action_onDestroy = Utils.LIFECYCLE_ONDESTROY;
+
+ private BroadcastReceiver mLifecycleTestBroadcastReceiver;
+ private CountDownLatch mHasResumedLatch = new CountDownLatch(1);
+ private CountDownLatch mActivityLifecycleLatch = new CountDownLatch(1);
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ setUpAndRegisterReceiver();
+ startTestActivity(Utils.LIFECYCLE);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ if (mLifecycleTestBroadcastReceiver != null) {
+ mContext.unregisterReceiver(mLifecycleTestBroadcastReceiver);
+ mLifecycleTestBroadcastReceiver = null;
+ }
+ }
+
+ private void setUpAndRegisterReceiver() {
+ if (mLifecycleTestBroadcastReceiver != null) {
+ mContext.unregisterReceiver(mLifecycleTestBroadcastReceiver);
+ }
+ mLifecycleTestBroadcastReceiver = new LifecycleTestReceiver();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(action_hasResumed);
+ filter.addAction(action_onPause);
+ filter.addAction(action_onStop);
+ filter.addAction(action_onDestroy);
+ filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+ mContext.registerReceiver(mLifecycleTestBroadcastReceiver, filter);
+
+ }
+
+ private void waitForOnResume() throws Exception {
+ Log.i(TAG, "waiting for onResume() before continuing");
+ if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+ }
+ }
+
+ private void waitAndSeeIfLifecycleMethodsAreTriggered() throws Exception {
+ if (mActivityLifecycleLatch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ fail("One or more lifecycle methods were called after triggering assist");
+ }
+ }
+
+ public void testLayerDoesNotTriggerLifecycleMethods() throws Exception {
+ mTestActivity.startTest(Utils.LIFECYCLE);
+ waitForAssistantToBeReady();
+ mTestActivity.start3pApp(Utils.LIFECYCLE);
+ waitForOnResume();
+ startSession();
+ waitForContext();
+ waitAndSeeIfLifecycleMethodsAreTriggered();
+ }
+
+ private class LifecycleTestReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(action_hasResumed)) {
+ mHasResumedLatch.countDown();
+ } else if (action.equals(action_onPause)) {
+ mActivityLifecycleLatch.countDown();
+ } else if (action.equals(action_onStop)) {
+ mActivityLifecycleLatch.countDown();
+ } else if (action.equals(action_onDestroy)) {
+ mActivityLifecycleLatch.countDown();
+ } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) {
+ mAssistantReadyLatch.countDown();
+ }
+ }
+ }
+}
diff --git a/tests/tests/assist/testapp/AndroidManifest.xml b/tests/tests/assist/testapp/AndroidManifest.xml
index 371ae7b..8d6169c 100644
--- a/tests/tests/assist/testapp/AndroidManifest.xml
+++ b/tests/tests/assist/testapp/AndroidManifest.xml
@@ -39,5 +39,13 @@
<category android:name="android.intent.category.VOICE" />
</intent-filter>
</activity>
+ <activity android:name="LifecycleActivity"
+ android:label="Life Cycle Check Activity"
+ android:theme="@android:style/Theme.Material.Light">
+ <intent-filter>
+ <action android:name="android.intent.action.TEST_APP_LIFECYCLE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/LifecycleActivity.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/LifecycleActivity.java
new file mode 100644
index 0000000..4e1dc80
--- /dev/null
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/LifecycleActivity.java
@@ -0,0 +1,60 @@
+/*
+ * 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 android.assist.testapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+public class LifecycleActivity extends Activity {
+ private static final String TAG = "LifecycleActivity";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.i(TAG, "LifecycleActivity created");
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ Log.i(TAG, "Activity has resumed");
+ sendBroadcast(new Intent("android.intent.action.lifecycle_hasResumed"));
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ Log.i(TAG, "activity was paused");
+ sendBroadcast(new Intent("android.intent.action.lifecycle_onpause"));
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ Log.i(TAG, "activity was stopped");
+ sendBroadcast(new Intent("android.intent.action.lifecycle_onstop"));
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ Log.i(TAG, "activity was destroyed");
+ sendBroadcast(new Intent("android.intent.action.lifecycle_ondestroy"));
+ }
+}
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/SecureActivity.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/SecureActivity.java
index 83f7549..d9b2ff2 100644
--- a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/SecureActivity.java
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/SecureActivity.java
@@ -17,6 +17,7 @@
package android.assist.testapp;
import android.app.Activity;
+import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
@@ -24,7 +25,6 @@
public class SecureActivity extends Activity {
static final String TAG = "SecureActivity";
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -33,4 +33,11 @@
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
}
-}
\ No newline at end of file
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ Log.i(TAG, "Activity has resumed");
+ sendBroadcast(new Intent("android.intent.action.flag_secure_hasResumed"));
+ }
+}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java b/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
index 1881774..8a217fd 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
@@ -32,6 +32,7 @@
private SurfaceView mSurfaceView;
private int currentWidth = 0;
private int currentHeight = 0;
+ private final Object sizeLock = new Object();
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -55,6 +56,12 @@
timeOutMs, expectWidth, expectHeight));
}
+ synchronized(sizeLock) {
+ if (expectWidth == currentWidth && expectHeight == currentHeight) {
+ return true;
+ }
+ }
+
int waitTimeMs = timeOutMs;
boolean changeSucceeded = false;
while (!changeSucceeded && waitTimeMs > 0) {
@@ -87,8 +94,10 @@
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.i(TAG, "Surface Changed to: " + width + "x" + height);
- currentWidth = width;
- currentHeight = height;
+ synchronized (sizeLock) {
+ currentWidth = width;
+ currentHeight = height;
+ }
surfaceChangedDone.open();
}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
index 7330a4c..c136b67 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -619,8 +619,8 @@
mPreviewSize.getHeight());
assertTrue("wait for surface change to " + mPreviewSize.toString() + " timed out", res);
mPreviewSurface = holder.getSurface();
- assertTrue("Preview surface is invalid", mPreviewSurface.isValid());
assertNotNull("Preview surface is null", mPreviewSurface);
+ assertTrue("Preview surface is invalid", mPreviewSurface.isValid());
}
/**
diff --git a/tests/tests/os/src/android/os/cts/StatFsTest.java b/tests/tests/os/src/android/os/cts/StatFsTest.java
index 67afde9..a0653fd 100644
--- a/tests/tests/os/src/android/os/cts/StatFsTest.java
+++ b/tests/tests/os/src/android/os/cts/StatFsTest.java
@@ -46,15 +46,15 @@
assertTrue(stat.getBlockSize() > 0);
assertTrue(stat.getBlockCount() > 0);
assertTrue(stat.getFreeBlocks() >= stat.getAvailableBlocks());
- assertTrue(stat.getAvailableBlocks() > 0);
+ assertTrue(stat.getAvailableBlocks() >= 0);
assertTrue(stat.getBlockSizeLong() > 0);
assertTrue(stat.getBlockCountLong() > 0);
assertTrue(stat.getFreeBlocksLong() >= stat.getAvailableBlocksLong());
- assertTrue(stat.getAvailableBlocksLong() > 0);
+ assertTrue(stat.getAvailableBlocksLong() >= 0);
- assertTrue(stat.getFreeBytes() > 0);
- assertTrue(stat.getAvailableBytes() > 0);
+ assertTrue(stat.getFreeBytes() >= 0);
+ assertTrue(stat.getAvailableBytes() >= 0);
assertTrue(stat.getTotalBytes() > 0);
}
}