Merge "Clarify documentation about when Activity#onCreateNavigateUpTaskStack will be called." into jb-dev
diff --git a/api/current.txt b/api/current.txt
index 43647ba..d12604b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2006,26 +2006,24 @@
     method protected void onServiceConnected();
     method public final boolean performGlobalAction(int);
     method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
-    field public static final int GESTURE_CLOCKWISE_CIRCLE = 9; // 0x9
-    field public static final int GESTURE_COUNTER_CLOCKWISE_CIRCLE = 10; // 0xa
     field public static final int GESTURE_SWIPE_DOWN = 2; // 0x2
-    field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 17; // 0x11
-    field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18; // 0x12
+    field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15; // 0xf
+    field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16; // 0x10
     field public static final int GESTURE_SWIPE_DOWN_AND_UP = 8; // 0x8
     field public static final int GESTURE_SWIPE_LEFT = 3; // 0x3
-    field public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 12; // 0xc
+    field public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 10; // 0xa
     field public static final int GESTURE_SWIPE_LEFT_AND_RIGHT = 5; // 0x5
-    field public static final int GESTURE_SWIPE_LEFT_AND_UP = 11; // 0xb
+    field public static final int GESTURE_SWIPE_LEFT_AND_UP = 9; // 0x9
     field public static final int GESTURE_SWIPE_RIGHT = 4; // 0x4
-    field public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 14; // 0xe
+    field public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 12; // 0xc
     field public static final int GESTURE_SWIPE_RIGHT_AND_LEFT = 6; // 0x6
-    field public static final int GESTURE_SWIPE_RIGHT_AND_UP = 13; // 0xd
+    field public static final int GESTURE_SWIPE_RIGHT_AND_UP = 11; // 0xb
     field public static final int GESTURE_SWIPE_UP = 1; // 0x1
     field public static final int GESTURE_SWIPE_UP_AND_DOWN = 7; // 0x7
-    field public static final int GESTURE_SWIPE_UP_AND_LEFT = 15; // 0xf
-    field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 16; // 0x10
-    field public static final int GESTURE_TWO_FINGER_LONG_PRESS = 20; // 0x14
-    field public static final int GESTURE_TWO_FINGER_TAP = 19; // 0x13
+    field public static final int GESTURE_SWIPE_UP_AND_LEFT = 13; // 0xd
+    field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14; // 0xe
+    field public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18; // 0x12
+    field public static final int GESTURE_TWO_FINGER_TAP = 17; // 0x11
     field public static final int GLOBAL_ACTION_BACK = 1; // 0x1
     field public static final int GLOBAL_ACTION_HOME = 2; // 0x2
     field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index c858e3c..b644dd1 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -244,64 +244,54 @@
     public static final int GESTURE_SWIPE_DOWN_AND_UP = 8;
 
     /**
-     * The user has performed a clockwise circle gesture on the touch screen.
-     */
-    public static final int GESTURE_CLOCKWISE_CIRCLE = 9;
-
-    /**
-     * The user has performed a counter clockwise circle gesture on the touch screen.
-     */
-    public static final int GESTURE_COUNTER_CLOCKWISE_CIRCLE = 10;
-
-    /**
      * The user has performed a left and up gesture on the touch screen.
      */
-    public static final int GESTURE_SWIPE_LEFT_AND_UP = 11;
+    public static final int GESTURE_SWIPE_LEFT_AND_UP = 9;
 
     /**
      * The user has performed a left and down gesture on the touch screen.
      */
-    public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 12;
+    public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 10;
 
     /**
      * The user has performed a right and up gesture on the touch screen.
      */
-    public static final int GESTURE_SWIPE_RIGHT_AND_UP = 13;
+    public static final int GESTURE_SWIPE_RIGHT_AND_UP = 11;
 
     /**
      * The user has performed a right and down gesture on the touch screen.
      */
-    public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 14;
+    public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 12;
 
     /**
      * The user has performed an up and left gesture on the touch screen.
      */
-    public static final int GESTURE_SWIPE_UP_AND_LEFT = 15;
+    public static final int GESTURE_SWIPE_UP_AND_LEFT = 13;
 
     /**
      * The user has performed an up and right gesture on the touch screen.
      */
-    public static final int GESTURE_SWIPE_UP_AND_RIGHT = 16;
+    public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14;
 
     /**
      * The user has performed an down and left gesture on the touch screen.
      */
-    public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 17;
+    public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15;
 
     /**
      * The user has performed an down and right gesture on the touch screen.
      */
-    public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18;
+    public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16;
 
     /**
      * The user has performed a two finger tap gesture on the touch screen.
      */
-    public static final int GESTURE_TWO_FINGER_TAP = 19;
+    public static final int GESTURE_TWO_FINGER_TAP = 17;
 
     /**
      * The user has performed a two finger long press gesture on the touch screen.
      */
-    public static final int GESTURE_TWO_FINGER_LONG_PRESS = 20;
+    public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18;
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1a46430b..b55ee26 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3843,7 +3843,7 @@
         windowManager.endTrimMemory();        
     }
 
