Merge "Merge "Docs: Removed note in "Platform Versions" section" into mnc-io-docs am: 9dfa75ef43 am: 202017dcbf am: 2c69d1ecae am: f986b700de" into nyc-mr1-dev-plus-aosp
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0cc44e7..e108dd6 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4323,18 +4323,23 @@
                 // experience
                 bigTextText = mBuilder.processLegacyText(text);
             }
-            contentView.setTextViewText(R.id.big_text, bigTextText);
-            contentView.setViewVisibility(R.id.big_text,
-                    TextUtils.isEmpty(bigTextText) ? View.GONE : View.VISIBLE);
-            contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines());
-            contentView.setBoolean(R.id.big_text, "setHasImage", mBuilder.mN.mLargeIcon != null);
+            applyBigTextContentView(mBuilder, contentView, bigTextText);
 
             return contentView;
         }
 
-        private int calculateMaxLines() {
+        static void applyBigTextContentView(Builder builder,
+                RemoteViews contentView, CharSequence bigTextText) {
+            contentView.setTextViewText(R.id.big_text, bigTextText);
+            contentView.setViewVisibility(R.id.big_text,
+                    TextUtils.isEmpty(bigTextText) ? View.GONE : View.VISIBLE);
+            contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines(builder));
+            contentView.setBoolean(R.id.big_text, "setHasImage", builder.mN.mLargeIcon != null);
+        }
+
+        private static int calculateMaxLines(Builder builder) {
             int lineCount = MAX_LINES;
-            boolean hasActions = mBuilder.mActions.size() > 0;
+            boolean hasActions = builder.mActions.size() > 0;
             if (hasActions) {
                 lineCount -= LINES_CONSUMED_BY_ACTIONS;
             }
@@ -4532,6 +4537,16 @@
                     : mConversationTitle;
             boolean hasTitle = !TextUtils.isEmpty(title);
 
+            if (!hasTitle && mMessages.size() == 1) {
+                CharSequence sender = mMessages.get(0).mSender;
+                CharSequence text = mMessages.get(0).mText;
+                RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
+                        mBuilder.getBigTextLayoutResource(),
+                        false /* progress */, sender, null /* text */);
+                BigTextStyle.applyBigTextContentView(mBuilder, contentView, text);
+                return contentView;
+            }
+
             RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
                     mBuilder.getMessagingLayoutResource(),
                     false /* hasProgress */,
diff --git a/core/jni/android_graphics_drawable_VectorDrawable.cpp b/core/jni/android_graphics_drawable_VectorDrawable.cpp
index 9e69f79..045f127 100644
--- a/core/jni/android_graphics_drawable_VectorDrawable.cpp
+++ b/core/jni/android_graphics_drawable_VectorDrawable.cpp
@@ -36,6 +36,13 @@
     return reinterpret_cast<jlong>(tree);
 }
 
