Merge "bug #2618035: applying Moto's patch to fix a email/shortcode parsing bug." into froyo
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index dc952e6..19abec1 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -301,6 +301,23 @@
     }
 
     @Override
+    protected void onDraw(Canvas canvas) {
+        // onDraw should only be called for password fields.  If WebTextView is
+        // still drawing, but is no longer corresponding to a password field,
+        // remove it.
+        if (mWebView == null || !mWebView.nativeFocusCandidateIsPassword()
+                || !isSameTextField(mWebView.nativeFocusCandidatePointer())) {
+            // Although calling remove() would seem to make more sense here,
+            // changing it to not be a password field will make it not draw.
+            // Other code will make sure that it is removed completely, but this
+            // way the user will not see it.
+            setInPassword(false);
+        } else {
+            super.onDraw(canvas);
+        }
+    }
+
+    @Override
     public void onEditorAction(int actionCode) {
         switch (actionCode) {
         case EditorInfo.IME_ACTION_NEXT:
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index e2f5de4..66dad0b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -7256,13 +7256,13 @@
     private native void     nativeFindNext(boolean forward);
     /* package */ native int      nativeFocusCandidateFramePointer();
     /* package */ native boolean  nativeFocusCandidateHasNextTextfield();
-    private native boolean  nativeFocusCandidateIsPassword();
+    /* package */ native boolean  nativeFocusCandidateIsPassword();
     private native boolean  nativeFocusCandidateIsRtlText();
     private native boolean  nativeFocusCandidateIsTextInput();
     /* package */ native int      nativeFocusCandidateMaxLength();
     /* package */ native String   nativeFocusCandidateName();
     private native Rect     nativeFocusCandidateNodeBounds();
-    private native int      nativeFocusCandidatePointer();
+    /* package */ native int      nativeFocusCandidatePointer();
     private native String   nativeFocusCandidateText();
     private native int      nativeFocusCandidateTextSize();
     /**
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 79c8f9a..6eaf0cc 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -416,7 +416,7 @@
                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
             }
         }
-        if (checkExt || checkBoth && !mediaAvailable) {
+        if ((checkExt || checkBoth) && !mediaAvailable) {
             return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
         }
         return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 657b6af..53de7d9 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -7580,15 +7580,17 @@
                 while (i > 0) {
                     i--;
                     WindowState c = (WindowState)mChildWindows.get(i);
-                    if (c.mSurface != null && c.mAttachedHidden) {
+                    if (c.mAttachedHidden) {
                         c.mAttachedHidden = false;
-                        c.performShowLocked();
-                        // It hadn't been shown, which means layout not
-                        // performed on it, so now we want to make sure to
-                        // do a layout.  If called from within the transaction
-                        // loop, this will cause it to restart with a new
-                        // layout.
-                        mLayoutNeeded = true;
+                        if (c.mSurface != null) {
+                            c.performShowLocked();
+                            // It hadn't been shown, which means layout not
+                            // performed on it, so now we want to make sure to
+                            // do a layout.  If called from within the transaction
+                            // loop, this will cause it to restart with a new
+                            // layout.
+                            mLayoutNeeded = true;
+                        }
                     }
                 }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 7e095b5..436bd17 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -315,6 +315,11 @@
     // without empty apps being able to push them out of memory.
     static final int MIN_HIDDEN_APPS = 2;
     
+    // The maximum number of hidden processes we will keep around before
+    // killing them; this is just a control to not let us go too crazy with
+    // keeping around processes on devices with large amounts of RAM.
+    static final int MAX_HIDDEN_APPS = 15;
+    
     // We put empty content processes after any hidden processes that have
     // been idle for less than 30 seconds.
     static final long CONTENT_APP_IDLE_OFFSET = 30*1000;
@@ -8488,8 +8493,7 @@
                 }
                 int adj = proc.setAdj;
                 if (adj >= worstType) {
-                    Slog.w(TAG, "Killing " + reason + " : " + proc + " (adj "
-                            + adj + ")");
+                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
                             proc.processName, adj, reason);
                     killed = true;
@@ -8904,9 +8908,10 @@
             }
             if (app.pid > 0 && app.pid != MY_PID) {
                 handleAppCrashLocked(app);
-                Slog.i(ActivityManagerService.TAG, "Killing process "
-                        + app.processName
-                        + " (pid=" + app.pid + ") at user's request");
+                Slog.i(ActivityManagerService.TAG, "Killing "
+                        + app.processName + " (pid=" + app.pid + "): user's request");
+                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+                        app.processName, app.setAdj, "user's request after error");
                 Process.killProcess(app.pid);
             }
         }
@@ -10434,10 +10439,11 @@
             if (!capp.persistent && capp.thread != null
                     && capp.pid != 0
                     && capp.pid != MY_PID) {
-                Slog.i(TAG, "Killing app " + capp.processName
-                        + " (pid " + capp.pid
-                        + ") because provider " + cpr.info.name
-                        + " is in dying process " + proc.processName);
+                Slog.i(TAG, "Kill " + capp.processName
+                        + " (pid " + capp.pid + "): provider " + cpr.info.name
+                        + " in dying process " + proc.processName);
+                EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
+                        capp.processName, capp.setAdj, "dying provider " + proc.processName);
                 Process.killProcess(capp.pid);
             }
         }
@@ -11522,6 +11528,7 @@
                     if (r.isForeground) {
                         r.isForeground = false;
                         if (r.app != null) {
+                            updateLruProcessLocked(r.app, false, true);
                             updateServiceForegroundLocked(r.app, true);
                         }
                     }
@@ -14244,6 +14251,7 @@
         int factor = (mLruProcesses.size()-4)/numSlots;
         if (factor < 1) factor = 1;
         int step = 0;
+        int numHidden = 0;
         
         // First try updating the OOM adjustment for each of the
         // application processes based on their current state.
@@ -14262,6 +14270,17 @@
                         curHiddenAdj++;
                     }
                 }
+                if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
+                    numHidden++;
+                    if (numHidden > MAX_HIDDEN_APPS) {
+                        Slog.i(TAG, "Kill " + app.processName
+                                + " (pid " + app.pid + "): hidden #" + numHidden
+                                + " beyond limit " + MAX_HIDDEN_APPS);
+                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+                                app.processName, app.setAdj, "too many background");
+                        Process.killProcess(app.pid);
+                    }
+                }
             } else {
                 didOomAdj = false;
             }