-    private void setupGraphicsSupport(LoadedApk info) {
+    private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
         if (Process.isIsolated()) {
             // Isolated processes aren't going to do UI.
             return;
@@ -3855,11 +3855,8 @@
             // If there are several packages in this application we won't
             // initialize the graphics disk caches 
             if (packages != null && packages.length == 1) {
-                ContextImpl appContext = new ContextImpl();
-                appContext.init(info, null, this);
-
-                HardwareRenderer.setupDiskCache(appContext.getCacheDir());
-                RenderScript.setupDiskCache(appContext.getCacheDir());
+                HardwareRenderer.setupDiskCache(cacheDir);
+                RenderScript.setupDiskCache(cacheDir);
             }
         } catch (RemoteException e) {
             // Ignore
@@ -3925,8 +3922,15 @@
 
         data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
 
-        setupGraphicsSupport(data.info);        
-        
+        final ContextImpl appContext = new ContextImpl();
+        appContext.init(data.info, null, this);
+        final File cacheDir = appContext.getCacheDir();
+
+        // Provide a usable directory for temporary files
+        System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
+
+        setupGraphicsSupport(data.info, cacheDir);
+
         /**
          * For system applications on userdebug/eng builds, log stack
          * traces of disk and network access to dropbox for analysis.
@@ -4003,8 +4007,6 @@
         }
 
         if (data.instrumentationName != null) {
-            ContextImpl appContext = new ContextImpl();
-            appContext.init(data.info, null, this);
             InstrumentationInfo ii = null;
             try {
                 ii = appContext.getPackageManager().
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index c62e5cf..3f0b4d4 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -16,17 +16,20 @@
 
 package android.app;
 
-import com.android.internal.R;
-
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
+import android.text.format.DateUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.DatePicker;
 import android.widget.DatePicker.OnDateChangedListener;
 
+import com.android.internal.R;
+
+import java.util.Calendar;
+
 /**
  * A simple dialog containing an {@link android.widget.DatePicker}.
  *
@@ -42,6 +45,9 @@
 
     private final DatePicker mDatePicker;
     private final OnDateSetListener mCallBack;
+    private final Calendar mCalendar;
+
+    private boolean mTitleNeedsUpdate = true;
 
     /**
      * The callback used to indicate the user is done filling in the date.
@@ -91,10 +97,11 @@
 
         mCallBack = callBack;
 
+        mCalendar = Calendar.getInstance();
+
         Context themeContext = getContext();
         setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this);
         setIcon(0);
-        setTitle(R.string.date_picker_dialog_title);
 
         LayoutInflater inflater =
                 (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -102,6 +109,7 @@
         setView(view);
         mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
         mDatePicker.init(year, monthOfYear, dayOfMonth, this);
+        updateTitle(year, monthOfYear, dayOfMonth);
     }
 
     public void onClick(DialogInterface dialog, int which) {
@@ -110,7 +118,8 @@
 
     public void onDateChanged(DatePicker view, int year,
             int month, int day) {
-        mDatePicker.init(year, month, day, null);
+        mDatePicker.init(year, month, day, this);
+        updateTitle(year, month, day);
     }
 
     /**
@@ -147,6 +156,28 @@
         super.onStop();
     }
 
+    private void updateTitle(int year, int month, int day) {
+        if (!mDatePicker.getCalendarViewShown()) {
+            mCalendar.set(Calendar.YEAR, year);
+            mCalendar.set(Calendar.MONTH, month);
+            mCalendar.set(Calendar.DAY_OF_MONTH, day);
+            String title = DateUtils.formatDateTime(mContext,
+                    mCalendar.getTimeInMillis(),
+                    DateUtils.FORMAT_SHOW_DATE
+                    | DateUtils.FORMAT_SHOW_WEEKDAY
+                    | DateUtils.FORMAT_SHOW_YEAR
+                    | DateUtils.FORMAT_ABBREV_MONTH
+                    | DateUtils.FORMAT_ABBREV_WEEKDAY);
+            setTitle(title);
+            mTitleNeedsUpdate = true;
+        } else {
+            if (mTitleNeedsUpdate) {
+                mTitleNeedsUpdate = false;
+                setTitle(R.string.date_picker_dialog_title);
+            }
+        }
+    }
+
     @Override
     public Bundle onSaveInstanceState() {
         Bundle state = super.onSaveInstanceState();
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 0713127..93f732c 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -1155,7 +1155,7 @@
         validateArgumentIsNonEmpty("description", description);
         validateArgumentIsNonEmpty("path", path);
         validateArgumentIsNonEmpty("mimeType", mimeType);
-        if (length <= 0) {
+        if (length < 0) {
             throw new IllegalArgumentException(" invalid value for param: totalBytes");
         }
 
diff --git a/core/java/android/server/BluetoothAdapterStateMachine.java b/core/java/android/server/BluetoothAdapterStateMachine.java
index 7711caa..f543de9 100644
--- a/core/java/android/server/BluetoothAdapterStateMachine.java
+++ b/core/java/android/server/BluetoothAdapterStateMachine.java
@@ -441,9 +441,10 @@
                         if (mPublicState == BluetoothAdapter.STATE_TURNING_OFF) {
                             transitionTo(mHotOff);
                             finishSwitchingOff();
-                            if (!mContext.getResources().getBoolean
-                            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-                                deferMessage(obtainMessage(TURN_COLD));
+                            deferMessage(obtainMessage(TURN_COLD));
+                            if (mContext.getResources().getBoolean
+                                (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
+                                deferMessage(obtainMessage(TURN_HOT));
                             }
                         }
                     } else {
@@ -612,9 +613,10 @@
                     removeMessages(POWER_DOWN_TIMEOUT);
                     if (!((Boolean) message.obj)) {
                         transitionTo(mHotOff);
-                        if (!mContext.getResources().getBoolean
+                        deferMessage(obtainMessage(TURN_COLD));
+                        if (mContext.getResources().getBoolean
                             (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-                            deferMessage(obtainMessage(TURN_COLD));
+                            deferMessage(obtainMessage(TURN_HOT));
                         }
                     } else {
                         if (!isTurningOn) {
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 78a7d46..5c60a12 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -135,7 +135,12 @@
      */
     public void setSource(View root, int virtualDescendantId) {
         enforceNotSealed();
-        final boolean important = (root != null) ? root.isImportantForAccessibility() : true;
+        final boolean important;
+        if (virtualDescendantId == UNDEFINED) {
+            important = (root != null) ? root.isImportantForAccessibility() : true;
+        } else {
+            important = true;
+        }
         setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, important);
         mSourceWindowId = (root != null) ? root.getAccessibilityWindowId() : UNDEFINED;
         final int rootViewId = (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 30229f1..99a3212 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -984,7 +984,6 @@
     static final int REQUEST_KEYBOARD                   = 118;
     static final int SHOW_FULLSCREEN                    = 120;
     static final int HIDE_FULLSCREEN                    = 121;
-    static final int REPLACE_BASE_CONTENT               = 123;
     static final int UPDATE_MATCH_COUNT                 = 126;
     static final int CENTER_FIT_RECT                    = 127;
     static final int SET_SCROLLBAR_MODES                = 129;
@@ -2018,6 +2017,11 @@
     }
 
     private void destroyImpl() {
+        int drawGLFunction = nativeGetDrawGLFunction(mNativeClass);
+        ViewRootImpl viewRoot = mWebView.getViewRootImpl();
+        Log.d(LOGTAG, String.format("destroyImpl, drawGLFunction %x,  viewroot == null %b, isHWAccel %b",
+                                    drawGLFunction, (viewRoot == null), mWebView.isHardwareAccelerated()));
+
         mCallbackProxy.blockMessages();
         clearHelpers();
         if (mListBoxDialog != null) {
@@ -4232,14 +4236,8 @@
                 df = mScrollFilter;
             }
             canvas.setDrawFilter(df);
-            // XXX: Revisit splitting content.  Right now it causes a
-            // synchronization problem with layers.
-            int content = nativeDraw(canvas, mVisibleContentRect, mBackgroundColor,
-                    extras, false);
+            nativeDraw(canvas, mVisibleContentRect, mBackgroundColor, extras);
             canvas.setDrawFilter(null);
-            if (!mBlockWebkitViewMessages && content != 0) {
-                mWebViewCore.sendMessage(EventHub.SPLIT_PICTURE_SET, content, 0);
-            }
         }
 
         canvas.restoreToCount(saveCount);
@@ -4362,7 +4360,9 @@
     }
 
     private void removeTouchHighlight() {
-        mWebViewCore.removeMessages(EventHub.HIT_TEST);
+        if (mWebViewCore != null) {
+            mWebViewCore.removeMessages(EventHub.HIT_TEST);
+        }
         mPrivateHandler.removeMessages(HIT_TEST_RESULT);
         setTouchHighlightRects(null);
     }
@@ -5434,9 +5434,11 @@
         removeAccessibilityApisFromJavaScript();
         updateHwAccelerated();
 
+        int drawGLFunction = nativeGetDrawGLFunction(mNativeClass);
+        ViewRootImpl viewRoot = mWebView.getViewRootImpl();
+        Log.d(LOGTAG, String.format("onDetachedFromWindow, drawGLFunction %x,  viewroot == null %b, isHWAccel %b",
+                                    drawGLFunction, (viewRoot == null), mWebView.isHardwareAccelerated()));
         if (mWebView.isHardwareAccelerated()) {
-            int drawGLFunction = nativeGetDrawGLFunction(mNativeClass);
-            ViewRootImpl viewRoot = mWebView.getViewRootImpl();
             if (drawGLFunction != 0 && viewRoot != null) {
                 viewRoot.detachFunctor(drawGLFunction);
             }
@@ -7256,10 +7258,6 @@
                     mZoomManager.updateDefaultZoomDensity(density);
                     break;
                 }
-                case REPLACE_BASE_CONTENT: {
-                    nativeReplaceBaseContent(msg.arg1);
-                    break;
-                }
                 case NEW_PICTURE_MSG_ID: {
                     // called for new content
                     final WebViewCore.DrawData draw = (WebViewCore.DrawData) msg.obj;
@@ -8434,18 +8432,6 @@
     }
 
     /**
-     * Draw the HTML page into the specified canvas. This call ignores any
-     * view-specific zoom, scroll offset, or other changes. It does not draw
-     * any view-specific chrome, such as progress or URL bars.
-     *
-     * only needs to be accessible to Browser and testing
-     */
-    public void drawPage(Canvas canvas) {
-        calcOurContentVisibleRectF(mVisibleContentRect);
-        nativeDraw(canvas, mVisibleContentRect, 0, 0, false);
-    }
-
-    /**
      * Enable the communication b/t the webView and VideoViewProxy
      *
      * only used by the Browser
@@ -8578,14 +8564,8 @@
     private native void     nativeDebugDump();
     private native void     nativeDestroy();
 
-    /**
-     * Draw the picture set with a background color and extra. If
-     * "splitIfNeeded" is true and the return value is not 0, the return value
-     * MUST be passed to WebViewCore with SPLIT_PICTURE_SET message so that the
-     * native allocation can be freed.
-     */
-    private native int nativeDraw(Canvas canvas, RectF visibleRect,
-            int color, int extra, boolean splitIfNeeded);
+    private native void nativeDraw(Canvas canvas, RectF visibleRect,
+            int color, int extra);
     private native void     nativeDumpDisplayTree(String urlOrNull);
     private native boolean  nativeEvaluateLayersAnimations(int nativeInstance);
     private native int      nativeCreateDrawGLFunction(int nativeInstance, Rect rect,
@@ -8599,7 +8579,6 @@
     private native boolean  nativeSetBaseLayer(int nativeInstance,
             int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout);
     private native int      nativeGetBaseLayer();
-    private native void     nativeReplaceBaseContent(int content);
     private native void     nativeCopyBaseContentToPicture(Picture pict);
     private native boolean  nativeHasContent();
     private native void     nativeStopGL();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 12c9d69..7a757a8 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -610,12 +610,6 @@
 
     private native boolean nativeFocusBoundsChanged(int nativeClass);
 
-    /**
-     * Splits slow parts of the picture set. Called from the webkit thread after
-     * WebView.nativeDraw() returns content to be split.
-     */
-    private native void nativeSplitContent(int nativeClass, int content);
-
     private native boolean nativeKey(int nativeClass, int keyCode,
             int unichar, int repeatCount, boolean isShift, boolean isAlt,
             boolean isSym, boolean isDown);
@@ -1018,7 +1012,7 @@
             "WEBKIT_DRAW", // = 130;
             "131", // = 131;
             "POST_URL", // = 132;
-            "SPLIT_PICTURE_SET", // = 133;
+            "", // = 133;
             "CLEAR_CONTENT", // = 134;
             "", // = 135;
             "", // = 136;
@@ -1094,7 +1088,6 @@
 
         static final int WEBKIT_DRAW = 130;
         static final int POST_URL = 132;
-        static final int SPLIT_PICTURE_SET = 133;
         static final int CLEAR_CONTENT = 134;
 
         // UI nav messages
@@ -1611,13 +1604,6 @@
                                     data.mOrigin, data.mAllow, data.mRemember);
                             break;
 
-                        case SPLIT_PICTURE_SET:
-                            nativeSplitContent(mNativeClass, msg.arg1);
-                            mWebViewClassic.mPrivateHandler.obtainMessage(
-                                    WebViewClassic.REPLACE_BASE_CONTENT, msg.arg1, 0);
-                            mSplitPictureIsScheduled = false;
-                            break;
-
                         case CLEAR_CONTENT:
                             // Clear the view so that onDraw() will draw nothing
                             // but white background
@@ -1879,7 +1865,6 @@
         private synchronized void removeMessages() {
             // reset mDrawIsScheduled flag as WEBKIT_DRAW may be removed
             mDrawIsScheduled = false;
-            mSplitPictureIsScheduled = false;
             if (mMessages != null) {
                 mMessages.clear();
             } else {
@@ -2141,20 +2126,9 @@
         return usedQuota;
     }
 
-    // called from UI thread
-    void splitContent(int content) {
-        if (!mSplitPictureIsScheduled) {
-            mSplitPictureIsScheduled = true;
-            sendMessage(EventHub.SPLIT_PICTURE_SET, content, 0);
-        }
-    }
-
     // Used to avoid posting more than one draw message.
     private boolean mDrawIsScheduled;
 
-    // Used to avoid posting more than one split picture message.
-    private boolean mSplitPictureIsScheduled;
-
     // Used to suspend drawing.
     private boolean mDrawIsPaused;
 
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 4d9ff0f..cb10d0a 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -658,7 +658,7 @@
     private void validateLayoutParams() {
         final boolean horizontal = (orientation == HORIZONTAL);
         final Axis axis = horizontal ? horizontalAxis : verticalAxis;
-        final int count = max(0, axis.getCount()); // Handle negative values, including UNDEFINED
+        final int count = (axis.definedCount != UNDEFINED) ? axis.definedCount : 0;
 
         int major = 0;
         int minor = 0;
diff --git a/core/java/com/android/server/NetworkManagementSocketTagger.java b/core/java/com/android/server/NetworkManagementSocketTagger.java
index c77992d..06ef4c9 100644
--- a/core/java/com/android/server/NetworkManagementSocketTagger.java
+++ b/core/java/com/android/server/NetworkManagementSocketTagger.java
@@ -16,20 +16,14 @@
 
 package com.android.server;
 
-import android.net.NetworkStats;
 import android.os.SystemProperties;
 import android.util.Log;
 import android.util.Slog;
 
 import dalvik.system.SocketTagger;
-import libcore.io.IoUtils;
 
 import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.math.BigInteger;
 import java.net.SocketException;
-import java.nio.charset.Charsets;
 
 /**
  * Assigns tags to sockets for traffic stats.
@@ -141,8 +135,12 @@
      * format like {@code 0x7fffffff00000000}.
      */
     public static int kernelToTag(String string) {
-        // TODO: migrate to direct integer instead of odd shifting
-        return (int) (Long.decode(string) >> 32);
+        int length = string.length();
+        if (length > 10) {
+            return Long.decode(string.substring(0, length - 8)).intValue();
+        } else {
+            return 0;
+        }
     }
 
     private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid);
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2d29d06..978e2a8 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1316,6 +1316,7 @@
   <java-symbol type="string" name="lockscreen_password_wrong" />
   <java-symbol type="string" name="lockscreen_pattern_instructions" />
   <java-symbol type="string" name="lockscreen_pattern_wrong" />
+  <java-symbol type="string" name="lockscreen_permanent_disabled_sim_message_short" />
   <java-symbol type="string" name="lockscreen_permanent_disabled_sim_instructions" />
   <java-symbol type="string" name="lockscreen_plugged_in" />
   <java-symbol type="string" name="lockscreen_sim_locked_message" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index bc1e79c..c863e7c 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1898,6 +1898,8 @@
     <string name="lockscreen_missing_sim_instructions">Insert a SIM card.</string>
     <!-- Shown in the lock screen to ask the user to insert a SIM card when sim is missing or not readable. -->
     <string name="lockscreen_missing_sim_instructions_long">The SIM card is missing or not readable. Insert a SIM card.</string>
+    <!-- Shown in the lock screen when SIM card is permanently disabled. -->
+    <string name="lockscreen_permanent_disabled_sim_message_short">Unusable SIM card.</string>
     <!-- Shown in the lock screen to inform the user to SIM card is permanently disabled. -->
     <string name="lockscreen_permanent_disabled_sim_instructions">Your SIM card has been permanently disabled.\n
     Contact your wireless service provider for another SIM card.</string>
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 8a5f8bb..77e4986 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -1229,9 +1229,8 @@
 
         installFromRawResource("install.apk", R.raw.install_loc_unspecified,
                 PackageManager.INSTALL_FORWARD_LOCK |
-                PackageManager.INSTALL_EXTERNAL, true, true,
-                PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
-                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+                PackageManager.INSTALL_EXTERNAL, true, false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
     }
 
     @LargeTest
@@ -1626,8 +1625,8 @@
 
         int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
-        boolean fail = true;
-        int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
+        boolean fail = false;
+        int result = PackageManager.MOVE_SUCCEEDED;
         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
     }
 
@@ -1950,7 +1949,7 @@
                 PackageManager.INSTALL_FORWARD_LOCK,
                 true,
                 false, -1,
-                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+                PackageInfo.INSTALL_LOCATION_AUTO);
     }
 
     /* The following test functions verify install location for existing apps.
diff --git a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
index 58269a8..b994483 100644
--- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -25,6 +25,7 @@
 
 import android.content.res.Resources;
 import android.net.NetworkStats;
+import android.net.TrafficStats;
 import android.test.AndroidTestCase;
 
 import com.android.frameworks.coretests.R;
@@ -138,6 +139,12 @@
         assertEquals(2147483647, kernelToTag("0x7fffffff00000000"));
         assertEquals(0, kernelToTag("0x0000000000000000"));
         assertEquals(2147483136, kernelToTag("0x7FFFFE0000000000"));
+
+        assertEquals(0, kernelToTag("0x0"));
+        assertEquals(0, kernelToTag("0xf00d"));
+        assertEquals(1, kernelToTag("0x100000000"));
+        assertEquals(14438007, kernelToTag("0xdc4e7700000000"));
+        assertEquals(TrafficStats.TAG_SYSTEM_DOWNLOAD, kernelToTag("0xffffff0100000000"));
     }
 
     public void testNetworkStatsWithSet() throws Exception {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index da2192f..80db693 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -247,6 +247,7 @@
 }
 
 void OpenGLRenderer::detachFunctor(Functor* functor) {
+    ALOGD("OGLR %p detachFunctor %p", this, functor);
     mFunctors.remove(functor);
 }
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
index a1cec01..9e40d37 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
@@ -47,20 +47,19 @@
     private int mHeight = 0;
     private int mTarget = FrameFormat.TARGET_UNSPECIFIED;
 
-    private Frame mNoiseFrame = null;
-    private Random mRandom;
-
     private final String mBlackWhiteShader =
             "precision mediump float;\n" +
             "uniform sampler2D tex_sampler_0;\n" +
-            "uniform sampler2D tex_sampler_1;\n" +
             "uniform float black;\n" +
             "uniform float scale;\n" +
             "uniform float stepsize;\n" +
             "varying vec2 v_texcoord;\n" +
+            "float rand(vec2 loc) {\n" +
+            "  return fract(sin(dot(loc, vec2(12.9898, 78.233))) * 43758.5453);\n" +
+            "}\n" +
             "void main() {\n" +
             "  vec4 color = texture2D(tex_sampler_0, v_texcoord);\n" +
-            "  float dither = texture2D(tex_sampler_1, v_texcoord).r;\n" +
+            "  float dither = rand(v_texcoord);\n" +
             "  vec3 xform = clamp((color.rgb - black) * scale, 0.0, 1.0);\n" +
             "  vec3 temp = clamp((color.rgb + stepsize - black) * scale, 0.0, 1.0);\n" +
             "  vec3 new_color = clamp(xform + (temp - xform) * (dither - 0.5), 0.0, 1.0);\n" +
@@ -69,8 +68,6 @@
 
     public BlackWhiteFilter(String name) {
         super(name);
-
-        mRandom = new Random();
     }
 
     @Override
@@ -84,14 +81,6 @@
         return inputFormat;
     }
 
-    @Override
-    public void tearDown(FilterContext context) {
-        if (mNoiseFrame != null) {
-            mNoiseFrame.release();
-            mNoiseFrame = null;
-        }
-    }
-
     public void initProgram(FilterContext context, int target) {
         switch (target) {
             case FrameFormat.TARGET_GPU:
@@ -139,33 +128,13 @@
         if (inputFormat.getWidth() != mWidth || inputFormat.getHeight() != mHeight) {
             mWidth = inputFormat.getWidth();
             mHeight = inputFormat.getHeight();
-
-            if (mNoiseFrame != null) {
-                mNoiseFrame.release();
-            }
-
-            int[] buffer = new int[mWidth * mHeight];
-            for (int i = 0; i < mWidth * mHeight; ++i) {
-              buffer[i] = mRandom.nextInt(255);
-            }
-            FrameFormat format = ImageFormat.create(mWidth, mHeight,
-                                                    ImageFormat.COLORSPACE_RGBA,
-                                                    FrameFormat.TARGET_GPU);
-            mNoiseFrame = context.getFrameManager().newFrame(format);
-            mNoiseFrame.setInts(buffer);
-        }
-
-        if (mNoiseFrame != null && (mNoiseFrame.getFormat().getWidth() != mWidth ||
-                                    mNoiseFrame.getFormat().getHeight() != mHeight)) {
-            throw new RuntimeException("Random map and imput image size mismatch!");
         }
 
         // Create output frame
         Frame output = context.getFrameManager().newFrame(inputFormat);
 
         // Process
-        Frame[] inputs = {input, mNoiseFrame};
-        mProgram.process(inputs, output);
+        mProgram.process(input, output);
 
         // Push output
         pushOutput("image", output);
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
index 3c7b846..0144d4e 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
@@ -41,21 +41,20 @@
     private int mHeight = 0;
     private int mTarget = FrameFormat.TARGET_UNSPECIFIED;
 
-    private Frame mNoiseFrame;
-    private Random mRandom;
-
     private final String mDocumentaryShader =
             "precision mediump float;\n" +
             "uniform sampler2D tex_sampler_0;\n" +
-            "uniform sampler2D tex_sampler_1;\n" +
             "uniform float stepsize;\n" +
             "uniform float inv_max_dist;\n" +
             "uniform vec2 center;\n" +
             "varying vec2 v_texcoord;\n" +
+            "float rand(vec2 loc) {\n" +
+            "  return fract(sin(dot(loc, vec2(12.9898, 78.233))) * 43758.5453);\n" +
+            "}\n" +
             "void main() {\n" +
             // black white
             "  vec4 color = texture2D(tex_sampler_0, v_texcoord);\n" +
-            "  float dither = texture2D(tex_sampler_1, v_texcoord).r;\n" +
+            "  float dither = rand(v_texcoord);\n" +
             "  vec3 xform = clamp(2.0 * color.rgb, 0.0, 1.0);\n" +
             "  vec3 temp = clamp(2.0 * (color.rgb + stepsize), 0.0, 1.0);\n" +
             "  vec3 new_color = clamp(xform + (temp - xform) * (dither - 0.5), 0.0, 1.0);\n" +
@@ -70,8 +69,6 @@
 
     public DocumentaryFilter(String name) {
         super(name);
-
-        mRandom = new Random();
     }
 
     @Override
@@ -85,14 +82,6 @@
         return inputFormat;
     }
 
-    @Override
-    public void tearDown(FilterContext context) {
-        if (mNoiseFrame != null) {
-            mNoiseFrame.release();
-            mNoiseFrame = null;
-        }
-    }
-
     public void initProgram(FilterContext context, int target) {
         switch (target) {
             case FrameFormat.TARGET_GPU:
@@ -123,34 +112,14 @@
         if (inputFormat.getWidth() != mWidth || inputFormat.getHeight() != mHeight) {
             mWidth = inputFormat.getWidth();
             mHeight = inputFormat.getHeight();
-
-            int[] buffer = new int[mWidth * mHeight];
-            for (int i = 0; i < mWidth * mHeight; ++i) {
-              buffer[i] = mRandom.nextInt(255);
-            }
-            FrameFormat format = ImageFormat.create(mWidth, mHeight,
-                                                    ImageFormat.COLORSPACE_RGBA,
-                                                    FrameFormat.TARGET_GPU);
-            if (mNoiseFrame != null) {
-                mNoiseFrame.release();
-            }
-            mNoiseFrame = context.getFrameManager().newFrame(format);
-            mNoiseFrame.setInts(buffer);
-
             initParameters();
         }
 
-        if (mNoiseFrame != null && (mNoiseFrame.getFormat().getWidth() != mWidth ||
-                                    mNoiseFrame.getFormat().getHeight() != mHeight)) {
-            throw new RuntimeException("Random map and imput image size mismatch!");
-        }
-
         // Create output frame
         Frame output = context.getFrameManager().newFrame(inputFormat);
 
         // Process
-        Frame[] inputs = {input, mNoiseFrame};
-        mProgram.process(inputs, output);
+        mProgram.process(input, output);
 
         // Push output
         pushOutput("image", output);
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
index 452a833..0814ba5 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
@@ -28,8 +28,6 @@
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import java.util.Random;
-
 public class LomoishFilter extends Filter {
 
     @GenerateFieldPort(name = "tile_size", hasDefault = true)
@@ -41,19 +39,18 @@
     private int mHeight = 0;
     private int mTarget = FrameFormat.TARGET_UNSPECIFIED;
 
-    private Frame mNoiseFrame;
-    private Random mRandom;
-
     private final String mLomoishShader =
             "precision mediump float;\n" +
             "uniform sampler2D tex_sampler_0;\n" +
-            "uniform sampler2D tex_sampler_1;\n" +
             "uniform float stepsizeX;\n" +
             "uniform float stepsizeY;\n" +
             "uniform float stepsize;\n" +
             "uniform vec2 center;\n" +
             "uniform float inv_max_dist;\n" +
             "varying vec2 v_texcoord;\n" +
+            "float rand(vec2 loc) {\n" +
+            "  return fract(sin(dot(loc, vec2(12.9898, 78.233))) * 43758.5453);\n" +
+            "}\n" +
             "void main() {\n" +
             // sharpen
             "  vec3 nbr_color = vec3(0.0, 0.0, 0.0);\n" +
@@ -99,7 +96,7 @@
             "  }\n" +
             "  c_color.b = s_color.b * 0.5 + 0.25;\n" +
             // blackwhite
-            "  float dither = texture2D(tex_sampler_1, v_texcoord).r;\n" +
+            "  float dither = rand(v_texcoord);\n" +
             "  vec3 xform = clamp((c_color.rgb - 0.15) * 1.53846, 0.0, 1.0);\n" +
             "  vec3 temp = clamp((color.rgb + stepsize - 0.15) * 1.53846, 0.0, 1.0);\n" +
             "  vec3 bw_color = clamp(xform + (temp - xform) * (dither - 0.5), 0.0, 1.0);\n" +
@@ -111,8 +108,6 @@
 
     public LomoishFilter(String name) {
         super(name);
-
-        mRandom = new Random();
     }
 
     @Override
@@ -126,14 +121,6 @@
         return inputFormat;
     }
 
-    @Override
-    public void tearDown(FilterContext context) {
-        if (mNoiseFrame != null) {
-            mNoiseFrame.release();
-            mNoiseFrame = null;
-        }
-    }
-
     public void initProgram(FilterContext context, int target) {
         switch (target) {
             case FrameFormat.TARGET_GPU:
@@ -180,34 +167,14 @@
         if (inputFormat.getWidth() != mWidth || inputFormat.getHeight() != mHeight) {
             mWidth = inputFormat.getWidth();
             mHeight = inputFormat.getHeight();
-
-            int[] buffer = new int[mWidth * mHeight];
-            for (int i = 0; i < mWidth * mHeight; ++i) {
-              buffer[i] = mRandom.nextInt(255);
-            }
-            FrameFormat format = ImageFormat.create(mWidth, mHeight,
-                                                    ImageFormat.COLORSPACE_RGBA,
-                                                    FrameFormat.TARGET_GPU);
-            if (mNoiseFrame != null) {
-                mNoiseFrame.release();
-            }
-            mNoiseFrame = context.getFrameManager().newFrame(format);
-            mNoiseFrame.setInts(buffer);
-
             initParameters();
         }
 
-        if (mNoiseFrame != null && (mNoiseFrame.getFormat().getWidth() != mWidth ||
-                                    mNoiseFrame.getFormat().getHeight() != mHeight)) {
-            throw new RuntimeException("Random map and imput image size mismatch!");
-        }
-
         // Create output frame
         Frame output = context.getFrameManager().newFrame(inputFormat);
 
         // Process
-        Frame[] inputs = {input, mNoiseFrame};
-        mProgram.process(inputs, output);
+        mProgram.process(input, output);
 
         // Push output
         pushOutput("image", output);
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 3eec18c..c709e40 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -311,6 +311,14 @@
             return null;
         }
 
+        try {
+            Libcore.os.chmod(resFile.getAbsolutePath(), 0640);
+        } catch (ErrnoException e) {
+            Slog.e(TAG, "Could not chown APK: " + e.getMessage());
+            PackageHelper.destroySdDir(newCid);
+            return null;
+        }
+
         if (isForwardLocked) {
             File publicZipFile = new File(newCachePath, publicResFileName);
             try {
@@ -326,10 +334,9 @@
             }
 
             try {
-                Libcore.os.chmod(resFile.getAbsolutePath(), 0640);
                 Libcore.os.chmod(publicZipFile.getAbsolutePath(), 0644);
             } catch (ErrnoException e) {
-                Slog.e(TAG, "Could not chown APK or resource file: " + e.getMessage());
+                Slog.e(TAG, "Could not chown public resource file: " + e.getMessage());
                 PackageHelper.destroySdDir(newCid);
                 return null;
             }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 9c9844e..9d3a942 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -29,6 +29,7 @@
     <uses-permission android:name="android.permission.DEVICE_POWER" />
     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
     <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
+    <uses-permission android:name="android.permission.MASTER_CLEAR" />
 
     <!-- ActivityManager -->
     <uses-permission android:name="android.permission.GET_TASKS" />
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index a6986de..d0fe42d 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -509,7 +509,8 @@
                 break;
 
             case SimPermDisabled:
-                carrierText = getContext().getText(R.string.lockscreen_missing_sim_message_short);
+                carrierText = getContext().getText(
+                        R.string.lockscreen_permanent_disabled_sim_message_short);
                 carrierHelpTextId = R.string.lockscreen_permanent_disabled_sim_instructions;
                 mEmergencyButtonEnabledBecauseSimLocked = true;
                 break;
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 21ae624..b5d0b60 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -5863,9 +5863,28 @@
                 Log.w(TAG, "Insufficient storage to install");
                 return;
             }
-            // Create the file args now.
+
+            mRet = srcArgs.doPreCopy();
+            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
+                return;
+            }
+
             mRet = targetArgs.copyApk(mContainerService, false);
-            targetArgs.doPreInstall(mRet);
+            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
+                srcArgs.doPostCopy(uid);
+                return;
+            }
+
+            mRet = srcArgs.doPostCopy(uid);
+            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
+                return;
+            }
+
+            mRet = targetArgs.doPreInstall(mRet);
+            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
+                return;
+            }
+
             if (DEBUG_SD_INSTALL) {
                 StringBuilder builder = new StringBuilder();
                 if (srcArgs != null) {
@@ -5936,7 +5955,7 @@
             String nativeLibraryPath) {
         if (installOnSd(flags) || installForwardLocked(flags)) {
             return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
-                    (flags & PackageManager.INSTALL_EXTERNAL) != 0);
+                    installOnSd(flags), installForwardLocked(flags));
         } else {
             return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
         }
@@ -5945,9 +5964,10 @@
     // Used by package mover
     private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
         if (installOnSd(flags) || installForwardLocked(flags)) {
-            String cid = getNextCodePath(null, pkgName, "/" + AsecInstallArgs.RES_FILE_NAME);
-            return new AsecInstallArgs(packageURI, cid,
-                    (flags & PackageManager.INSTALL_EXTERNAL) != 0);
+            String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
+                    + AsecInstallArgs.RES_FILE_NAME);
+            return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
+                    installForwardLocked(flags));
         } else {
             return new FileInstallArgs(packageURI, pkgName, dataDir);
         }
@@ -5984,6 +6004,26 @@
         abstract boolean doPostDeleteLI(boolean delete);
         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
 
+        /**
+         * Called before the source arguments are copied. This is used mostly
+         * for MoveParams when it needs to read the source file to put it in the
+         * destination.
+         */
+        int doPreCopy() {
+            return PackageManager.INSTALL_SUCCEEDED;
+        }
+
+        /**
+         * Called after the source arguments are copied. This is used mostly for
+         * MoveParams when it needs to read the source file to put it in the
+         * destination.
+         *
+         * @return
+         */
+        int doPostCopy(int uid) {
+            return PackageManager.INSTALL_SUCCEEDED;
+        }
+
         protected boolean isFwdLocked() {
             return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
         }
