Merge "Set broadcast nextReceiver correctly when package is disabled" into mnc-dev
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index dbe91f9..0adce5d 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -777,7 +777,9 @@
     public List<ProviderInfo> queryContentProviders(String processName,
                                                     int uid, int flags) {
         try {
-            return mPM.queryContentProviders(processName, uid, flags);
+            ParceledListSlice<ProviderInfo> slice
+                    = mPM.queryContentProviders(processName, uid, flags);
+            return slice != null ? slice.getList() : null;
         } catch (RemoteException e) {
             throw new RuntimeException("Package manager has died", e);
         }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0336645..a5e9faf 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -203,7 +203,7 @@
     void querySyncProviders(inout List<String> outNames,
             inout List<ProviderInfo> outInfo);
 
-    List<ProviderInfo> queryContentProviders(
+    ParceledListSlice queryContentProviders(
             String processName, int uid, int flags);
 
     InstrumentationInfo getInstrumentationInfo(
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 670d3c0..fbe3ece 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -218,7 +218,6 @@
 }
 
 const SkImageInfo& Bitmap::info() const {
-    assertValid();
     return mPixelRef->info();
 }
 
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 8ad7c12..3e4d93b 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -23,6 +23,7 @@
 import android.os.Parcelable;
 import android.os.Trace;
 import android.util.DisplayMetrics;
+import android.util.Log;
 
 import dalvik.system.VMRuntime;
 
@@ -33,6 +34,8 @@
 import java.nio.ShortBuffer;
 
 public final class Bitmap implements Parcelable {
+    private static final String TAG = "Bitmap";
+
     /**
      * Indicates that the bitmap was created for an unknown pixel density.
      *
@@ -159,6 +162,9 @@
      * @see #DENSITY_NONE
      */
     public int getDensity() {
+        if (mRecycled) {
+            Log.w(TAG, "Called getDensity() on a recycle()'d bitmap! This is undefined behavior!");
+        }
         return mDensity;
     }
 
@@ -330,7 +336,9 @@
      * @return The current generation ID for this bitmap.
      */
     public int getGenerationId() {
-        if (mRecycled) return 0;
+        if (mRecycled) {
+            Log.w(TAG, "Called getGenerationId() on a recycle()'d bitmap! This is undefined behavior!");
+        }
         return nativeGenerationId(mFinalizer.mNativeBitmap);
     }
 
@@ -1057,7 +1065,9 @@
      * @see BitmapFactory.Options#inPremultiplied
      */
     public final boolean isPremultiplied() {
-        if (mRecycled) return false;
+        if (mRecycled) {
+            Log.w(TAG, "Called isPremultiplied() on a recycle()'d bitmap! This is undefined behavior!");
+        }
         return nativeIsPremultiplied(mFinalizer.mNativeBitmap);
     }
 
@@ -1089,11 +1099,17 @@
 
     /** Returns the bitmap's width */
     public final int getWidth() {
+        if (mRecycled) {
+            Log.w(TAG, "Called getWidth() on a recycle()'d bitmap! This is undefined behavior!");
+        }
         return mWidth;
     }
 
     /** Returns the bitmap's height */
     public final int getHeight() {
+        if (mRecycled) {
+            Log.w(TAG, "Called getHeight() on a recycle()'d bitmap! This is undefined behavior!");
+        }
         return mHeight;
     }
 
@@ -1176,7 +1192,9 @@
      * @return number of bytes between rows of the native bitmap pixels.
      */
     public final int getRowBytes() {
-        if (mRecycled) return 0;
+        if (mRecycled) {
+            Log.w(TAG, "Called getRowBytes() on a recycle()'d bitmap! This is undefined behavior!");
+        }
         return nativeRowBytes(mFinalizer.mNativeBitmap);
     }
 
@@ -1220,7 +1238,9 @@
      * that config, otherwise return null.
      */
     public final Config getConfig() {
-        if (mRecycled) return Config.ARGB_8888;
+        if (mRecycled) {
+            Log.w(TAG, "Called getConfig() on a recycle()'d bitmap! This is undefined behavior!");
+        }
         return Config.nativeToConfig(nativeConfig(mFinalizer.mNativeBitmap));
     }
 
@@ -1233,7 +1253,9 @@
      * it will return true by default.
      */
     public final boolean hasAlpha() {
-        if (mRecycled) return false;
+        if (mRecycled) {
+            Log.w(TAG, "Called hasAlpha() on a recycle()'d bitmap! This is undefined behavior!");
+        }
         return nativeHasAlpha(mFinalizer.mNativeBitmap);
     }
 
@@ -1270,7 +1292,9 @@
      * @see #setHasMipMap(boolean)
      */
     public final boolean hasMipMap() {
-        if (mRecycled) return false;
+        if (mRecycled) {
+            Log.w(TAG, "Called hasMipMap() on a recycle()'d bitmap! This is undefined behavior!");
+        }
         return nativeHasMipMap(mFinalizer.mNativeBitmap);
     }
 
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index e472e93..6dfb6e8 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -229,10 +229,11 @@
     SkRect dirty;
     mDamageAccumulator.finish(&dirty);
 
-    if (dirty.isEmpty() && Properties::skipEmptyFrames) {
-        mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
-        return;
-    }
+    // TODO: Re-enable after figuring out cause of b/22592975
+//    if (dirty.isEmpty() && Properties::skipEmptyFrames) {
+//        mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
+//        return;
+//    }
 
     mCurrentFrameInfo->markIssueDrawCommandsStart();
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 3e9b122..73971ad 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -42,6 +42,9 @@
 import android.os.Bundle;
 import android.os.DropBoxManager;
 import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.SystemProperties;
@@ -204,9 +207,6 @@
     // We have to call in the user manager with no lock held,
     private volatile UserManager mUserManager;
 
-    // We have to call in the app ops manager with no lock held,
-    private volatile AppOpsManager mAppOpsManager;
-
     // We have to call in the package manager with no lock held,
     private volatile PackageManager mPackageManager;
 
@@ -214,7 +214,6 @@
     public boolean onCreate() {
         synchronized (mLock) {
             mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
-            mAppOpsManager = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
             mPackageManager = getContext().getPackageManager();
             mSettingsRegistry = new SettingsRegistry();
         }
@@ -532,7 +531,7 @@
         } while (cursor.moveToNext());
     }
 
-    private static final String toDumpString(String s) {
+    private static String toDumpString(String s) {
         if (s != null) {
             return s;
         }
@@ -1158,18 +1157,6 @@
                 getCallingPackage());
     }
 
-    private void sendNotify(Uri uri, int userId) {
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            getContext().getContentResolver().notifyChange(uri, null, true, userId);
-            if (DEBUG) {
-                Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
     private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
             int targetSdkVersion, String name) {
         // If the app targets Lollipop MR1 or older SDK we warn, otherwise crash.
@@ -1390,8 +1377,11 @@
 
         private final BackupManager mBackupManager;
 
+        private final Handler mHandler;
+
         public SettingsRegistry() {
             mBackupManager = new BackupManager(getContext());
+            mHandler = new MyHandler(getContext().getMainLooper());
             migrateAllLegacySettingsIfNeeded();
         }
 
@@ -1733,7 +1723,7 @@
 
             // Inform the backup manager about a data change
             if (backedUpDataChanged) {
-                mBackupManager.dataChanged();
+                mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget();
             }
 
             // Now send the notification through the content framework.
@@ -1741,7 +1731,9 @@
             final int userId = getUserIdFromKey(key);
             Uri uri = getNotificationUriFor(key, name);
 
-            sendNotify(uri, userId);
+            mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
+                    userId, 0, uri).sendToTarget();
+
             if (isSecureSettingsKey(key)) {
                 maybeNotifyProfiles(userId, uri, name, sSecureCloneToManagedSettings);
             } else if (isSystemSettingsKey(key)) {
@@ -1758,7 +1750,8 @@
                     UserInfo profile = profiles.get(i);
                     // the notification for userId has already been sent.
                     if (profile.id != userId) {
-                        sendNotify(uri, profile.id);
+                        mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
+                                profile.id, 0, uri).sendToTarget();
                     }
                 }
             }
@@ -1834,6 +1827,33 @@
             }
         }
 