+static jlong createTreeFromCopy(JNIEnv*, jobject, jlong treePtr, jlong groupPtr) {
+    VectorDrawable::Group* rootGroup = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
+    VectorDrawable::Tree* treeToCopy = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
+    VectorDrawable::Tree* tree = new VectorDrawable::Tree(treeToCopy, rootGroup);
+    return reinterpret_cast<jlong>(tree);
+}
+
 static jlong createEmptyFullPath(JNIEnv*, jobject) {
     VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath();
     return reinterpret_cast<jlong>(newPath);
@@ -344,6 +351,7 @@
 
 static const JNINativeMethod gMethods[] = {
         {"nCreateTree", "!(J)J", (void*)createTree},
+        {"nCreateTreeFromCopy", "!(JJ)J", (void*)createTreeFromCopy},
         {"nSetRendererViewportSize", "!(JFF)V", (void*)setTreeViewportSize},
         {"nSetRootAlpha", "!(JF)Z", (void*)setRootAlpha},
         {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha},
diff --git a/core/res/res/layout/app_error_dialog.xml b/core/res/res/layout/app_error_dialog.xml
index 7147ea2..9a5bbd4 100644
--- a/core/res/res/layout/app_error_dialog.xml
+++ b/core/res/res/layout/app_error_dialog.xml
@@ -35,11 +35,11 @@
     />
 
     <Button
-            android:id="@+id/aerr_reset"
+            android:id="@+id/aerr_close"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:text="@string/aerr_reset"
-            android:drawableStart="@drawable/ic_refresh"
+            android:text="@string/aerr_close"
+            android:drawableStart="@drawable/ic_close"
             style="@style/aerr_list_item"
     />
 
@@ -53,15 +53,6 @@
     />
 
     <Button
-            android:id="@+id/aerr_close"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/aerr_close"
-            android:drawableStart="@drawable/ic_close"
-            style="@style/aerr_list_item"
-    />
-
-    <Button
             android:id="@+id/aerr_mute"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 236940d..3a28822 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2725,9 +2725,7 @@
     <!-- Text of the alert that is displayed when a process has crashed repeatedly. -->
     <string name="aerr_process_repeated"><xliff:g id="process">%1$s</xliff:g> keeps stopping</string>
     <!-- Button that restarts a crashed application -->
-    <string name="aerr_restart">Restart app</string>
-    <!-- Button that clears cache and restarts a crashed application -->
-    <string name="aerr_reset">Reset and restart app</string>
+    <string name="aerr_restart">Open app again</string>
     <!-- Button that sends feedback about a crashed application -->
     <string name="aerr_report">Send feedback</string>
     <!-- Button that closes a crashed application -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 115c49f..0f20b5c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2446,7 +2446,6 @@
   <java-symbol type="id" name="work_widget_badge_icon" />
 
   <java-symbol type="id" name="aerr_report" />
-  <java-symbol type="id" name="aerr_reset" />
   <java-symbol type="id" name="aerr_restart" />
   <java-symbol type="id" name="aerr_close" />
   <java-symbol type="id" name="aerr_mute" />
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index dd33e98..f5592fa 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -804,7 +804,7 @@
                 mTintMode = copy.mTintMode;
                 mAutoMirrored = copy.mAutoMirrored;
                 mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
-                createNativeTree(mRootGroup);
+                createNativeTreeFromCopy(copy, mRootGroup);
 
                 mBaseWidth = copy.mBaseWidth;
                 mBaseHeight = copy.mBaseHeight;
@@ -826,6 +826,16 @@
             VMRuntime.getRuntime().registerNativeAllocation(NATIVE_ALLOCATION_SIZE);
         }
 
+        // Create a new native tree with the given root group, and copy the properties from the
+        // given VectorDrawableState's native tree.
+        private void createNativeTreeFromCopy(VectorDrawableState copy, VGroup rootGroup) {
+            mNativeTree = new VirtualRefBasePtr(nCreateTreeFromCopy(
+                    copy.mNativeTree.get(), rootGroup.mNativePtr));
+            // Register tree size
+            VMRuntime.getRuntime().registerNativeAllocation(NATIVE_ALLOCATION_SIZE);
+        }
+
+
         void onTreeConstructionFinished() {
             mRootGroup.setTree(mNativeTree);
             mAllocationOfAllNodes = mRootGroup.getNativeSize();
@@ -1777,6 +1787,7 @@
     }
 
     private static native long nCreateTree(long rootGroupPtr);
+    private static native long nCreateTreeFromCopy(long treeToCopy, long rootGroupPtr);
     private static native void nSetRendererViewportSize(long rendererPtr, float viewportWidth,
             float viewportHeight);
     private static native boolean nSetRootAlpha(long rendererPtr, float alpha);
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index f0348e4..2b79941 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -530,7 +530,7 @@
     if (prop->getRootAlpha() == 1.0f && prop->getColorFilter() == nullptr) {
         return nullptr;
     } else {
-        outPaint->setColorFilter(mStagingProperties.getColorFilter());
+        outPaint->setColorFilter(prop->getColorFilter());
         outPaint->setFilterQuality(kLow_SkFilterQuality);
         outPaint->setAlpha(prop->getRootAlpha() * 255);
         return outPaint;
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index b33f26c..a5d1d4b 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -542,6 +542,12 @@
     Tree(Group* rootNode) : mRootNode(rootNode) {
         mRootNode->setPropertyChangedListener(&mPropertyChangedListener);
     }
+
+    // Copy properties from the tree and use the give node as the root node
+    Tree(const Tree* copy, Group* rootNode) : Tree(rootNode) {
+        mStagingProperties.syncAnimatableProperties(*copy->stagingProperties());
+        mStagingProperties.syncNonAnimatableProperties(*copy->stagingProperties());
+    }
     // Draws the VD onto a bitmap cache, then the bitmap cache will be rendered onto the input
     // canvas. Returns the number of pixels needed for the bitmap cache.
     int draw(Canvas* outCanvas, SkColorFilter* colorFilter,
@@ -666,7 +672,7 @@
     };
     void onPropertyChanged(TreeProperties* prop);
     TreeProperties* mutateStagingProperties() { return &mStagingProperties; }
-    const TreeProperties* stagingProperties() { return &mStagingProperties; }
+    const TreeProperties* stagingProperties() const { return &mStagingProperties; }
     PushStagingFunctor* getFunctor() { return &mFunctor;}
 
     // This should only be called from animations on RT
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/Camera2SurfaceViewTestCase.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/Camera2SurfaceViewTestCase.java
index 423c3b0..a8b782e8 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/Camera2SurfaceViewTestCase.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/Camera2SurfaceViewTestCase.java
@@ -37,6 +37,7 @@
 import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.params.StreamConfigurationMap;
 import android.media.ImageReader;
 import android.graphics.SurfaceTexture;
 import android.os.Bundle;
@@ -127,6 +128,7 @@
     protected List<Size> mOrderedRAW10Sizes; // In descending order.
     protected List<Size> mOrderedYUV420888Sizes; // In descending order.
     protected HashMap<Size, Long> mMinPreviewFrameDurationMap;
+    protected boolean mSupportRAW10;
 
     protected WindowManager mWindowManager;
 
@@ -603,16 +605,21 @@
         mCamera = CameraTestUtils.openCamera(
                 mCameraManager, cameraId, mCameraListener, mHandler);
         mCollector.setCameraId(cameraId);
-        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
-                CheckLevel.ASSERT, /*collector*/null);
+        CameraCharacteristics properties = mCameraManager.getCameraCharacteristics(cameraId);
+        mStaticInfo = new StaticMetadata(properties, CheckLevel.ASSERT, /*collector*/null);
+        StreamConfigurationMap configMap =
+                properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+        mSupportRAW10 = configMap.isOutputSupportedFor(ImageFormat.RAW10);
         if (mStaticInfo.isColorOutputSupported()) {
             mOrderedPreviewSizes = getSupportedPreviewSizes(cameraId, mCameraManager,
                     getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
             mOrderedVideoSizes = getSupportedVideoSizes(
                     cameraId, mCameraManager, PREVIEW_SIZE_BOUND);
             mOrderedStillSizes = getSupportedStillSizes(cameraId, mCameraManager, null);
-            mOrderedRAW10Sizes = getSortedSizesForFormat(
-                    cameraId, mCameraManager, ImageFormat.RAW10, null);
+            if (mSupportRAW10) {
+                mOrderedRAW10Sizes = getSortedSizesForFormat(
+                        cameraId, mCameraManager, ImageFormat.RAW10, null);
+            }
             mOrderedYUV420888Sizes = getSortedSizesForFormat(
                     cameraId, mCameraManager, ImageFormat.YUV_420_888, null);
             // Use ImageFormat.YUV_420_888 for now. TODO: need figure out what's format for preview
@@ -636,6 +643,7 @@
             mOrderedPreviewSizes = null;
             mOrderedVideoSizes = null;
             mOrderedStillSizes = null;
+            mSupportRAW10 = false;
         }
     }
 
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 2a78f90..3745e0b 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -17,12 +17,10 @@
 package com.android.server;
 
 import android.Manifest.permission;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.net.INetworkScoreCache;
@@ -33,7 +31,6 @@
 import android.net.ScoredNetwork;
 import android.os.Binder;
 import android.os.IBinder;
-import android.os.PatternMatcher;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -42,6 +39,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.content.PackageMonitor;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -62,39 +60,75 @@
 
     private final Context mContext;
     private final Map<Integer, INetworkScoreCache> mScoreCaches;
-    /** Lock used to update mReceiver when scorer package changes occur. */
-    private final Object mReceiverLock = new Object[0];
+    /** Lock used to update mPackageMonitor when scorer package changes occur. */
+    private final Object mPackageMonitorLock = new Object[0];
 
-    /** Clears scores when the active scorer package is no longer valid. */
-    @GuardedBy("mReceiverLock")
-    private ScorerChangedReceiver mReceiver;
+    @GuardedBy("mPackageMonitorLock")
+    private NetworkScorerPackageMonitor mPackageMonitor;
     private ScoringServiceConnection mServiceConnection;
 
-    private class ScorerChangedReceiver extends BroadcastReceiver {
+    /**
+     * Clears scores when the active scorer package is no longer valid and
+     * manages the service connection.
+     */
+    private class NetworkScorerPackageMonitor extends PackageMonitor {
         final String mRegisteredPackage;
 
-        ScorerChangedReceiver(String packageName) {
-            mRegisteredPackage = packageName;
+        private NetworkScorerPackageMonitor(String mRegisteredPackage) {
+            this.mRegisteredPackage = mRegisteredPackage;
         }
 
         @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (Intent.ACTION_PACKAGE_CHANGED.equals(action)
-                    || Intent.ACTION_PACKAGE_REPLACED.equals(action)
-                    || Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action)) {
-                NetworkScorerAppData activeScorer =
+        public void onPackageAdded(String packageName, int uid) {
+            evaluateBinding(packageName, true /* forceUnbind */);
+        }
+
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            evaluateBinding(packageName, true /* forceUnbind */);
+        }
+
+        @Override
+        public void onPackageModified(String packageName) {
+            evaluateBinding(packageName, false /* forceUnbind */);
+        }
+
+        @Override
+        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
+            if (doit) { // "doit" means the force stop happened instead of just being queried for.
+                for (String packageName : packages) {
+                    evaluateBinding(packageName, true /* forceUnbind */);
+                }
+            }
+            return super.onHandleForceStop(intent, packages, uid, doit);
+        }
+
+        @Override
+        public void onPackageUpdateFinished(String packageName, int uid) {
+            evaluateBinding(packageName, true /* forceUnbind */);
+        }
+
+        private void evaluateBinding(String scorerPackageName, boolean forceUnbind) {
+            if (mRegisteredPackage.equals(scorerPackageName)) {
+                if (DBG) {
+                    Log.d(TAG, "Evaluating binding for: " + scorerPackageName
+                            + ", forceUnbind=" + forceUnbind);
+                }
+                final NetworkScorerAppData activeScorer =
                         NetworkScorerAppManager.getActiveScorer(mContext);
                 if (activeScorer == null) {
-                    // Package change has invalidated a scorer.
+                    // Package change has invalidated a scorer, this will also unbind any service
+                    // connection.
                     Log.i(TAG, "Package " + mRegisteredPackage +
                             " is no longer valid, disabling scoring.");
                     setScorerInternal(null);
                 } else if (activeScorer.mScoringServiceClassName == null) {
                     // The scoring service is not available, make sure it's unbound.
                     unbindFromScoringServiceIfNeeded();
-                } else {
-                    // The scoring service may have changed or been added.
+                } else { // The scoring service changed in some way.
+                    if (forceUnbind) {
+                        unbindFromScoringServiceIfNeeded();
+                    }
                     bindToScoringServiceIfNeeded(activeScorer);
                 }
             }
@@ -121,7 +155,7 @@
             Settings.Global.putInt(cr, Settings.Global.NETWORK_SCORING_PROVISIONED, 1);
         }
 
-        registerPackageReceiverIfNeeded();
+        registerPackageMonitorIfNeeded();
     }
 
     /** Called when the system is ready for us to start third-party code. */
@@ -130,33 +164,29 @@
         bindToScoringServiceIfNeeded();
     }
 
