Merge "Preventing overdraw in custom content screen" into ub-launcher3-burnaby
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index fce4691..f9f5fc2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -45,6 +45,10 @@
         android:protectionLevel="signature"
         />
     <permission
+        android:name="com.android.launcher3.permission.RECEIVE_UPDATE_ORIENTATION_BROADCASTS"
+        android:protectionLevel="signature"
+        />
+    <permission
         android:name="com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST"
         android:protectionLevel="signatureOrSystem" />
 
@@ -62,6 +66,7 @@
     <uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" />
     <uses-permission android:name="com.android.launcher3.permission.WRITE_SETTINGS" />
     <uses-permission android:name="com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS" />
+    <uses-permission android:name="com.android.launcher3.permission.RECEIVE_UPDATE_ORIENTATION_BROADCASTS" />
     <uses-permission android:name="com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST" />
 
     <application
@@ -152,7 +157,8 @@
         <activity
             android:name="com.android.launcher3.SettingsActivity"
             android:label="@string/settings_button_text"
-            android:autoRemoveFromRecents="true">
+            android:autoRemoveFromRecents="true"
+            android:process=":settings_process">
         </activity>
 
         <!-- Debugging tools -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 440a537..305c310 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -27,6 +27,9 @@
     <!-- Permission to receive the com.android.launcher3.action.LAUNCH intent -->
     <string name="receive_launch_broadcasts_permission" translatable="false">com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS</string>
 
+    <!-- Permission to receive the com.android.launcher3.SCREEN_ORIENTATION_PREF_CHANGED intent -->
+    <string name="receive_update_orientation_broadcasts_permission" translatable="false">com.android.launcher3.permission.RECEIVE_UPDATE_ORIENTATION_BROADCASTS</string>
+
     <!-- Permission to receive the com.android.launcher3.action.FIRST_LOAD_COMPLETE intent -->
     <string name="receive_first_load_broadcast_permission" translatable="false">com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST</string>
 
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index fe25bb9..3165337 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -275,6 +275,7 @@
             ComponentName component = ComponentName.unflattenFromString(cn);
             PackageInfo info = pkgInfoMap.get(component.getPackageName());
             if (info == null) {
+                remove(component, user);
                 itemsToRemove.add(c.getInt(rowIndex));
                 continue;
             }
