Merge "Include system packages in packages.list." into klp-dev
diff --git a/api/current.txt b/api/current.txt
index b8caad8..3c4555f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12172,7 +12172,7 @@
     method public int getSampleRate();
     method public int getState();
     method public int getStreamType();
-    method public android.media.AudioTimestamp getTimestamp(android.media.AudioTimestamp);
+    method public boolean getTimestamp(android.media.AudioTimestamp);
     method public void pause() throws java.lang.IllegalStateException;
     method public void play() throws java.lang.IllegalStateException;
     method public void release();
@@ -12790,6 +12790,7 @@
     ctor public MediaMuxer(java.lang.String, int) throws java.io.IOException;
     method public int addTrack(android.media.MediaFormat);
     method public void release();
+    method public void setLocation(float, float);
     method public void setOrientationHint(int);
     method public void start();
     method public void stop();
@@ -15266,7 +15267,7 @@
     method public final void notifyUnhandled();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public abstract void onDeactivated(int);
-    method public byte[] processCommandApdu(byte[], android.os.Bundle);
+    method public abstract byte[] processCommandApdu(byte[], android.os.Bundle);
     method public final void sendResponseApdu(byte[]);
     field public static final int DEACTIVATION_DESELECTED = 1; // 0x1
     field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 653559d..6b24e6b 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1917,7 +1917,8 @@
             data.enforceInterface(IActivityManager.descriptor);
             int pid = data.readInt();
             boolean aboveSystem = data.readInt() != 0;
-            long res = inputDispatchingTimedOut(pid, aboveSystem);
+            String reason = data.readString();
+            long res = inputDispatchingTimedOut(pid, aboveSystem, reason);
             reply.writeNoException();
             reply.writeLong(res);
             return true;