-    private void registerPackageReceiverIfNeeded() {
-        if (DBG) Log.d(TAG, "registerPackageReceiverIfNeeded");
+    private void registerPackageMonitorIfNeeded() {
+        if (DBG) Log.d(TAG, "registerPackageMonitorIfNeeded");
         NetworkScorerAppData scorer = NetworkScorerAppManager.getActiveScorer(mContext);
-        synchronized (mReceiverLock) {
-            // Unregister the receiver if the current scorer has changed since last registration.
-            if (mReceiver != null) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "Unregistering receiver for " + mReceiver.mRegisteredPackage);
+        synchronized (mPackageMonitorLock) {
+            // Unregister the current monitor if needed.
+            if (mPackageMonitor != null) {
+                if (DBG) {
+                    Log.d(TAG, "Unregistering package monitor for "
+                            + mPackageMonitor.mRegisteredPackage);
                 }
-                mContext.unregisterReceiver(mReceiver);
-                mReceiver = null;
+                mPackageMonitor.unregister();
+                mPackageMonitor = null;
             }
 
-            // Register receiver if a scorer is active.
+            // Create and register the monitor if a scorer is active.
             if (scorer != null) {
-                IntentFilter filter = new IntentFilter();
-                filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-                filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
-                filter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
-                filter.addDataScheme("package");
-                filter.addDataSchemeSpecificPart(scorer.mPackageName,
-                        PatternMatcher.PATTERN_LITERAL);
-                mReceiver = new ScorerChangedReceiver(scorer.mPackageName);
+                mPackageMonitor = new NetworkScorerPackageMonitor(scorer.mPackageName);
                 // TODO: Need to update when we support per-user scorers. http://b/23422763
-                mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, null, null);
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "Registered receiver for " + scorer.mPackageName);
+                mPackageMonitor.register(mContext, null /* thread */, UserHandle.SYSTEM,
+                        false /* externalStorage */);
+                if (DBG) {
+                    Log.d(TAG, "Registered package monitor for "
+                            + mPackageMonitor.mRegisteredPackage);
                 }
             }
         }
