Merge "PackageSignatureTest: detect devkeys."
diff --git a/suite/pts/PtsBuild.mk b/suite/pts/PtsBuild.mk
index 3c4df8b..7455c9a 100644
--- a/suite/pts/PtsBuild.mk
+++ b/suite/pts/PtsBuild.mk
@@ -24,11 +24,17 @@
     PtsDeviceUi \
     PtsDeviceDram
 
+
 PTS_SUPPORT_PACKAGES := \
-	TestDeviceSetup
+    TestDeviceSetup \
+    PtsDeviceTaskswitchingAppA \
+    PtsDeviceTaskswitchingAppB \
+    PtsDeviceTaskswitchingControl \
+    com.replica.replicaisland
 
 PTS_HOST_CASES := \
-    PtsHostBootup
+    PtsHostBootup \
+    PtsHostUi
 
 PTS_HOST_LIBS := \
     $(HOST_OUT_JAVA_LIBRARIES)/ptscommonutilhost.jar
diff --git a/suite/pts/hostTests/bootup/Android.mk b/suite/pts/hostTests/bootup/Android.mk
index b0226c3..4d779a0 100644
--- a/suite/pts/hostTests/bootup/Android.mk
+++ b/suite/pts/hostTests/bootup/Android.mk
@@ -28,4 +28,3 @@
 
 include $(BUILD_PTS_HOST_JAVA_LIBRARY)
 
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/pts/hostTests/bootup/src/com/android/pts/bootup/BootupTimeTest.java b/suite/pts/hostTests/bootup/src/com/android/pts/bootup/BootupTimeTest.java
index 709588b..e78289b 100644
--- a/suite/pts/hostTests/bootup/src/com/android/pts/bootup/BootupTimeTest.java
+++ b/suite/pts/hostTests/bootup/src/com/android/pts/bootup/BootupTimeTest.java
@@ -26,10 +26,15 @@
 import com.android.tradefed.device.TestDeviceOptions;
 import com.android.tradefed.testtype.DeviceTestCase;
 