+        private final class MyHandler extends Handler {
+            private static final int MSG_NOTIFY_URI_CHANGED = 1;
+            private static final int MSG_NOTIFY_DATA_CHANGED = 2;
+
+            public MyHandler(Looper looper) {
+                super(looper);
+            }
+
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_NOTIFY_URI_CHANGED: {
+                        final int userId = msg.arg1;
+                        Uri uri = (Uri) msg.obj;
+                        getContext().getContentResolver().notifyChange(uri, null, true, userId);
+                        if (DEBUG) {
+                            Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri);
+                        }
+                    } break;
+
+                    case MSG_NOTIFY_DATA_CHANGED: {
+                        mBackupManager.dataChanged();
+                    } break;
+                }
+            }
+        }
+
         private final class UpgradeController {
             private static final int SETTINGS_VERSION = 122;
 
@@ -1963,9 +1983,11 @@
                     currentVersion = 120;
                 }
 
-                // Before 121, we used a different string encoding logic.  We just bump the version
-                // here; SettingsState knows how to handle pre-version 120 files.
-                currentVersion = 121;
+                if (currentVersion == 120) {
+                    // Before 121, we used a different string encoding logic.  We just bump the
+                    // version here; SettingsState knows how to handle pre-version 120 files.
+                    currentVersion = 121;
+                }
 
                 if (currentVersion == 121) {
                     // Version 122: allow OEMs to set a default payment component in resources.
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 6ab2fd7..53e8d14 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -559,6 +559,7 @@
     private static final int H_FSTRIM = 4;
     private static final int H_VOLUME_MOUNT = 5;
     private static final int H_VOLUME_BROADCAST = 6;
+    private static final int H_INTERNAL_BROADCAST = 7;
 
     class MountServiceHandler extends Handler {
         public MountServiceHandler(Looper looper) {
@@ -655,6 +656,13 @@
                     }
                     break;
                 }
+                case H_INTERNAL_BROADCAST: {
+                    // Internal broadcasts aimed at system components, not for
+                    // third-party apps.
+                    final Intent intent = (Intent) msg.obj;
+                    mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                            android.Manifest.permission.WRITE_MEDIA_STORAGE);
+                }
             }
         }
     }
