Merge "Using a proxy call for isAttachedToWindow for pre 19 devices" into ub-now-queens
diff --git a/res/drawable-hdpi/ic_pageindicator_current.png b/res/drawable-hdpi/ic_pageindicator_current.png
index 2e841f5..283f44d 100644
--- a/res/drawable-hdpi/ic_pageindicator_current.png
+++ b/res/drawable-hdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_pageindicator_default.png b/res/drawable-hdpi/ic_pageindicator_default.png
index 07ab948..e63ee50 100644
--- a/res/drawable-hdpi/ic_pageindicator_default.png
+++ b/res/drawable-hdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_pageindicator_current.png b/res/drawable-mdpi/ic_pageindicator_current.png
index 08f43b4..b41e1bb 100644
--- a/res/drawable-mdpi/ic_pageindicator_current.png
+++ b/res/drawable-mdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_pageindicator_default.png b/res/drawable-mdpi/ic_pageindicator_default.png
index 635be4a..7584a9e 100644
--- a/res/drawable-mdpi/ic_pageindicator_default.png
+++ b/res/drawable-mdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pageindicator_current.png b/res/drawable-xhdpi/ic_pageindicator_current.png
index 0e9a52f..8fa774d 100644
--- a/res/drawable-xhdpi/ic_pageindicator_current.png
+++ b/res/drawable-xhdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pageindicator_default.png b/res/drawable-xhdpi/ic_pageindicator_default.png
index d0f14cd..f9c71b1 100644
--- a/res/drawable-xhdpi/ic_pageindicator_default.png
+++ b/res/drawable-xhdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_pageindicator_current.png b/res/drawable-xxhdpi/ic_pageindicator_current.png
index b74e92e..22b290e 100644
--- a/res/drawable-xxhdpi/ic_pageindicator_current.png
+++ b/res/drawable-xxhdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_pageindicator_default.png b/res/drawable-xxhdpi/ic_pageindicator_default.png
index e362ece..b9b5066 100644
--- a/res/drawable-xxhdpi/ic_pageindicator_default.png
+++ b/res/drawable-xxhdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 0858d6a..6f95bd5 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -17,7 +17,7 @@
 <!-- Full screen view projects under the status bar and contains the background -->
 <com.android.launcher3.LauncherRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:id="@+id/launcher"
     android:layout_width="match_parent"
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 7ba7a89..9e4c245 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -17,7 +17,7 @@
 <!-- Full screen view projects under the status bar and contains the background -->
 <com.android.launcher3.LauncherRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:id="@+id/launcher"
     android:layout_width="match_parent"
diff --git a/res/layout-port/qsb.xml b/res/layout-port/qsb.xml
index 4c9963d..0afc2d2 100644
--- a/res/layout-port/qsb.xml
+++ b/res/layout-port/qsb.xml
@@ -15,7 +15,7 @@
 -->
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/search_frame">
diff --git a/res/layout-sw720dp/external_widget_drop_list_item.xml b/res/layout-sw720dp/external_widget_drop_list_item.xml
deleted file mode 100644
index 48e333b..0000000
--- a/res/layout-sw720dp/external_widget_drop_list_item.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="match_parent"
-    android:layout_height="64dp">
-    <ImageView
-        android:id="@+id/provider_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:layout_marginStart="20dp"
-        android:maxWidth="32dp"
-        android:maxHeight="32dp"
-        android:scaleType="fitCenter"
-        android:src="@mipmap/ic_launcher_application" />
-    <TextView
-        android:id="@+id/provider"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginStart="5dp"
-        android:gravity="center_vertical"
-        android:textSize="18sp" />
-</LinearLayout>
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index d4fa2fa..1ef7df5 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -17,7 +17,7 @@
 <!-- Full screen view projects under the status bar and contains the background -->
 <com.android.launcher3.LauncherRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:id="@+id/launcher"
     android:layout_width="match_parent"
diff --git a/res/layout-sw720dp/qsb.xml b/res/layout-sw720dp/qsb.xml
index 4c9963d..0afc2d2 100644
--- a/res/layout-sw720dp/qsb.xml
+++ b/res/layout-sw720dp/qsb.xml
@@ -15,7 +15,7 @@
 -->
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/search_frame">
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index bf5f71b..e42576f 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.AppsCustomizeTabHost
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:clipChildren="false">
 
     <LinearLayout
