Removing ContentObserver in launcher

> Using callback insted of using a content observer
> Setting the listener in LauncherAppState to prevent resource leak

Change-Id: Id23a4d5c8812e86178997e536226e09ec3740f84
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ce0f304..9989abb 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -36,7 +36,6 @@
 import android.content.BroadcastReceiver;
 import android.content.ComponentCallbacks2;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -48,7 +47,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
-import android.database.ContentObserver;
 import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -241,7 +239,6 @@
 
     private final BroadcastReceiver mCloseSystemDialogsReceiver
             = new CloseSystemDialogsIntentReceiver();
-    private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();
 
     private LayoutInflater mInflater;
 
@@ -438,7 +435,6 @@
 
         LauncherAppState.setApplicationContext(getApplicationContext());
         LauncherAppState app = LauncherAppState.getInstance();
-        LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);
 
         // Load configuration-specific DeviceProfile
         mDeviceProfile = getResources().getConfiguration().orientation
@@ -478,8 +474,6 @@
         setupViews();
         mDeviceProfile.layout(this);
 
-        registerContentObservers();
-
         lockAllApps();
 
         mSavedState = savedInstanceState;
@@ -2017,7 +2011,6 @@
 
         TextKeyListener.getInstance().release();
 
-        getContentResolver().unregisterContentObserver(mWidgetObserver);
         unregisterReceiver(mCloseSystemDialogsReceiver);
 
         mDragLayer.clearAllResizeFrames();
@@ -2386,16 +2379,6 @@
         sFolders.remove(folder.id);
     }
 
-    /**
-     * Registers various content observers. The current implementation registers
-     * only a favorites observer to keep track of the favorites applications.
-     */
-    private void registerContentObservers() {
-        ContentResolver resolver = getContentResolver();
-        resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,
-                true, mWidgetObserver);
-    }
-
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (event.getAction() == KeyEvent.ACTION_DOWN) {
@@ -2452,9 +2435,10 @@
     }
 
     /**
-     * Re-listen when widgets are reset.
+     * Re-listen when widget host is reset.
      */
-    @Thunk void onAppWidgetReset() {
+    @Override
+    public void onAppWidgetHostReset() {
         if (mAppWidgetHost != null) {
             mAppWidgetHost.startListening();
         }
@@ -2939,7 +2923,7 @@
         return false;
     }
 
-    private boolean startActivitySafely(View v, Intent intent, Object tag) {
+    @Thunk boolean startActivitySafely(View v, Intent intent, Object tag) {
         boolean success = false;
         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {
             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
@@ -3562,20 +3546,6 @@
     }
 
     /**
-     * Receives notifications whenever the appwidgets are reset.
-     */
-    private class AppWidgetResetObserver extends ContentObserver {
-        public AppWidgetResetObserver() {
-            super(new Handler());
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            onAppWidgetReset();
-        }
-    }
-
-    /**
      * If the activity is currently paused, signal that we need to run the passed Runnable
      * in onResume.
      *
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 540bdf8..0565d3f 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -84,7 +84,7 @@
 
         mInvariantDeviceProfile = new InvariantDeviceProfile(sContext);
         mIconCache = new IconCache(sContext, mInvariantDeviceProfile);
-        mWidgetCache = new WidgetPreviewLoader(sContext, mInvariantDeviceProfile, mIconCache);
+        mWidgetCache = new WidgetPreviewLoader(sContext, mIconCache);
 
         mAppFilter = AppFilter.loadByName(sContext.getString(R.string.app_filter_class));
         mBuildInfo = BuildInfo.loadByName(sContext.getString(R.string.build_info_class));
@@ -125,6 +125,7 @@
     }
 
     LauncherModel setLauncher(Launcher launcher) {
+        getLauncherProvider().setLauncherProviderChangeListener(launcher);
         mModel.initialize(launcher);
         mAccessibilityDelegate = ((launcher != null) && Utilities.isLmpOrAbove()) ?
             new LauncherAccessibilityDelegate(launcher) : null;
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index cb808c2..71ddb1a 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -80,16 +80,7 @@
 
     private static final String RESTRICTION_PACKAGE_NAME = "workspace.configuration.package.name";
 
-    private LauncherProviderChangeListener mListener;
-
-    /**
-     * {@link Uri} triggered at any registered {@link android.database.ContentObserver} when
-     * {@link AppWidgetHost#deleteHost()} is called during database creation.
-     * Use this to recall {@link AppWidgetHost#startListening()} if needed.
-     */
-    static final Uri CONTENT_APPWIDGET_RESET_URI =
-            Uri.parse("content://" + AUTHORITY + "/appWidgetReset");
-
+    @Thunk LauncherProviderChangeListener mListener;
     @Thunk DatabaseHelper mOpenHelper;
 
     @Override
@@ -279,6 +270,18 @@
         }
     }
 
+    @Thunk void notifyAppWidgetHostReset() {
+        new MainThreadExecutor().execute(new Runnable() {
+
+            @Override
+            public void run() {
+                if (mListener != null) {
+                    mListener.onAppWidgetHostReset();
+                }
+            }
+        });
+    }
+
     @Thunk static void addModifiedTime(ContentValues values) {
         values.put(LauncherSettings.ChangeLogColumns.MODIFIED, System.currentTimeMillis());
     }
@@ -455,17 +458,6 @@
             return mNewDbCreated;
         }
 