@@ -6280,8 +6320,9 @@
         }
 
         AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
-                boolean isExternal) {
-            super(null, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null);
+                boolean isExternal, boolean isForwardLocked) {
+            super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
+                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), null, null);
             // Extract cid from fullCodePath
             int eidx = fullCodePath.lastIndexOf("/");
             String subStr1 = fullCodePath.substring(0, eidx);
@@ -6296,8 +6337,9 @@
             setCachePath(PackageHelper.getSdDir(cid));
         }
 
-        AsecInstallArgs(Uri packageURI, String cid, boolean isExternal) {
-            super(packageURI, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null);
+        AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
+            super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
+                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), null, null);
             this.cid = cid;
         }
 
@@ -6443,8 +6485,18 @@
             if (status != PackageManager.INSTALL_SUCCEEDED) {
                 cleanUp();
             } else {
+                final int groupOwner;
+                final String protectedFile;
+                if (isFwdLocked()) {
+                    groupOwner = uid;
+                    protectedFile = RES_FILE_NAME;
+                } else {
+                    groupOwner = -1;
+                    protectedFile = null;
+                }
+
                 if (uid < Process.FIRST_APPLICATION_UID
-                        || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) {
+                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
                     Slog.e(TAG, "Failed to finalize " + cid);
                     PackageHelper.destroySdDir(cid);
                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
@@ -6505,6 +6557,33 @@
             }
             return ret;
         }