@@ -299,7 +329,7 @@
             // will be made to bind to the new scorer.
             bindToScoringServiceIfNeeded();
             if (result) { // new scorer successfully set
-                registerPackageReceiverIfNeeded();
+                registerPackageMonitorIfNeeded();
 
                 Intent intent = new Intent(NetworkScoreManager.ACTION_SCORER_CHANGED);
                 if (prevScorer != null) { // Directly notify the old scorer.
@@ -391,20 +421,24 @@
     private static class ScoringServiceConnection implements ServiceConnection {
         private final ComponentName mComponentName;
         private boolean mBound = false;
+        private boolean mConnected = false;
 
         ScoringServiceConnection(ComponentName componentName) {
             mComponentName = componentName;
         }
 
         void connect(Context context) {
-            disconnect(context);
-            Intent service = new Intent();
-            service.setComponent(mComponentName);
-            mBound = context.bindServiceAsUser(service, this,
-                    Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
-                    UserHandle.SYSTEM);
             if (!mBound) {
-                Log.w(TAG, "Bind call failed for " + service);
+                Intent service = new Intent();
+                service.setComponent(mComponentName);
+                mBound = context.bindServiceAsUser(service, this,
+                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+                        UserHandle.SYSTEM);
+                if (!mBound) {
+                    Log.w(TAG, "Bind call failed for " + service);
+                } else {
+                    if (DBG) Log.d(TAG, "ScoringServiceConnection bound.");
+                }
             }
         }
 
@@ -413,6 +447,7 @@
                 if (mBound) {
                     mBound = false;
                     context.unbindService(this);
+                    if (DBG) Log.d(TAG, "ScoringServiceConnection unbound.");
                 }
             } catch (RuntimeException e) {
                 Log.e(TAG, "Unbind failed.", e);
@@ -422,15 +457,20 @@
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             if (DBG) Log.d(TAG, "ScoringServiceConnection: " + name.flattenToString());
+            mConnected = true;
         }
 
         @Override
         public void onServiceDisconnected(ComponentName name) {
-            if (DBG) Log.d(TAG, "ScoringServiceConnection, disconnected: " + name.flattenToString());
+            if (DBG) {
+                Log.d(TAG, "ScoringServiceConnection, disconnected: " + name.flattenToString());
+            }
+            mConnected = false;
         }
 
         public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-            writer.println("ScoringServiceConnection: " + mComponentName + ", bound: " + mBound);
+            writer.println("ScoringServiceConnection: " + mComponentName + ", bound: " + mBound
+                    + ", connected: " + mConnected);
         }
     }
 }
diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java
index ddfab4d..e37feb2 100644
--- a/services/core/java/com/android/server/am/AppErrorDialog.java
+++ b/services/core/java/com/android/server/am/AppErrorDialog.java
@@ -18,13 +18,17 @@
 
 import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.provider.Settings;
 import android.text.BidiFormatter;
 import android.util.Slog;
 import android.view.LayoutInflater;
@@ -43,6 +47,7 @@
     private final AppErrorResult mResult;
     private final ProcessRecord mProc;
     private final boolean mRepeating;
+    private final boolean mForeground;
 
     private CharSequence mName;
 
@@ -54,9 +59,9 @@
     static final int FORCE_QUIT = 1;
     static final int FORCE_QUIT_AND_REPORT = 2;
     static final int RESTART = 3;
-    static final int RESET = 4;
     static final int MUTE = 5;
     static final int TIMEOUT = 6;
+    static final int CANCEL = 7;
 
     // 5-minute timeout, then we automatically dismiss the crash dialog
     static final long DISMISS_TIMEOUT = 1000 * 60 * 5;
@@ -69,6 +74,7 @@
         mProc = data.proc;
         mResult = data.result;
         mRepeating = data.repeating;
+        mForeground = data.task != null;
         BidiFormatter bidi = BidiFormatter.getInstance();
 
         if ((mProc.pkgList.size() == 1) &&
@@ -86,7 +92,8 @@
                     bidi.unicodeWrap(mName.toString())));
         }
 