-
+/**
+ *  Measure reboot-time using adb shell reboot
+ */
 public class BootupTimeTest extends DeviceTestCase {
 
     private ReportLog mReport = null;
+    // add some delay before each reboot
+    final static long SLEEP_BEFORE_REBOOT_TIME = 2 * 60 * 1000L;
+    final static int REBOOT_TIMEOUT_MS = 10 * 60 * 1000;
 
     @Override
     protected void setUp() throws Exception {
@@ -40,8 +45,8 @@
 
     @Override
     protected void tearDown() throws Exception {
-        mReport.throwReportToHost();
         super.tearDown();
+        mReport.throwReportToHost();
     }
 
     @TimeoutReq(minutes = 30)
@@ -53,8 +58,7 @@
                 if (i == 0) {
                     return;
                 }
-                final long SLEEP_TIME = 2 * 60 * 1000L;
-                Thread.sleep(SLEEP_TIME);
+                Thread.sleep(SLEEP_BEFORE_REBOOT_TIME);
             }
             @Override
             public void run(int i) throws Exception {
@@ -67,13 +71,12 @@
     }
 
     private void rebootDevice() throws DeviceNotAvailableException {
-        final int TIMEOUT_MS = 10 * 60 * 1000;
         TestDeviceOptions options = getDevice().getOptions();
         // store default value and increase time-out for reboot
         int rebootTimeout = options.getRebootTimeout();
         long onlineTimeout = options.getOnlineTimeout();
-        options.setRebootTimeout(TIMEOUT_MS);
-        options.setOnlineTimeout(TIMEOUT_MS);
+        options.setRebootTimeout(REBOOT_TIMEOUT_MS);
+        options.setOnlineTimeout(REBOOT_TIMEOUT_MS);
         getDevice().setOptions(options);
         getDevice().reboot();
         // restore default values
diff --git a/suite/pts/hostTests/uihost/Android.mk b/suite/pts/hostTests/uihost/Android.mk
new file mode 100644
index 0000000..77673a2
--- /dev/null
+++ b/suite/pts/hostTests/uihost/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2012 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_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := PtsHostUi
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt ddmlib-prebuilt junit ptscommonutilhost
+
+LOCAL_PTS_TEST_PACKAGE := com.android.pts.uihost
+
+include $(BUILD_PTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/pts/hostTests/uihost/appA/Android.mk b/suite/pts/hostTests/uihost/appA/Android.mk
new file mode 100644
index 0000000..7dce44c
--- /dev/null
+++ b/suite/pts/hostTests/uihost/appA/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2012 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
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ptsutil ctsutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PtsDeviceTaskswitchingAppA
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_PTS_PACKAGE)
+
+
diff --git a/suite/pts/hostTests/uihost/appA/AndroidManifest.xml b/suite/pts/hostTests/uihost/appA/AndroidManifest.xml
new file mode 100644
index 0000000..1115ee6
--- /dev/null
+++ b/suite/pts/hostTests/uihost/appA/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.pts.taskswitching.appa">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <application>
+        <activity
+                android:name=".AppAActivity"
+                android:screenOrientation="portrait"
+                android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/suite/pts/hostTests/uihost/appA/src/com/android/pts/taskswitching/appa/AppAActivity.java b/suite/pts/hostTests/uihost/appA/src/com/android/pts/taskswitching/appa/AppAActivity.java
new file mode 100644
index 0000000..bb0c158
--- /dev/null
+++ b/suite/pts/hostTests/uihost/appA/src/com/android/pts/taskswitching/appa/AppAActivity.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 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.pts.taskswitching.appa;
+
+
+import android.app.ListActivity;
+import android.content.Intent;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.WindowManager;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * Simple activity to notify completion via broadcast after onResume.
+ * This is for measuring taskswitching time between two apps.
+ */
+public class AppAActivity extends ListActivity {
+    static final String TAG = "AppAActivity";
+    private static final int NUMBER_ELEMENTS = 1000;
+    private static final String TASKSWITCHING_INTENT = "com.android.pts.taskswitching.appa";
+    private Handler mHandler;
+
+    private String[] mItems = new String[NUMBER_ELEMENTS];
+
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        for (int i = 0; i < NUMBER_ELEMENTS; i++) {
+            mItems[i] = "A" + Integer.toString(i);
+        }
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mItems));
+        ListView view = getListView();
+        mHandler = new Handler();
+    }
+
+    public void onResume() {
+        super.onResume();
+        mHandler.post(new Runnable() {
+
+            @Override
+            public void run() {
+                Intent intent = new Intent(TASKSWITCHING_INTENT);
+                sendBroadcast(intent);
+            }
+        });
+    }
+}
diff --git a/suite/pts/hostTests/uihost/appB/Android.mk b/suite/pts/hostTests/uihost/appB/Android.mk
new file mode 100644
index 0000000..caa1090
--- /dev/null
+++ b/suite/pts/hostTests/uihost/appB/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2012 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
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ptsutil ctsutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PtsDeviceTaskswitchingAppB
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_PTS_PACKAGE)
+
+
diff --git a/suite/pts/hostTests/uihost/appB/AndroidManifest.xml b/suite/pts/hostTests/uihost/appB/AndroidManifest.xml
new file mode 100644
index 0000000..d0ec4d7
--- /dev/null
+++ b/suite/pts/hostTests/uihost/appB/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.pts.taskswitching.appb">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <application>
+        <activity
+                android:name=".AppBActivity"
+                android:screenOrientation="portrait"
+                android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/suite/pts/hostTests/uihost/appB/src/com/android/pts/taskswitching/appb/AppBActivity.java b/suite/pts/hostTests/uihost/appB/src/com/android/pts/taskswitching/appb/AppBActivity.java
new file mode 100644
index 0000000..22ebdac
--- /dev/null
+++ b/suite/pts/hostTests/uihost/appB/src/com/android/pts/taskswitching/appb/AppBActivity.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 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.pts.taskswitching.appb;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.WindowManager;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * Simple activity to notify completion via broadcast after onResume.
+ * This is for measuring taskswitching time between two apps.
+ */
+public class AppBActivity extends ListActivity {
+    static final String TAG = "AppBActivity";
+    private static final int NUMBER_ELEMENTS = 1000;
+    private static final String TASKSWITCHING_INTENT = "com.android.pts.taskswitching.appb";
+    private Handler mHandler;
+
+    private String[] mItems = new String[NUMBER_ELEMENTS];
+
+    public void onCreate(Bundle icicle)
+    {
+        super.onCreate(icicle);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        for (int i = 0; i < NUMBER_ELEMENTS; i++) {
+            mItems[i] = "B" + Integer.toString(i);
+        }
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mItems));
+        ListView view = getListView();
+        mHandler = new Handler();
+    }
+
+    public void onResume()
+    {
+        super.onResume();
+        mHandler.post(new Runnable() {
+
+            @Override
+            public void run() {
+                Intent intent = new Intent(TASKSWITCHING_INTENT);
+                sendBroadcast(intent);
+            }
+        });
+    }
+}
diff --git a/suite/pts/hostTests/uihost/control/Android.mk b/suite/pts/hostTests/uihost/control/Android.mk
new file mode 100644
index 0000000..86ceb7c
--- /dev/null
+++ b/suite/pts/hostTests/uihost/control/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2012 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
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ptsutil ctsutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PtsDeviceTaskswitchingControl
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_PTS_PACKAGE)
diff --git a/suite/pts/hostTests/uihost/control/AndroidManifest.xml b/suite/pts/hostTests/uihost/control/AndroidManifest.xml
new file mode 100644
index 0000000..a7ab928
--- /dev/null
+++ b/suite/pts/hostTests/uihost/control/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.pts.taskswitching.control">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation
+        android:targetPackage="com.android.pts.taskswitching.control"
+        android:name="android.test.InstrumentationCtsTestRunner" />
+</manifest>
diff --git a/suite/pts/hostTests/uihost/control/src/com/android/pts/taskswitching/control/TaskswitchingDeviceTest.java b/suite/pts/hostTests/uihost/control/src/com/android/pts/taskswitching/control/TaskswitchingDeviceTest.java
new file mode 100644
index 0000000..fc5bc04
--- /dev/null
+++ b/suite/pts/hostTests/uihost/control/src/com/android/pts/taskswitching/control/TaskswitchingDeviceTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2012 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.pts.taskswitching.control;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.MeasureTime;
+import com.android.pts.util.PtsAndroidTestCase;
+import com.android.pts.util.Stat;
+
+
+/**
+ * Device test which actually launches two apps sequentially and
+ * measure time for switching.
+ * Completion of launch is notified via broadcast.
+ */
+public class TaskswitchingDeviceTest extends PtsAndroidTestCase {
+    private static final String PKG_A = "com.android.pts.taskswitching.appa";
+    private static final String PKG_B = "com.android.pts.taskswitching.appb";
+    private static final String ACTIVITY_A = "AppAActivity";
+    private static final String ACTIVITY_B = "AppBActivity";
+    private static final long TASK_SWITCHING_WAIT_TIME = 5;
+    private final AppBroadcastReceiver mReceiverA = new AppBroadcastReceiver();
+    private final AppBroadcastReceiver mReceiverB = new AppBroadcastReceiver();
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        startActivity(PKG_A, ACTIVITY_A);
+        startActivity(PKG_B, ACTIVITY_B);
+        IntentFilter filterA = new IntentFilter();
+        filterA.addAction(PKG_A);
+        IntentFilter filterB = new IntentFilter();
+        filterB.addAction(PKG_B);
+        getContext().registerReceiver(mReceiverA, filterA);
+        getContext().registerReceiver(mReceiverB, filterB);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        getContext().unregisterReceiver(mReceiverA);
+        getContext().unregisterReceiver(mReceiverB);
+        super.tearDown();
+    }
+
+    public void testMeasureTaskSwitching() throws Exception {
+        final int NUMBER_REPEAT = 10;
+        final int SWITCHING_PER_ONE_TRY = 10;
+
+        double[] results = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws Exception {
+                for (int j = 0; j < SWITCHING_PER_ONE_TRY; j++) {
+                    startActivity(PKG_A, ACTIVITY_A);
+                    assertTrue(mReceiverA.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
+                    startActivity(PKG_B, ACTIVITY_B);
+                    assertTrue(mReceiverB.waitForBroadcast(TASK_SWITCHING_WAIT_TIME));
+                }
+            }
+        });
+        getReportLog().printArray("ms", results, false);
+        Stat.StatResult stat = Stat.getStat(results);
+        getReportLog().printSummary("Time ms", stat.mAverage, stat.mStddev);
+    }
+
+    private void startActivity(String packageName, String activityName) {
+        Context context = getContext();
+        Intent intent = new Intent();
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addCategory(Intent.CATEGORY_LAUNCHER);
+        intent.setComponent(new ComponentName(packageName, packageName + "." + activityName));
+        context.startActivity(intent);
+    }
+
+    class AppBroadcastReceiver extends BroadcastReceiver {
+        private final Semaphore mSemaphore = new Semaphore(0);
+
+        public boolean waitForBroadcast(long timeoutInSec) throws InterruptedException {
+            return mSemaphore.tryAcquire(timeoutInSec, TimeUnit.SECONDS);
+        }
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mSemaphore.release();
+        }
+    }
+}
diff --git a/suite/pts/hostTests/uihost/src/com/android/pts/uihost/InstallTimeTest.java b/suite/pts/hostTests/uihost/src/com/android/pts/uihost/InstallTimeTest.java
new file mode 100644
index 0000000..4bfcde1
--- /dev/null
+++ b/suite/pts/hostTests/uihost/src/com/android/pts/uihost/InstallTimeTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 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.pts.uihost;
+
+import android.cts.util.TimeoutReq;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.MeasureTime;
+import com.android.pts.util.PtsException;
+import com.android.pts.util.ReportLog;
+import com.android.pts.util.Stat;
+import com.android.pts.util.Stat.StatResult;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.device.TestDeviceOptions;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.TestResult;
+import com.android.tradefed.result.TestRunResult;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ * Test to measure installation time of a APK.
+ */
+public class InstallTimeTest extends DeviceTestCase implements IBuildReceiver {
+    private static final String TAG = "InstallTimeTest";
+    private final static String CTS_RUNNER = "android.test.InstrumentationCtsTestRunner";
+    private CtsBuildHelper mBuild;
+    private ITestDevice mDevice;
+    private ReportLog mReport = null;
+
+    static final String PACKAGE = "com.replica.replicaisland";
+    static final String APK = "com.replica.replicaisland.apk";
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mReport = new ReportLog();
+        mDevice = getDevice();
+    }
+
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mDevice.uninstallPackage(PACKAGE);
+        mReport.throwReportToHost();
+    }
+
+    public void testInstallTime() throws Exception {
+        final int NUMBER_REPEAT = 10;
+        final CtsBuildHelper build = mBuild;
+        final ITestDevice device = mDevice;
+        double[] result = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
+            @Override
+            public void prepare(int i) throws Exception {
+                device.uninstallPackage(PACKAGE);
+            }
+            @Override
+            public void run(int i) throws Exception {
+                File app = build.getTestApp(APK);
+                device.installPackage(app, false);
+            }
+        });
+        mReport.printArray("time in ms", result, false);
+        StatResult stat = Stat.getStat(result);
+        mReport.printSummary("time in ms", stat.mAverage, stat.mStddev);
+    }
+
+}
diff --git a/suite/pts/hostTests/uihost/src/com/android/pts/uihost/TaskSwitchingTest.java b/suite/pts/hostTests/uihost/src/com/android/pts/uihost/TaskSwitchingTest.java
new file mode 100644
index 0000000..49d14a3
--- /dev/null
+++ b/suite/pts/hostTests/uihost/src/com/android/pts/uihost/TaskSwitchingTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2012 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.pts.uihost;
+
+import android.cts.util.TimeoutReq;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.MeasureTime;
+import com.android.pts.util.PtsException;
+import com.android.pts.util.Stat;
+import com.android.pts.util.Stat.StatResult;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.device.TestDeviceOptions;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.TestResult;
+import com.android.tradefed.result.TestRunResult;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ * Measure time to taskswitching between two Apps: A & B
+ * Actual test is done in device, but this host side code installs all necessary APKs
+ * and starts device test which is in PtsDeviceTaskswitchingControl.
+ */
+public class TaskSwitchingTest extends DeviceTestCase implements IBuildReceiver {
+    private static final String TAG = "TaskSwitchingTest";
+    private final static String CTS_RUNNER = "android.test.InstrumentationCtsTestRunner";
+    private CtsBuildHelper mBuild;
+    private ITestDevice mDevice;
+
+    static final String[] PACKAGES = {
+        "com.android.pts.taskswitching.control",
+        "com.android.pts.taskswitching.appa",
+        "com.android.pts.taskswitching.appb"
+    };
+    static final String[] APKS = {
+        "PtsDeviceTaskswitchingControl.apk",
+        "PtsDeviceTaskswitchingAppA.apk",
+        "PtsDeviceTaskswitchingAppB.apk"
+    };
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDevice = getDevice();
+        for (int i = 0; i < PACKAGES.length; i++) {
+            mDevice.uninstallPackage(PACKAGES[i]);
+            File app = mBuild.getTestApp(APKS[i]);
+            mDevice.installPackage(app, false);
+        }
+    }
+
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        for (int i = 0; i < PACKAGES.length; i++) {
+            mDevice.uninstallPackage(PACKAGES[i]);
+        }
+    }
+
+    @TimeoutReq(minutes = 30)
+    public void testTaskswitching() throws Exception {
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(PACKAGES[0], CTS_RUNNER,
+                mDevice.getIDevice());
+        CollectingTestListener listener = new CollectingTestListener();
+        mDevice.runInstrumentationTests(testRunner, listener);
+        TestRunResult result = listener.getCurrentRunResults();
+        if (result.isRunFailure()) {
+            fail(result.getRunFailureMessage());
+        }
+        Map<TestIdentifier, TestResult> details = result.getTestResults();
+        final String expectedException = "com.android.pts.util.PtsException";
+        for (Map.Entry<TestIdentifier, TestResult> entry : details.entrySet()) {
+            TestResult res = entry.getValue();
+            String stackTrace = res.getStackTrace();
+            if (stackTrace != null) {
+                if (stackTrace.startsWith(expectedException)) {
+                    String[] lines = stackTrace.split("[\r\n]+");
+                    String msg = lines[0].substring(expectedException.length() + 1).trim();
+                    throw new PtsException(msg);
+                }
+            }
+        }
+        fail("no performance data");
+    }
+
+}
diff --git a/tests/res/drawable/icon_black.jpg b/tests/res/drawable/icon_black.jpg
new file mode 100644
index 0000000..4c9062a
--- /dev/null
+++ b/tests/res/drawable/icon_black.jpg
Binary files differ
diff --git a/tests/res/drawable/icon_blue.jpg b/tests/res/drawable/icon_blue.jpg
new file mode 100644
index 0000000..9e6c1c8
--- /dev/null
+++ b/tests/res/drawable/icon_blue.jpg
Binary files differ
diff --git a/tests/res/drawable/icon_green.jpg b/tests/res/drawable/icon_green.jpg
new file mode 100644
index 0000000..55a78f2
--- /dev/null
+++ b/tests/res/drawable/icon_green.jpg
Binary files differ
diff --git a/tests/res/drawable/icon_red.jpg b/tests/res/drawable/icon_red.jpg
new file mode 100644
index 0000000..6bc9e1f
--- /dev/null
+++ b/tests/res/drawable/icon_red.jpg
Binary files differ
diff --git a/tests/res/drawable/icon_yellow.jpg b/tests/res/drawable/icon_yellow.jpg
new file mode 100644
index 0000000..e748059
--- /dev/null
+++ b/tests/res/drawable/icon_yellow.jpg
Binary files differ
diff --git a/tests/res/layout/textview_layout.xml b/tests/res/layout/textview_layout.xml
index 512184f..5aea538 100644
--- a/tests/res/layout/textview_layout.xml
+++ b/tests/res/layout/textview_layout.xml
@@ -96,4 +96,120 @@
               android:layout_height="wrap_content"
               android:layout_width="wrap_content"/>
 
+    <TextView android:id="@+id/textview_drawable_1_1"
+              android:layout_height="wrap_content"
+              android:layout_width="wrap_content"
+              android:drawableLeft="@drawable/icon_blue"
+              android:drawableRight="@drawable/icon_red"
+              android:drawableTop="@drawable/icon_green"
+              android:drawableBottom="@drawable/icon_yellow"
+            />
+
+    <TextView android:id="@+id/textview_drawable_1_2"
+              android:layout_height="wrap_content"
+              android:layout_width="wrap_content"
+              android:drawableLeft="@drawable/icon_blue"
+              android:drawableRight="@drawable/icon_red"
+              android:drawableTop="@drawable/icon_green"
+              android:drawableBottom="@drawable/icon_yellow"
+              android:layoutDirection="rtl"
+            />
+
+    <TextView android:id="@+id/textview_drawable_2_1"
+              android:layout_height="wrap_content"
+              android:layout_width="wrap_content"
+              android:drawableStart="@drawable/icon_blue"
+              android:drawableEnd="@drawable/icon_red"
+              android:drawableTop="@drawable/icon_green"
+              android:drawableBottom="@drawable/icon_yellow"
+            />
+
+    <TextView android:id="@+id/textview_drawable_2_2"
+              android:layout_height="wrap_content"
+              android:layout_width="wrap_content"
+              android:drawableStart="@drawable/icon_blue"
+              android:drawableEnd="@drawable/icon_red"
+              android:drawableTop="@drawable/icon_green"
+              android:drawableBottom="@drawable/icon_yellow"
+              android:layoutDirection="rtl"
+            />
+
+    <TextView android:id="@+id/textview_drawable_3_1"
+              android:layout_height="wrap_content"
+              android:layout_width="wrap_content"
+              android:drawableLeft="@drawable/icon_black"
+              android:drawableRight="@drawable/icon_black"
+              android:drawableStart="@drawable/icon_blue"
+              android:drawableEnd="@drawable/icon_red"
+              android:drawableTop="@drawable/icon_green"
+              android:drawableBottom="@drawable/icon_yellow"
+            />
+
+    <TextView android:id="@+id/textview_drawable_3_2"
+              android:layout_height="wrap_content"
+              android:layout_width="wrap_content"
+              android:drawableLeft="@drawable/icon_black"
+              android:drawableRight="@drawable/icon_black"
+              android:drawableStart="@drawable/icon_blue"
+              android:drawableEnd="@drawable/icon_red"
+              android:drawableTop="@drawable/icon_green"
+              android:drawableBottom="@drawable/icon_yellow"
+              android:layoutDirection="rtl"
+            />
+
+
+    <LinearLayout android:orientation="vertical"
+                  android:layout_width="match_parent"
+                  android:layout_height="match_parent"
+                  android:layoutDirection="ltr">
+
+        <TextView android:id="@+id/textview_drawable_4_1"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:drawableStart="@drawable/icon_blue"
+                  android:drawableEnd="@drawable/icon_red"
+                  android:drawableTop="@drawable/icon_green"
+                  android:drawableBottom="@drawable/icon_yellow"
+                />
+
+        <TextView android:id="@+id/textview_drawable_5_1"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:drawableLeft="@drawable/icon_black"
+                  android:drawableRight="@drawable/icon_black"
+                  android:drawableStart="@drawable/icon_blue"
+                  android:drawableEnd="@drawable/icon_red"
+                  android:drawableTop="@drawable/icon_green"
+                  android:drawableBottom="@drawable/icon_yellow"
+                />
+
+    </LinearLayout>
+
+    <LinearLayout android:orientation="vertical"
+                  android:layout_width="match_parent"
+                  android:layout_height="match_parent"
+                  android:layoutDirection="rtl">
+
+        <TextView android:id="@+id/textview_drawable_4_2"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:drawableStart="@drawable/icon_blue"
+                  android:drawableEnd="@drawable/icon_red"
+                  android:drawableTop="@drawable/icon_green"
+                  android:drawableBottom="@drawable/icon_yellow"
+                />
+
+        <TextView android:id="@+id/textview_drawable_5_2"
+                  android:layout_height="wrap_content"
+                  android:layout_width="wrap_content"
+                  android:drawableLeft="@drawable/icon_black"
+                  android:drawableRight="@drawable/icon_black"
+                  android:drawableStart="@drawable/icon_blue"
+                  android:drawableEnd="@drawable/icon_red"
+                  android:drawableTop="@drawable/icon_green"
+                  android:drawableBottom="@drawable/icon_yellow"
+                />
+
+    </LinearLayout>
+
 </LinearLayout>
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 7408301..283f63b 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -55,9 +55,10 @@
 
     private static final int STATE_NULL = 0;
     private static final int STATE_WIFI_CHANGING = 1;