@@ -291,6 +292,7 @@
                 continue;
             }
             if (app == null) {
+                remove(component, user);
                 itemsToRemove.add(c.getInt(rowIndex));
             } else {
                 appsToUpdate.add(app);
@@ -562,9 +564,10 @@
      */
     private CacheEntry getEntryForPackageLocked(String packageName, UserHandleCompat user,
             boolean useLowResIcon) {
-        ComponentName cn = new ComponentName(packageName, EMPTY_CLASS_NAME);
+        ComponentName cn = new ComponentName(packageName, packageName + EMPTY_CLASS_NAME);
         ComponentKey cacheKey = new ComponentKey(cn, user);
         CacheEntry entry = mCache.get(cacheKey);
+
         if (entry == null || (entry.isLowResIcon && !useLowResIcon)) {
             entry = new CacheEntry();
             boolean entryUpdated = true;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index dc63a76..6dfe0eb 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -403,22 +403,34 @@
     FocusIndicatorView mFocusHandler;
 
     @Thunk boolean mRotationEnabled = false;
-    private boolean mPreferenceObserverRegistered = false;
+    private boolean mScreenOrientationSettingReceiverRegistered = false;
 
-    final private SharedPreferences.OnSharedPreferenceChangeListener mSettingsObserver =
-            new SharedPreferences.OnSharedPreferenceChangeListener() {
-        @Override
-        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
-            if (Utilities.ALLOW_ROTATION_PREFERENCE_KEY.equals(key)) {
-                if (mRotationEnabled = sharedPreferences.getBoolean(
-                        Utilities.ALLOW_ROTATION_PREFERENCE_KEY, false)) {
-                    unlockScreenOrientation(true);
-                } else {
-                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
+    final private BroadcastReceiver mScreenOrientationSettingReceiver =
+            new BroadcastReceiver() {
+                @Thunk Runnable mUpdateOrientationRunnable = new Runnable() {
+                    public void run() {
+                        setOrientation();
+                    }
+                };
+
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    mRotationEnabled = intent.getBooleanExtra(
+                            Utilities.SCREEN_ROTATION_SETTING_EXTRA, false);
+                    if (!waitUntilResume(mUpdateOrientationRunnable, true)) {
+                        setOrientation();
+                    }
                 }
-            }
+            };
+
+    @Thunk void setOrientation() {
+        if (mRotationEnabled) {
+            unlockScreenOrientation(true);
+        } else {
+            setRequestedOrientation(
+                    ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
         }
-    };
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -520,16 +532,18 @@
         // In case we are on a device with locked rotation, we should look at preferences to check
         // if the user has specifically allowed rotation.
         if (!mRotationEnabled) {
-            getSharedPreferences(LauncherFiles.ROTATION_PREF_FILE,
-                    Context.MODE_MULTI_PROCESS).registerOnSharedPreferenceChangeListener(
-                    mSettingsObserver);
-            mPreferenceObserverRegistered = true;
+            String updateOrientationBroadcastPermission = getResources().getString(
+                    R.string.receive_update_orientation_broadcasts_permission);
+            registerReceiver(mScreenOrientationSettingReceiver,
+                    new IntentFilter(Utilities.SCREEN_ROTATION_SETTING_INTENT),
+                    updateOrientationBroadcastPermission, null);
+            mScreenOrientationSettingReceiverRegistered = true;
             mRotationEnabled = Utilities.isAllowRotationPrefEnabled(getApplicationContext());
         }
 
         // On large interfaces, or on devices that a user has specifically enabled screen rotation,
         // we want the screen to auto-rotate based on the current orientation
-        unlockScreenOrientation(true);
+        setOrientation();
 
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onCreate(savedInstanceState);
@@ -2016,11 +2030,9 @@
     public void onDestroy() {
         super.onDestroy();
 
-        if (mPreferenceObserverRegistered) {
-            getSharedPreferences(LauncherFiles.ROTATION_PREF_FILE,
-                    Context.MODE_MULTI_PROCESS).unregisterOnSharedPreferenceChangeListener(
-                    mSettingsObserver);
-            mPreferenceObserverRegistered = false;
+        if (mScreenOrientationSettingReceiverRegistered) {
+            unregisterReceiver(mScreenOrientationSettingReceiver);
+            mScreenOrientationSettingReceiverRegistered = false;
         }
 
         // Remove all pending runnables
@@ -3663,7 +3675,7 @@
      *
      * @return {@code true} if we are currently paused. The caller might be able to skip some work
      */
-    private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {
+    @Thunk boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {
         if (mPaused) {
             if (LOGD) Log.d(TAG, "Deferring update until onResume");
             if (deletePreviousRunnables) {
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 4974daf..53966a5 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -2932,6 +2932,9 @@
                 }
             });
         }
+
+        // Reload widget list. No need to refresh, as we only want to update the icons and labels.
+        loadAndBindWidgetsAndShortcuts(mApp.getContext(), callbacks, false);
     }
 
     void enqueuePackageUpdated(PackageUpdatedTask task) {
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index a1da1b6..27763f5 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -18,12 +18,14 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.content.Intent;
 import android.os.Bundle;
+import android.preference.Preference;
 import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
 
 /**
- * Settings activity for Launcher. Currently implements the following setting:
- * LockToPortrait
+ * Settings activity for Launcher. Currently implements the following setting: Allow rotation
  */
 public class SettingsActivity extends Activity {
     @Override
@@ -41,13 +43,25 @@
      */
     @SuppressWarnings("WeakerAccess")
     public static class LauncherSettingsFragment extends PreferenceFragment {
-
         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
-            getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE);
+            getPreferenceManager().setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);
             getPreferenceManager().setSharedPreferencesName(LauncherFiles.ROTATION_PREF_FILE);
             addPreferencesFromResource(R.xml.launcher_preferences);
         }
+
+        @Override
+        public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+                                             Preference preference) {
+            boolean allowRotation = getPreferenceManager().getSharedPreferences().getBoolean(
+                    Utilities.ALLOW_ROTATION_PREFERENCE_KEY, false);
+            Intent rotationSetting = new Intent(Utilities.SCREEN_ROTATION_SETTING_INTENT);
+            String launchBroadcastPermission = getResources().getString(
+                            R.string.receive_update_orientation_broadcasts_permission);
+            rotationSetting.putExtra(Utilities.SCREEN_ROTATION_SETTING_EXTRA, allowRotation);
+            getActivity().sendBroadcast(rotationSetting, launchBroadcastPermission);
+            return true;
+        }
     }
 }
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index cffcd34..b267f75 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -93,6 +93,9 @@
     private static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
 
     public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
+    public static final String SCREEN_ROTATION_SETTING_INTENT =
+            "come.android.launcher3.SCREEN_ORIENTATION_PREF_CHANGED";
+    public static final String SCREEN_ROTATION_SETTING_EXTRA = "screenRotationPref";
 
     public static boolean isPropertyEnabled(String propertyName) {
         return Log.isLoggable(propertyName, Log.VERBOSE);
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index 76e6a9d..625d4d6 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -8,7 +8,6 @@
 import com.android.launcher3.IconCache;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
-
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.AlphabeticIndexCompat;
 import com.android.launcher3.compat.UserHandleCompat;