@@ -1126,8 +1134,7 @@
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
         intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.id);
         intent.putExtra(DiskInfo.EXTRA_VOLUME_COUNT, volumeCount);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
-                android.Manifest.permission.WRITE_MEDIA_STORAGE);
+        mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget();
 
         final CountDownLatch latch = mDiskScanLatches.remove(disk.id);
         if (latch != null) {
@@ -1239,8 +1246,7 @@
             intent.putExtra(VolumeInfo.EXTRA_VOLUME_STATE, newState);
             intent.putExtra(VolumeRecord.EXTRA_FS_UUID, vol.fsUuid);
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
-                    android.Manifest.permission.WRITE_MEDIA_STORAGE);
+            mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget();
         }
 
         final String oldStateEnv = VolumeInfo.getEnvironmentForState(oldState);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 783dea5..e8ffdb6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9154,9 +9154,10 @@
     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
         List<ProviderInfo> providers = null;
         try {
-            providers = AppGlobals.getPackageManager().
+            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
                 queryContentProviders(app.processName, app.uid,
                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
+            providers = slice != null ? slice.getList() : null;
         } catch (RemoteException ex) {
         }
         if (DEBUG_MU) Slog.v(TAG_MU,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 26304ab..6fe8b8a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5435,7 +5435,7 @@
     }
 
     @Override
-    public List<ProviderInfo> queryContentProviders(String processName,
+    public ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
             int uid, int flags) {
         ArrayList<ProviderInfo> finalList = null;
         // reader
@@ -5467,9 +5467,10 @@
 
         if (finalList != null) {
             Collections.sort(finalList, mProviderInitOrderSorter);
+            return new ParceledListSlice<ProviderInfo>(finalList);
         }
 
-        return finalList;
+        return null;
     }
 
     @Override