Merge "Fix issue #2485441: SettingsBackupAgent crashed system server"
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 90e8c14..179b807 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1632,12 +1632,20 @@
 
     /**
      * Broadcast Action:  External media is unmounted because it is being shared via USB mass storage.
-     * The path to the mount point for the removed media is contained in the Intent.mData field.
+     * The path to the mount point for the shared media is contained in the Intent.mData field.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_MEDIA_SHARED = "android.intent.action.MEDIA_SHARED";
 
     /**
+     * Broadcast Action:  External media is no longer being shared via USB mass storage.
+     * The path to the mount point for the previously shared media is contained in the Intent.mData field.
+     *
+     * @hide
+     */
+    public static final String ACTION_MEDIA_UNSHARED = "android.intent.action.MEDIA_UNSHARED";
+
+    /**
      * Broadcast Action:  External media was removed from SD card slot, but mount point was not unmounted.
      * The path to the mount point for the removed media is contained in the Intent.mData field.
      */
diff --git a/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java b/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java
new file mode 100644
index 0000000..8ac4c0f
--- /dev/null
+++ b/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 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 android.database.sqlite;
+
+/**
+ * An exception that indicates that garbage-collector is finalizing a database object
+ * that is not explicitly closed
+ * @hide
+ */
+public class DatabaseObjectNotClosedException extends RuntimeException
+{
+    private static final String s = "Application did not close the cursor or database object " +
+            "that was opened here";
+
+    public DatabaseObjectNotClosedException()
+    {
+        super(s);
+    }
+}
diff --git a/core/java/android/database/sqlite/SQLiteCompiledSql.java b/core/java/android/database/sqlite/SQLiteCompiledSql.java
index 486ad20..4ccf6b0 100644
--- a/core/java/android/database/sqlite/SQLiteCompiledSql.java
+++ b/core/java/android/database/sqlite/SQLiteCompiledSql.java
@@ -56,7 +56,7 @@
     /* package */ SQLiteCompiledSql(SQLiteDatabase db, String sql) {
         mDatabase = db;
         mSqlStmt = sql;
-        mStackTrace = new Exception().fillInStackTrace();
+        mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
         this.nHandle = db.mNativeHandle;
         compile(sql, true);
     }
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 96ed297..3f0fcb1 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -207,7 +207,7 @@
             String editTable, SQLiteQuery query) {
         // The AbstractCursor constructor needs to do some setup.
         super();
-        mStackTrace = new Exception().fillInStackTrace();
+        mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
         mDatabase = db;
         mDriver = driver;
         mEditTable = editTable;
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index d8ccf85..9fa9368 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1749,7 +1749,7 @@
         mFlags = flags;
         mPath = path;
         mSlowQueryThreshold = SystemProperties.getInt(LOG_SLOW_QUERIES_PROPERTY, -1);
-        mStackTrace = new Exception().fillInStackTrace();
+        mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
         mFactory = factory;
         dbopen(mPath, mFlags);
         if (SQLiteDebug.DEBUG_SQL_CACHE) {
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index b28cf43..f363828 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -274,9 +274,11 @@
 
     private void onDeviceRemoved(String deviceObjectPath) {
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
-        if (address != null)
+        if (address != null) {
             mBluetoothService.getBondState().setBondState(address.toUpperCase(),
                     BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED);
+            mBluetoothService.setRemoteDeviceProperty(address, "UUIDs", null);
+        }
     }
 
     /*package*/ void onPropertyChanged(String[] propValues) {
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index da760a1..9e4a16b 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -317,7 +317,7 @@
         List<String> providers = getProviders(enabledOnly);
         for (String providerName : providers) {
             LocationProvider provider = getProvider(providerName);
-            if (provider.meetsCriteria(criteria)) {
+            if (provider != null && provider.meetsCriteria(criteria)) {
                 if (goodProviders.isEmpty()) {
                     goodProviders = new ArrayList<String>();
                 }
diff --git a/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp b/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp
index 2d05a49..7537e35 100644
--- a/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp
+++ b/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp
@@ -32,8 +32,7 @@
     }
 
 protected:
-    virtual bool onDecode(SkStream* stream, SkBitmap* bm,
-                          SkBitmap::Config pref, Mode);
+    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
 };
 
 int nullObjectReturn(const char msg[]) {
diff --git a/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp b/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp
index f229f9d..209e71c 100644
--- a/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp
+++ b/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp
@@ -97,14 +97,14 @@
 }
 
 bool OmxJpegImageDecoder::onDecode(SkStream* stream,
-        SkBitmap* bm, SkBitmap::Config pref, Mode mode) {
+        SkBitmap* bm, Mode mode) {
     sp<MediaSource> source = prepareMediaSource(stream);
     sp<MetaData> meta = source->getFormat();
     int width;
     int height;
     meta->findInt32(kKeyWidth, &width);
     meta->findInt32(kKeyHeight, &height);
-    configBitmapSize(bm, pref, width, height);
+    configBitmapSize(bm, getPrefConfig(k32Bit_SrcDepth, false), width, height);
 
     // mode == DecodeBounds
     if (mode == SkImageDecoder::kDecodeBounds_Mode) {
diff --git a/media/tests/omxjpegdecoder/omx_jpeg_decoder.h b/media/tests/omxjpegdecoder/omx_jpeg_decoder.h
index 7d8bac09c..a313877 100644
--- a/media/tests/omxjpegdecoder/omx_jpeg_decoder.h
+++ b/media/tests/omxjpegdecoder/omx_jpeg_decoder.h
@@ -42,8 +42,7 @@
     }
 
 protected:
-    virtual bool onDecode(SkStream* stream, SkBitmap* bm,
-            SkBitmap::Config pref, Mode mode);
+    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
 
 private:
     JPEGSource* prepareMediaSource(SkStream* stream);
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 41f3850..3849023 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -523,6 +523,11 @@
 
         Intent in = null;
 
+        if (oldState == VolumeState.Shared && newState != oldState) {
+            mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_UNSHARED,
+                                                Uri.parse("file://" + path)));
+        }
+
         if (newState == VolumeState.Init) {
         } else if (newState == VolumeState.NoMedia) {
             // NoMedia is handled via Disk Remove events
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 6d121c3..53076de 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -447,7 +447,7 @@
             String []tok = line.split(" ");
             int code = Integer.parseInt(tok[0]);
             if (code == NetdResponseCode.UsbRNDISStatusResult) {
-                if (tok[2].equals("started"))
+                if (tok[3].equals("started"))
                     return true;
                 return false;
             } else {