Revert "Revert Cls stopping now-master running on googlefood"

This reverts commit 7bc272a11b701a32d2ed91277341c382cbd84aeb.

Conflicts:
	src/com/android/launcher3/BubbleTextView.java

Change-Id: Id1fb2e1249e72658ce5477165c9bcacba9de2b04
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index c85626b..bfcad84 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -94,7 +94,7 @@
     }
 
     private static int initFlags(LauncherActivityInfoCompat info) {
-        int appFlags = info.getApplicationFlags();
+        int appFlags = info.getApplicationInfo().flags;
         int flags = 0;
         if ((appFlags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) {
             flags |= DOWNLOADED_FLAG;
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 992ac58..160a5eb 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -122,6 +122,9 @@
         Drawable iconDrawable = Utilities.createIconDrawable(b);
         setCompoundDrawables(null, iconDrawable, null, null);
         setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
+        if (info.contentDescription != null) {
+            setContentDescription(info.contentDescription);
+        }
         setTag(info);
         if (info.isPromise()) {
             applyState();
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 896be70..2216b9e 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -571,6 +571,9 @@
         textView.setCompoundDrawables(null,
                 Utilities.createIconDrawable(item.getIcon(mIconCache)), null, null);
         textView.setText(item.title);
+        if (item.contentDescription != null) {
+            textView.setContentDescription(item.contentDescription);
+        }
         textView.setTag(item);
         textView.setTextColor(getResources().getColor(R.color.folder_items_text_color));
         textView.setShadowsEnabled(false);
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index be02d35..7d8628d 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -65,6 +65,7 @@
     private static class CacheEntry {
         public Bitmap icon;
         public String title;
+        public String contentDescription;
     }
 
     private static class CacheKey {
@@ -240,6 +241,7 @@
 
             application.title = entry.title;
             application.iconBitmap = entry.icon;
+            application.contentDescription = entry.contentDescription;
         }
     }
 
@@ -262,6 +264,7 @@
             CacheEntry entry = cacheLocked(component, launcherActInfo, null, user);
             if (title != null) {
                 entry.title = title;
+                entry.contentDescription = mUserManager.getBadgedLabelForUser(title, user);
             }
             return entry.icon;
         }
@@ -310,6 +313,7 @@
                     }
                 }
 
+                entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
                 entry.icon = Utilities.createIconBitmap(
                         info.getBadgedIcon(mIconDpi), mContext);
             } else {
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index 74f16e3..fe03017 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -108,6 +108,11 @@
     CharSequence title;
 
     /**
+     * Content description of the item.
+     */
+    String contentDescription;
+
+    /**
      * The position of the item in a drag-and-drop operation.
      */
     int[] dropPos = null;
@@ -115,6 +120,7 @@
     UserHandleCompat user;
 
     ItemInfo() {
+        user = UserHandleCompat.myUserHandle();
     }
 
     ItemInfo(ItemInfo info) {
@@ -127,6 +133,7 @@
         itemType = info.itemType;
         container = info.container;
         user = info.user;
+        contentDescription = info.contentDescription;
         // tempdebug:
         LauncherModel.checkItemInfo(this);
     }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4ca3c50..f8c38ec 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2794,8 +2794,8 @@
                 // Could be launching some bookkeeping activity
                 startActivity(intent, optsBundle);
             } else {
-                launcherApps.startActivityForProfile(intent.getComponent(),
-                        intent.getSourceBounds(), optsBundle, user);
+                launcherApps.startActivityForProfile(intent.getComponent(), user,
+                        intent.getSourceBounds(), optsBundle);
             }
             return true;
         } catch (SecurityException e) {
@@ -4730,7 +4730,9 @@
 
     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,
             Bitmap icon, UserHandleCompat user) {
-        return new ShortcutInfo(shortcutIntent, caption, icon, user);
+        UserManagerCompat userManager = UserManagerCompat.getInstance(this);
+        String contentDescription = userManager.getBadgedLabelForUser(caption.toString(), user);
+        return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);
     }
 
     protected void moveWorkspaceToDefaultScreen() {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 79bc084..27bcd81 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -95,7 +95,7 @@
         mBuildInfo = BuildInfo.loadByName(sContext.getString(R.string.build_info_class));
         mModel = new LauncherModel(this, mIconCache, mAppFilter);
         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext);
-        launcherApps.addOnAppsChangedListener(mModel);
+        launcherApps.addOnAppsChangedCallback(mModel);
 
         // Register intent receivers
         IntentFilter filter = new IntentFilter();
@@ -128,7 +128,7 @@
     public void onTerminate() {
         sContext.unregisterReceiver(mModel);
         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext);
