Shortcut launcher demo:

- Listen to work profile broadcasts and refresh the screen.
- Fix the bug about mixing up user 0 and user 10.
- Add a "user has any shortcuts or not" test to detect
user unlock races.

Change-Id: I4c5ae34317b669dd8fcda466a960074b22e88d5a
diff --git a/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/AppListFragment.java b/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/AppListFragment.java
index 7b21424..8c3edb1 100644
--- a/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/AppListFragment.java
+++ b/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/AppListFragment.java
@@ -23,6 +23,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -82,12 +83,14 @@
     public class AppAdapter extends BaseAdapter implements OnClickListener {
         private final Context mContext;
         private final LayoutInflater mInflater;
-        private LauncherApps mLauncherApps;
+        private final UserManager mUserManager;
+        private final LauncherApps mLauncherApps;
         private List<LauncherActivityInfo> mList;
 
         public AppAdapter(Context context) {
             mContext = context;
             mInflater = mContext.getSystemService(LayoutInflater.class);
+            mUserManager = mContext.getSystemService(UserManager.class);
             mLauncherApps = mContext.getSystemService(LauncherApps.class);
         }
 
@@ -156,7 +159,8 @@
 
                 v.setVisibility(View.INVISIBLE);
                 try {
-                    if (mLauncherApps.hasShortcutHostPermission()) {
+                    if (mUserManager.isUserUnlocked(ai.getUser())
+                            && mLauncherApps.hasShortcutHostPermission()) {
                         mQuery.setPackage(ai.getComponentName().getPackageName());
                         mQuery.setQueryFlags(ShortcutQuery.FLAG_MATCH_DYNAMIC
                                 | ShortcutQuery.FLAG_MATCH_PINNED
diff --git a/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/MyBaseListFragment.java b/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/MyBaseListFragment.java
index 1759ead..23044d6 100644
--- a/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/MyBaseListFragment.java
+++ b/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/MyBaseListFragment.java
@@ -16,6 +16,10 @@
 package com.example.android.pm.shortcutlauncherdemo;
 
 import android.app.ListFragment;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.LauncherApps.ShortcutQuery;
@@ -39,6 +43,23 @@
 
     protected final ShortcutQuery mQuery = new ShortcutQuery();
 
+    public final static IntentFilter sProfileFilter = new IntentFilter();
+
+    static {
+        sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
+        sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+        sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
+        sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+        sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
+    }
+
+    private final BroadcastReceiver mProfileReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            refreshList();
+        }
+    };
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -49,19 +70,23 @@
     }
 
     @Override
-    public void onStart() {
-        super.onStart();
-
-        Log.d(Global.TAG, "Started");
-
-        refreshList();
-    }
-
-    @Override
     public void onResume() {
         super.onResume();
 
+        Log.d(Global.TAG, "Resumed");
+
         showPermissionWarningToastWhenNeeded();
+
+        refreshList();
+
+        getActivity().registerReceiver(mProfileReceiver, sProfileFilter);
+    }
+
+    @Override
+    public void onPause() {
+        getActivity().unregisterReceiver(mProfileReceiver);
+
+        super.onPause();
     }
 
     @Override
diff --git a/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/ShortcutLauncherMain.java b/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/ShortcutLauncherMain.java
index 3364221..cc63494 100644
--- a/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/ShortcutLauncherMain.java
+++ b/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/ShortcutLauncherMain.java
@@ -22,7 +22,6 @@
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
-import android.content.pm.LauncherApps;
 import android.os.Bundle;
 import android.support.v13.app.FragmentStatePagerAdapter;
 import android.support.v4.view.PagerAdapter;
diff --git a/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/ShortcutListFragment.java b/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/ShortcutListFragment.java
index 379c574..26d4484 100644
--- a/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/ShortcutListFragment.java
+++ b/samples/ShortcutDemo/launcher/src/com/example/android/pm/shortcutlauncherdemo/ShortcutListFragment.java
@@ -23,7 +23,6 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.text.TextUtils;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -93,6 +92,7 @@
 
     private void togglePin(ShortcutInfo selected) {
         final String packageName = selected.getPackage();
+        final UserHandle user = selected.getUserHandle();
 
         try {
             final ShortcutQuery q = new ShortcutQuery()
@@ -101,7 +101,7 @@
                     ;
 
             final List<String> pinned = new ArrayList<>();
-            for (ShortcutInfo si : mLauncherApps.getShortcuts(q, android.os.Process.myUserHandle())) {
+            for (ShortcutInfo si : mLauncherApps.getShortcuts(q, user)) {
                 pinned.add(si.getId());
             }
             if (selected.isPinned()) {
@@ -126,6 +126,7 @@
 
     @Override
     protected void refreshList() {
+        Log.i(TAG, "Refreshing shortcuts");
         try {
             if (!mLauncherApps.hasShortcutHostPermission()) {
                 return;
@@ -134,6 +135,25 @@
             final List<ShortcutInfo> list = new ArrayList<>();
 
             for (UserHandle user : getTargetUsers()) {
+                if (!mUserManager.isUserUnlocked(user)) {
+                    continue;
+                }
+
+                // To detect a race condition, first fetch all shortcuts and report if none found.
+                mQuery.setQueryFlags(
+                        ShortcutQuery.FLAG_MATCH_PINNED | ShortcutQuery.FLAG_MATCH_DYNAMIC
+                                | ShortcutQuery.FLAG_MATCH_MANIFEST
+                                | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY);
+                mQuery.setPackage(null);
+                mQuery.setActivity(null);
+                mQuery.setChangedSince(0);
+                final int numShortcuts = mLauncherApps.getShortcuts(mQuery, user).size();
+                if (numShortcuts == 0) {
+                    final String message = "No shortcut found for " + user;
+                    Log.e(TAG, message);
+                    Global.showToast(getContext(), message);
+                }
+
                 final Bundle b = getArguments();
                 mQuery.setQueryFlags(
                         (b.getBoolean(ARG_INCLUDE_DYNAMIC) ? ShortcutQuery.FLAG_MATCH_DYNAMIC : 0) |