@@ -4462,12 +4463,14 @@
         reply.recycle();
     }
 
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException {
+    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(pid);
         data.writeInt(aboveSystem ? 1 : 0);
+        data.writeString(reason);
         mRemote.transact(INPUT_DISPATCHING_TIMED_OUT_TRANSACTION, data, reply, 0);
         reply.readException();
         long res = reply.readInt();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 19a028d..64054c5 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -185,11 +185,11 @@
             OP_CALL_PHONE,
             OP_READ_SMS,
             OP_WRITE_SMS,
-            OP_READ_SMS,
-            OP_READ_SMS,
-            OP_READ_SMS,
-            OP_READ_SMS,
-            OP_WRITE_SMS,
+            OP_RECEIVE_SMS,
+            OP_RECEIVE_SMS,
+            OP_RECEIVE_SMS,
+            OP_RECEIVE_SMS,
+            OP_SEND_SMS,
             OP_READ_SMS,
             OP_WRITE_SMS,
             OP_WRITE_SETTINGS,
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index af9a245..e362afb 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -384,7 +384,8 @@
 
     public void requestBugReport() throws RemoteException;
 
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException;
+    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
+            throws RemoteException;
 
     public Bundle getAssistContextExtras(int requestType) throws RemoteException;
 
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 8903b4a..ff9282e 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -55,7 +55,7 @@
 
     private final ICameraService mCameraService;
     private ArrayList<String> mDeviceIdList;
-    private HashSet<CameraListener> mListenerSet = new HashSet<CameraListener>();
+    private final HashSet<CameraListener> mListenerSet = new HashSet<CameraListener>();
     private final Context mContext;
     private final Object mLock = new Object();
 
@@ -332,7 +332,7 @@
 
                 Integer oldStatus = mDeviceStatus.put(id, status);
 
-                if (oldStatus == status) {
+                if (oldStatus != null && oldStatus == status) {
                     Log.v(TAG, String.format(
                             "Device status changed to 0x%x, which is what it already was",
                             status));
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4cf38b6..c78a973 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1476,4 +1476,20 @@
         } catch (RemoteException e) {
         }
     }
+
+    /**
+     * Set the value for enabling/disabling airplane mode
+     *
+     * @param enable whether to enable airplane mode or not
+     *
+     * <p>This method requires the call to hold the permission
+     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
+     * @hide
+     */
+    public void setAirplaneMode(boolean enable) {
+        try {
+            mService.setAirplaneMode(enable);
+        } catch (RemoteException e) {
+        }
+    }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index a6f10ec..b3fa79f 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -156,4 +156,6 @@
     LinkQualityInfo[] getAllLinkQualityInfo();
 
     void setProvisioningNotificationVisible(boolean visible, int networkType, in String extraInfo, in String url);
+
+    void setAirplaneMode(boolean enable);
 }
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 41c6603..d3e5752 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -105,12 +105,8 @@
             if (onHost) {
                 parser = si.loadXmlMetaData(pm, HostApduService.SERVICE_META_DATA);
                 if (parser == null) {
-                    Log.d(TAG, "Didn't find service meta-data, trying legacy.");
-                    parser = si.loadXmlMetaData(pm, HostApduService.OLD_SERVICE_META_DATA);
-                    if (parser == null) {
-                        throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA +
-                                " meta-data");
-                    }
+                    throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA +
+                            " meta-data");
                 }
             } else {
                 parser = si.loadXmlMetaData(pm, OffHostApduService.SERVICE_META_DATA);
diff --git a/core/java/android/nfc/cardemulation/CardEmulationManager.java b/core/java/android/nfc/cardemulation/CardEmulationManager.java
deleted file mode 100644
index 124ea1c..0000000
--- a/core/java/android/nfc/cardemulation/CardEmulationManager.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.app.ActivityThread;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.nfc.INfcCardEmulation;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * TODO Remove when calling .apks are upgraded
- * @hide
- */
-public final class CardEmulationManager {
-    static final String TAG = "CardEmulationManager";
-
-    /**
-     * Activity action: ask the user to change the default
-     * card emulation service for a certain category. This will
-     * show a dialog that asks the user whether he wants to
-     * replace the current default service with the service
-     * identified with the ComponentName specified in
-     * {@link #EXTRA_SERVICE_COMPONENT}, for the category
-     * specified in {@link #EXTRA_CATEGORY}
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_CHANGE_DEFAULT =
-            "android.nfc.cardemulation.ACTION_CHANGE_DEFAULT";
-
-    /**
-     * The category extra for {@link #ACTION_CHANGE_DEFAULT}
-     *
-     * @see #ACTION_CHANGE_DEFAULT
-     */
-    public static final String EXTRA_CATEGORY = "category";
-
-    /**
-     * The ComponentName object passed in as a parcelable
-     * extra for {@link #ACTION_CHANGE_DEFAULT}
-     *
-     * @see #ACTION_CHANGE_DEFAULT
-     */
-    public static final String EXTRA_SERVICE_COMPONENT = "component";
-
-    /**
-     * The payment category can be used to indicate that an AID
-     * represents a payment application.
-     */
-    public static final String CATEGORY_PAYMENT = "payment";
-
-    /**
-     * If an AID group does not contain a category, or the
-     * specified category is not defined by the platform version
-     * that is parsing the AID group, all AIDs in the group will
-     * automatically be categorized under the {@link #CATEGORY_OTHER}
-     * category.
-     */
-    public static final String CATEGORY_OTHER = "other";
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, the user has set a default service for this
-     *    AID category. If a remote reader selects any of the AIDs
-     *    that the default service has registered in this category,
-     *    that service will automatically be bound to to handle
-     *    the transaction.
-     *
-     * <p>There are still cases where a service that is
-     *    not the default for a category can selected:
-     *    <p>
-     *    If a remote reader selects an AID in this category
-     *    that is not handled by the default service, and there is a set
-     *    of other services {S} that do handle this AID, the
-     *    user is asked if he wants to use any of the services in
-     *    {S} instead.
-     *    <p>
-     *    As a special case, if the size of {S} is one, containing a single service X,
-     *    and all AIDs X has registered in this category are not
-     *    registered by any other service, then X will be
-     *    selected automatically without asking the user.
-     *    <p>Example:
-     *    <ul>
-     *    <li>Service A registers AIDs "1", "2" and "3" in the category
-     *    <li>Service B registers AIDs "3" and "4" in the category
-     *    <li>Service C registers AIDs "5" and "6" in the category
-     *    </ul>
-     *    In this case, the following will happen when service A
-     *    is the default:
-     *    <ul>
-     *    <li>Reader selects AID "1", "2" or "3": service A is invoked automatically
-     *    <li>Reader selects AID "4": the user is asked to confirm he
-     *        wants to use service B, because its AIDs overlap with service A.
-     *    <li>Reader selects AID "5" or "6": service C is invoked automatically,
-     *        because all AIDs it has asked for are only registered by C,
-     *        and there is no overlap.
-     *    </ul>
-     *
-     */
-    public static final int SELECTION_MODE_PREFER_DEFAULT = 0;
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, whenever an AID of this category is selected,
-     *    the user is asked which service he wants to use to handle
-     *    the transaction, even if there is only one matching service.
-     */
-    public static final int SELECTION_MODE_ALWAYS_ASK = 1;
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, the user will only be asked to select a service
-     *    if the selected AID has been registered by multiple applications.
-     */
-    public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2;
-
-    static boolean sIsInitialized = false;
-    static HashMap<Context, CardEmulationManager> sCardEmuManagers = new HashMap();
-    static INfcCardEmulation sService;
-
-    final Context mContext;
-
-    private CardEmulationManager(Context context, INfcCardEmulation service) {
-        mContext = context.getApplicationContext();
-        sService = service;
-    }
-
-    public static synchronized CardEmulationManager getInstance(NfcAdapter adapter) {
-        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
-        Context context = adapter.getContext();
-        if (context == null) {
-            Log.e(TAG, "NfcAdapter context is null.");
-            throw new UnsupportedOperationException();
-        }
-        if (!sIsInitialized) {
-            IPackageManager pm = ActivityThread.getPackageManager();
-            if (pm == null) {
-                Log.e(TAG, "Cannot get PackageManager");
-                throw new UnsupportedOperationException();
-            }
-            try {
-                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
-                    Log.e(TAG, "This device does not support card emulation");
-                    throw new UnsupportedOperationException();
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "PackageManager query failed.");
-                throw new UnsupportedOperationException();
-            }
-            sIsInitialized = true;
-        }
-        CardEmulationManager manager = sCardEmuManagers.get(context);
-        if (manager == null) {
-            // Get card emu service
-            INfcCardEmulation service = adapter.getCardEmulationService();
-            manager = new CardEmulationManager(context, service);
-            sCardEmuManagers.put(context, manager);
-        }
-        return manager;
-    }
-
-    /**
-     * Allows an application to query whether a service is currently
-     * the default service to handle a card emulation category.
-     *
-     * <p>Note that if {@link #getSelectionModeForCategory(String)}
-     * returns {@link #SELECTION_MODE_ALWAYS_ASK}, this method will always
-     * return false.
-     *
-     * @param service The ComponentName of the service
-     * @param category The category
-     * @return whether service is currently the default service for the category.
-     */
-    public boolean isDefaultServiceForCategory(ComponentName service, String category) {
-        try {
-            return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service, category);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service,
-                        category);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-        }
-    }
-
-    /**
-     *
-     * Allows an application to query whether a service is currently
-     * the default handler for a specified ISO7816-4 Application ID.
-     *
-     * @param service The ComponentName of the service
-     * @param aid The ISO7816-4 Application ID
-     * @return
-     */
-    public boolean isDefaultServiceForAid(ComponentName service, String aid) {
-        try {
-            return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Returns the application selection mode for the passed in category.
-     * Valid return values are:
-     * <p>{@link #SELECTION_MODE_PREFER_DEFAULT} the user has requested a default
-     *    application for this category, which will be preferred.
-     * <p>{@link #SELECTION_MODE_ALWAYS_ASK} the user has requested to be asked
-     *    every time what app he would like to use in this category.
-     * <p>{@link #SELECTION_MODE_ASK_IF_CONFLICT} the user will only be asked
-     *    to pick a service if there is a conflict.
-     * @param category The category, for example {@link #CATEGORY_PAYMENT}
-     * @return
-     */
-    public int getSelectionModeForCategory(String category) {
-        if (CATEGORY_PAYMENT.equals(category)) {
-            String defaultComponent = Settings.Secure.getString(mContext.getContentResolver(),
-                    Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
-            if (defaultComponent != null) {
-                return SELECTION_MODE_PREFER_DEFAULT;
-            } else {
-                return SELECTION_MODE_ALWAYS_ASK;
-            }
-        } else {
-            // All other categories are in "only ask if conflict" mode
-            return SELECTION_MODE_ASK_IF_CONFLICT;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultServiceForCategory(ComponentName service, String category) {
-        try {
-            return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service, category);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service,
-                        category);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return false;
-            }
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultForNextTap(ComponentName service) {
-        try {
-            return sService.setDefaultForNextTap(UserHandle.myUserId(), service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.setDefaultForNextTap(UserHandle.myUserId(), service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return false;
-            }
-        }
-    }
-    /**
-     * @hide
-     */
-    public List<ApduServiceInfo> getServices(String category) {
-        try {
-            return sService.getServices(UserHandle.myUserId(), category);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
-            }
-            try {
-                return sService.getServices(UserHandle.myUserId(), category);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return null;
-            }
-        }
-    }
-
-    void recoverService() {
-        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
-        sService = adapter.getCardEmulationService();
-    }
-}
diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java
index 174acc0..e2c3ca6 100644
--- a/core/java/android/nfc/cardemulation/HostApduService.java
+++ b/core/java/android/nfc/cardemulation/HostApduService.java
@@ -50,23 +50,6 @@
             "android.nfc.cardemulation.host_apdu_service";
 
     /**
-     * The {@link Intent} that must be declared as handled by the service.
-     * TODO Remove
-     * @hide
-     */
-    public static final String OLD_SERVICE_INTERFACE =
-            "android.nfc.HostApduService";
-
-    /**
-     * The name of the meta-data element that contains
-     * more information about this service.
-     *
-     * TODO Remove
-     * @hide
-     */
-    public static final String OLD_SERVICE_META_DATA = "android.nfc.HostApduService";
-
-    /**
      * Reason for {@link #onDeactivated(int)}.
      * Indicates deactivation was due to the NFC link
      * being lost.
@@ -282,37 +265,7 @@
      * @return a byte-array containing the response APDU, or null if no
      *         response APDU can be sent at this point.
      */
-    public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
-        // TODO make this abstract
-        return processCommandApdu(commandApdu, 0);
-    }
-
-    /**
-     * <p>This method will be called when a command APDU has been received
-     * from a remote device. A response APDU can be provided directly
-     * by returning a byte-array in this method. Note that in general
-     * response APDUs must be sent as quickly as possible, given the fact
-     * that the user is likely holding his device over an NFC reader
-     * when this method is called.
-     *
-     * <p class="note">If there are multiple services that have registered for the same
-     * AIDs in their meta-data entry, you will only get called if the user has
-     * explicitly selected your service, either as a default or just for the next tap.
-     *
-     * <p class="note">This method is running on the main thread of your application.
-     * If you cannot return a response APDU immediately, return null
-     * and use the {@link #sendResponseApdu(byte[])} method later.
-     *
-     * @deprecated use {@link #processCommandApdu(byte[], Bundle)}
-     * @param commandApdu
-     * @param flags
-     * @return a byte-array containing the response APDU, or null if no
-     *         response APDU can be sent at this point.
-     * @hide
-     */
-    public byte[] processCommandApdu(byte[] commandApdu, int flags) {
-        return null;
-    }
+    public abstract byte[] processCommandApdu(byte[] commandApdu, Bundle extras);
 
     /**
      * This method will be called in two possible scenarios:
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 9d52c83..a6f23a8 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -137,8 +137,18 @@
         public static final String NUMBER = "number";
 
         /**
-         * The number presenting rules set by the network for "allowed",
-         * "payphone", "restricted" or "unknown".
+         * The number presenting rules set by the network.
+         *
+         * <p>
+         * Allowed values:
+         * <ul>
+         * <li>{@link #PRESENTATION_ALLOWED}</li>
+         * <li>{@link #PRESENTATION_RESTRICTED}</li>
+         * <li>{@link #PRESENTATION_UNKNOWN}</li>
+         * <li>{@link #PRESENTATION_PAYPHONE}</li>
+         * </ul>
+         * </p>
+         *
          * <P>Type: INTEGER</P>
          */
         public static final String NUMBER_PRESENTATION = "presentation";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1a80818..b70d74a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2439,7 +2439,9 @@
             SIP_CALL_OPTIONS,
             SIP_RECEIVE_CALLS,
             POINTER_SPEED,
-            VIBRATE_WHEN_RINGING
+            VIBRATE_WHEN_RINGING,
+            RINGTONE,
+            NOTIFICATION_SOUND
         };
 
         // Settings moved to Settings.Secure
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 59df183..8ea9d48 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -122,6 +122,10 @@
     // Whether this transition is currently paused, due to a call to pause()
     boolean mPaused = false;
 
+    // Whether this transition has ended. Used to avoid pause/resume on transitions
+    // that have completed
+    private boolean mEnded = false;
+
     // The set of listeners to be sent transition lifecycle events.
     ArrayList<TransitionListener> mListeners = null;
 
@@ -914,21 +918,23 @@
      * @hide
      */
     public void pause() {
-        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-        int numOldAnims = runningAnimators.size();
-        for (int i = numOldAnims - 1; i >= 0; i--) {
-            Animator anim = runningAnimators.keyAt(i);
-            anim.pause();
-        }
-        if (mListeners != null && mListeners.size() > 0) {
-            ArrayList<TransitionListener> tmpListeners =
-                    (ArrayList<TransitionListener>) mListeners.clone();
-            int numListeners = tmpListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                tmpListeners.get(i).onTransitionPause(this);
+        if (!mEnded) {
+            ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+            int numOldAnims = runningAnimators.size();
+            for (int i = numOldAnims - 1; i >= 0; i--) {
+                Animator anim = runningAnimators.keyAt(i);
+                anim.pause();
             }
+            if (mListeners != null && mListeners.size() > 0) {
+                ArrayList<TransitionListener> tmpListeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onTransitionPause(this);
+                }
+            }
+            mPaused = true;
         }
-        mPaused = true;
     }
 
     /**
@@ -940,18 +946,20 @@
      */
     public void resume() {
         if (mPaused) {
-            ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-            int numOldAnims = runningAnimators.size();
-            for (int i = numOldAnims - 1; i >= 0; i--) {
-                Animator anim = runningAnimators.keyAt(i);
-                anim.resume();
-            }
-            if (mListeners != null && mListeners.size() > 0) {
-                ArrayList<TransitionListener> tmpListeners =
-                        (ArrayList<TransitionListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onTransitionResume(this);
+            if (!mEnded) {
+                ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+                int numOldAnims = runningAnimators.size();
+                for (int i = numOldAnims - 1; i >= 0; i--) {
+                    Animator anim = runningAnimators.keyAt(i);
+                    anim.resume();
+                }
+                if (mListeners != null && mListeners.size() > 0) {
+                    ArrayList<TransitionListener> tmpListeners =
+                            (ArrayList<TransitionListener>) mListeners.clone();
+                    int numListeners = tmpListeners.size();
+                    for (int i = 0; i < numListeners; ++i) {
+                        tmpListeners.get(i).onTransitionResume(this);
+                    }
                 }
             }
             mPaused = false;
@@ -1071,6 +1079,7 @@
                     tmpListeners.get(i).onTransitionStart(this);
                 }
             }
+            mEnded = false;
         }
         mNumInstances++;
     }
@@ -1111,6 +1120,7 @@
                     v.setHasTransientState(false);
                 }
             }
+            mEnded = true;
         }
     }
 
diff --git a/core/java/android/view/IApplicationToken.aidl b/core/java/android/view/IApplicationToken.aidl
index 5f0600f..633b40f 100644
--- a/core/java/android/view/IApplicationToken.aidl
+++ b/core/java/android/view/IApplicationToken.aidl
@@ -23,7 +23,7 @@
     void windowsDrawn();
     void windowsVisible();
     void windowsGone();
-    boolean keyDispatchingTimedOut();
+    boolean keyDispatchingTimedOut(String reason);
     long getKeyDispatchingTimeout();
 }
 
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 389d9d6..b239fbd 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1555,8 +1555,9 @@
             } else if (mItemCount != mAdapter.getCount()) {
                 throw new IllegalStateException("The content of the adapter has changed but "
                         + "ListView did not receive a notification. Make sure the content of "
-                        + "your adapter is not modified from a background thread, but only "
-                        + "from the UI thread. [in ListView(" + getId() + ", " + getClass() 
+                        + "your adapter is not modified from a background thread, but only from "
+                        + "the UI thread. Make sure your adapter calls notifyDataSetChanged() "
+                        + "when its content changes. [in ListView(" + getId() + ", " + getClass()
                         + ") with Adapter(" + mAdapter.getClass() + ")]");
             }
 
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index b87ed7a..b75d36f 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -412,6 +412,8 @@
     public void setAdapter(SpinnerAdapter adapter) {
         super.setAdapter(adapter);
 
+        mRecycler.clear();
+
         if (mPopup != null) {
             mPopup.setAdapter(new DropDownAdapter(adapter));
         } else {
@@ -426,9 +428,8 @@
         if (getChildCount() > 0) {
             child = getChildAt(0);
         } else if (mAdapter != null && mAdapter.getCount() > 0) {
-            child = makeAndAddView(0);
+            child = makeView(0, false);
             mRecycler.put(0, child);
-            removeAllViewsInLayout();
         }
 
         if (child != null) {
@@ -536,7 +537,7 @@
         mFirstPosition = mSelectedPosition;
 
         if (mAdapter != null) {
-            View sel = makeAndAddView(mSelectedPosition);
+            View sel = makeView(mSelectedPosition, true);
             int width = sel.getMeasuredWidth();
             int selectedOffset = childrenLeft;
             final int layoutDirection = getLayoutDirection();
@@ -571,17 +572,17 @@
      * from the old to new positions.
      *
      * @param position Position in the spinner for the view to obtain
-     * @return A view that has been added to the spinner
+     * @param addChild true to add the child to the spinner, false to obtain and configure only.
+     * @return A view for the given position
      */
-    private View makeAndAddView(int position) {
-
+    private View makeView(int position, boolean addChild) {
         View child;
 
         if (!mDataChanged) {
             child = mRecycler.get(position);
             if (child != null) {
                 // Position the view
-                setUpChild(child);
+                setUpChild(child, addChild);
 
                 return child;
             }
@@ -591,7 +592,7 @@
         child = mAdapter.getView(position, null, this);
 
         // Position the view
-        setUpChild(child);
+        setUpChild(child, addChild);
 
         return child;
     }
@@ -601,8 +602,9 @@
      * and fill out its layout paramters.
      *
      * @param child The view to position
+     * @param addChild true if the child should be added to the Spinner during setup
      */
-    private void setUpChild(View child) {
+    private void setUpChild(View child, boolean addChild) {
 
         // Respect layout params that are already in the view. Otherwise
         // make some up...
@@ -611,7 +613,9 @@
             lp = generateDefaultLayoutParams();
         }
 
-        addViewInLayout(child, 0, lp);
+        if (addChild) {
+            addViewInLayout(child, 0, lp);
+        }
 
         child.setSelected(hasFocus());
         if (mDisableChildrenWhenDisabled) {
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index e8456af..7e99a5f 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -732,7 +732,7 @@
 
         if (mRs == 0) {
             mRs = new RSC::RS();
-            if (!mRs->init(RSC::RS_INIT_LOW_LATENCY & RSC::RS_INIT_SYNCHRONOUS)) {
+            if (!mRs->init(RSC::RS_INIT_LOW_LATENCY | RSC::RS_INIT_SYNCHRONOUS)) {
                 ALOGE("blur RS failed to init");
             }
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 238d9a4..2066f69 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -471,12 +471,14 @@
     info.height = getSnapshot()->height;
     getSnapshot()->transform->copyTo(&info.transform[0]);
 
+    bool dirtyClip = mDirtyClip;
     // setup GL state for functor
     if (mDirtyClip) {
-        setScissorFromClip();
         setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt()
     }
-    mCaches.enableScissor();
+    if (mCaches.enableScissor() || dirtyClip) {
+        setScissorFromClip();
+    }
     interrupt();
 
     // call functor immediately after GL state setup
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 788257d..78a37c5 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -746,31 +746,28 @@
     * If you need such features, consider implementing them at application level.
     *
     * @param timestamp a reference to a non-null AudioTimestamp instance allocated
-    *        and owned by caller, or null.
-    * @return that same instance if timestamp parameter is non-null and a timestamp is available,
-    *         or a reference to a new AudioTimestamp instance which is now owned by caller
-    *         if timestamp parameter is null and a timestamp is available,
-    *         or null if no timestamp is available.  In either successful case,
+    *        and owned by caller.
+    * @return true if a timestamp is available, or false if no timestamp is available.
+    *         If a timestamp if available,
     *         the AudioTimestamp instance is filled in with a position in frame units, together
     *         with the estimated time when that frame was presented or is committed to
     *         be presented.
     *         In the case that no timestamp is available, any supplied instance is left unaltered.
     */
-    public AudioTimestamp getTimestamp(AudioTimestamp timestamp)
+    public boolean getTimestamp(AudioTimestamp timestamp)
     {
+        if (timestamp == null) {
+            throw new IllegalArgumentException();
+        }
         // It's unfortunate, but we have to either create garbage every time or use synchronized
         long[] longArray = new long[2];
         int ret = native_get_timestamp(longArray);
-        if (ret == SUCCESS) {
-            if (timestamp == null) {
-                timestamp = new AudioTimestamp();
-            }
-            timestamp.framePosition = longArray[0];
-            timestamp.nanoTime = longArray[1];
-        } else {
-            timestamp = null;
+        if (ret != SUCCESS) {
+            return false;
         }
-        return timestamp;
+        timestamp.framePosition = longArray[0];
+        timestamp.nanoTime = longArray[1];
+        return true;
     }
 
 
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index 774964e..65a9308 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -92,6 +92,7 @@
             Object[] values);
     private static native void nativeSetOrientationHint(int nativeObject,
             int degrees);
+    private static native void nativeSetLocation(int nativeObject, int latitude, int longitude);
     private static native void nativeWriteSampleData(int nativeObject,
             int trackIndex, ByteBuffer byteBuf,
             int offset, int size, long presentationTimeUs, int flags);
@@ -165,6 +166,41 @@
     }
 
     /**
+     * Set and store the geodata (latitude and longitude) in the output file.
+     * This method should be called before {@link #start}. The geodata is stored
+     * in udta box if the output format is
+     * {@link OutputFormat#MUXER_OUTPUT_MPEG_4}, and is ignored for other output
+     * formats. The geodata is stored according to ISO-6709 standard.
+     *
+     * @param latitude Latitude in degrees. Its value must be in the range [-90,
+     * 90].
+     * @param longitude Longitude in degrees. Its value must be in the range
+     * [-180, 180].
+     * @throws IllegalArgumentException If the given latitude or longitude is out
+     * of range.
+     * @throws IllegalStateException If this method is called after {@link #start}.
+     */
+    public void setLocation(float latitude, float longitude) {
+        int latitudex10000  = (int) (latitude * 10000 + 0.5);
+        int longitudex10000 = (int) (longitude * 10000 + 0.5);
+
+        if (latitudex10000 > 900000 || latitudex10000 < -900000) {
+            String msg = "Latitude: " + latitude + " out of range.";
+            throw new IllegalArgumentException(msg);
+        }
+        if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
+            String msg = "Longitude: " + longitude + " out of range";
+            throw new IllegalArgumentException(msg);
+        }
+
+        if (mState == MUXER_STATE_INITIALIZED && mNativeObject != 0) {
+            nativeSetLocation(mNativeObject, latitudex10000, longitudex10000);
+        } else {
+            throw new IllegalStateException("Can't set location due to wrong state.");
+        }
+    }
+
+    /**
      * Starts the muxer.
      * <p>Make sure this is called after {@link #addTrack} and before
      * {@link #writeSampleData}.</p>
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index 7517e85..457b956 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -164,6 +164,18 @@
 
 }
 
+static void android_media_MediaMuxer_setLocation(
+        JNIEnv *env, jclass clazz, jint nativeObject, jint latitude, jint longitude) {
+    MediaMuxer* muxer = reinterpret_cast<MediaMuxer *>(nativeObject);
+
+    status_t res = muxer->setLocation(latitude, longitude);
+    if (res != OK) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "Failed to set location");
+        return;
+    }
+}
+
 static void android_media_MediaMuxer_start(JNIEnv *env, jclass clazz,
                                            jint nativeObject) {
     sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
@@ -216,6 +228,9 @@
     { "nativeSetOrientationHint", "(II)V",
         (void *)android_media_MediaMuxer_setOrientationHint},
 
+    { "nativeSetLocation", "(III)V",
+        (void *)android_media_MediaMuxer_setLocation},
+
     { "nativeStart", "(I)V", (void *)android_media_MediaMuxer_start},
 
     { "nativeWriteSampleData", "(IILjava/nio/ByteBuffer;IIJI)V",
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 3f04470..344446f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -738,10 +738,12 @@
                 }
             }
 
+            // Intercept the keys and see if they need special handling
+            value = mSettingsHelper.onBackupValue(key, value);
+
             if (value == null) {
                 continue;
             }
-
             // Write the key and value in the intermediary array.
             byte[] keyBytes = key.getBytes();
             totalSize += INTEGER_BYTE_COUNT + keyBytes.length;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index a446e40..080290c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -23,6 +23,8 @@
 import android.content.res.Configuration;
 import android.location.LocationManager;
 import android.media.AudioManager;
+import android.media.RingtoneManager;
+import android.net.Uri;
 import android.os.IPowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -33,6 +35,7 @@
 import java.util.Locale;
 
 public class SettingsHelper {
+    private static final String SILENT_RINGTONE = "_silent";
     private Context mContext;
     private AudioManager mAudioManager;
 
@@ -63,10 +66,56 @@
             setAutoRestore(Integer.parseInt(value) == 1);
         } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) {
             return false;
+        } else if (Settings.System.RINGTONE.equals(name)
+                || Settings.System.NOTIFICATION_SOUND.equals(name)) {
+            setRingtone(name, value);
+            return false;
         }
         return true;
     }
 
+    public String onBackupValue(String name, String value) {
+        // Special processing for backing up ringtones
+        if (Settings.System.RINGTONE.equals(name)
+                || Settings.System.NOTIFICATION_SOUND.equals(name)) {
+            if (value == null) {
+                // Silent ringtone
+                return SILENT_RINGTONE;
+            } else {
+                return getCanonicalRingtoneValue(value);
+            }
+        }
+        // Return the original value
+        return value;
+    }
+
+    /**
+     * Sets the ringtone of type specified by the name.
+     *
+     * @param name should be Settings.System.RINGTONE or Settings.System.NOTIFICATION_SOUND.
+     * @param value can be a canonicalized uri or "_silent" to indicate a silent (null) ringtone.
+     */
+    private void setRingtone(String name, String value) {
+        // If it's null, don't change the default
+        if (value == null) return;
+        Uri ringtoneUri = null;
+        if (SILENT_RINGTONE.equals(value)) {
+            ringtoneUri = null;
+        } else {
+            Uri canonicalUri = Uri.parse(value);
+            ringtoneUri = mContext.getContentResolver().uncanonicalize(canonicalUri);
+        }
+        final int ringtoneType = Settings.System.RINGTONE.equals(name)
+                ? RingtoneManager.TYPE_RINGTONE : RingtoneManager.TYPE_NOTIFICATION;
+        RingtoneManager.setActualDefaultRingtoneUri(mContext, ringtoneType, ringtoneUri);
+    }
+
+    private String getCanonicalRingtoneValue(String value) {
+        final Uri ringtoneUri = Uri.parse(value);
+        final Uri canonicalUri = mContext.getContentResolver().canonicalize(ringtoneUri);
+        return canonicalUri == null ? null : canonicalUri.toString();
+    }
+
     private boolean isAlreadyConfiguredCriticalAccessibilitySetting(String name) {
         // These are the critical accessibility settings that are required for a
         // blind user to be able to interact with the device. If these settings are
diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
index 7e76025..c6b76f1 100644
--- a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
+++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
@@ -25,6 +25,9 @@
 
 import com.android.net.IProxyService;
 
+import java.net.MalformedURLException;
+import java.net.URL;
+
 public class PacService extends Service {
     private static final String TAG = "PacService";
 
@@ -68,7 +71,18 @@
 
         @Override
         public String resolvePacFile(String host, String url) throws RemoteException {
-            return mPacNative.makeProxyRequest(url, host);
+            try {
+                // Check for characters that could be used for an injection attack.
+                new URL(url);
+                for (char c : host.toCharArray()) {
+                    if (!Character.isLetterOrDigit(c) && (c != '.') && (c != '-')) {
+                        throw new RemoteException("Invalid host was passed");
+                    }
+                }
+                return mPacNative.makeProxyRequest(url, host);
+            } catch (MalformedURLException e) {
+                throw new RemoteException("Invalid URL was passed");
+            }
         }
 
         @Override
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 795ab47..9e7a15d 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -3405,6 +3405,7 @@
             & InputDispatcher::doNotifyANRLockedInterruptible);
     commandEntry->inputApplicationHandle = applicationHandle;
     commandEntry->inputWindowHandle = windowHandle;
+    commandEntry->reason = reason;
 }
 
 void InputDispatcher::doNotifyConfigurationChangedInterruptible(
@@ -3434,7 +3435,8 @@
     mLock.unlock();
 
     nsecs_t newTimeout = mPolicy->notifyANR(
-            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
+            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle,
+            commandEntry->reason);
 
     mLock.lock();
 
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 0273dc4..190e7b2 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -202,7 +202,8 @@
     /* Notifies the system that an application is not responding.
      * Returns a new timeout to continue waiting, or 0 to abort dispatch. */
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle) = 0;
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason) = 0;
 
     /* Notifies the system that an input channel is unrecoverably broken. */
     virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0;
@@ -596,6 +597,7 @@
         KeyEntry* keyEntry;
         sp<InputApplicationHandle> inputApplicationHandle;
         sp<InputWindowHandle> inputWindowHandle;
+        String8 reason;
         int32_t userActivityEventType;
         uint32_t seq;
         bool handled;
diff --git a/services/input/tests/InputDispatcher_test.cpp b/services/input/tests/InputDispatcher_test.cpp
index ed2b4a5..26b4fab 100644
--- a/services/input/tests/InputDispatcher_test.cpp
+++ b/services/input/tests/InputDispatcher_test.cpp
@@ -50,7 +50,8 @@
     }
 
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle) {
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason) {
         return 0;
     }
 
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 02a78de..4e3faca 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -4681,6 +4681,21 @@
         setProvNotificationVisible(visible, networkType, extraInfo, url);
     }
 
+    @Override
+    public void setAirplaneMode(boolean enable) {
+        enforceConnectivityInternalPermission();
+        final ContentResolver cr = mContext.getContentResolver();
+        Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);
+        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+        intent.putExtra("state", enable);
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mContext.sendBroadcast(intent);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     private void onUserStart(int userId) {
         synchronized(mVpns) {
             Vpn userVpn = mVpns.get(userId);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1e3fb40..13eb169 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -7970,8 +7970,8 @@
         return KEY_DISPATCHING_TIMEOUT;
     }
 
-
-    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem) {
+    @Override
+    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires permission "
@@ -7986,7 +7986,7 @@
             timeout = getInputDispatchingTimeoutLocked(proc);
         }
 
-        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem)) {
+        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
             return -1;
         }
 
@@ -7999,13 +7999,20 @@
      */
     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
             final ActivityRecord activity, final ActivityRecord parent,
-            final boolean aboveSystem) {
+            final boolean aboveSystem, String reason) {
         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires permission "
                     + android.Manifest.permission.FILTER_EVENTS);
         }
 