diff --git a/res/layout/apps_customize_widget.xml b/res/layout/apps_customize_widget.xml
index e299b32..a8344e3 100644
--- a/res/layout/apps_customize_widget.xml
+++ b/res/layout/apps_customize_widget.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.PagedViewWidget
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:layout_width="match_parent"
     android:layout_height="match_parent"
@@ -66,7 +66,7 @@
         android:background="@color/widget_text_panel"
         android:orientation="horizontal">
         <!-- The name of the widget. -->
-        <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        <TextView
             android:id="@+id/widget_name"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -85,7 +85,7 @@
 
         <!-- The original dimensions of the widget (can't be the same text as above due to different
              style. -->
-        <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        <TextView
             android:id="@+id/widget_dims"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
index dc9ed2a..7bef889 100644
--- a/res/layout/hotseat.xml
+++ b/res/layout/hotseat.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.Hotseat
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+    xmlns:launcher="http://schemas.android.com/apk/res-auto">
     <com.android.launcher3.CellLayout
         android:id="@+id/layout"
         android:layout_width="wrap_content"
diff --git a/res/layout/launcher_overlay_example.xml b/res/layout/launcher_overlay_example.xml
index 1556b6f..7d92d4f 100644
--- a/res/layout/launcher_overlay_example.xml
+++ b/res/layout/launcher_overlay_example.xml
@@ -16,7 +16,7 @@
 
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     launcher:layout_ignoreInsets="true">
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
index 14eff75..68fe3dd 100644
--- a/res/layout/page_indicator.xml
+++ b/res/layout/page_indicator.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.PageIndicator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:animateLayoutChanges="true"
     launcher:windowSize="@integer/config_maxNumberOfPageIndicatorsToShow">
 </com.android.launcher3.PageIndicator>
diff --git a/res/layout/page_indicator_marker.xml b/res/layout/page_indicator_marker.xml
index 7c0c389..686d275 100644
--- a/res/layout/page_indicator_marker.xml
+++ b/res/layout/page_indicator_marker.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.PageIndicatorMarker
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="16dp"
     android:layout_height="16dp"
     android:layout_gravity="center_vertical">
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index 31e9da0..ed8d43e 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -16,7 +16,7 @@
 
 <com.android.launcher3.Folder
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:orientation="vertical"
diff --git a/res/layout/workspace_screen.xml b/res/layout/workspace_screen.xml
index 855cf39..83b319b 100644
--- a/res/layout/workspace_screen.xml
+++ b/res/layout/workspace_screen.xml
@@ -16,7 +16,7 @@
 
 <com.android.launcher3.CellLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
diff --git a/res/mipmap-hdpi/ic_launcher_application.png b/res/mipmap-hdpi/ic_launcher_application.png
deleted file mode 100644
index b9aa101..0000000
--- a/res/mipmap-hdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_application.png b/res/mipmap-mdpi/ic_launcher_application.png
deleted file mode 100644
index 4771b85..0000000
--- a/res/mipmap-mdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_application.png b/res/mipmap-xhdpi/ic_launcher_application.png
deleted file mode 100644
index 932f0f7..0000000
--- a/res/mipmap-xhdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_application.png b/res/mipmap-xxhdpi/ic_launcher_application.png
deleted file mode 100644
index 7fc739a..0000000
--- a/res/mipmap-xxhdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/src/com/android/launcher3/AppsCustomizeTabHost.java b/src/com/android/launcher3/AppsCustomizeTabHost.java
index df65cba..69e3ac1 100644
--- a/src/com/android/launcher3/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher3/AppsCustomizeTabHost.java
@@ -16,27 +16,13 @@
 
 package com.android.launcher3;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
 import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Color;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.TabHost;
-import android.widget.TabWidget;
-import android.widget.TextView;
-
-import java.util.ArrayList;
 
 public class AppsCustomizeTabHost extends FrameLayout implements LauncherTransitionable, Insettable  {
     static final String LOG_TAG = "AppsCustomizeTabHost";
diff --git a/src/com/android/launcher3/InstallWidgetReceiver.java b/src/com/android/launcher3/InstallWidgetReceiver.java
deleted file mode 100644
index 74b9e3d..0000000
--- a/src/com/android/launcher3/InstallWidgetReceiver.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.ClipData;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.database.DataSetObserver;
-import android.graphics.drawable.Drawable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-
-import java.util.List;
-
-
-/**
- * We will likely flesh this out later, to handle allow external apps to place widgets, but for now,
- * we just want to expose the action around for checking elsewhere.
- */
-public class InstallWidgetReceiver {
-    public static final String ACTION_INSTALL_WIDGET =
-            "com.android.launcher3.action.INSTALL_WIDGET";
-    public static final String ACTION_SUPPORTS_CLIPDATA_MIMETYPE =
-            "com.android.launcher3.action.SUPPORTS_CLIPDATA_MIMETYPE";
-
-    // Currently not exposed.  Put into Intent when we want to make it public.
-    // TEMP: Should we call this "EXTRA_APPWIDGET_PROVIDER"?
-    public static final String EXTRA_APPWIDGET_COMPONENT =
-        "com.android.launcher3.extra.widget.COMPONENT";
-    public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA_MIME_TYPE =
-        "com.android.launcher3.extra.widget.CONFIGURATION_DATA_MIME_TYPE";
-    public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA =
-        "com.android.launcher3.extra.widget.CONFIGURATION_DATA";
-
-    /**
-     * A simple data class that contains per-item information that the adapter below can reference.
-     */
-    public static class WidgetMimeTypeHandlerData {
-        public ResolveInfo resolveInfo;
-        public AppWidgetProviderInfo widgetInfo;
-
-        public WidgetMimeTypeHandlerData(ResolveInfo rInfo, AppWidgetProviderInfo wInfo) {
-            resolveInfo = rInfo;
-            widgetInfo = wInfo;
-        }
-    }
-
-    /**
-     * The ListAdapter which presents all the valid widgets that can be created for a given drop.
-     */
-    public static class WidgetListAdapter implements ListAdapter, DialogInterface.OnClickListener {
-        private LayoutInflater mInflater;
-        private Launcher mLauncher;
-        private String mMimeType;
-        private ClipData mClipData;
-        private List<WidgetMimeTypeHandlerData> mActivities;
-        private int mTargetLayoutScreen;
-        private int[] mTargetLayoutPos;
-
-        public WidgetListAdapter(Launcher l, String mimeType, ClipData data,
-                List<WidgetMimeTypeHandlerData> list, int targetScreen, int[] targetPos) {
-            mLauncher = l;
-            mMimeType = mimeType;
-            mClipData = data;
-            mActivities = list;
-            mTargetLayoutScreen = targetScreen;
-            mTargetLayoutPos = targetPos;
-        }
-
-        @Override
-        public void registerDataSetObserver(DataSetObserver observer) {
-        }
-
-        @Override
-        public void unregisterDataSetObserver(DataSetObserver observer) {
-        }
-
-        @Override
-        public int getCount() {
-            return mActivities.size();
-        }
-
-        @Override
-        public Object getItem(int position) {
-            return null;
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public boolean hasStableIds() {
-            return true;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            final Context context = parent.getContext();
-            final PackageManager packageManager = context.getPackageManager();
-
-            // Lazy-create inflater
-            if (mInflater == null) {
-                mInflater = LayoutInflater.from(context);
-            }
-
-            // Use the convert-view where possible
-            if (convertView == null) {
-                convertView = mInflater.inflate(R.layout.external_widget_drop_list_item, parent,
-                        false);
-            }
-
-            final WidgetMimeTypeHandlerData data = mActivities.get(position);
-            final ResolveInfo resolveInfo = data.resolveInfo;
-            final AppWidgetProviderInfo widgetInfo = data.widgetInfo;
-
-            // Set the icon
-            Drawable d = resolveInfo.loadIcon(packageManager);
-            ImageView i = (ImageView) convertView.findViewById(R.id.provider_icon);
-            i.setImageDrawable(d);
-
-            // Set the text
-            final CharSequence component = resolveInfo.loadLabel(packageManager);
-            final int[] widgetSpan = new int[2];
-            CellLayout.rectToCell(widgetInfo.minWidth, widgetInfo.minHeight, widgetSpan);
-            TextView t = (TextView) convertView.findViewById(R.id.provider);
-            t.setText(context.getString(R.string.external_drop_widget_pick_format,
-                    component, widgetSpan[0], widgetSpan[1]));
-
-            return convertView;
-        }
-
-        @Override
-        public int getItemViewType(int position) {
-            return 0;
-        }
-
-        @Override
-        public int getViewTypeCount() {
-            return 1;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return mActivities.isEmpty();
-        }
-
-        @Override
-        public boolean areAllItemsEnabled() {
-            return false;
-        }
-
-        @Override
-        public boolean isEnabled(int position) {
-            return true;
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            final AppWidgetProviderInfo widgetInfo = mActivities.get(which).widgetInfo;
-
-            final PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo(widgetInfo, mMimeType,
-                    mClipData);
-            mLauncher.addAppWidgetFromDrop(createInfo, LauncherSettings.Favorites.CONTAINER_DESKTOP,
-                    mTargetLayoutScreen, null, null, mTargetLayoutPos);
-        }
-    }
-}
diff --git a/src/com/android/launcher3/PagedViewWidgetImageView.java b/src/com/android/launcher3/PagedViewWidgetImageView.java
index 71f5eea..7d82795 100644
--- a/src/com/android/launcher3/PagedViewWidgetImageView.java
+++ b/src/com/android/launcher3/PagedViewWidgetImageView.java
@@ -21,7 +21,7 @@
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
-class PagedViewWidgetImageView extends ImageView {
+public class PagedViewWidgetImageView extends ImageView {
     public boolean mAllowRequestLayout = true;
 
     public PagedViewWidgetImageView(Context context, AttributeSet attrs) {
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index a84bf02..601f04c 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -20,6 +20,7 @@
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionCallback;
 import android.content.pm.PackageInstaller.SessionInfo;
+import android.os.Handler;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -29,15 +30,18 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 
-public class PackageInstallerCompatVL extends PackageInstallerCompat {
+public class PackageInstallerCompatVL extends PackageInstallerCompat implements Runnable {
 
     private static final String TAG = "PackageInstallerCompatVL";
     private static final boolean DEBUG = false;
 
+    // All updates to these sets must happen on the {@link #mWorker} thread.
     private final SparseArray<SessionInfo> mPendingReplays = new SparseArray<SessionInfo>();
     private final HashSet<String> mPendingBadgeUpdates = new HashSet<String>();
+
     private final PackageInstaller mInstaller;
     private final IconCache mCache;
+    private final Handler mWorker;
 
     private boolean mResumed;
     private boolean mBound;
@@ -46,16 +50,23 @@
         mInstaller = context.getPackageManager().getPackageInstaller();
         LauncherAppState.setApplicationContext(context.getApplicationContext());
         mCache = LauncherAppState.getInstance().getIconCache();
+        mWorker = new Handler();
 
         mResumed = false;
         mBound = false;
 
-        mInstaller.registerSessionCallback(mCallback);
+        mInstaller.registerSessionCallback(mCallback, mWorker);
 
         // On start, send updates for all active sessions
-        for (SessionInfo info : mInstaller.getAllSessions()) {
-            mPendingReplays.append(info.getSessionId(), info);
-        }
+        mWorker.post(new Runnable() {
+
+            @Override
+            public void run() {
+                for (SessionInfo info : mInstaller.getAllSessions()) {
+                    mPendingReplays.append(info.getSessionId(), info);
+                }
+            }
+        });
     }
 
     @Override
@@ -87,7 +98,7 @@
     @Override
     public void onFinishBind() {
         mBound = true;
-        replayUpdates(null);
+        mWorker.post(this);
     }
 
     @Override
@@ -98,7 +109,7 @@
     @Override
     public void onResume() {
         mResumed = true;
-        replayUpdates(null);
+        mWorker.post(this);
     }
 
     @Override
@@ -106,6 +117,12 @@
         // No op
     }
 
+    @Override
+    public void run() {
+        // Called on mWorker thread.
+        replayUpdates(null);
+    }
+
     private void replayUpdates(PackageInstallInfo newInfo) {
         if (DEBUG) Log.d(TAG, "updates resumed");
         if (!mResumed || !mBound) {