+
+        @Override
+        int doPreCopy() {
+            if (isFwdLocked()) {
+                if (!PackageHelper.fixSdPermissions(cid,
+                        getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
+                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
+                }
+            }
+
+            return PackageManager.INSTALL_SUCCEEDED;
+        }
+
+        @Override
+        int doPostCopy(int uid) {
+            if (isFwdLocked()) {
+                PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME);
+                if (uid < Process.FIRST_APPLICATION_UID
+                        || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) {
+                    Slog.e(TAG, "Failed to finalize " + cid);
+                    PackageHelper.destroySdDir(cid);
+                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
+                }
+            }
+
+            return PackageManager.INSTALL_SUCCEEDED;
+        }
     };
 
     // Utility method used to create code paths based on package name and available index.
@@ -8696,9 +8775,15 @@
                                 : PackageManager.INSTALL_INTERNAL;
                         currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
                                 : PackageManager.INSTALL_INTERNAL;
+
                         if (newFlags == currFlags) {
                             Slog.w(TAG, "No move required. Trying to move to same location");
                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
+                        } else {
+                            if (isForwardLocked(pkg)) {
+                                currFlags |= PackageManager.INSTALL_FORWARD_LOCK;
+                                newFlags |= PackageManager.INSTALL_FORWARD_LOCK;
+                            }
                         }
                     }
                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