+        final String annotation;
+        if (reason == null) {
+            annotation = "Input dispatching timed out";
+        } else {
+            annotation = "Input dispatching timed out (" + reason + ")";
+        }
+
         if (proc != null) {
             synchronized (this) {
                 if (proc.debugging) {
@@ -8021,7 +8028,7 @@
                 if (proc.instrumentationClass != null) {
                     Bundle info = new Bundle();
                     info.putString("shortMsg", "keyDispatchingTimedOut");
-                    info.putString("longMsg", "Timed out while dispatching key event");
+                    info.putString("longMsg", annotation);
                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
                     return true;
                 }
@@ -8029,7 +8036,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    appNotResponding(proc, activity, parent, aboveSystem, "keyDispatchingTimedOut");
+                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
                 }
             });
         }
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index bf3713b..6e50808 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -305,9 +305,9 @@
             }
         }
 
-        @Override public boolean keyDispatchingTimedOut() {
+        @Override public boolean keyDispatchingTimedOut(String reason) {
             ActivityRecord activity = weakActivity.get();
-            return activity != null && activity.keyDispatchingTimedOut();
+            return activity != null && activity.keyDispatchingTimedOut(reason);
         }
 
         @Override public long getKeyDispatchingTimeout() {
@@ -960,14 +960,14 @@
         return r;
     }
 
-    public boolean keyDispatchingTimedOut() {
+    public boolean keyDispatchingTimedOut(String reason) {
         ActivityRecord r;
         ProcessRecord anrApp;
         synchronized(service) {
             r = getWaitingHistoryRecordLocked();
             anrApp = r != null ? r.app : null;
         }
-        return service.inputDispatchingTimedOut(anrApp, r, this, false);
+        return service.inputDispatchingTimedOut(anrApp, r, this, false, reason);
     }
 
     /** Returns the key dispatching timeout for this application token. */
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 2b76e71..e994c23 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -620,7 +620,13 @@
     }
 
     void clearLaunchTime(ActivityRecord r) {
-        r.displayStartTime = r.fullyDrawnStartTime = 0;
+        // Make sure that there is no activity waiting for this to launch.
+        if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
+            r.displayStartTime = r.fullyDrawnStartTime = 0;
+        } else {
+            mStackSupervisor.removeTimeoutsForActivityLocked(r);
+            mStackSupervisor.scheduleIdleTimeoutLocked(r);
+        }
     }
 
     void awakeFromSleepingLocked() {
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 7b4c077..d749e6c 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -1292,8 +1292,9 @@
 
     // Native callback.
     private long notifyANR(InputApplicationHandle inputApplicationHandle,
-            InputWindowHandle inputWindowHandle) {
-        return mWindowManagerCallbacks.notifyANR(inputApplicationHandle, inputWindowHandle);
+            InputWindowHandle inputWindowHandle, String reason) {
+        return mWindowManagerCallbacks.notifyANR(
+                inputApplicationHandle, inputWindowHandle, reason);
     }
 
     // Native callback.
@@ -1477,7 +1478,7 @@
         public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle);
 
         public long notifyANR(InputApplicationHandle inputApplicationHandle,
-                InputWindowHandle inputWindowHandle);
+                InputWindowHandle inputWindowHandle, String reason);
 
         public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
 
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 9620612..ea3af26 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -88,7 +88,7 @@
      */
     @Override
     public long notifyANR(InputApplicationHandle inputApplicationHandle,
-            InputWindowHandle inputWindowHandle) {
+            InputWindowHandle inputWindowHandle, String reason) {
         AppWindowToken appWindowToken = null;
         WindowState windowState = null;
         boolean aboveSystem = false;
@@ -105,7 +105,8 @@
 
             if (windowState != null) {
                 Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
-                        + "sending to " + windowState.mAttrs.getTitle());
+                        + "sending to " + windowState.mAttrs.getTitle()
+                        + ".  Reason: " + reason);
                 // Figure out whether this window is layered above system windows.
                 // We need to do this here to help the activity manager know how to
                 // layer its ANR dialog.