-        setCancelable(false);
+        setCancelable(true);
+        setCancelMessage(mHandler.obtainMessage(CANCEL));
 
         WindowManager.LayoutParams attrs = getWindow().getAttributes();
         attrs.setTitle("Application Error: " + mProc.info.processName);
@@ -111,25 +118,41 @@
         LayoutInflater.from(context).inflate(
                 com.android.internal.R.layout.app_error_dialog, frame, true);
 
+        boolean hasRestart = !mRepeating && mForeground;
+        final boolean hasReceiver = mProc.errorReportReceiver != null;
+
         final TextView restart = (TextView) findViewById(com.android.internal.R.id.aerr_restart);
         restart.setOnClickListener(this);
-        restart.setVisibility(!mRepeating ? View.VISIBLE : View.GONE);
-        final TextView reset = (TextView) findViewById(com.android.internal.R.id.aerr_reset);
-        reset.setOnClickListener(this);
-        reset.setVisibility(mRepeating ? View.VISIBLE : View.GONE);
+        restart.setVisibility(hasRestart ? View.VISIBLE : View.GONE);
         final TextView report = (TextView) findViewById(com.android.internal.R.id.aerr_report);
         report.setOnClickListener(this);
-        final boolean hasReceiver = mProc.errorReportReceiver != null;
         report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
         final TextView close = (TextView) findViewById(com.android.internal.R.id.aerr_close);
+        close.setVisibility(!hasRestart ? View.VISIBLE : View.GONE);
         close.setOnClickListener(this);
+
+        boolean showMute = !IS_USER_BUILD && Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
         final TextView mute = (TextView) findViewById(com.android.internal.R.id.aerr_mute);
         mute.setOnClickListener(this);
-        mute.setVisibility(!IS_USER_BUILD ? View.VISIBLE : View.GONE);
+        mute.setVisibility(showMute ? View.VISIBLE : View.GONE);
 
         findViewById(com.android.internal.R.id.customPanel).setVisibility(View.VISIBLE);
     }
 
+    @Override
+    public void onStart() {
+        super.onStart();
+        getContext().registerReceiver(mReceiver,
+                new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        getContext().unregisterReceiver(mReceiver);
+    }
+
     private final Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
             final int result = msg.what;
@@ -163,9 +186,6 @@
             case com.android.internal.R.id.aerr_restart:
                 mHandler.obtainMessage(RESTART).sendToTarget();
                 break;
-            case com.android.internal.R.id.aerr_reset:
-                mHandler.obtainMessage(RESET).sendToTarget();
-                break;
             case com.android.internal.R.id.aerr_report:
                 mHandler.obtainMessage(FORCE_QUIT_AND_REPORT).sendToTarget();
                 break;
@@ -180,6 +200,15 @@
         }
     }
 
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
+                cancel();
+            }
+        }
+    };
+
     static class Data {
         AppErrorResult result;
         TaskRecord task;
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 3ed9969..49106f4 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -370,38 +370,9 @@
 
         Intent appErrorIntent = null;
         MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
-        if (res == AppErrorDialog.TIMEOUT) {
+        if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) {
             res = AppErrorDialog.FORCE_QUIT;
         }
-        if (res == AppErrorDialog.RESET) {
-            String[] packageList = r.getPackageList();
-            if (packageList != null) {
-                PackageManager pm = mContext.getPackageManager();
-                final Semaphore s = new Semaphore(0);
-                for (int i = 0; i < packageList.length; i++) {
-                    if (i < packageList.length - 1) {
-                        pm.deleteApplicationCacheFiles(packageList[i], null);
-                    } else {
-                        pm.deleteApplicationCacheFiles(packageList[i],
-                                new IPackageDataObserver.Stub() {
-                                    @Override
-                                    public void onRemoveCompleted(String packageName,
-                                                                  boolean succeeded) {
-                                        s.release();
-                                    }
-                                });
-
-                        // Wait until cache has been cleared before we restart.
-                        try {
-                            s.acquire();
-                        } catch (InterruptedException e) {
-                        }
-                    }
-                }
-            }
-            // If there was nothing to reset, just restart;
-            res = AppErrorDialog.RESTART;
-        }
         synchronized (mService) {
             if (res == AppErrorDialog.MUTE) {
                 stopReportingCrashesLocked(r);