@@ -8784,21 +8869,31 @@
                                     final String newNativePath = mp.targetArgs
                                             .getNativeLibraryPath();
 
-                                    if ((mp.flags & PackageManager.INSTALL_EXTERNAL) == 0) {
-                                        if (mInstaller
-                                                .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
-                                            returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+                                    try {
+                                        final File newNativeDir = new File(newNativePath);
+
+                                        final String libParentDir = newNativeDir.getParentFile()
+                                                .getCanonicalPath();
+                                        if (newNativeDir.getParentFile().getCanonicalPath()
+                                                .equals(pkg.applicationInfo.dataDir)) {
+                                            if (mInstaller
+                                                    .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
+                                                returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+                                            } else {
+                                                NativeLibraryHelper.copyNativeBinariesIfNeededLI(
+                                                        new File(newCodePath), newNativeDir);
+                                            }
                                         } else {
-                                            NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File(
-                                                    newCodePath), new File(newNativePath));
+                                            if (mInstaller.linkNativeLibraryDirectory(
+                                                    pkg.applicationInfo.dataDir, newNativePath) < 0) {
+                                                returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+                                            }
                                         }
-                                    } else {
-                                        if (mInstaller.linkNativeLibraryDirectory(
-                                                pkg.applicationInfo.dataDir, newNativePath) < 0) {
-                                            returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
-                                        }
+                                    } catch (IOException e) {
+                                        returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
                                     }
 
+
                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
                                         pkg.mPath = newCodePath;
                                         // Move dex files around
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index d635e8c..de756b1 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -85,6 +85,9 @@
             animation = sDummyAnimation;
             animInitialized = false;
         }