@@ -114,19 +115,21 @@
                 aboveSystem = windowState.mBaseLayer > systemAlertLayer;
             } else if (appWindowToken != null) {
                 Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
-                        + "sending to application " + appWindowToken.stringName);
+                        + "sending to application " + appWindowToken.stringName
+                        + ".  Reason: " + reason);
             } else {
-                Slog.i(WindowManagerService.TAG, "Input event dispatching timed out.");
+                Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
+                        + ".  Reason: " + reason);
             }
 
-            mService.saveANRStateLocked(appWindowToken, windowState);
+            mService.saveANRStateLocked(appWindowToken, windowState, reason);
         }
 
         if (appWindowToken != null && appWindowToken.appToken != null) {
             try {
                 // Notify the activity manager about the timeout and let it decide whether
                 // to abort dispatching or keep waiting.
-                boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
+                boolean abort = appWindowToken.appToken.keyDispatchingTimedOut(reason);
                 if (! abort) {
                     // The activity manager declined to abort dispatching.
                     // Wait a bit longer and timeout again later.
@@ -139,7 +142,7 @@
                 // Notify the activity manager about the timeout and let it decide whether
                 // to abort dispatching or keep waiting.
                 long timeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut(
-                        windowState.mSession.mPid, aboveSystem);
+                        windowState.mSession.mPid, aboveSystem, reason);
                 if (timeout >= 0) {
                     // The activity manager declined to abort dispatching.
                     // Wait a bit longer and timeout again later.
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 34d8973..b8d2050 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -10541,8 +10541,10 @@
      *
      * @param appWindowToken The application that ANR'd, may be null.
      * @param windowState The window that ANR'd, may be null.
+     * @param reason The reason for the ANR, may be null.
      */
-    public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
+    public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState,
+            String reason) {
         StringWriter sw = new StringWriter();
         PrintWriter pw = new FastPrintWriter(sw, false, 1024);
         pw.println("  ANR time: " + DateFormat.getInstance().format(new Date()));
@@ -10552,6 +10554,9 @@
         if (windowState != null) {
             pw.println("  Window at fault: " + windowState.mAttrs.getTitle());
         }
+        if (reason != null) {
+            pw.println("  Reason: " + reason);
+        }
         pw.println();
         dumpWindowsNoHeaderLocked(pw, true, null);
         pw.close();
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 09e5be4..d8b8b94 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -191,7 +191,8 @@
             uint32_t policyFlags);
     virtual void notifyConfigurationChanged(nsecs_t when);
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle);
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason);
     virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
     virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
     virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