-    private static final int STATE_WIFI_CHANGED = 2;
-    private static final int STATE_SCANING = 3;
-    private static final int STATE_SCAN_RESULTS_AVAILABLE = 4;
+    private static final int STATE_WIFI_ENABLED = 2;
+    private static final int STATE_WIFI_DISABLED = 3;
+    private static final int STATE_SCANNING = 4;
+    private static final int STATE_SCAN_RESULTS_AVAILABLE = 5;
 
     private static final String TAG = "WifiManagerTest";
     private static final String SSID1 = "\"WifiManagerTest\"";
@@ -76,20 +77,29 @@
                         mScanResult = mWifiManager.getScanResults();
                         mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE;
                         mScanResult = mWifiManager.getScanResults();
-                        mMySync.notify();
+                        mMySync.notifyAll();
                     }
                 }
-            } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
+            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+                int newState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                        WifiManager.WIFI_STATE_UNKNOWN);
                 synchronized (mMySync) {
-                    mMySync.expectedState = STATE_WIFI_CHANGED;
-                    mMySync.notify();
+                    if (newState == WifiManager.WIFI_STATE_ENABLED) {
+                        Log.d(TAG, "*** New WiFi state is ENABLED ***");
+                        mMySync.expectedState = STATE_WIFI_ENABLED;
+                        mMySync.notifyAll();
+                    } else if (newState == WifiManager.WIFI_STATE_DISABLED) {
+                        Log.d(TAG, "*** New WiFi state is DISABLED ***");
+                        mMySync.expectedState = STATE_WIFI_DISABLED;
+                        mMySync.notifyAll();
+                    }
                 }
             } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                 synchronized (mMySync) {
                     mNetworkInfo =
                             (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                     if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED)
-                        mMySync.notify();
+                        mMySync.notifyAll();
                 }
             }
         }