+        hasTransformation = true;
+        transformation.clear();
+        transformation.setAlpha(mAppToken.reportedVisible ? 1 : 0);
     }
 
     public void clearAnimation() {
@@ -186,8 +189,6 @@
                 // it as not animating for purposes of scheduling transactions;
                 // when it is really time to animate, this will be set to
                 // a real animation and the next call will execute normally.
-                hasTransformation = true;
-                transformation.setAlpha(mAppToken.reportedVisible ? 1 : 0);
                 return false;
             }
 
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index e5b1f2c..2e817ca 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -140,6 +140,8 @@
                     mService.debugLayoutRepeats("appToken " + appAnimator.mAppToken + " done",
                         mPendingLayoutChanges);
                 }
+                if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
+                        "updateWindowsApps...: done animating " + appAnimator.mAppToken);
             }
         }
 
@@ -154,9 +156,11 @@
                 // stopped animating, do one more pass through the layout
                 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                    mService.debugLayoutRepeats("exiting appToken " + appAnimator.mAppToken 
+                    mService.debugLayoutRepeats("exiting appToken " + appAnimator.mAppToken
                         + " done", mPendingLayoutChanges);
                 }
+                if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
+                        "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken);
             }
         }
 
@@ -246,9 +250,9 @@
 
                 if (mPolicy.doesForceHide(win, win.mAttrs)) {
                     if (!wasAnimating && nowAnimating) {
-                        if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
-                                "Animation started that could impact force hide: "
-                                + win);
+                        if (WindowManagerService.DEBUG_ANIM ||
+                                WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                                "Animation started that could impact force hide: " + win);
                         mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
                         mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 9eb2577..ee74e40 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -130,8 +130,6 @@
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.ScaleAnimation;
-import android.view.animation.Transformation;
-import android.view.animation.TranslateAnimation;
 
 import java.io.BufferedWriter;
 import java.io.DataInputStream;
@@ -3245,12 +3243,21 @@
             if (mNextAppTransitionType == ActivityOptions.ANIM_CUSTOM) {
                 a = loadAnimation(mNextAppTransitionPackage, enter ?
                         mNextAppTransitionEnter : mNextAppTransitionExit);
+                if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
+                        + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
+                        + " transit=" + transit + " Callers " + Debug.getCallers(3));
             } else if (mNextAppTransitionType == ActivityOptions.ANIM_SCALE_UP) {
                 a = createScaleUpAnimationLocked(transit, enter);
                 initialized = true;
+                if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
+                        + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
+                        + " transit=" + transit + " Callers " + Debug.getCallers(3));
             } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL) {
                 a = createThumbnailAnimationLocked(transit, enter, false);
                 initialized = true;
+                if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
+                        + " anim=" + a + " nextAppTransition=ANIM_THUMBNAIL"
+                        + " transit=" + transit + " Callers " + Debug.getCallers(3));
             } else {
                 int animAttr = 0;
                 switch (transit) {
@@ -3309,7 +3316,7 @@
                 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
                         + " anim=" + a
                         + " animAttr=0x" + Integer.toHexString(animAttr)
-                        + " transit=" + transit);
+                        + " transit=" + transit + " Callers " + Debug.getCallers(3));
             }
             if (a != null) {
                 if (DEBUG_ANIM) {
@@ -7856,7 +7863,9 @@
                 mToTopApps.clear();
             }
 
-            WindowState oldWallpaper = mWallpaperTarget;
+            WindowState oldWallpaper =
+                    mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
+                    ? null : mWallpaperTarget;
 
             adjustWallpaperWindowsLocked();
             mInnerFields.mWallpaperMayChange = false;
@@ -8167,8 +8176,8 @@
                 // to go through the process of getting informed
                 // by the application when it has finished drawing.
                 if (w.mOrientationChanging) {
-                    if (DEBUG_ORIENTATION) Slog.v(TAG,
-                            "Orientation start waiting for draw in "
+                    if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
+                            "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
                             + w + ", surface " + winAnimator.mSurface);
                     winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
                     if (w.mAppToken != null) {
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 9147a10..2e38332 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -380,8 +380,9 @@
 
     boolean finishDrawingLocked() {
         if (mDrawState == DRAW_PENDING) {
-            if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
-                TAG, "finishDrawingLocked: " + this + " in " + mSurface);
+            if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
+                TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
+                        + mSurface);
             mDrawState = COMMIT_DRAW_PENDING;
             return true;
         }
@@ -393,7 +394,8 @@
         if (mDrawState != COMMIT_DRAW_PENDING) {
             return false;
         }
-        //Slog.i(TAG, "commitFinishDrawingLocked: Draw pending. " + mSurface);
+        if (DEBUG_ANIM)
+            Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurface);
         mDrawState = READY_TO_SHOW;
         final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
         final AppWindowToken atoken = mWin.mAppToken;
@@ -526,8 +528,8 @@
         if (mSurface == null) {
             mReportDestroySurface = false;
             mSurfacePendingDestroy = false;
-            if (DEBUG_ORIENTATION) Slog.i(TAG,
-                    "createSurface " + this + ": DRAW NOW PENDING");
+            if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
+                    "createSurface " + this + ": mDrawState=DRAW_PENDING");
             mDrawState = DRAW_PENDING;
             if (mWin.mAppToken != null) {
                 mWin.mAppToken.allDrawn = false;
@@ -1062,6 +1064,9 @@
                 }
             }
         } else {
+            if (DEBUG_ANIM) {
+                Slog.v(TAG, "prepareSurface: No changes in animation for " + mWin);
+            }
             displayed = true;
         }
 