@@ -553,7 +554,7 @@
 }
 
 nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-        const sp<InputWindowHandle>& inputWindowHandle) {
+        const sp<InputWindowHandle>& inputWindowHandle, const String8& reason) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
     ALOGD("notifyANR");
 #endif
@@ -564,15 +565,18 @@
             getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
     jobject inputWindowHandleObj =
             getInputWindowHandleObjLocalRef(env, inputWindowHandle);
+    jstring reasonObj = env->NewStringUTF(reason.string());
 
     jlong newTimeout = env->CallLongMethod(mServiceObj,
-                gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
+                gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj,
+                reasonObj);
     if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
         newTimeout = 0; // abort dispatch
     } else {
         assert(newTimeout >= 0);
     }
 
+    env->DeleteLocalRef(reasonObj);
     env->DeleteLocalRef(inputWindowHandleObj);
     env->DeleteLocalRef(inputApplicationHandleObj);
     return newTimeout;
@@ -1379,7 +1383,7 @@
 
     GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz,
             "notifyANR",
-            "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;)J");
+            "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;Ljava/lang/String;)J");
 
     GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
             "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 83789e2..5626192 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -25,6 +25,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Native calls for bring up/shut down of the supplicant daemon and for
@@ -457,7 +458,7 @@
     }
 
     public boolean setCountryCode(String countryCode) {
-        return doBooleanCommand("DRIVER COUNTRY " + countryCode);
+        return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
     }
 
     public void enableBackgroundScan(boolean enable) {
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 3ccdbea..2bc22f2 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -88,7 +88,6 @@
 import java.net.Inet6Address;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.Iterator;
@@ -1431,6 +1430,7 @@
                     countryCode);
         }
         sendMessage(CMD_SET_COUNTRY_CODE, countryCode);