-        launcherApps.removeOnAppsChangedListener(mModel);
+        launcherApps.removeOnAppsChangedCallback(mModel);
 
         ContentResolver resolver = sContext.getContentResolver();
         resolver.unregisterContentObserver(mFavoritesObserver);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 4d0ec78..29cfbb2 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -73,7 +73,7 @@
  * for the Launcher.
  */
 public class LauncherModel extends BroadcastReceiver
-        implements LauncherAppsCompat.OnAppsChangedListenerCompat {
+        implements LauncherAppsCompat.OnAppsChangedCallbackCompat {
     static final boolean DEBUG_LOADERS = false;
     private static final boolean DEBUG_RECEIVER = true;  // STOPSHIP(cwren) temporary for debugging
 
@@ -1203,28 +1203,28 @@
     }
 
     @Override
-    public void onPackageChanged(UserHandleCompat user, String packageName) {
+    public void onPackageChanged(String packageName, UserHandleCompat user) {
         int op = PackageUpdatedTask.OP_UPDATE;
         enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName },
                 user));
     }
 
     @Override
-    public void onPackageRemoved(UserHandleCompat user, String packageName) {
+    public void onPackageRemoved(String packageName, UserHandleCompat user) {
         int op = PackageUpdatedTask.OP_REMOVE;
         enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName },
                 user));
     }
 
     @Override
-    public void onPackageAdded(UserHandleCompat user, String packageName) {
+    public void onPackageAdded(String packageName, UserHandleCompat user) {
         int op = PackageUpdatedTask.OP_ADD;
         enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName },
                 user));
     }
 
     @Override
-    public void onPackagesAvailable(UserHandleCompat user, String[] packageNames,
+    public void onPackagesAvailable(String[] packageNames, UserHandleCompat user,
             boolean replacing) {
         if (!replacing) {
             enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_ADD, packageNames,
@@ -1243,7 +1243,7 @@
     }
 
     @Override
-    public void onPackagesUnavailable(UserHandleCompat user, String[] packageNames,
+    public void onPackagesUnavailable(String[] packageNames, UserHandleCompat user,
             boolean replacing) {
         if (!replacing) {
             enqueuePackageUpdated(new PackageUpdatedTask(
@@ -2837,6 +2837,7 @@
                         if (isShortcutInfoUpdateable(i)) {
                             ShortcutInfo info = (ShortcutInfo) i;
                             info.title = a.title.toString();
+                            info.contentDescription = a.contentDescription;
                             updateItemInDatabase(context, info);
                         }
                     }
@@ -2972,6 +2973,8 @@
             info.title = "";
         }
         info.user = UserHandleCompat.myUserHandle();
+        info.contentDescription = mUserManager.getBadgedLabelForUser(
+                info.title.toString(), info.user);
         info.setIcon(mIconCache.getIcon(intent, info.title.toString(), info.user));
         info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
         info.restoredIntent = intent;
@@ -3079,6 +3082,8 @@
         }
         info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
         info.user = user;
+        info.contentDescription = mUserManager.getBadgedLabelForUser(
+                info.title.toString(), info.user);
         return info;
     }
 
@@ -3360,6 +3365,8 @@
         info.setIcon(icon);
 
         info.title = name;
+        info.contentDescription = mUserManager.getBadgedLabelForUser(
+                info.title.toString(), info.user);
         info.intent = intent;
         info.customIcon = customIcon;
         info.iconResource = iconResource;
diff --git a/src/com/android/launcher3/PagedViewIcon.java b/src/com/android/launcher3/PagedViewIcon.java
index f7cb997..713d3a4 100644
--- a/src/com/android/launcher3/PagedViewIcon.java
+++ b/src/com/android/launcher3/PagedViewIcon.java
@@ -77,6 +77,9 @@
         setCompoundDrawables(null, icon, null, null);
         setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
         setText(info.title);
+        if (info.contentDescription != null) {
+            setContentDescription(info.contentDescription);
+        }
         setTag(info);
     }
 
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index a84a903..d2573a4 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -119,10 +119,12 @@
         }
     }
 