-        /**
-         * Send notification that we've deleted the {@link AppWidgetHost},
-         * probably as part of the initial database creation. The receiver may
-         * want to re-call {@link AppWidgetHost#startListening()} to ensure
-         * callbacks are correctly set.
-         */
-        private void sendAppWidgetResetNotify() {
-            final ContentResolver resolver = mContext.getContentResolver();
-            resolver.notifyChange(CONTENT_APPWIDGET_RESET_URI, null);
-        }
-
         @Override
         public void onCreate(SQLiteDatabase db) {
             if (LOGD) Log.d(TAG, "creating new launcher database");
@@ -509,7 +501,14 @@
             // Database was just created, so wipe any previous widgets
             if (mAppWidgetHost != null) {
                 mAppWidgetHost.deleteHost();
-                sendAppWidgetResetNotify();
+
+                /**
+                 * Send notification that we've deleted the {@link AppWidgetHost},
+                 * probably as part of the initial database creation. The receiver may
+                 * want to re-call {@link AppWidgetHost#startListening()} to ensure
+                 * callbacks are correctly set.
+                 */
+                LauncherAppState.getLauncherProvider().notifyAppWidgetHostReset();
             }
 
             // Fresh and clean launcher DB.
@@ -517,7 +516,7 @@
             setFlagEmptyDbCreated();
 
             // When a new DB is created, remove all previously stored managed profile information.
-            ManagedProfileHeuristic.processAllUsers(Collections.EMPTY_LIST, mContext);
+            ManagedProfileHeuristic.processAllUsers(Collections.<UserHandleCompat>emptyList(), mContext);
         }
 
         private void addWorkspacesTable(SQLiteDatabase db) {
diff --git a/src/com/android/launcher3/LauncherProviderChangeListener.java b/src/com/android/launcher3/LauncherProviderChangeListener.java
index 5b5c6c5..1b78e9c 100644
--- a/src/com/android/launcher3/LauncherProviderChangeListener.java
+++ b/src/com/android/launcher3/LauncherProviderChangeListener.java
@@ -10,4 +10,6 @@
     public void onLauncherProviderChange();
 
     public void onSettingsChanged(String settings, boolean value);
+
+    public void onAppWidgetHostReset();
 }
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 75952d1..c1cc42b 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -27,6 +27,7 @@
 import android.os.Handler;
 import android.util.Log;
 import android.util.LongSparseArray;
+
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.UserHandleCompat;
 import com.android.launcher3.compat.UserManagerCompat;
@@ -69,7 +70,7 @@
     private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
     @Thunk final Handler mWorkerHandler;
 
-    public WidgetPreviewLoader(Context context, InvariantDeviceProfile inv, IconCache iconCache) {
+    public WidgetPreviewLoader(Context context, IconCache iconCache) {
         mContext = context;
         mIconCache = iconCache;
         mManager = AppWidgetManagerCompat.getInstance(context);
diff --git a/src/com/android/launcher3/allapps/DefaultAppSearchController.java b/src/com/android/launcher3/allapps/DefaultAppSearchController.java
index 1601c62..a61df3a 100644
--- a/src/com/android/launcher3/allapps/DefaultAppSearchController.java
+++ b/src/com/android/launcher3/allapps/DefaultAppSearchController.java
@@ -56,7 +56,7 @@
     private View mDismissSearchButtonView;
     @Thunk AllAppsSearchEditView mSearchBarEditView;
     @Thunk AllAppsRecyclerView mAppsRecyclerView;
-    private Runnable mFocusRecyclerViewRunnable = new Runnable() {
+    @Thunk Runnable mFocusRecyclerViewRunnable = new Runnable() {
         @Override
         public void run() {
             mAppsRecyclerView.requestFocus();