@@ -122,7 +132,9 @@
             setWifiEnabled(true);
         Thread.sleep(DURATION);
         assertTrue(mWifiManager.isWifiEnabled());
-        mMySync.expectedState = STATE_NULL;
+        synchronized (mMySync) {
+            mMySync.expectedState = STATE_NULL;
+        }
     }
 
     @Override
@@ -132,31 +144,34 @@
             super.tearDown();
             return;
         }
-        mWifiLock.release();
-        mContext.unregisterReceiver(mReceiver);
         if (!mWifiManager.isWifiEnabled())
             setWifiEnabled(true);
+        mWifiLock.release();
+        mContext.unregisterReceiver(mReceiver);
         Thread.sleep(DURATION);
         super.tearDown();
     }
 
     private void setWifiEnabled(boolean enable) throws Exception {
         synchronized (mMySync) {
-            mMySync.expectedState = STATE_WIFI_CHANGING;
             assertTrue(mWifiManager.setWifiEnabled(enable));
-            long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-            while (System.currentTimeMillis() < timeout
-                    && mMySync.expectedState == STATE_WIFI_CHANGING)
-                mMySync.wait(WAIT_MSEC);
+            if (mWifiManager.isWifiEnabled() != enable) {
+                mMySync.expectedState = STATE_WIFI_CHANGING;
+                long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+                int expectedState = (enable ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED);
+                while (System.currentTimeMillis() < timeout
+                        && mMySync.expectedState != expectedState)
+                    mMySync.wait(WAIT_MSEC);
+            }
         }
     }
 
     private void startScan() throws Exception {
         synchronized (mMySync) {
-            mMySync.expectedState = STATE_SCANING;
+            mMySync.expectedState = STATE_SCANNING;
             assertTrue(mWifiManager.startScan());
             long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-            while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANING)
+            while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANNING)
                 mMySync.wait(WAIT_MSEC);
         }
     }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
