Merge "Update edge and glow rendering to match new specs."
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index ed09362b..b69e0b1 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -987,7 +987,7 @@
             }
 
             // Not perfect, but fast and good enough for dup suppression.
-            Integer crashFingerprint = info.crashInfo.stackTrace.hashCode();
+            Integer crashFingerprint = info.hashCode();
             long lastViolationTime = 0;
             if (mLastViolationTime.containsKey(crashFingerprint)) {
                 lastViolationTime = mLastViolationTime.get(crashFingerprint);
@@ -1550,6 +1550,24 @@
             }
         }
 
+        @Override
+        public int hashCode() {
+            int result = 17;
+            result = 37 * result + crashInfo.stackTrace.hashCode();
+            if (numAnimationsRunning != 0) {
+                result *= 37;
+            }
+            if (broadcastIntentAction != null) {
+                result = 37 * result + broadcastIntentAction.hashCode();
+            }
+            if (tags != null) {
+                for (String tag : tags) {
+                    result = 37 * result + tag.hashCode();
+                }
+            }
+            return result;
+        }
+
         /**
          * Create an instance of ViolationInfo initialized from a Parcel.
          */
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 2b4284d..9b519c2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -5015,7 +5015,7 @@
 
         final ScaleGestureDetector detector =
                 mZoomManager.getMultiTouchGestureDetector();
-        boolean skipScaleGesture = false;
+        boolean isScrollGesture = false;
         // Set to the mid-point of a two-finger gesture used to detect if the
         // user has touched a layer.
         float gestureX = x;
@@ -5043,7 +5043,7 @@
                 }
                 action = ev.getActionMasked();
                 if (dist < DRAG_LAYER_FINGER_DISTANCE) {
-                    skipScaleGesture = true;
+                    isScrollGesture = true;
                 } else if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
                     // Fingers moved too far apart while dragging, the user
                     // might be trying to zoom.
@@ -5052,9 +5052,13 @@
             }
         }
 
-        // If the page disallows zoom, pass multi-pointer events to webkit.
-        if (!skipScaleGesture && ev.getPointerCount() > 1
-            && (mZoomManager.isZoomScaleFixed() || mDeferMultitouch)) {
+        // If the page disallows zoom, pass multi-touch events to webkit.
+        // mDeferMultitouch is a hack for layout tests, where it is used to
+        // force passing multi-touch events to webkit.
+        // FIXME: always pass multi-touch events to webkit and remove everything
+        // related to mDeferMultitouch.
+        if (ev.getPointerCount() > 1 &&
+                (mDeferMultitouch || (!isScrollGesture && mZoomManager.isZoomScaleFixed()))) {
             if (DebugFlags.WEB_VIEW) {
                 Log.v(LOGTAG, "passing " + ev.getPointerCount() + " points to webkit");
             }
@@ -5063,7 +5067,7 @@
         }
 
         if (mZoomManager.supportsMultiTouchZoom() && ev.getPointerCount() > 1 &&
-                mTouchMode != TOUCH_DRAG_LAYER_MODE && !skipScaleGesture) {
+                mTouchMode != TOUCH_DRAG_LAYER_MODE && !isScrollGesture) {
             if (!detector.isInProgress() &&
                     ev.getActionMasked() != MotionEvent.ACTION_POINTER_DOWN) {
                 // Insert a fake pointer down event in order to start
@@ -5336,7 +5340,7 @@
                     deltaX = 0;
                     deltaY = 0;
 
-                    if (skipScaleGesture) {
+                    if (isScrollGesture) {
                         startScrollingLayer(gestureX, gestureY);
                     }
                     startDrag();
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
index 3aa8950..b082c53 100644
--- a/libs/ui/Overlay.cpp
+++ b/libs/ui/Overlay.cpp
@@ -96,7 +96,6 @@
 }
 
 void Overlay::destroy() {  
-    if (mStatus != NO_ERROR) return;
 
     // Must delete the objects in reverse creation order, thus the
     //  data side must be closed first and then the destroy send to
@@ -104,9 +103,15 @@
     if (mOverlayData) {
         overlay_data_close(mOverlayData);
         mOverlayData = NULL;
+    } else {
+        LOGD("Overlay::destroy mOverlayData is NULL");
     }
 
-    mOverlayRef->mOverlayChannel->destroy();
+    if (mOverlayRef != 0) {
+        mOverlayRef->mOverlayChannel->destroy();
+    } else {
+        LOGD("Overlay::destroy mOverlayRef is NULL");
+    }
 }
 
 status_t Overlay::getStatus() const {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1773eca..1a10cff 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -557,7 +557,7 @@
             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
 
     /**
-     * Fingerprints (String.hashCode()) of stack traces that we've
+     * Fingerprints (hashCode()) of stack traces that we've
      * already logged DropBox entries for.  Guarded by itself.  If
      * something (rogue user app) forces this over
      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
@@ -6671,7 +6671,7 @@
         ProcessRecord r = findAppProcess(app);
 
         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
-            Integer stackFingerprint = info.crashInfo.stackTrace.hashCode();
+            Integer stackFingerprint = info.hashCode();
             boolean logIt = true;
             synchronized (mAlreadyLoggedViolatedStacks) {
                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {