Backporting shortcut manager CTS to mr1

Bug 29612099

Change-Id: I620c7190b17c4ff9abd9f20f06ac0ab3d9cb7c3a
diff --git a/hostsidetests/shortcuts/deviceside/Android.mk b/hostsidetests/shortcuts/deviceside/Android.mk
new file mode 100644
index 0000000..3d02f9c
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/Android.mk
@@ -0,0 +1,17 @@
+# Copyright (C) 2016 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 $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/shortcuts/deviceside/backup/Android.mk b/hostsidetests/shortcuts/deviceside/backup/Android.mk
new file mode 100644
index 0000000..3d02f9c
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/Android.mk
@@ -0,0 +1,17 @@
+# Copyright (C) 2016 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 $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher1/Android.mk b/hostsidetests/shortcuts/deviceside/backup/launcher1/Android.mk
new file mode 100644
index 0000000..a463b59
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher1/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2016 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)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsShortcutBackupLauncher1
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../../common/src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target-minus-junit4 \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher1/AndroidManifest.xml b/hostsidetests/shortcuts/deviceside/backup/launcher1/AndroidManifest.xml
new file mode 100644
index 0000000..75b3ca0
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher1/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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="android.content.pm.cts.shortcut.backup.launcher1">
+
+    <application>
+        <activity android:name="MainActivity" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.HOME" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.content.pm.cts.shortcut.backup.launcher1"  />
+</manifest>
+
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher1/src/android/content/pm/cts/shortcut/backup/launcher1/MainActivity.java b/hostsidetests/shortcuts/deviceside/backup/launcher1/src/android/content/pm/cts/shortcut/backup/launcher1/MainActivity.java
new file mode 100644
index 0000000..3d8a1de
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher1/src/android/content/pm/cts/shortcut/backup/launcher1/MainActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.launcher1;
+
+import android.app.Activity;
+
+public class MainActivity extends Activity {
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher1/src/android/content/pm/cts/shortcut/backup/launcher1/ShortcutManagerPostBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/launcher1/src/android/content/pm/cts/shortcut/backup/launcher1/ShortcutManagerPostBackupTest.java
new file mode 100644
index 0000000..b82bb1d
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher1/src/android/content/pm/cts/shortcut/backup/launcher1/ShortcutManagerPostBackupTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.launcher1;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+
+public class ShortcutManagerPostBackupTest extends ShortcutManagerDeviceTestBase {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        setAsDefaultLauncher(MainActivity.class);
+    }
+
+    public void testWithUninstall_beforeAppRestore() {
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER1_PKG)).isEmpty();
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER2_PKG)).isEmpty();
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER3_PKG)).isEmpty();
+    }
+
+    public void testWithUninstall_afterAppRestore() {
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER1_PKG))
+                .haveIds("ms1", "ms2", "s1")
+                .areAllEnabled()
+
+                .selectByIds("s1", "ms1")
+                .areAllPinned()
+
+                .revertToOriginalList()
+                .selectByIds("ms2")
+                .areAllNotPinned();
+
+        // Note s3 and ms2 were disabled before backup, so they were not backed up.
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER2_PKG))
+                .haveIds("ms1", "ms2", "s1", "s2")
+                .areAllEnabled()
+
+                .selectByIds("s1", "s2")
+                .areAllPinned()
+
+                .revertToOriginalList()
+                .selectByIds("ms1")
+                .areAllNotPinned();
+
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER3_PKG))
+                .haveIds("ms1", "ms2")
+                .areAllEnabled()
+                .areAllNotPinned(); // P3 doesn't get backed up, so no longer pinned.
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher1/src/android/content/pm/cts/shortcut/backup/launcher1/ShortcutManagerPreBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/launcher1/src/android/content/pm/cts/shortcut/backup/launcher1/ShortcutManagerPreBackupTest.java
new file mode 100644
index 0000000..56639ce
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher1/src/android/content/pm/cts/shortcut/backup/launcher1/ShortcutManagerPreBackupTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.launcher1;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public class ShortcutManagerPreBackupTest extends ShortcutManagerDeviceTestBase {
+    static final String PUBLISHER1_PKG =
+            "android.content.pm.cts.shortcut.backup.publisher1";
+    static final String PUBLISHER2_PKG =
+            "android.content.pm.cts.shortcut.backup.publisher2";
+    static final String PUBLISHER3_PKG =
+            "android.content.pm.cts.shortcut.backup.publisher3";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        setAsDefaultLauncher(MainActivity.class);
+    }
+
+    public void testPreBackup() {
+        getLauncherApps().pinShortcuts(PUBLISHER1_PKG, list("s1", "ms1"), getUserHandle());
+        getLauncherApps().pinShortcuts(PUBLISHER2_PKG, list("s1", "s2", "ms2"), getUserHandle());
+        getLauncherApps().pinShortcuts(PUBLISHER3_PKG, list("s1", "s2", "ms1", "ms2"),
+                getUserHandle());
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher2/Android.mk b/hostsidetests/shortcuts/deviceside/backup/launcher2/Android.mk
new file mode 100644
index 0000000..2f37101
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher2/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2016 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)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsShortcutBackupLauncher2
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../../common/src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target-minus-junit4 \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher2/AndroidManifest.xml b/hostsidetests/shortcuts/deviceside/backup/launcher2/AndroidManifest.xml
new file mode 100644
index 0000000..71ffc61
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher2/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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="android.content.pm.cts.shortcut.backup.launcher2">
+
+    <application>
+        <activity android:name="MainActivity" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.HOME" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.content.pm.cts.shortcut.backup.launcher2"  />
+</manifest>
+
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher2/src/android/content/pm/cts/shortcut/backup/launcher2/MainActivity.java b/hostsidetests/shortcuts/deviceside/backup/launcher2/src/android/content/pm/cts/shortcut/backup/launcher2/MainActivity.java
new file mode 100644
index 0000000..f418ea1
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher2/src/android/content/pm/cts/shortcut/backup/launcher2/MainActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.launcher2;
+
+import android.app.Activity;
+
+public class MainActivity extends Activity {
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher2/src/android/content/pm/cts/shortcut/backup/launcher2/ShortcutManagerPostBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/launcher2/src/android/content/pm/cts/shortcut/backup/launcher2/ShortcutManagerPostBackupTest.java
new file mode 100644
index 0000000..75c79c5
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher2/src/android/content/pm/cts/shortcut/backup/launcher2/ShortcutManagerPostBackupTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.launcher2;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+
+public class ShortcutManagerPostBackupTest extends ShortcutManagerDeviceTestBase {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        setAsDefaultLauncher(MainActivity.class);
+    }
+
+    public void testWithUninstall_afterAppRestore() {
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER1_PKG))
+                .haveIds("ms1", "ms2", "s3")
+                .areAllEnabled()
+
+                .selectByIds("s3", "ms2")
+                .areAllPinned()
+
+                .revertToOriginalList()
+                .selectByIds("ms1")
+                .areAllNotPinned();
+
+        // Note s3 and ms2 were disabled before backup, so they were not backed up.
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER2_PKG))
+                .haveIds("ms1", "ms2", "s2")
+                .areAllEnabled()
+
+                .selectByIds("s2", "ms1")
+                .areAllPinned()
+
+                .revertToOriginalList()
+                .selectByIds("ms2")
+                .areAllNotPinned();
+
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER3_PKG))
+                .haveIds("ms1", "ms2")
+                .areAllEnabled();
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher2/src/android/content/pm/cts/shortcut/backup/launcher2/ShortcutManagerPreBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/launcher2/src/android/content/pm/cts/shortcut/backup/launcher2/ShortcutManagerPreBackupTest.java
new file mode 100644
index 0000000..b0e0e2c
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher2/src/android/content/pm/cts/shortcut/backup/launcher2/ShortcutManagerPreBackupTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.launcher2;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public class ShortcutManagerPreBackupTest extends ShortcutManagerDeviceTestBase {
+    static final String PUBLISHER1_PKG =
+            "android.content.pm.cts.shortcut.backup.publisher1";
+    static final String PUBLISHER2_PKG =
+            "android.content.pm.cts.shortcut.backup.publisher2";
+    static final String PUBLISHER3_PKG =
+            "android.content.pm.cts.shortcut.backup.publisher3";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        setAsDefaultLauncher(MainActivity.class);
+    }
+
+    public void testPreBackup() {
+        getLauncherApps().pinShortcuts(PUBLISHER1_PKG, list("s3", "ms2"), getUserHandle());
+        getLauncherApps().pinShortcuts(PUBLISHER2_PKG, list("s2", "s3", "ms1"), getUserHandle());
+        getLauncherApps().pinShortcuts(PUBLISHER3_PKG, list("s2", "s3", "ms1", "ms2"),
+                getUserHandle());
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher3/Android.mk b/hostsidetests/shortcuts/deviceside/backup/launcher3/Android.mk
new file mode 100644
index 0000000..3bbd906
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher3/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2016 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)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsShortcutBackupLauncher3
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../../common/src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target-minus-junit4 \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher3/AndroidManifest.xml b/hostsidetests/shortcuts/deviceside/backup/launcher3/AndroidManifest.xml
new file mode 100644
index 0000000..82dc28f
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher3/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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="android.content.pm.cts.shortcut.backup.launcher3">
+
+    <application android:allowBackup="false">
+        <activity android:name="MainActivity" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.HOME" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.content.pm.cts.shortcut.backup.launcher3"  />
+</manifest>
+
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher3/src/android/content/pm/cts/shortcut/backup/launcher3/MainActivity.java b/hostsidetests/shortcuts/deviceside/backup/launcher3/src/android/content/pm/cts/shortcut/backup/launcher3/MainActivity.java
new file mode 100644
index 0000000..064a881
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher3/src/android/content/pm/cts/shortcut/backup/launcher3/MainActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.launcher3;
+
+import android.app.Activity;
+
+public class MainActivity extends Activity {
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher3/src/android/content/pm/cts/shortcut/backup/launcher3/ShortcutManagerPostBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/launcher3/src/android/content/pm/cts/shortcut/backup/launcher3/ShortcutManagerPostBackupTest.java
new file mode 100644
index 0000000..3945a2b
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher3/src/android/content/pm/cts/shortcut/backup/launcher3/ShortcutManagerPostBackupTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.launcher3;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+
+public class ShortcutManagerPostBackupTest extends ShortcutManagerDeviceTestBase {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        setAsDefaultLauncher(MainActivity.class);
+    }
+
+    public void testWithUninstall_afterAppRestore() {
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER1_PKG))
+                .haveIds("ms1", "ms2")
+                .areAllEnabled()
+                .areAllNotPinned();
+
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER2_PKG))
+                .haveIds("ms1", "ms2")
+                .areAllEnabled();
+
+        assertWith(getPackageShortcuts(ShortcutManagerPreBackupTest.PUBLISHER3_PKG))
+                .haveIds("ms1", "ms2")
+                .areAllEnabled();
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/launcher3/src/android/content/pm/cts/shortcut/backup/launcher3/ShortcutManagerPreBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/launcher3/src/android/content/pm/cts/shortcut/backup/launcher3/ShortcutManagerPreBackupTest.java
new file mode 100644
index 0000000..2638df3
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/launcher3/src/android/content/pm/cts/shortcut/backup/launcher3/ShortcutManagerPreBackupTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.launcher3;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public class ShortcutManagerPreBackupTest extends ShortcutManagerDeviceTestBase {
+    static final String PUBLISHER1_PKG =
+            "android.content.pm.cts.shortcut.backup.publisher1";
+    static final String PUBLISHER2_PKG =
+            "android.content.pm.cts.shortcut.backup.publisher2";
+    static final String PUBLISHER3_PKG =
+            "android.content.pm.cts.shortcut.backup.publisher3";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        setAsDefaultLauncher(MainActivity.class);
+    }
+
+    public void testPreBackup() {
+        getLauncherApps().pinShortcuts(PUBLISHER1_PKG, list("s3", "ms1", "ms2"), getUserHandle());
+        getLauncherApps().pinShortcuts(PUBLISHER2_PKG, list("s1", "s3", "ms2"), getUserHandle());
+        getLauncherApps().pinShortcuts(PUBLISHER3_PKG, list("s1", "s3", "ms1"),
+                getUserHandle());
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/Android.mk b/hostsidetests/shortcuts/deviceside/backup/publisher1/Android.mk
new file mode 100644
index 0000000..2ac759a
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2016 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)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsShortcutBackupPublisher1
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../../common/src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target-minus-junit4 \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/AndroidManifest.xml b/hostsidetests/shortcuts/deviceside/backup/publisher1/AndroidManifest.xml
new file mode 100644
index 0000000..3d23c72
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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="android.content.pm.cts.shortcut.backup.publisher1">
+
+    <application>
+        <activity android:name="MainActivity" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/>
+        </activity>
+        <activity-alias android:name="MainActivity2"
+            android:targetActivity="android.content.pm.cts.shortcut.backup.publisher1.MainActivity"
+            android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity-alias>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.content.pm.cts.shortcut.backup.publisher1"  />
+</manifest>
+
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/res/drawable-nodpi/black_16x16.png b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/drawable-nodpi/black_16x16.png
new file mode 100644
index 0000000..a26da5c
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/drawable-nodpi/black_16x16.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/res/drawable-nodpi/black_16x64.png b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/drawable-nodpi/black_16x64.png
new file mode 100644
index 0000000..ed049fa
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/drawable-nodpi/black_16x64.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/res/drawable-nodpi/black_64x16.png b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/drawable-nodpi/black_64x16.png
new file mode 100644
index 0000000..a0983c7
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/drawable-nodpi/black_64x16.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/res/values/strings.xml b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/values/strings.xml
new file mode 100644
index 0000000..068c991
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/values/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="label1">Shortcut 1</string>
+    <string name="long_label1">Long shortcut label1</string>
+    <string name="disabled_message1">Shortcut 1 is disabled</string>
+
+    <string name="label2">Shortcut 2</string>
+    <string name="long_label2">Long shortcut label2</string>
+    <string name="disabled_message2">Shortcut 2 is disabled</string>
+
+    <string name="label3">Shortcut 3</string>
+    <string name="long_label3">Long shortcut label3</string>
+    <string name="disabled_message3">Shortcut 3 is disabled</string>
+
+    <string name="label4">Shortcut 4</string>
+    <string name="long_label4">Long shortcut label4</string>
+    <string name="disabled_message4">Shortcut 4 is disabled</string>
+
+    <string name="label5">Shortcut 5</string>
+    <string name="long_label5">Long shortcut label5</string>
+    <string name="disabled_message5">Shortcut 5 is disabled</string>
+</resources>
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/res/xml/shortcuts.xml b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/xml/shortcuts.xml
new file mode 100644
index 0000000..1b4661b
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/res/xml/shortcuts.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
+    <shortcut
+        android:shortcutId="ms1"
+        android:icon="@drawable/black_16x16"
+        android:shortcutShortLabel="@string/label1"
+        android:shortcutLongLabel="@string/long_label1"
+        android:shortcutDisabledMessage="@string/disabled_message1">
+        <intent
+            android:action="android.intent.action.VIEW" />
+        <categories android:name="android.shortcut.conversation" />
+        <categories android:name="android.shortcut.media" />
+    </shortcut>
+    <shortcut
+        android:shortcutId="ms2"
+        android:shortcutShortLabel="@string/label2">
+        <intent android:action="action" />
+        <intent android:action="action2"
+            android:data="data"
+            android:mimeType="a/b"
+            android:targetPackage="pkg"
+            android:targetClass="pkg.class"
+            >
+            <categories android:name="icat1"/>
+            <categories android:name="icat2"/>
+            <extra android:name="key1" android:value="value1" />
+            <extra android:name="key2" android:value="123" />
+            <extra android:name="key3" android:value="true" />
+        </intent>
+    </shortcut>
+</shortcuts>
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/src/android/content/pm/cts/shortcut/backup/publisher1/MainActivity.java b/hostsidetests/shortcuts/deviceside/backup/publisher1/src/android/content/pm/cts/shortcut/backup/publisher1/MainActivity.java
new file mode 100644
index 0000000..95c75e6
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/src/android/content/pm/cts/shortcut/backup/publisher1/MainActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher1;
+
+import android.app.Activity;
+
+public class MainActivity extends Activity {
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/src/android/content/pm/cts/shortcut/backup/publisher1/ShortcutManagerPostBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/publisher1/src/android/content/pm/cts/shortcut/backup/publisher1/ShortcutManagerPostBackupTest.java
new file mode 100644
index 0000000..2129482
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/src/android/content/pm/cts/shortcut/backup/publisher1/ShortcutManagerPostBackupTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher1;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+
+public class ShortcutManagerPostBackupTest extends ShortcutManagerDeviceTestBase {
+    public void testWithUninstall() {
+        assertWith(getManager().getDynamicShortcuts())
+                .isEmpty();
+
+        assertWith(getManager().getPinnedShortcuts())
+                .haveIds("s1", "s3", "ms1", "ms2")
+                .areAllEnabled();
+
+        assertWith(getManager().getManifestShortcuts())
+                .haveIds("ms1", "ms2")
+                .areAllPinned()
+                .areAllEnabled();
+    }
+
+    public void testWithNoUninstall() {
+        // Ideally this shouldn't be cleared, but for now it will be.
+//        assertWith(getManager().getDynamicShortcuts())
+//                .isEmpty();
+
+        assertWith(getManager().getPinnedShortcuts())
+                .isEmpty();
+
+        // Should still have the manifest shortcuts.
+        assertWith(getManager().getManifestShortcuts())
+                .haveIds("ms1", "ms2")
+                .areAllEnabled();
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher1/src/android/content/pm/cts/shortcut/backup/publisher1/ShortcutManagerPreBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/publisher1/src/android/content/pm/cts/shortcut/backup/publisher1/ShortcutManagerPreBackupTest.java
new file mode 100644
index 0000000..22b63e7
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher1/src/android/content/pm/cts/shortcut/backup/publisher1/ShortcutManagerPreBackupTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher1;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makePersistableBundle;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
+
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.Icon;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public class ShortcutManagerPreBackupTest extends ShortcutManagerDeviceTestBase {
+    public void testPreBackup() {
+        final Icon icon1 = Icon.createWithBitmap(BitmapFactory.decodeResource(
+                getContext().getResources(), R.drawable.black_16x64));
+        final Icon icon3 = Icon.createWithResource(getContext(), R.drawable.black_64x16);
+
+        final ShortcutInfo s1 = new ShortcutInfo.Builder(getContext(), "s1")
+                .setShortLabel("shortlabel1")
+                .setLongLabel("longlabel1")
+                .setIcon(icon1)
+                .setActivity(getActivity("MainActivity"))
+                .setDisabledMessage("disabledmessage1")
+                .setIntents(new Intent[]{new Intent("view").putExtra("k1", "v1")})
+                .setExtras(makePersistableBundle("ek1", "ev1"))
+                .setCategories(set("cat1"))
+                .build();
+
+        final ShortcutInfo s2 = new ShortcutInfo.Builder(getContext(), "s2")
+                .setShortLabel("shortlabel2")
+                .setActivity(getActivity("MainActivity2"))
+                .setIntents(new Intent[]{new Intent("main")})
+                .build();
+
+        final ShortcutInfo s3 = new ShortcutInfo.Builder(getContext(), "s3")
+                .setShortLabel("shortlabel2")
+                .setIcon(icon3)
+                .setActivity(getActivity("MainActivity2"))
+                .setIntents(new Intent[]{new Intent("main")})
+                .build();
+
+        assertTrue(getManager().setDynamicShortcuts(list(s1, s2, s3)));
+
+        assertWith(getManager().getDynamicShortcuts())
+                .haveIds("s1", "s2", "s3")
+                .areAllNotPinned();
+
+        assertWith(getManager().getManifestShortcuts())
+                .haveIds("ms1", "ms2")
+                .areAllNotPinned();
+   }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/Android.mk b/hostsidetests/shortcuts/deviceside/backup/publisher2/Android.mk
new file mode 100644
index 0000000..62ad16e
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2016 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)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsShortcutBackupPublisher2
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../../common/src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target-minus-junit4 \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/AndroidManifest.xml b/hostsidetests/shortcuts/deviceside/backup/publisher2/AndroidManifest.xml
new file mode 100644
index 0000000..c3271b4
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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="android.content.pm.cts.shortcut.backup.publisher2">
+
+    <application>
+        <activity android:name="MainActivity" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/>
+        </activity>
+        <activity-alias android:name="MainActivity2"
+            android:targetActivity="android.content.pm.cts.shortcut.backup.publisher2.MainActivity"
+            android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts_b"/>
+        </activity-alias>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.content.pm.cts.shortcut.backup.publisher2"  />
+</manifest>
+
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/res/drawable-nodpi/black_16x16.png b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/drawable-nodpi/black_16x16.png
new file mode 100644
index 0000000..a26da5c
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/drawable-nodpi/black_16x16.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/res/drawable-nodpi/black_16x64.png b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/drawable-nodpi/black_16x64.png
new file mode 100644
index 0000000..ed049fa
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/drawable-nodpi/black_16x64.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/res/drawable-nodpi/black_64x16.png b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/drawable-nodpi/black_64x16.png
new file mode 100644
index 0000000..a0983c7
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/drawable-nodpi/black_64x16.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/res/values/strings.xml b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/values/strings.xml
new file mode 100644
index 0000000..068c991
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/values/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="label1">Shortcut 1</string>
+    <string name="long_label1">Long shortcut label1</string>
+    <string name="disabled_message1">Shortcut 1 is disabled</string>
+
+    <string name="label2">Shortcut 2</string>
+    <string name="long_label2">Long shortcut label2</string>
+    <string name="disabled_message2">Shortcut 2 is disabled</string>
+
+    <string name="label3">Shortcut 3</string>
+    <string name="long_label3">Long shortcut label3</string>
+    <string name="disabled_message3">Shortcut 3 is disabled</string>
+
+    <string name="label4">Shortcut 4</string>
+    <string name="long_label4">Long shortcut label4</string>
+    <string name="disabled_message4">Shortcut 4 is disabled</string>
+
+    <string name="label5">Shortcut 5</string>
+    <string name="long_label5">Long shortcut label5</string>
+    <string name="disabled_message5">Shortcut 5 is disabled</string>
+</resources>
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/res/xml/shortcuts.xml b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/xml/shortcuts.xml
new file mode 100644
index 0000000..1b4661b
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/xml/shortcuts.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
+    <shortcut
+        android:shortcutId="ms1"
+        android:icon="@drawable/black_16x16"
+        android:shortcutShortLabel="@string/label1"
+        android:shortcutLongLabel="@string/long_label1"
+        android:shortcutDisabledMessage="@string/disabled_message1">
+        <intent
+            android:action="android.intent.action.VIEW" />
+        <categories android:name="android.shortcut.conversation" />
+        <categories android:name="android.shortcut.media" />
+    </shortcut>
+    <shortcut
+        android:shortcutId="ms2"
+        android:shortcutShortLabel="@string/label2">
+        <intent android:action="action" />
+        <intent android:action="action2"
+            android:data="data"
+            android:mimeType="a/b"
+            android:targetPackage="pkg"
+            android:targetClass="pkg.class"
+            >
+            <categories android:name="icat1"/>
+            <categories android:name="icat2"/>
+            <extra android:name="key1" android:value="value1" />
+            <extra android:name="key2" android:value="123" />
+            <extra android:name="key3" android:value="true" />
+        </intent>
+    </shortcut>
+</shortcuts>
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/res/xml/shortcuts_b.xml b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/xml/shortcuts_b.xml
new file mode 100644
index 0000000..408e94d
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/res/xml/shortcuts_b.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
+    <shortcut
+        android:shortcutId="ms1"
+        android:icon="@drawable/black_16x16"
+        android:shortcutShortLabel="@string/label1"
+        android:shortcutLongLabel="@string/long_label1"
+        android:shortcutDisabledMessage="@string/disabled_message1">
+        <intent
+            android:action="android.intent.action.VIEW" />
+        <categories android:name="android.shortcut.conversation" />
+        <categories android:name="android.shortcut.media" />
+    </shortcut>
+</shortcuts>
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/MainActivity.java b/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/MainActivity.java
new file mode 100644
index 0000000..a6ca8f1
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/MainActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher2;
+
+import android.app.Activity;
+
+public class MainActivity extends Activity {
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/ShortcutManagerPostBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/ShortcutManagerPostBackupTest.java
new file mode 100644
index 0000000..ce2b950
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/ShortcutManagerPostBackupTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher2;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+
+public class ShortcutManagerPostBackupTest extends ShortcutManagerDeviceTestBase {
+    public void testWithUninstall() {
+        assertWith(getManager().getDynamicShortcuts())
+                .isEmpty();
+
+        assertWith(getManager().getPinnedShortcuts())
+                .haveIds("s1", "s2", "ms1")
+                .areAllEnabled();
+
+        assertWith(getManager().getManifestShortcuts())
+                .haveIds("ms1", "ms2")
+                .areAllEnabled();
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/ShortcutManagerPreBackup2Test.java b/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/ShortcutManagerPreBackup2Test.java
new file mode 100644
index 0000000..d307c57
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/ShortcutManagerPreBackup2Test.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher2;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.retryUntil;
+
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public class ShortcutManagerPreBackup2Test extends ShortcutManagerDeviceTestBase {
+    public void testPreBackup() {
+        getManager().removeDynamicShortcuts(list("s2"));
+        getManager().disableShortcuts(list("s3"));
+
+        getContext().getPackageManager().setComponentEnabledSetting(
+                new ComponentName(getContext(), MainActivity.class),
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                PackageManager.DONT_KILL_APP);
+
+        retryUntil(() -> getManager().getManifestShortcuts().size() == 1,
+                "Manifest shortcuts didn't update");
+
+        assertWith(getManager().getDynamicShortcuts())
+                .haveIds("s1")
+                .areAllEnabled();
+
+        assertWith(getManager().getManifestShortcuts())
+                .haveIds("ms1")
+                .areAllEnabled();
+
+        assertWith(getManager().getPinnedShortcuts())
+                .haveIds("s1", "s2", "s3", "ms1", "ms2")
+                .selectByIds("s1", "s2", "ms1")
+                .areAllEnabled()
+
+                .revertToOriginalList()
+                .selectByIds("s3", "ms2")
+                .areAllDisabled();
+
+   }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/ShortcutManagerPreBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/ShortcutManagerPreBackupTest.java
new file mode 100644
index 0000000..3d28145
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher2/src/android/content/pm/cts/shortcut/backup/publisher2/ShortcutManagerPreBackupTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher2;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makePersistableBundle;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
+
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.Icon;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public class ShortcutManagerPreBackupTest extends ShortcutManagerDeviceTestBase {
+    public void testPreBackup() {
+        final Icon icon1 = Icon.createWithBitmap(BitmapFactory.decodeResource(
+                getContext().getResources(), R.drawable.black_16x64));
+        final Icon icon3 = Icon.createWithResource(getContext(), R.drawable.black_64x16);
+
+        final ShortcutInfo s1 = new ShortcutInfo.Builder(getContext(), "s1")
+                .setShortLabel("shortlabel1")
+                .setLongLabel("longlabel1")
+                .setIcon(icon1)
+                .setActivity(getActivity("MainActivity2"))
+                .setDisabledMessage("disabledmessage1")
+                .setIntents(new Intent[]{new Intent("view").putExtra("k1", "v1")})
+                .setExtras(makePersistableBundle("ek1", "ev1"))
+                .setCategories(set("cat1"))
+                .build();
+
+        final ShortcutInfo s2 = new ShortcutInfo.Builder(getContext(), "s2")
+                .setShortLabel("shortlabel2")
+                .setActivity(getActivity("MainActivity2"))
+                .setIntents(new Intent[]{new Intent("main")})
+                .build();
+
+        final ShortcutInfo s3 = new ShortcutInfo.Builder(getContext(), "s3")
+                .setShortLabel("shortlabel2")
+                .setIcon(icon3)
+                .setActivity(getActivity("MainActivity2"))
+                .setIntents(new Intent[]{new Intent("main")})
+                .build();
+
+        assertTrue(getManager().setDynamicShortcuts(list(s1, s2, s3)));
+
+        assertWith(getManager().getDynamicShortcuts())
+                .haveIds("s1", "s2", "s3")
+                .areAllNotPinned();
+
+        assertWith(getManager().getManifestShortcuts())
+                .haveIds("ms1", "ms2")
+                .areAllNotPinned()
+                // Note MainActivity2 have manifest shortcuts too, but because of the ID overlap,
+                // they're ignored at this point.
+                .areAllWithActivity(getActivity("MainActivity"));
+   }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/Android.mk b/hostsidetests/shortcuts/deviceside/backup/publisher3/Android.mk
new file mode 100644
index 0000000..049691d
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2016 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)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsShortcutBackupPublisher3
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../../common/src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target-minus-junit4 \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/AndroidManifest.xml b/hostsidetests/shortcuts/deviceside/backup/publisher3/AndroidManifest.xml
new file mode 100644
index 0000000..5e03ff8
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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="android.content.pm.cts.shortcut.backup.publisher3">
+
+    <application android:allowBackup="false">
+        <activity android:name="MainActivity" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.content.pm.cts.shortcut.backup.publisher3"  />
+</manifest>
+
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/res/drawable-nodpi/black_16x16.png b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/drawable-nodpi/black_16x16.png
new file mode 100644
index 0000000..a26da5c
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/drawable-nodpi/black_16x16.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/res/drawable-nodpi/black_16x64.png b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/drawable-nodpi/black_16x64.png
new file mode 100644
index 0000000..ed049fa
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/drawable-nodpi/black_16x64.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/res/drawable-nodpi/black_64x16.png b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/drawable-nodpi/black_64x16.png
new file mode 100644
index 0000000..a0983c7
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/drawable-nodpi/black_64x16.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/res/values/strings.xml b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/values/strings.xml
new file mode 100644
index 0000000..068c991
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/values/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="label1">Shortcut 1</string>
+    <string name="long_label1">Long shortcut label1</string>
+    <string name="disabled_message1">Shortcut 1 is disabled</string>
+
+    <string name="label2">Shortcut 2</string>
+    <string name="long_label2">Long shortcut label2</string>
+    <string name="disabled_message2">Shortcut 2 is disabled</string>
+
+    <string name="label3">Shortcut 3</string>
+    <string name="long_label3">Long shortcut label3</string>
+    <string name="disabled_message3">Shortcut 3 is disabled</string>
+
+    <string name="label4">Shortcut 4</string>
+    <string name="long_label4">Long shortcut label4</string>
+    <string name="disabled_message4">Shortcut 4 is disabled</string>
+
+    <string name="label5">Shortcut 5</string>
+    <string name="long_label5">Long shortcut label5</string>
+    <string name="disabled_message5">Shortcut 5 is disabled</string>
+</resources>
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/res/xml/shortcuts.xml b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/xml/shortcuts.xml
new file mode 100644
index 0000000..1b4661b
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/res/xml/shortcuts.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
+    <shortcut
+        android:shortcutId="ms1"
+        android:icon="@drawable/black_16x16"
+        android:shortcutShortLabel="@string/label1"
+        android:shortcutLongLabel="@string/long_label1"
+        android:shortcutDisabledMessage="@string/disabled_message1">
+        <intent
+            android:action="android.intent.action.VIEW" />
+        <categories android:name="android.shortcut.conversation" />
+        <categories android:name="android.shortcut.media" />
+    </shortcut>
+    <shortcut
+        android:shortcutId="ms2"
+        android:shortcutShortLabel="@string/label2">
+        <intent android:action="action" />
+        <intent android:action="action2"
+            android:data="data"
+            android:mimeType="a/b"
+            android:targetPackage="pkg"
+            android:targetClass="pkg.class"
+            >
+            <categories android:name="icat1"/>
+            <categories android:name="icat2"/>
+            <extra android:name="key1" android:value="value1" />
+            <extra android:name="key2" android:value="123" />
+            <extra android:name="key3" android:value="true" />
+        </intent>
+    </shortcut>
+</shortcuts>
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/src/android/content/pm/cts/shortcut/backup/publisher3/MainActivity.java b/hostsidetests/shortcuts/deviceside/backup/publisher3/src/android/content/pm/cts/shortcut/backup/publisher3/MainActivity.java
new file mode 100644
index 0000000..ad66bd9
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/src/android/content/pm/cts/shortcut/backup/publisher3/MainActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher3;
+
+import android.app.Activity;
+
+public class MainActivity extends Activity {
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/src/android/content/pm/cts/shortcut/backup/publisher3/ShortcutManagerPostBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/publisher3/src/android/content/pm/cts/shortcut/backup/publisher3/ShortcutManagerPostBackupTest.java
new file mode 100644
index 0000000..a36cc66
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/src/android/content/pm/cts/shortcut/backup/publisher3/ShortcutManagerPostBackupTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher3;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+
+public class ShortcutManagerPostBackupTest extends ShortcutManagerDeviceTestBase {
+    public void testWithUninstall() {
+        // backup = false, so no pinned shortcuts should be restored.
+        assertWith(getManager().getPinnedShortcuts())
+                .isEmpty();
+
+        assertWith(getManager().getManifestShortcuts())
+                .haveIds("ms1", "ms2")
+                .areAllNotPinned();
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/backup/publisher3/src/android/content/pm/cts/shortcut/backup/publisher3/ShortcutManagerPreBackupTest.java b/hostsidetests/shortcuts/deviceside/backup/publisher3/src/android/content/pm/cts/shortcut/backup/publisher3/ShortcutManagerPreBackupTest.java
new file mode 100644
index 0000000..01166e7
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/backup/publisher3/src/android/content/pm/cts/shortcut/backup/publisher3/ShortcutManagerPreBackupTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.backup.publisher3;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makePersistableBundle;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
+
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.Icon;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public class ShortcutManagerPreBackupTest extends ShortcutManagerDeviceTestBase {
+    public void testPreBackup() {
+        final Icon icon1 = Icon.createWithBitmap(BitmapFactory.decodeResource(
+                getContext().getResources(), R.drawable.black_16x64));
+        final Icon icon3 = Icon.createWithResource(getContext(), R.drawable.black_64x16);
+
+        final ShortcutInfo s1 = new ShortcutInfo.Builder(getContext(), "s1")
+                .setShortLabel("shortlabel1")
+                .setLongLabel("longlabel1")
+                .setIcon(icon1)
+                .setDisabledMessage("disabledmessage1")
+                .setIntents(new Intent[]{new Intent("view").putExtra("k1", "v1")})
+                .setExtras(makePersistableBundle("ek1", "ev1"))
+                .setCategories(set("cat1"))
+                .build();
+
+        final ShortcutInfo s2 = new ShortcutInfo.Builder(getContext(), "s2")
+                .setShortLabel("shortlabel2")
+                .setIntents(new Intent[]{new Intent("main")})
+                .build();
+
+        final ShortcutInfo s3 = new ShortcutInfo.Builder(getContext(), "s3")
+                .setShortLabel("shortlabel2")
+                .setIcon(icon3)
+                .setIntents(new Intent[]{new Intent("main")})
+                .build();
+
+        assertTrue(getManager().setDynamicShortcuts(list(s1, s2, s3)));
+
+        assertWith(getManager().getDynamicShortcuts())
+                .haveIds("s1", "s2", "s3")
+                .areAllNotPinned();
+
+        assertWith(getManager().getManifestShortcuts())
+                .haveIds("ms1", "ms2")
+                .areAllNotPinned();
+   }
+}
diff --git a/hostsidetests/shortcuts/deviceside/common/src/android/content/pm/cts/shortcut/device/common/ShortcutManagerDeviceTestBase.java b/hostsidetests/shortcuts/deviceside/common/src/android/content/pm/cts/shortcut/device/common/ShortcutManagerDeviceTestBase.java
new file mode 100644
index 0000000..f3fd238
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/common/src/android/content/pm/cts/shortcut/device/common/ShortcutManagerDeviceTestBase.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.device.common;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.getDefaultLauncher;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.setDefaultLauncher;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.os.UserHandle;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+
+import java.util.List;
+
+/**
+ * Base class for device side tests for the host test.
+ */
+public abstract class ShortcutManagerDeviceTestBase extends InstrumentationTestCase {
+    private ShortcutManager mManager;
+    private LauncherApps mLauncherApps;
+
+    private String mOriginalLauncher;
+
+    protected Context getContext() {
+        return getInstrumentation().getTargetContext();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mOriginalLauncher = getDefaultLauncher(getInstrumentation());
+
+        mManager = getContext().getSystemService(ShortcutManager.class);
+        mLauncherApps = getContext().getSystemService(LauncherApps.class);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!TextUtils.isEmpty(mOriginalLauncher)) {
+            setDefaultLauncher(getInstrumentation(), mOriginalLauncher);
+        }
+
+        super.tearDown();
+    }
+
+    protected ShortcutManager getManager() {
+        return mManager;
+    }
+
+    protected LauncherApps getLauncherApps() {
+        return mLauncherApps;
+    }
+
+    protected UserHandle getUserHandle() {
+        return android.os.Process.myUserHandle();
+    }
+
+    protected void setAsDefaultLauncher(Class<?> clazz) {
+        setDefaultLauncher(getInstrumentation(),
+                getContext().getPackageName() + "/" + clazz.getName());
+    }
+
+    protected Drawable getIconAsLauncher(String packageName, String shortcutId) {
+        final ShortcutQuery q = new ShortcutQuery()
+                .setQueryFlags(ShortcutQuery.FLAG_MATCH_DYNAMIC
+                        | ShortcutQuery.FLAG_MATCH_MANIFEST
+                        | ShortcutQuery.FLAG_MATCH_PINNED
+                        | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY)
+                .setPackage(packageName)
+                .setShortcutIds(list(shortcutId));
+        final List<ShortcutInfo> found = getLauncherApps().getShortcuts(q, getUserHandle());
+
+        assertEquals("Shortcut not found", 1, found.size());
+
+        return getLauncherApps().getShortcutIconDrawable(found.get(0), 0);
+    }
+
+    protected void assertIconDimensions(String packageName,
+            String shortcutId, Icon expectedIcon) {
+        final Drawable actual = getIconAsLauncher(packageName, shortcutId);
+        if (actual == null && expectedIcon == null) {
+            return; // okay
+        }
+        final Drawable expected = expectedIcon.loadDrawable(getContext());
+        assertEquals(expected.getIntrinsicWidth(), actual.getIntrinsicWidth());
+        assertEquals(expected.getIntrinsicHeight(), actual.getIntrinsicHeight());
+    }
+
+    public ComponentName getActivity(String className) {
+        return new ComponentName(getContext(), getContext().getPackageName() + "." + className);
+    }
+
+    protected List<ShortcutInfo> getPackageShortcuts(String packageName) {
+        final ShortcutQuery q = new ShortcutQuery()
+                .setQueryFlags(ShortcutQuery.FLAG_MATCH_DYNAMIC
+                        | ShortcutQuery.FLAG_MATCH_MANIFEST
+                        | ShortcutQuery.FLAG_MATCH_PINNED)
+                .setPackage(packageName);
+        return getLauncherApps().getShortcuts(q, getUserHandle());
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/multiuser/Android.mk b/hostsidetests/shortcuts/deviceside/multiuser/Android.mk
new file mode 100644
index 0000000..2897e8c
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/multiuser/Android.mk
@@ -0,0 +1,44 @@
+# Copyright (C) 2016 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.
+
+# We build two APKs from the same source files, each with a different set of resources.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsShortcutMultiuserTest
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../common/src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target-minus-junit4 \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/shortcuts/deviceside/multiuser/AndroidManifest.xml b/hostsidetests/shortcuts/deviceside/multiuser/AndroidManifest.xml
new file mode 100644
index 0000000..3fbed5f
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/multiuser/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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="android.content.pm.cts.shortcut.multiuser">
+
+    <application>
+        <activity android:name="Launcher" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.HOME" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="MainActivity" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.content.pm.cts.shortcut.multiuser"  />
+</manifest>
+
diff --git a/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/Consts.java b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/Consts.java
new file mode 100644
index 0000000..fb15f93
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/Consts.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.multiuser;
+
+public class Consts {
+    private Consts() {
+    }
+
+    public static final String TAG = "ShortcutMultiuserCTS";
+}
diff --git a/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/Launcher.java b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/Launcher.java
new file mode 100644
index 0000000..c860523
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/Launcher.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.multiuser;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.setDefaultLauncher;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Context;
+
+public class Launcher extends Activity {
+    public static void setAsDefaultLauncher(Instrumentation instrumentation, Context context) {
+        setDefaultLauncher(instrumentation,
+                context.getPackageName() + "/" + Launcher.class.getName());
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/MainActivity.java b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/MainActivity.java
new file mode 100644
index 0000000..76a081e
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/MainActivity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.multiuser;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+    private static volatile long sLastCreateTime;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        sLastCreateTime = System.currentTimeMillis();
+
+        finish();
+    }
+
+    public static long getLastCreateTime() {
+        return sLastCreateTime;
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerManagedUserTest.java b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerManagedUserTest.java
new file mode 100644
index 0000000..0c5e662
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerManagedUserTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.multiuser;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+public class ShortcutManagerManagedUserTest extends ShortcutManagerDeviceTestBase {
+    public void test01_managedProfileNotStarted() {
+        Launcher.setAsDefaultLauncher(getInstrumentation(), getContext());
+
+        // Get user-0's handle.
+        final UserHandle userManaged = getManagedUser();
+
+        final ShortcutQuery q = new ShortcutQuery();
+
+        try {
+            getLauncherApps().getShortcuts(q, userManaged);
+            fail("Didn't throw SecurityException");
+        } catch (IllegalStateException e) {
+            assertTrue(e.getMessage().contains("locked or not running"));
+        }
+    }
+
+    public void test02_createShortuctsOnPrimaryUser() {
+        assertTrue(getManager().setDynamicShortcuts(list(
+                new ShortcutInfo.Builder(getContext(), "s1")
+                        .setShortLabel("label1")
+                        .setIntent(new Intent(Intent.ACTION_VIEW).setComponent(
+                                new ComponentName(getContext(), MainActivity.class))).build())));
+    }
+
+    public void test03_createShortuctsOnManagedProfile() {
+        assertTrue(getManager().setDynamicShortcuts(list(
+                new ShortcutInfo.Builder(getContext(), "s1")
+                        .setShortLabel("label2")
+                        .setIntent(new Intent(Intent.ACTION_VIEW).setComponent(
+                                new ComponentName(getContext(), MainActivity.class))).build())));
+    }
+
+    public void test04_getAndLaunch() {
+        Launcher.setAsDefaultLauncher(getInstrumentation(), getContext());
+
+        final UserHandle userMain = android.os.Process.myUserHandle();
+        final UserHandle userManaged = getManagedUser();
+
+        final ShortcutQuery q = new ShortcutQuery()
+                .setQueryFlags(ShortcutQuery.FLAG_MATCH_DYNAMIC)
+                .setPackage(getContext().getPackageName())
+                .setShortcutIds(list("s1"));
+        assertWith(getLauncherApps().getShortcuts(q, userMain))
+                .haveIds("s1")
+                .areAllDynamic()
+                .forShortcutWithId("s1", si -> {
+                    assertEquals("label1", si.getShortLabel());
+                    assertEquals(userMain, si.getUserHandle());
+                });
+        assertWith(getLauncherApps().getShortcuts(q, userManaged))
+                .haveIds("s1")
+                .areAllDynamic()
+                .forShortcutWithId("s1", si -> {
+                    assertEquals("label2", si.getShortLabel());
+                    assertEquals(userManaged, si.getUserHandle());
+                });
+
+        // Just call start and make sure they don't throw.
+        getLauncherApps().startShortcut(getContext().getPackageName(), "s1", null, null,
+                userMain);
+
+        // TODO Make sure the activity actually starts.
+        getLauncherApps().startShortcut(getContext().getPackageName(), "s1", null, null,
+                userManaged);
+    }
+
+    private UserHandle getManagedUser() {
+        for (UserHandle user : getContext().getSystemService(UserManager.class).getUserProfiles()) {
+            if (user.equals(android.os.Process.myUserHandle())) {
+                continue;
+            }
+            return user;
+        }
+        fail("Managed user not found");
+        return null;
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerSecondaryUserTest.java b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerSecondaryUserTest.java
new file mode 100644
index 0000000..618bbae
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerSecondaryUserTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.multiuser;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.retryUntil;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.os.UserHandle;
+import android.util.DisplayMetrics;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+public class ShortcutManagerSecondaryUserTest extends ShortcutManagerDeviceTestBase {
+    public void testCreateAndStart() {
+        Launcher.setAsDefaultLauncher(getInstrumentation(), getContext());
+
+        // Publish a shortcut.
+        final UserHandle user = android.os.Process.myUserHandle();
+
+        assertTrue(getManager().setDynamicShortcuts(list(
+                new ShortcutInfo.Builder(getContext(), "s1")
+                    .setShortLabel("label")
+                    .setIntent(new Intent(Intent.ACTION_VIEW).setComponent(
+                            new ComponentName(getContext(), MainActivity.class))).build())));
+
+        // Retrieve as a launcher.
+        final ShortcutQuery q = new ShortcutQuery()
+                .setQueryFlags(ShortcutQuery.FLAG_MATCH_DYNAMIC)
+                .setPackage(getContext().getPackageName())
+                .setShortcutIds(list("s1"));
+        final List<ShortcutInfo> list = getLauncherApps().getShortcuts(q, user);
+        assertWith(list)
+                .haveIds("s1")
+                .areAllDynamic()
+                .forShortcutWithId("s1", si -> {
+                    assertEquals(user, si.getUserHandle());
+                });
+
+        final ShortcutInfo s1 = list.get(0);
+
+        // Just make sure they don't throw SecurityException.
+        getLauncherApps().getShortcutIconDrawable(s1, DisplayMetrics.DENSITY_DEFAULT);
+        getLauncherApps().getShortcutBadgedIconDrawable(s1, DisplayMetrics.DENSITY_DEFAULT);
+
+        final long now = System.currentTimeMillis();
+
+        // Start it.
+        getLauncherApps().startShortcut(s1, null, null);
+
+        retryUntil(() -> MainActivity.getLastCreateTime() >= now, "Activity not started");
+    }
+
+    public void testDifferentUserNotAccessible() throws Exception {
+        Launcher.setAsDefaultLauncher(getInstrumentation(), getContext());
+
+        // Get user-0's handle.
+        final UserHandle user0 = getUser0Handle();
+
+        final ShortcutQuery q = new ShortcutQuery();
+
+        try {
+            getLauncherApps().getShortcuts(q, user0);
+            fail("Didn't throw SecurityException");
+        } catch (SecurityException e) {
+            assertTrue(e.getMessage().contains("unrelated profile"));
+        }
+    }
+
+    private static UserHandle getUser0Handle() throws Exception {
+        Method of = UserHandle.class.getMethod("of", int.class);
+
+        return (UserHandle) of.invoke(null, 0);
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/Android.mk b/hostsidetests/shortcuts/deviceside/upgrade/Android.mk
new file mode 100644
index 0000000..21b07a0
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/Android.mk
@@ -0,0 +1,79 @@
+# Copyright (C) 2016 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.
+
+# We build two APKs from the same source files, each with a different set of resources.
+
+# =================================
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsShortcutUpgradeVersion1
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../common/src)
+
+LOCAL_RESOURCE_DIR :=  $(LOCAL_PATH)/version1/res
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target-minus-junit4 \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+
+# =============================
+
+include $(CLEAR_VARS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsShortcutUpgradeVersion2
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, ../common/src)
+
+LOCAL_RESOURCE_DIR :=  $(LOCAL_PATH)/version2/res
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    android-support-v4 \
+    mockito-target-minus-junit4 \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ShortcutManagerTestUtils
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/AndroidManifest.xml b/hostsidetests/shortcuts/deviceside/upgrade/AndroidManifest.xml
new file mode 100644
index 0000000..1b88d5e
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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="android.content.pm.cts.shortcut.upgrade">
+
+    <application>
+        <activity android:name="Launcher" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.HOME" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="MainActivty" android:exported="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.content.pm.cts.shortcut.upgrade"  />
+</manifest>
+
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/Consts.java b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/Consts.java
new file mode 100644
index 0000000..c13e3d0
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/Consts.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.upgrade;
+
+public class Consts {
+    private Consts() {
+    }
+
+    public static final String TAG = "ShortcutUpgradeCTS";
+
+    public static String EXTRA_ICON_RES_ID =
+            "android.content.pm.cts.shortcut.upgrade.EXTRA_ICON_RES_ID";
+}
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/Launcher.java b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/Launcher.java
new file mode 100644
index 0000000..21b0b03
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/Launcher.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.upgrade;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.setDefaultLauncher;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Context;
+
+public class Launcher extends Activity {
+    public static void setAsDefaultLauncher(Instrumentation instrumentation, Context context) {
+        setDefaultLauncher(instrumentation,
+                context.getPackageName() + "/" + Launcher.class.getName());
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/MainActivity.java b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/MainActivity.java
new file mode 100644
index 0000000..51c7a76
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/MainActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.upgrade;
+
+import android.app.Activity;
+
+public class MainActivity extends Activity {
+}
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/ShortcutManagerPostUpgradeTest.java b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/ShortcutManagerPostUpgradeTest.java
new file mode 100644
index 0000000..d20992d
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/ShortcutManagerPostUpgradeTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.upgrade;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.graphics.drawable.Icon;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import junit.framework.AssertionFailedError;
+
+@SmallTest
+public class ShortcutManagerPostUpgradeTest extends ShortcutManagerDeviceTestBase {
+    public void testPostUpgrade() {
+        Log.i(Consts.TAG, "Post: ResIDs=" + R.drawable.black_32x32 + ", " + R.drawable.black_64x64);
+
+        // Get the shortcuts published by the "pre" apk.
+
+        // Check their original res IDs (stored in the extras) and make sure the res IDs are
+        // different now.
+        assertWith(getManager().getDynamicShortcuts())
+                .haveIds("s1", "s2")
+                .forShortcutWithId("s1", s -> {
+                    assertTrue(
+                            R.drawable.black_32x32 !=
+                            s.getExtras().getInt(Consts.EXTRA_ICON_RES_ID));
+                })
+                .forShortcutWithId("s2", s -> {
+                    assertTrue(
+                            R.drawable.black_64x64 !=
+                            s.getExtras().getInt(Consts.EXTRA_ICON_RES_ID));
+                });
+
+        // Next, actually fetch the icons as a launcher, and make sure the dimensions are correct.
+        final Icon icon1 = Icon.createWithResource(getContext(), R.drawable.black_32x32);
+        final Icon icon2 = Icon.createWithResource(getContext(), R.drawable.black_64x64);
+
+        // Set this package as a default launcher to access LauncherApps.
+        Launcher.setAsDefaultLauncher(getInstrumentation(), getContext());
+
+        // Check the published icons as a launcher.
+        assertIconDimensions(getContext().getPackageName(), "s1", icon1);
+        assertIconDimensions(getContext().getPackageName(), "s2", icon2);
+
+        // Paranoid: this should fail.
+        boolean notThrown = false;
+        try {
+            assertIconDimensions(getContext().getPackageName(), "s1", icon2);
+            notThrown = true;
+        } catch (AssertionFailedError expected) {
+            // okay
+        }
+        assertFalse(notThrown);
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/ShortcutManagerPreUpgradeTest.java b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/ShortcutManagerPreUpgradeTest.java
new file mode 100644
index 0000000..50c2f78
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/src/android/content/pm/cts/shortcut/upgrade/ShortcutManagerPreUpgradeTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 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.content.pm.cts.shortcut.upgrade;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.cts.shortcut.device.common.ShortcutManagerDeviceTestBase;
+import android.graphics.drawable.Icon;
+import android.os.PersistableBundle;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import junit.framework.AssertionFailedError;
+
+@SmallTest
+public class ShortcutManagerPreUpgradeTest extends ShortcutManagerDeviceTestBase {
+    public void testPreUpgrade() {
+        Log.i(Consts.TAG, "Pre: ResIDs=" + R.drawable.black_32x32 + ", " + R.drawable.black_64x64);
+
+        // Publish shortcuts with drawable icons.
+        final Icon icon1 = Icon.createWithResource(getContext(), R.drawable.black_32x32);
+        final Icon icon2 = Icon.createWithResource(getContext(), R.drawable.black_64x64);
+
+        // Store the original resource ID in the extras.
+        final PersistableBundle b1 = new PersistableBundle();
+        b1.putInt(Consts.EXTRA_ICON_RES_ID, R.drawable.black_32x32);
+        final ShortcutInfo s1 = new ShortcutInfo.Builder(getContext(), "s1")
+                .setShortLabel("shortlabel1")
+                .setIcon(icon1)
+                .setIntents(new Intent[]{new Intent(Intent.ACTION_VIEW)})
+                .setExtras(b1)
+                .build();
+
+        final PersistableBundle b2 = new PersistableBundle();
+        b2.putInt(Consts.EXTRA_ICON_RES_ID, R.drawable.black_64x64);
+        final ShortcutInfo s2 = new ShortcutInfo.Builder(getContext(), "s2")
+                .setShortLabel("shortlabel2")
+                .setIcon(icon2)
+                .setIntents(new Intent[]{new Intent(Intent.ACTION_VIEW)})
+                .setExtras(b2)
+                .build();
+
+        assertTrue(getManager().setDynamicShortcuts(list(s1, s2)));
+
+        // Set this package as a default launcher to access LauncherApps.
+        Launcher.setAsDefaultLauncher(getInstrumentation(), getContext());
+
+        // Check the published icons as a launcher.
+        assertIconDimensions(getContext().getPackageName(), "s1", icon1);
+        assertIconDimensions(getContext().getPackageName(), "s2", icon2);
+
+        // Paranoid: this should fail.
+        boolean notThrown = false;
+        try {
+            assertIconDimensions(getContext().getPackageName(), "s1", icon2);
+            notThrown = true;
+        } catch (AssertionFailedError expected) {
+            // okay
+        }
+        assertFalse(notThrown);
+    }
+}
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_16x16.png b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_16x16.png
new file mode 100644
index 0000000..a26da5c
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_16x16.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_16x64.png b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_16x64.png
new file mode 100644
index 0000000..ed049fa
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_16x64.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_32x32.png b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_32x32.png
new file mode 100644
index 0000000..a1e25c1
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_32x32.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_64x16.png b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_64x16.png
new file mode 100644
index 0000000..a0983c7
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_64x16.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_64x64.png b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_64x64.png
new file mode 100644
index 0000000..7cc9373
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/version1/res/drawable-nodpi/black_64x64.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/version2/res/drawable-nodpi/black_32x32.png b/hostsidetests/shortcuts/deviceside/upgrade/version2/res/drawable-nodpi/black_32x32.png
new file mode 100644
index 0000000..a1e25c1
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/version2/res/drawable-nodpi/black_32x32.png
Binary files differ
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/version2/res/drawable-nodpi/black_64x64.png b/hostsidetests/shortcuts/deviceside/upgrade/version2/res/drawable-nodpi/black_64x64.png
new file mode 100644
index 0000000..7cc9373
--- /dev/null
+++ b/hostsidetests/shortcuts/deviceside/upgrade/version2/res/drawable-nodpi/black_64x64.png
Binary files differ