index 1138233..17182c2 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
@@ -98,6 +98,7 @@
         // Insert an audio file into the content provider.
         ContentValues values = Audio1.getInstance().getContentValues(true);
         Uri audioUri = mContentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
+        assertNotNull(audioUri);
         long audioId = ContentUris.parseId(audioUri);
         assertTrue(audioId != -1);
 
@@ -105,6 +106,7 @@
         values.clear();
         values.put(Genres.NAME, "Soda Pop");
         Uri genreUri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+        assertNotNull(genreUri);
         long genreId = ContentUris.parseId(genreUri);
         assertTrue(genreId != -1);
 
@@ -131,6 +133,8 @@
             if (cursor != null) {
                 cursor.close();
             }
+            assertEquals(1, mContentResolver.delete(audioUri, null, null));
+            assertEquals(1, mContentResolver.delete(genreUri, null, null));
         }
     }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index fa269e4..95abee7 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -294,6 +294,7 @@
         } finally {
             // delete
             assertEquals(1, mContentResolver.delete(uri, null, null));
+            new File(externalPath).delete();
         }
     }
 
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
index 2a4b46c..8f6f729 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
@@ -99,6 +99,8 @@
             assertFalse("thumbnail file should no longer exist", new File(path).exists());
         }
         c.close();