+        mWifiP2pChannel.sendMessage(WifiP2pService.SET_COUNTRY_CODE, countryCode);
     }
 
     /**
@@ -2952,7 +2952,7 @@
                 case CMD_SET_COUNTRY_CODE:
                     String country = (String) message.obj;
                     if (DBG) log("set country code " + country);
-                    if (!mWifiNative.setCountryCode(country.toUpperCase(Locale.ROOT))) {
+                    if (!mWifiNative.setCountryCode(country)) {
                         loge("Failed to set country code " + country);
                     }
                     break;
@@ -4256,7 +4256,7 @@
     /**
      * arg2 on the source message has a unique id that needs to be retained in replies
      * to match the request
-     *
+
      * see WifiManager for details
      */
     private Message obtainMessageWithArg2(Message srcMsg) {
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 05196b8..625ffb8 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -174,6 +174,9 @@
     //   msg.obj  = StateMachine to send to when blocked
     public static final int BLOCK_DISCOVERY                 =   BASE + 15;
 
+    // set country code
+    public static final int SET_COUNTRY_CODE                =   BASE + 16;
+
     public static final int ENABLED                         = 1;
     public static final int DISABLED                        = 0;
 
@@ -632,6 +635,7 @@
                 case WifiP2pManager.START_LISTEN:
                 case WifiP2pManager.STOP_LISTEN:
                 case WifiP2pManager.SET_CHANNEL:
+                case SET_COUNTRY_CODE:
                     break;
                 case WifiStateMachine.CMD_ENABLE_P2P:
                     // Enable is lazy and has no response
@@ -1064,6 +1068,10 @@
                         replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED);
                     }
                     break;
+                case SET_COUNTRY_CODE:
+                    String countryCode = (String) message.obj;
+                    mWifiNative.setCountryCode(countryCode);
+                    break;
                 default:
                    return NOT_HANDLED;
             }
@@ -2537,6 +2545,12 @@
         mServiceTransactionId = 0;
         mServiceDiscReqId = null;
 
+        String countryCode = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.WIFI_COUNTRY_CODE);
+        if (countryCode != null && !countryCode.isEmpty()) {
+            mP2pStateMachine.sendMessage(SET_COUNTRY_CODE, countryCode);
+        }
+
         updatePersistentNetworks(RELOAD);
     }