-    ShortcutInfo(Intent intent, CharSequence title, Bitmap icon, UserHandleCompat user) {
+    ShortcutInfo(Intent intent, CharSequence title, String contentDescrition,
+            Bitmap icon, UserHandleCompat user) {
         this();
         this.intent = intent;
         this.title = title;
+        this.contentDescription = contentDescription;
         mIcon = icon;
         this.user = user;
     }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 74ef1d4..550b203 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -4781,6 +4781,7 @@
                 shortcutInfo.restore();
                 shortcutInfo.updateIcon(mIconCache);
                 shortcutInfo.title = appInfo.title.toString();
+                shortcutInfo.contentDescription = appInfo.contentDescription;
                 shortcut.applyFromShortcutInfo(shortcutInfo, mIconCache);
             }
         }
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
index 3ba93ea..90a4d1a 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
@@ -17,6 +17,7 @@
 package com.android.launcher3.compat;
 
 import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
 import android.graphics.drawable.Drawable;
 
 public abstract class LauncherActivityInfoCompat {
@@ -28,7 +29,7 @@
     public abstract UserHandleCompat getUser();
     public abstract CharSequence getLabel();
     public abstract Drawable getIcon(int density);
-    public abstract int getApplicationFlags();
+    public abstract ApplicationInfo getApplicationInfo();
     public abstract long getFirstInstallTime();
     public abstract Drawable getBadgedIcon(int density);
 }
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
index 052d434..1d41a6f 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
@@ -18,6 +18,7 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
@@ -75,8 +76,8 @@
         return d;
     }
 
-    public int getApplicationFlags() {
-        return mActivityInfo.applicationInfo.flags;
+    public ApplicationInfo getApplicationInfo() {
+        return mActivityInfo.applicationInfo;
     }
 
     public long getFirstInstallTime() {
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
index 76125bd..b52cf1d 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
@@ -17,66 +17,44 @@
 package com.android.launcher3.compat;
 
 import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.LauncherActivityInfo;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
 public class LauncherActivityInfoCompatVL extends LauncherActivityInfoCompat {
-    private Object mLauncherActivityInfo;
-    private Class mLauncherActivityInfoClass;
-    private Method mGetComponentName;
-    private Method mGetUser;
-    private Method mGetLabel;
-    private Method mGetIcon;
-    private Method mGetApplicationFlags;
-    private Method mGetFirstInstallTime;
-    private Method mGetBadgedIcon;
+    private LauncherActivityInfo mLauncherActivityInfo;
 
-    LauncherActivityInfoCompatVL(Object launcherActivityInfo) {
+    LauncherActivityInfoCompatVL(LauncherActivityInfo launcherActivityInfo) {
         super();
         mLauncherActivityInfo = launcherActivityInfo;
-        mLauncherActivityInfoClass = ReflectUtils.getClassForName(
-                "android.content.pm.LauncherActivityInfo");
-        mGetComponentName = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getComponentName");
-        mGetUser = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getUser");
-        mGetLabel = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getLabel");
-        mGetIcon = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getIcon", int.class);
-        mGetApplicationFlags = ReflectUtils.getMethod(mLauncherActivityInfoClass,
-                "getApplicationFlags");
-        mGetFirstInstallTime = ReflectUtils.getMethod(mLauncherActivityInfoClass,
-                "getFirstInstallTime");
-        mGetBadgedIcon = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getBadgedIcon",
-                int.class);
     }
 
     public ComponentName getComponentName() {
-        return (ComponentName) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetComponentName);
+        return mLauncherActivityInfo.getComponentName();
     }
 
     public UserHandleCompat getUser() {
-        return UserHandleCompat.fromUser((UserHandle) ReflectUtils.invokeMethod(
-                        mLauncherActivityInfo, mGetUser));
+        return UserHandleCompat.fromUser(mLauncherActivityInfo.getUser());
     }
 
     public CharSequence getLabel() {
-        return (CharSequence) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetLabel);
+        return mLauncherActivityInfo.getLabel();
     }
 
     public Drawable getIcon(int density) {
-        return (Drawable) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetIcon, density);
+        return mLauncherActivityInfo.getIcon(density);
     }
 
-    public int getApplicationFlags() {
-        return (Integer) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetApplicationFlags);
+    public ApplicationInfo getApplicationInfo() {
+        return mLauncherActivityInfo.getApplicationInfo();
     }
 
     public long getFirstInstallTime() {
-        return (Long) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetFirstInstallTime);
+        return mLauncherActivityInfo.getFirstInstallTime();
     }
 
     public Drawable getBadgedIcon(int density) {
-        return (Drawable) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetBadgedIcon, density);
+        return mLauncherActivityInfo.getBadgedIcon(density);
     }
 }
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 069e3de..8d978d4 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -39,40 +39,42 @@
     public static final String ACTION_MANAGED_PROFILE_REMOVED =
             "android.intent.action.MANAGED_PROFILE_REMOVED";
 