+
+        assertEquals(1, mResolver.delete(videoUri, null, null));
     }
 
     private Uri insertVideo() throws IOException {
diff --git a/tests/tests/security/src/android/security/cts/BannedFilesTest.java b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
index 4409e49..6ce8588 100644
--- a/tests/tests/security/src/android/security/cts/BannedFilesTest.java
+++ b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
@@ -22,6 +22,18 @@
 
 public class BannedFilesTest extends TestCase {
 
+    /**
+     * Detect devices vulnerable to the cmdclient privilege escalation bug.
+     *
+     * References:
+     *
+     * http://vulnfactory.org/blog/2012/02/18/xoom-fe-stupid-bugs-and-more-plagiarism/
+     * http://forum.xda-developers.com/showthread.php?t=1213014
+     */
+    public void testNoCmdClient() {
+        assertNotSetugid("/system/bin/cmdclient");
+    }
+
     public void testNoSyncAgent() {
         assertNotSetugid("/system/bin/sync_agent");
     }
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 01d58ae..4857112 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -33,6 +33,8 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.StrictMode;
+import android.os.StrictMode.ThreadPolicy;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
@@ -122,6 +124,18 @@
         mWebServer = new CtsTestServer(getActivity(), secure);
     }
 
+    private void stopWebServer() throws Exception {
+        assertNotNull(mWebServer);
+        ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
+        ThreadPolicy tmpPolicy = new ThreadPolicy.Builder(oldPolicy)
+                .permitNetwork()
+                .build();
+        StrictMode.setThreadPolicy(tmpPolicy);
+        mWebServer.shutdown();
+        mWebServer = null;
+        StrictMode.setThreadPolicy(oldPolicy);
+    }
+
     @UiThreadTest
     public void testConstructor() {
         new WebView(getActivity());
@@ -1437,21 +1451,30 @@
     }
 
     @UiThreadTest
-    public void testSetAndGetCertificate() {
-        assertNull(mWebView.getCertificate());
-        SslCertificate certificate = new SslCertificate("foo", "bar", new Date(42), new Date(43));
-        mWebView.setCertificate(certificate);
-        assertEquals(certificate, mWebView.getCertificate());
-    }
-
-    @UiThreadTest
     public void testInsecureSiteClearsCertificate() throws Throwable {
-        final SslCertificate certificate =
-                new SslCertificate("foo", "bar", new Date(42), new Date(43));
+        final class MockWebViewClient extends WaitForLoadedClient {
+            public MockWebViewClient() {
+                super(mOnUiThread);
+            }
+            @Override
+            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
+                handler.proceed();
+            }
+        }
+
+        startWebServer(true);
+        mOnUiThread.setWebViewClient(new MockWebViewClient());
+        mOnUiThread.loadUrlAndWaitForCompletion(
+                mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
+        SslCertificate cert = mWebView.getCertificate();
+        assertNotNull(cert);
+        assertEquals("Android", cert.getIssuedTo().getUName());
+
+        stopWebServer();
+
         startWebServer(false);
-        final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
-        mWebView.setCertificate(certificate);
-        mOnUiThread.loadUrlAndWaitForCompletion(url);
+        mOnUiThread.loadUrlAndWaitForCompletion(
+                mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
         assertNull(mWebView.getCertificate());
     }
 
@@ -1467,11 +1490,17 @@
             }
         }
 