@@ -1145,6 +1150,7 @@
 
             // Force the show in the next prepareSurfaceLocked() call.
             mLastAlpha = -1;
+            if (DEBUG_ANIM) Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN");
             mDrawState = HAS_DRAWN;
             mService.scheduleAnimationLocked();
 
@@ -1285,7 +1291,7 @@
                     + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
                     + " a=" + a
                     + " mAnimation=" + mAnimation
-                    + " isEntrance=" + isEntrance);
+                    + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
             if (a != null) {
                 if (WindowManagerService.DEBUG_ANIM) {
                     RuntimeException e = null;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 80988fd..52e2caf 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -1459,6 +1459,11 @@
      * After starting, FSM will search SPN EFs in order and stop after finding
      * the first valid SPN
      *
+     * If the FSM gets restart while waiting for one of
+     * SPN EFs results (i.e. a SIM refresh occurs after issuing
+     * read EF_CPHS_SPN), it will re-initialize only after
+     * receiving and discarding the unfinished SPN EF result.
+     *
      * @param start set true only for initialize loading
      * @param ar the AsyncResult from loadEFTransparent
      *        ar.exception holds exception in error
@@ -1468,7 +1473,19 @@
         byte[] data;
 
         if (start) {
-            spnState = Get_Spn_Fsm_State.INIT;
+            // Check previous state to see if there is outstanding
+            // SPN read
+            if(spnState == Get_Spn_Fsm_State.READ_SPN_3GPP ||
+               spnState == Get_Spn_Fsm_State.READ_SPN_CPHS ||
+               spnState == Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS ||
+               spnState == Get_Spn_Fsm_State.INIT) {
+                // Set INIT then return so the INIT code
+                // will run when the outstanding read done.
+                spnState = Get_Spn_Fsm_State.INIT;
+                return;
+            } else {
+                spnState = Get_Spn_Fsm_State.INIT;
+            }
         }
 
         switch(spnState){
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 8aa613b..36f38f9 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1557,7 +1557,7 @@
          */
         public void acquire() {
             synchronized (mBinder) {
-                if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) {
+                if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
                     try {
                         mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource);
                         synchronized (WifiManager.this) {
@@ -1786,7 +1786,7 @@
          */
         public void acquire() {
             synchronized (mBinder) {
-                if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) {
+                if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) {
                     try {
                         mService.acquireMulticastLock(mBinder, mTag);
                         synchronized (WifiManager.this) {