-    public interface OnAppsChangedListenerCompat {
-        void onPackageRemoved(UserHandleCompat user, String packageName);
-        void onPackageAdded(UserHandleCompat user, String packageName);
-        void onPackageChanged(UserHandleCompat user, String packageName);
-        void onPackagesAvailable(UserHandleCompat user, String[] packageNames, boolean replacing);
-        void onPackagesUnavailable(UserHandleCompat user, String[] packageNames, boolean replacing);
+    public interface OnAppsChangedCallbackCompat {
+        void onPackageRemoved(String packageName, UserHandleCompat user);
+        void onPackageAdded(String packageName, UserHandleCompat user);
+        void onPackageChanged(String packageName, UserHandleCompat user);
+        void onPackagesAvailable(String[] packageNames, UserHandleCompat user, boolean replacing);
+        void onPackagesUnavailable(String[] packageNames, UserHandleCompat user, boolean replacing);
     }
 
     protected LauncherAppsCompat() {
     }
 
+    private static LauncherAppsCompat sInstance;
+    private static Object sInstanceLock = new Object();
+
     public static LauncherAppsCompat getInstance(Context context) {
-        // TODO change this to use api version once L gets an API number.
-        if ("L".equals(Build.VERSION.CODENAME)) {
-            Object launcherApps = context.getSystemService("launcherapps");
-            if (launcherApps != null) {
-                LauncherAppsCompatVL compat = LauncherAppsCompatVL.build(context, launcherApps);
-                if (compat != null) {
-                    return compat;
+        synchronized (sInstanceLock) {
+            // TODO change this to use api version once L gets an API number.
+            if (sInstance == null) {
+                if ("L".equals(Build.VERSION.CODENAME)) {
+                    sInstance = new LauncherAppsCompatVL(context);
+                } else {
+                    sInstance = new LauncherAppsCompatV16(context);
                 }
             }
+            return sInstance;
         }
-        // Pre L or lunacher apps service not running, or reflection failed to find something.
-        return new LauncherAppsCompatV16(context);
     }
 
     public abstract List<LauncherActivityInfoCompat> getActivityList(String packageName,
             UserHandleCompat user);
     public abstract LauncherActivityInfoCompat resolveActivity(Intent intent,
             UserHandleCompat user);
-    public abstract void startActivityForProfile(ComponentName component, Rect sourceBounds,
-            Bundle opts, UserHandleCompat user);
-    public abstract void addOnAppsChangedListener(OnAppsChangedListenerCompat listener);
-    public abstract void removeOnAppsChangedListener(OnAppsChangedListenerCompat listener);
+    public abstract void startActivityForProfile(ComponentName component, UserHandleCompat user,
+            Rect sourceBounds, Bundle opts);
+    public abstract void addOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
+    public abstract void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
     public abstract boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user);
     public abstract boolean isActivityEnabledForProfile(ComponentName component,
             UserHandleCompat user);
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatV16.java b/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
index c739eb9..f30c28b 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
@@ -39,8 +39,8 @@
 
     private PackageManager mPm;
     private Context mContext;
-    private List<OnAppsChangedListenerCompat> mListeners
-            = new ArrayList<OnAppsChangedListenerCompat>();
+    private List<OnAppsChangedCallbackCompat> mCallbacks
+            = new ArrayList<OnAppsChangedCallbackCompat>();
     private PackageMonitor mPackageMonitor;
 
     LauncherAppsCompatV16(Context context) {
@@ -71,8 +71,8 @@
         return null;
     }
 
-    public void startActivityForProfile(ComponentName component, Rect sourceBounds,
-            Bundle opts, UserHandleCompat user) {
+    public void startActivityForProfile(ComponentName component, UserHandleCompat user,
+            Rect sourceBounds, Bundle opts) {
         Intent launchIntent = new Intent(Intent.ACTION_MAIN);
         launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
         launchIntent.setComponent(component);
@@ -81,18 +81,18 @@
         mContext.startActivity(launchIntent, opts);
     }
 
-    public synchronized void addOnAppsChangedListener(OnAppsChangedListenerCompat listener) {
-        if (listener != null && !mListeners.contains(listener)) {
-            mListeners.add(listener);
-            if (mListeners.size() == 1) {
+    public synchronized void addOnAppsChangedCallback(OnAppsChangedCallbackCompat callback) {
+        if (callback != null && !mCallbacks.contains(callback)) {
+            mCallbacks.add(callback);
+            if (mCallbacks.size() == 1) {
                 registerForPackageIntents();
             }
         }
     }
 
-    public synchronized void removeOnAppsChangedListener(OnAppsChangedListenerCompat listener) {
-        mListeners.remove(listener);
-        if (mListeners.size() == 0) {
+    public synchronized void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat callback) {
+        mCallbacks.remove(callback);
+        if (mCallbacks.size() == 0) {
             unregisterForPackageIntents();
         }
     }
@@ -131,8 +131,8 @@
         mContext.registerReceiver(mPackageMonitor, filter);
     }
 
-    private synchronized List<OnAppsChangedListenerCompat> getListeners() {
-        return new ArrayList<OnAppsChangedListenerCompat>(mListeners);
+    private synchronized List<OnAppsChangedCallbackCompat> getCallbacks() {
+        return new ArrayList<OnAppsChangedCallbackCompat>(mCallbacks);
     }
 
     private class PackageMonitor extends BroadcastReceiver {
@@ -151,39 +151,39 @@
                     return;
                 }
                 if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
-                    for (OnAppsChangedListenerCompat listener : getListeners()) {
-                        listener.onPackageChanged(user, packageName);
+                    for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
+                        callback.onPackageChanged(packageName, user);
                     }
                 } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
                     if (!replacing) {
-                        for (OnAppsChangedListenerCompat listener : getListeners()) {
-                            listener.onPackageRemoved(user, packageName);
+                        for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
+                            callback.onPackageRemoved(packageName, user);
                         }
                     }
                     // else, we are replacing the package, so a PACKAGE_ADDED will be sent
                     // later, we will update the package at this time
                 } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
                     if (!replacing) {
-                        for (OnAppsChangedListenerCompat listener : getListeners()) {
-                            listener.onPackageAdded(user, packageName);
+                        for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
+                            callback.onPackageAdded(packageName, user);
                         }
                     } else {
-                        for (OnAppsChangedListenerCompat listener : getListeners()) {
-                            listener.onPackageChanged(user, packageName);
+                        for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
+                            callback.onPackageChanged(packageName, user);
                         }
                     }
                 }
             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
                 final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                 String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
-                for (OnAppsChangedListenerCompat listener : getListeners()) {
-                    listener.onPackagesAvailable(user, packages, replacing);
+                for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
+                    callback.onPackagesAvailable(packages, user, replacing);
                 }
             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
                 final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                 String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
-                for (OnAppsChangedListenerCompat listener : getListeners()) {
-                    listener.onPackagesUnavailable(user, packages, replacing);
+                for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
+                    callback.onPackagesUnavailable(packages, user, replacing);
                 }
             }
         }
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index 21f2659..ca9b671 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -19,99 +19,48 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.graphics.Rect;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.UserHandle;
 
-import java.lang.reflect.InvocationHandler;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import java.lang.reflect.Proxy;
-import java.lang.reflect.Method;
-
 public class LauncherAppsCompatVL extends LauncherAppsCompat {
 
-    private Object mLauncherApps;
-    private Class mLauncherAppsClass;
-    private Class mListenerClass;
-    private Method mGetActivityList;
-    private Method mResolveActivity;
-    private Method mStartActivityForProfile;
-    private Method mAddOnAppsChangedListener;
-    private Method mRemoveOnAppsChangedListener;
-    private Method mIsPackageEnabledForProfile;
-    private Method mIsActivityEnabledForProfile;
+    private LauncherApps mLauncherApps;
 
-    private Map<OnAppsChangedListenerCompat, Object> mListeners
-            = new HashMap<OnAppsChangedListenerCompat, Object>();
+    private Map<OnAppsChangedCallbackCompat, WrappedCallback> mCallbacks
+            = new HashMap<OnAppsChangedCallbackCompat, WrappedCallback>();
 
-    static LauncherAppsCompatVL build(Context context, Object launcherApps) {
-        LauncherAppsCompatVL compat = new LauncherAppsCompatVL(context, launcherApps);
-
-        compat.mListenerClass = ReflectUtils.getClassForName(
-                "android.content.pm.LauncherApps$OnAppsChangedListener");
-        compat.mLauncherAppsClass = ReflectUtils.getClassForName("android.content.pm.LauncherApps");
-
-        compat.mGetActivityList = ReflectUtils.getMethod(compat.mLauncherAppsClass,
-                "getActivityList",
-                String.class, UserHandle.class);
-        compat.mResolveActivity = ReflectUtils.getMethod(compat.mLauncherAppsClass,
-                "resolveActivity",
-                Intent.class, UserHandle.class);
-        compat.mStartActivityForProfile = ReflectUtils.getMethod(compat.mLauncherAppsClass,
-                "startActivityForProfile",
-                ComponentName.class, Rect.class, Bundle.class, UserHandle.class);
-        compat.mAddOnAppsChangedListener = ReflectUtils.getMethod(compat.mLauncherAppsClass,
-                "addOnAppsChangedListener", compat.mListenerClass);
-        compat.mRemoveOnAppsChangedListener = ReflectUtils.getMethod(compat.mLauncherAppsClass,
-                "removeOnAppsChangedListener", compat.mListenerClass);
-        compat.mIsPackageEnabledForProfile = ReflectUtils.getMethod(compat.mLauncherAppsClass,
-                "isPackageEnabledForProfile", String.class, UserHandle.class);
-        compat.mIsActivityEnabledForProfile = ReflectUtils.getMethod(compat.mLauncherAppsClass,
-                "isActivityEnabledForProfile", ComponentName.class, UserHandle.class);
-
-        if (compat.mListenerClass != null
-                && compat.mLauncherAppsClass != null
-                && compat.mGetActivityList != null
-                && compat.mResolveActivity != null
-                && compat.mStartActivityForProfile != null
-                && compat.mAddOnAppsChangedListener != null
-                && compat.mRemoveOnAppsChangedListener != null
-                && compat.mIsPackageEnabledForProfile != null
-                && compat.mIsActivityEnabledForProfile != null) {
-            return compat;
-        }
-        return null;
-    }
-
-    private LauncherAppsCompatVL(Context context, Object launcherApps) {
+    LauncherAppsCompatVL(Context context) {
         super();
-        mLauncherApps = launcherApps;
+        mLauncherApps = (LauncherApps) context.getSystemService("launcherapps");
     }
 
     public List<LauncherActivityInfoCompat> getActivityList(String packageName,
             UserHandleCompat user) {
-        List<Object> list = (List<Object>) ReflectUtils.invokeMethod(mLauncherApps,
-                mGetActivityList, packageName, user.getUser());
+        List<LauncherActivityInfo> list = mLauncherApps.getActivityList(packageName,
+                user.getUser());
         if (list.size() == 0) {
             return Collections.EMPTY_LIST;
         }
         ArrayList<LauncherActivityInfoCompat> compatList =
                 new ArrayList<LauncherActivityInfoCompat>(list.size());
-        for (Object info : list) {
+        for (LauncherActivityInfo info : list) {
             compatList.add(new LauncherActivityInfoCompatVL(info));
         }
         return compatList;
     }
 
     public LauncherActivityInfoCompat resolveActivity(Intent intent, UserHandleCompat user) {
-        Object activity = ReflectUtils.invokeMethod(mLauncherApps, mResolveActivity,
-                        intent, user.getUser());
+        LauncherActivityInfo activity = mLauncherApps.resolveActivity(intent, user.getUser());
         if (activity != null) {
             return new LauncherActivityInfoCompatVL(activity);
         } else {
@@ -119,89 +68,64 @@
         }
     }
 
-    public void startActivityForProfile(ComponentName component, Rect sourceBounds,
-            Bundle opts, UserHandleCompat user) {
-        ReflectUtils.invokeMethod(mLauncherApps, mStartActivityForProfile,
-                component, sourceBounds, opts, user.getUser());
+    public void startActivityForProfile(ComponentName component, UserHandleCompat user,
+            Rect sourceBounds, Bundle opts) {
+        mLauncherApps.startActivityForProfile(component, user.getUser(), sourceBounds, opts);
     }
 
-    public void addOnAppsChangedListener(LauncherAppsCompat.OnAppsChangedListenerCompat listener) {
-        Object wrappedListener = Proxy.newProxyInstance(mListenerClass.getClassLoader(),
-                new Class[]{mListenerClass}, new WrappedListener(listener));
-        synchronized (mListeners) {
-            mListeners.put(listener, wrappedListener);
+    public void addOnAppsChangedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
+        WrappedCallback wrappedCallback = new WrappedCallback(callback);
+        synchronized (mCallbacks) {
+            mCallbacks.put(callback, wrappedCallback);
         }
-        ReflectUtils.invokeMethod(mLauncherApps, mAddOnAppsChangedListener, wrappedListener);
+        mLauncherApps.addOnAppsChangedCallback(wrappedCallback);
     }
 
-    public void removeOnAppsChangedListener(
-            LauncherAppsCompat.OnAppsChangedListenerCompat listener) {
-        Object wrappedListener = null;
-        synchronized (mListeners) {
-            wrappedListener = mListeners.remove(listener);
+    public void removeOnAppsChangedCallback(
+            LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
+        WrappedCallback wrappedCallback = null;
+        synchronized (mCallbacks) {
+            wrappedCallback = mCallbacks.remove(callback);
         }
-        if (wrappedListener != null) {
-            ReflectUtils.invokeMethod(mLauncherApps, mRemoveOnAppsChangedListener, wrappedListener);
+        if (wrappedCallback != null) {
+            mLauncherApps.removeOnAppsChangedCallback(wrappedCallback);
         }
     }
 
     public boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user) {
-        return (Boolean) ReflectUtils.invokeMethod(mLauncherApps, mIsPackageEnabledForProfile,
-                packageName, user.getUser());
+        return mLauncherApps.isPackageEnabledForProfile(packageName, user.getUser());
     }
 
     public boolean isActivityEnabledForProfile(ComponentName component, UserHandleCompat user) {
-        return (Boolean) ReflectUtils.invokeMethod(mLauncherApps, mIsActivityEnabledForProfile,
-                component, user.getUser());
+        return mLauncherApps.isActivityEnabledForProfile(component, user.getUser());
     }
 
-    private static class WrappedListener implements InvocationHandler {
-        private LauncherAppsCompat.OnAppsChangedListenerCompat mListener;
+    private static class WrappedCallback extends LauncherApps.OnAppsChangedCallback {
+        private LauncherAppsCompat.OnAppsChangedCallbackCompat mCallback;
 
-        public WrappedListener(LauncherAppsCompat.OnAppsChangedListenerCompat listener) {
-            mListener = listener;
+        public WrappedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
+            mCallback = callback;
         }
 
-        public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
-            try {
-                String methodName = m.getName();
-                if ("onPackageRemoved".equals(methodName)) {
-                    onPackageRemoved((UserHandle) args[0], (String) args[1]);
-                } else if ("onPackageAdded".equals(methodName)) {
-                    onPackageAdded((UserHandle) args[0], (String) args[1]);
-                } else if ("onPackageChanged".equals(methodName)) {
-                    onPackageChanged((UserHandle) args[0], (String) args[1]);
-                } else if ("onPackagesAvailable".equals(methodName)) {
-                    onPackagesAvailable((UserHandle) args[0], (String []) args[1],
-                            (Boolean) args[2]);
-                } else if ("onPackagesUnavailable".equals(methodName)) {
-                    onPackagesUnavailable((UserHandle) args[0], (String []) args[1],
-                            (Boolean) args[2]);
-                }
-            } finally {
-                return null;
-            }
+        public void onPackageRemoved(String packageName, UserHandle user) {
+            mCallback.onPackageRemoved(packageName, UserHandleCompat.fromUser(user));
         }
 
-        public void onPackageRemoved(UserHandle user, String packageName) {
-            mListener.onPackageRemoved(UserHandleCompat.fromUser(user), packageName);
+        public void onPackageAdded(String packageName, UserHandle user) {
+            mCallback.onPackageAdded(packageName, UserHandleCompat.fromUser(user));
         }
 
-        public void onPackageAdded(UserHandle user, String packageName) {
-            mListener.onPackageAdded(UserHandleCompat.fromUser(user), packageName);
+        public void onPackageChanged(String packageName, UserHandle user) {
+            mCallback.onPackageChanged(packageName, UserHandleCompat.fromUser(user));
         }
 
-        public void onPackageChanged(UserHandle user, String packageName) {
-            mListener.onPackageChanged(UserHandleCompat.fromUser(user), packageName);
+        public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
+            mCallback.onPackagesAvailable(packageNames, UserHandleCompat.fromUser(user), replacing);
         }
 
-        public void onPackagesAvailable(UserHandle user, String[] packageNames, boolean replacing) {
-            mListener.onPackagesAvailable(UserHandleCompat.fromUser(user), packageNames, replacing);
-        }
-
-        public void onPackagesUnavailable(UserHandle user, String[] packageNames,
+        public void onPackagesUnavailable(String[] packageNames, UserHandle user,
                 boolean replacing) {
-            mListener.onPackagesUnavailable(UserHandleCompat.fromUser(user), packageNames,
+            mCallback.onPackagesUnavailable(packageNames, UserHandleCompat.fromUser(user),
                     replacing);
         }
     }
diff --git a/src/com/android/launcher3/compat/ReflectUtils.java b/src/com/android/launcher3/compat/ReflectUtils.java
deleted file mode 100644
index e1b8a1f..0000000
--- a/src/com/android/launcher3/compat/ReflectUtils.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.compat;
-
-import android.util.Log;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-public class ReflectUtils {
-    private static final String TAG = "LauncherReflect";
-
-    public static Class getClassForName(String className) {
-        try {
-            return Class.forName(className);
-        } catch (ClassNotFoundException e) {
-            Log.e(TAG, "Couldn't find class " + className, e);
-            return null;
-        }
-    }
-
-    public static Method getMethod(Class clazz, String method) {
-        try {
-            return clazz.getMethod(method);
-        } catch (NoSuchMethodException e) {
-            Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
-            return null;
-        }
-    }
-
-    public static Method getMethod(Class clazz, String method, Class param1) {
-        try {
-            return clazz.getMethod(method, param1);
-        } catch (NoSuchMethodException e) {
-            Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
-            return null;
-        }
-    }
-
-    public static Method getMethod(Class clazz, String method, Class param1, Class param2) {
-        try {
-            return clazz.getMethod(method, param1, param2);
-        } catch (NoSuchMethodException e) {
-            Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
-            return null;
-        }
-    }
-
-    public static Method getMethod(Class clazz, String method, Class param1, Class param2,
-            Class param3) {
-        try {
-            return clazz.getMethod(method, param1, param2, param3);
-        } catch (NoSuchMethodException e) {
-            Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
-            return null;
-        }
-    }
-
-    public static Method getMethod(Class clazz, String method, Class param1, Class param2,
-            Class param3, Class param4) {
-        try {
-            return clazz.getMethod(method, param1, param2, param3, param4);
-        } catch (NoSuchMethodException e) {
-            Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
-            return null;
-        }
-    }
-
-    public static Object invokeMethod(Object object, Method method) {
-        try {
-            return method.invoke(object);
-        } catch (SecurityException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalAccessException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (InvocationTargetException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        }
-        return null;
-    }
-
-    public static Object invokeMethod(Object object, Method method, Object param1) {
-        try {
-            return method.invoke(object, param1);
-        } catch (SecurityException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalAccessException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (InvocationTargetException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        }
-        return null;
-    }
-
-    public static Object invokeMethod(Object object, Method method, Object param1, Object param2) {
-        try {
-            return method.invoke(object, param1, param2);
-        } catch (SecurityException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalAccessException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (InvocationTargetException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        }
-        return null;
-    }
-
-    public static Object invokeMethod(Object object, Method method, Object param1, Object param2,
-            Object param3) {
-        try {
-            return method.invoke(object, param1, param2, param3);
-        } catch (SecurityException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalAccessException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (InvocationTargetException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        }
-        return null;
-    }
-
-    public static Object invokeMethod(Object object, Method method, Object param1, Object param2,
-            Object param3, Object param4) {
-        try {
-            return method.invoke(object, param1, param2, param3, param4);
-        } catch (SecurityException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (IllegalAccessException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        } catch (InvocationTargetException e) {
-            Log.e(TAG, "Couldn't invoke method " + method, e);
-        }
-        return null;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index 256e04a..c10a743 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -41,4 +41,5 @@
     public abstract long getSerialNumberForUser(UserHandleCompat user);
     public abstract UserHandleCompat getUserForSerialNumber(long serialNumber);
     public abstract Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user);
+    public abstract String getBadgedLabelForUser(String label, UserHandleCompat user);
 }
diff --git a/src/com/android/launcher3/compat/UserManagerCompatV16.java b/src/com/android/launcher3/compat/UserManagerCompatV16.java
index 2009e4e..03dd097 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatV16.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatV16.java
@@ -44,4 +44,8 @@
     public long getSerialNumberForUser(UserHandleCompat user) {
         return 0;
     }
+
+    public String getBadgedLabelForUser(String label, UserHandleCompat user) {
+        return label;
+    }
 }
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index 8d3ca85..e071a8f 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -22,9 +22,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 public class UserManagerCompatVL extends UserManagerCompatV17 {
@@ -34,35 +33,27 @@
     }
 
     public List<UserHandleCompat> getUserProfiles() {
-        Method method = ReflectUtils.getMethod(mUserManager.getClass(), "getUserProfiles");
-        if (method != null) {
-            List<UserHandle> users = (List<UserHandle>) ReflectUtils.invokeMethod(
-                    mUserManager, method);
-            if (users != null) {
-                ArrayList<UserHandleCompat> compatUsers = new ArrayList<UserHandleCompat>(
-                        users.size());
-                for (UserHandle user : users) {
-                    compatUsers.add(UserHandleCompat.fromUser(user));
-                }
-                return compatUsers;
-            }
+        List<UserHandle> users = mUserManager.getUserProfiles();
+        if (users == null) {
+            return Collections.EMPTY_LIST;
         }
-        // Fall back to non L version.
-        return super.getUserProfiles();
+        ArrayList<UserHandleCompat> compatUsers = new ArrayList<UserHandleCompat>(
+                users.size());
+        for (UserHandle user : users) {
+            compatUsers.add(UserHandleCompat.fromUser(user));
+        }
+        return compatUsers;
     }
 
     public Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user) {
-        Method method = ReflectUtils.getMethod(mUserManager.getClass(), "getBadgedDrawableForUser",
-                Drawable.class, UserHandle.class);
-        if (method != null) {
-            Drawable d = (Drawable) ReflectUtils.invokeMethod(mUserManager, method, unbadged,
-                    user.getUser());
-            if (d != null) {
-                return d;
-            }
+        return mUserManager.getBadgedDrawableForUser(unbadged, user.getUser());
+    }
+
+    public String getBadgedLabelForUser(String label, UserHandleCompat user) {
+        if (user == null) {
+            return label;
         }
-        // Fall back to non L version.
-        return super.getBadgedDrawableForUser(unbadged, user);
+        return mUserManager.getBadgedLabelForUser(label, user.getUser());
     }
 }