+        startWebServer(false);
+        mOnUiThread.loadUrlAndWaitForCompletion(
+                mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
+        assertNull(mWebView.getCertificate());
+
+        stopWebServer();
+
         startWebServer(true);
-        final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
         mOnUiThread.setWebViewClient(new MockWebViewClient());
-        mWebView.setCertificate(null);
-        mOnUiThread.loadUrlAndWaitForCompletion(url);
+        mOnUiThread.loadUrlAndWaitForCompletion(
+                mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
         SslCertificate cert = mWebView.getCertificate();
         assertNotNull(cert);
         assertEquals("Android", cert.getIssuedTo().getUName());
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index b4279f2..9080320 100755
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -3279,6 +3279,150 @@
         assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
     }
 
+    @UiThreadTest
+    public void testDrawableResolution() {
+        final int LEFT = 0;
+        final int TOP = 1;
+        final int RIGHT = 2;
+        final int BOTTOM = 3;
+
+        TextViewStubActivity activity = getActivity();
+
+        // Case 1.1: left / right drawable defined in default LTR mode
+        TextView tv = (TextView) activity.findViewById(R.id.textview_drawable_1_1);
+        Drawable[] drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+
+        // Case 1.2: left / right drawable defined in default RTL mode
+        tv = (TextView) activity.findViewById(R.id.textview_drawable_1_2);
+        drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+
+        // Case 2.1: start / end drawable defined in LTR mode
+        tv = (TextView) activity.findViewById(R.id.textview_drawable_2_1);
+        drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+
+        // Case 2.2: start / end drawable defined in RTL mode
+        tv = (TextView) activity.findViewById(R.id.textview_drawable_2_2);
+        drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+
+        // Case 3.1: left / right / start / end drawable defined in LTR mode
+        tv = (TextView) activity.findViewById(R.id.textview_drawable_3_1);
+        drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+
+        // Case 3.2: left / right / start / end drawable defined in RTL mode
+        tv = (TextView) activity.findViewById(R.id.textview_drawable_3_2);
+        drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+
+        // Case 4.1: start / end drawable defined in LTR mode inside a layout
+        // that defines the layout direction
+        tv = (TextView) activity.findViewById(R.id.textview_drawable_4_1);
+        drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+
+        // Case 4.2: start / end drawable defined in RTL mode inside a layout
+        // that defines the layout direction
+        tv = (TextView) activity.findViewById(R.id.textview_drawable_4_2);
+        drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+
+        // Case 5.1: left / right / start / end drawable defined in LTR mode inside a layout
+        // that defines the layout direction
+        tv = (TextView) activity.findViewById(R.id.textview_drawable_3_1);
+        drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+
+        // Case 5.2: left / right / start / end drawable defined in RTL mode inside a layout
+        // that defines the layout direction
+        tv = (TextView) activity.findViewById(R.id.textview_drawable_3_2);
+        drawables = tv.getCompoundDrawables();
+
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_red),
+                ((BitmapDrawable) drawables[LEFT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_blue),
+                ((BitmapDrawable) drawables[RIGHT]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_green),
+                ((BitmapDrawable) drawables[TOP]).getBitmap());
+        WidgetTestUtils.assertEquals(getBitmap(R.drawable.icon_yellow),
+                ((BitmapDrawable) drawables[BOTTOM]).getBitmap());
+    }
+
     private static class MockOnEditorActionListener implements OnEditorActionListener {
         private boolean isOnEditorActionCalled;