Merge "Add DENSITY_360" into mnc-dev
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 8441541..166ff38 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -21,6 +21,7 @@
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources.NotFoundException;
 import android.database.Cursor;
+import android.media.MediaPlayer.OnCompletionListener;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.RemoteException;
@@ -29,6 +30,7 @@
 import android.util.Log;
 
 import java.io.IOException;
+import java.util.ArrayList;
 
 /**
  * Ringtone provides a quick method for playing a ringtone, notification, or
@@ -49,6 +51,9 @@
         MediaStore.Audio.Media.TITLE
     };
 
+    // keep references on active Ringtones until stopped or completion listener called.
+    private static final ArrayList<Ringtone> sActiveRingtones = new ArrayList<Ringtone>();
+
     private final Context mContext;
     private final AudioManager mAudioManager;
 
@@ -62,6 +67,7 @@
     private final Binder mRemoteToken;
 
     private MediaPlayer mLocalPlayer;
+    private final MyOnCompletionListener mCompletionListener = new MyOnCompletionListener();
 
     private Uri mUri;
     private String mTitle;
@@ -247,7 +253,7 @@
             // (typically because ringer mode is silent).
             if (mAudioManager.getStreamVolume(
                     AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) {
-                mLocalPlayer.start();
+                startLocalPlayer();
             }
         } else if (mAllowRemote && (mRemotePlayer != null)) {
             final Uri canonicalUri = mUri.getCanonicalUri();
@@ -285,9 +291,23 @@
             mLocalPlayer.reset();
             mLocalPlayer.release();
             mLocalPlayer = null;
+            synchronized (sActiveRingtones) {
+                sActiveRingtones.remove(this);
+            }
         }
     }
 
+    private void startLocalPlayer() {
+        if (mLocalPlayer == null) {
+            return;
+        }
+        synchronized (sActiveRingtones) {
+            sActiveRingtones.add(this);
+        }
+        mLocalPlayer.setOnCompletionListener(mCompletionListener);
+        mLocalPlayer.start();
+    }
+
     /**
      * Whether this ringtone is currently playing.
      * 
@@ -330,7 +350,7 @@
                         }
                         mLocalPlayer.setAudioAttributes(mAudioAttributes);
                         mLocalPlayer.prepare();
-                        mLocalPlayer.start();
+                        startLocalPlayer();
                         afd.close();
                         return true;
                     } else {
@@ -352,4 +372,20 @@
     void setTitle(String title) {
         mTitle = title;
     }
+
+    @Override
+    protected void finalize() {
+        if (mLocalPlayer != null) {
+            mLocalPlayer.release();
+        }
+    }
+
+    class MyOnCompletionListener implements MediaPlayer.OnCompletionListener {
+        public void onCompletion(MediaPlayer mp)
+        {
+            synchronized (sActiveRingtones) {
+                sActiveRingtones.remove(Ringtone.this);
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 0369ab5..5d74604 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -74,7 +74,11 @@
         state.visible = mFlashlightController.isAvailable();
         state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
         if (arg instanceof UserBoolean) {
-            state.value = ((UserBoolean) arg).value;
+            boolean value = ((UserBoolean) arg).value;
+            if (value == state.value) {
+                return;
+            }
+            state.value = value;
         }
         final AnimationIcon icon = state.value ? mEnable : mDisable;
         icon.setAllowAnimation(arg instanceof UserBoolean && ((UserBoolean) arg).userInitiated);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 928d1d6..44d00d7 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4509,7 +4509,7 @@
             info.setDetailedState(DetailedState.CONNECTED, null, info.getExtraInfo());
             sendConnectedBroadcast(info);
         } else {
-            info.setDetailedState(DetailedState.DISCONNECTED, null, info.getExtraInfo());
+            info.setDetailedState(DetailedState.DISCONNECTED, info.getReason(), info.getExtraInfo());
             Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7dfe836..e370afc 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1876,7 +1876,7 @@
             alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
 
             /**
-             * And there are a number of commands implemented in Java, which
+             * There are a number of commands implemented in Java, which
              * we currently need to do the dexopt on so that they can be
              * run from a non-root shell.
              */
@@ -6361,63 +6361,39 @@
 
         final String path = scanFile.getPath();
         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
-        if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
-            setBundledAppAbisAndRoots(pkg, pkgSetting);
 
-            // If we haven't found any native libraries for the app, check if it has
-            // renderscript code. We'll need to force the app to 32 bit if it has
-            // renderscript bitcode.
-            if (pkg.applicationInfo.primaryCpuAbi == null
-                    && pkg.applicationInfo.secondaryCpuAbi == null
-                    && Build.SUPPORTED_64_BIT_ABIS.length >  0) {
-                NativeLibraryHelper.Handle handle = null;
-                try {
-                    handle = NativeLibraryHelper.Handle.create(scanFile);
-                    if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
-                        pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
-                    }
-                } catch (IOException ioe) {
-                    Slog.w(TAG, "Error scanning system app : " + ioe);
-                } finally {
-                    IoUtils.closeQuietly(handle);
-                }
-            }
-
-            setNativeLibraryPaths(pkg);
+        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
+            derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
         } else {
-            if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
-                deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
-            } else {
-                if ((scanFlags & SCAN_MOVE) != 0) {
-                    // We haven't run dex-opt for this move (since we've moved the compiled output too)
-                    // but we already have this packages package info in the PackageSetting. We just
-                    // use that and derive the native library path based on the new codepath.
-                    pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
-                    pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
-                }
-
-                // Set native library paths again. For moves, the path will be updated based on the
-                // ABIs we've determined above. For non-moves, the path will be updated based on the
-                // ABIs we determined during compilation, but the path will depend on the final
-                // package path (after the rename away from the stage path).
-                setNativeLibraryPaths(pkg);
+            if ((scanFlags & SCAN_MOVE) != 0) {
+                // We haven't run dex-opt for this move (since we've moved the compiled output too)
+                // but we already have this packages package info in the PackageSetting. We just
+                // use that and derive the native library path based on the new codepath.
+                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
+                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
             }
 
-            if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
-            final int[] userIds = sUserManager.getUserIds();
-            synchronized (mInstallLock) {
-                // Create a native library symlink only if we have native libraries
-                // and if the native libraries are 32 bit libraries. We do not provide
-                // this symlink for 64 bit libraries.
-                if (pkg.applicationInfo.primaryCpuAbi != null &&
-                        !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
-                    final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
-                    for (int userId : userIds) {
-                        if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
-                                nativeLibPath, userId) < 0) {
-                            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                                    "Failed linking native library dir (user=" + userId + ")");
-                        }
+            // Set native library paths again. For moves, the path will be updated based on the
+            // ABIs we've determined above. For non-moves, the path will be updated based on the
+            // ABIs we determined during compilation, but the path will depend on the final
+            // package path (after the rename away from the stage path).
+            setNativeLibraryPaths(pkg);
+        }
+
+        if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
+        final int[] userIds = sUserManager.getUserIds();
+        synchronized (mInstallLock) {
+            // Create a native library symlink only if we have native libraries
+            // and if the native libraries are 32 bit libraries. We do not provide
+            // this symlink for 64 bit libraries.
+            if (pkg.applicationInfo.primaryCpuAbi != null &&
+                    !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
+                final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
+                for (int userId : userIds) {
+                    if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
+                            nativeLibPath, userId) < 0) {
+                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                                "Failed linking native library dir (user=" + userId + ")");
                     }
                 }
             }
@@ -6946,8 +6922,8 @@
      *
      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
      */
-    public void deriveNonSystemPackageAbi(PackageParser.Package pkg, File scanFile,
-                                          String cpuAbiOverride, boolean extractLibs)
+    public void derivePackageAbi(PackageParser.Package pkg, File scanFile,
+                                 String cpuAbiOverride, boolean extractLibs)
             throws PackageManagerException {
         // TODO: We can probably be smarter about this stuff. For installed apps,
         // we can calculate this information at install time once and for all. For
@@ -6959,8 +6935,10 @@
         setNativeLibraryPaths(pkg);
 
         // We would never need to extract libs for forward-locked and external packages,
-        // since the container service will do it for us.
-        if (pkg.isForwardLocked() || isExternal(pkg)) {
+        // since the container service will do it for us. We shouldn't attempt to
+        // extract libs from system app when it was not updated.
+        if (pkg.isForwardLocked() || isExternal(pkg) ||
+            (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) ) {
             extractLibs = false;
         }
 
@@ -7291,33 +7269,6 @@
     }
 
     /**
-     * Calculate the abis and roots for a bundled app. These can uniquely
-     * be determined from the contents of the system partition, i.e whether
-     * it contains 64 or 32 bit shared libraries etc. We do not validate any
-     * of this information, and instead assume that the system was built
-     * sensibly.
-     */
-    private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
-                                           PackageSetting pkgSetting) {
-        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
-
-        // If "/system/lib64/apkname" exists, assume that is the per-package
-        // native library directory to use; otherwise use "/system/lib/apkname".
-        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
-        setBundledAppAbi(pkg, apkRoot, apkName);
-        // pkgSetting might be null during rescan following uninstall of updates
-        // to a bundled app, so accommodate that possibility.  The settings in
-        // that case will be established later from the parsed package.
-        //
-        // If the settings aren't null, sync them up with what we've just derived.
-        // note that apkRoot isn't stored in the package settings.
-        if (pkgSetting != null) {
-            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
-            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
-        }
-    }
-
-    /**
      * Deduces the ABI of a bundled app and sets the relevant fields on the
      * parsed pkg object.
      *
@@ -11695,7 +11646,7 @@
             scanFlags |= SCAN_NO_DEX;
 
             try {
-                deriveNonSystemPackageAbi(pkg, new File(pkg.codePath), args.abiOverride,
+                derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride,
                         true /* extract libs */);
             } catch (PackageManagerException pme) {
                 Slog.e(TAG, "Error deriving application ABI", pme);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f51cb65..2445bf6e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2298,7 +2298,8 @@
     }
 
     /**
-     * Returns the voice mail count. Return 0 if unavailable.
+     * Returns the voice mail count. Return 0 if unavailable, -1 if there are unread voice messages
+     * but the count is unknown.
      * <p>
      * Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}