Merge "Remove default constructors from static utility classes."
diff --git a/api/current.xml b/api/current.xml
index 0b4645f7..5ceca12 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -90769,7 +90769,7 @@
 <method name="addCallbackBuffer"
  return="void"
  abstract="false"
- native="true"
+ native="false"
  synchronized="false"
  static="false"
  final="true"
@@ -95413,50 +95413,6 @@
  visibility="public"
 >
 </field>
-<field name="EXTRA_ACCESSORY_MANUFACTURER"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;accessory-manufacturer&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="EXTRA_ACCESSORY_PRODUCT"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;accessory-product&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="EXTRA_ACCESSORY_TYPE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;accessory-type&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="EXTRA_ACCESSORY_VERSION"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;accessory-version&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="EXTRA_DEVICE"
  type="java.lang.String"
  transient="false"
@@ -95468,72 +95424,6 @@
  visibility="public"
 >
 </field>
-<field name="EXTRA_DEVICE_CLASS"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;device_class&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="EXTRA_DEVICE_NAME"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;device_name&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="EXTRA_DEVICE_PROTOCOL"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;device_protocol&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="EXTRA_DEVICE_SUBCLASS"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;device_subclass&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="EXTRA_PRODUCT_ID"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;product_id&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="EXTRA_VENDOR_ID"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;vendor_id&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="USB_CONFIGURATION"
  type="java.lang.String"
  transient="false"
@@ -223815,6 +223705,19 @@
 <parameter name="bottom" type="int">
 </parameter>
 </method>
+<method name="setCameraDistance"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="distance" type="float">
+</parameter>
+</method>
 <method name="setClickable"
  return="void"
  abstract="false"
@@ -249745,6 +249648,17 @@
 <parameter name="defStyle" type="int">
 </parameter>
 </constructor>
+<method name="getCalendarView"
+ return="android.widget.CalendarView"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getCalendarViewShown"
  return="boolean"
  abstract="false"
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index 116a068..9855709 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -82,7 +82,6 @@
     public static final int TRANSITION_TO_STABLE = 102;
     public static final int CONNECT_OTHER_PROFILES = 103;
 
-    private static final int AUTO_CONNECT_DELAY = 6000; // 6 secs
     private static final int CONNECT_OTHER_PROFILES_DELAY = 4000; // 4 secs
 
     private BondedDevice mBondedDevice = new BondedDevice();
diff --git a/core/java/android/hardware/UsbManager.java b/core/java/android/hardware/UsbManager.java
index 0f616ff..dcfdcf4 100644
--- a/core/java/android/hardware/UsbManager.java
+++ b/core/java/android/hardware/UsbManager.java
@@ -62,12 +62,6 @@
      *
      * This intent is sent when a USB device is attached to the USB bus when in host mode.
      * <ul>
-     * <li> {@link #EXTRA_DEVICE_NAME} containing the device's name (String)
-     * <li> {@link #EXTRA_VENDOR_ID} containing the device's vendor ID (Integer)
-     * <li> {@link #EXTRA_PRODUCT_ID} containing the device's product ID (Integer)
-     * <li> {@link #EXTRA_DEVICE_CLASS} } containing the device class (Integer)
-     * <li> {@link #EXTRA_DEVICE_SUBCLASS} containing the device subclass (Integer)
-     * <li> {@link #EXTRA_DEVICE_PROTOCOL} containing the device protocol (Integer)
      * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.UsbDevice}
      * for the attached device
      * </ul>
@@ -80,7 +74,8 @@
      *
      * This intent is sent when a USB device is detached from the USB bus when in host mode.
      * <ul>
-     * <li> {@link #EXTRA_DEVICE_NAME} containing the device's name (String)
+     * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.UsbDevice}
+     * for the detached device
      * </ul>
      */
     public static final String ACTION_USB_DEVICE_DETACHED =
@@ -91,10 +86,6 @@
      *
      * This intent is sent when a USB accessory is attached.
      * <ul>
-     * <li> {@link #EXTRA_ACCESSORY_MANUFACTURER} containing the accessory's manufacturer (String)
-     * <li> {@link #EXTRA_ACCESSORY_PRODUCT} containing the accessory's product name (String)
-     * <li> {@link #EXTRA_ACCESSORY_TYPE} containing the accessory's type (String)
-     * <li> {@link #EXTRA_ACCESSORY_VERSION} containing the accessory's version (String)
      * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.UsbAccessory}
      * for the attached accessory
      * </ul>
@@ -172,43 +163,7 @@
 
     /**
      * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} and
-     * {@link #ACTION_USB_DEVICE_DETACHED} broadcasts
-     * containing the device's ID (String).
-     */
-    public static final String EXTRA_DEVICE_NAME = "device_name";
-
-    /**
-     * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} broadcast
-     * containing the device's vendor ID (int).
-     */
-    public static final String EXTRA_VENDOR_ID = "vendor_id";
-
-    /**
-     * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} broadcast
-     * containing the device's product ID (int).
-     */
-    public static final String EXTRA_PRODUCT_ID = "product_id";
-
-    /**
-     * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} broadcast
-     * containing the device's class (int).
-     */
-    public static final String EXTRA_DEVICE_CLASS = "device_class";
-
-    /**
-     * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} broadcast
-     * containing the device's class (int).
-     */
-    public static final String EXTRA_DEVICE_SUBCLASS = "device_subclass";
-
-    /**
-     * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} broadcast
-     * containing the device's class (int).
-     */
-    public static final String EXTRA_DEVICE_PROTOCOL = "device_protocol";
-
-    /**
-     * Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} broadcast
+     * {@link #ACTION_USB_DEVICE_DETACHED} broadcasts.
      * containing the UsbDevice object for the device.
      */
 
@@ -220,30 +175,6 @@
      */
     public static final String EXTRA_ACCESSORY = "accessory";
 
-    /**
-     * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
-     * containing the accessory's manufacturer name.
-     */
-    public static final String EXTRA_ACCESSORY_MANUFACTURER = "accessory-manufacturer";
-
-    /**
-     * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
-     * containing the accessory's product name.
-     */
-    public static final String EXTRA_ACCESSORY_PRODUCT = "accessory-product";
-
-    /**
-     * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
-     * containing the accessory's type.
-     */
-    public static final String EXTRA_ACCESSORY_TYPE = "accessory-type";
-
-    /**
-     * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
-     * containing the accessory's version.
-     */
-    public static final String EXTRA_ACCESSORY_VERSION = "accessory-version";
-
     private IUsbManager mService;
 
     /**
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index b5e85a0..132c346 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -16,7 +16,7 @@
 
 /**
  * TODO: Move this to services.jar
- * and make the contructor package private again.
+ * and make the constructor package private again.
  * @hide
  */
 
@@ -57,8 +57,6 @@
 
     private static final String PROPERTY_STATE = "State";
 
-    private static int mSinkCount;
-
     private final Context mContext;
     private final IntentFilter mIntentFilter;
     private HashMap<BluetoothDevice, Integer> mAudioDevices;
@@ -128,7 +126,6 @@
         }
     };
 
-
     private boolean isPhoneDocked(BluetoothDevice device) {
         // This works only because these broadcast intents are "sticky"
         Intent i = mContext.registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
@@ -184,7 +181,7 @@
         }
     }
 
-    private int convertBluezSinkStringtoState(String value) {
+    private int convertBluezSinkStringToState(String value) {
         if (value.equalsIgnoreCase("disconnected"))
             return BluetoothA2dp.STATE_DISCONNECTED;
         if (value.equalsIgnoreCase("connecting"))
@@ -204,7 +201,7 @@
         return false;
     }
 
-    private synchronized boolean addAudioSink (BluetoothDevice device) {
+    private synchronized boolean addAudioSink(BluetoothDevice device) {
         String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
         String propValues[] = (String []) getSinkPropertiesNative(path);
         if (propValues == null) {
@@ -215,7 +212,7 @@
         // Properties are name-value pairs
         for (int i = 0; i < propValues.length; i+=2) {
             if (propValues[i].equals(PROPERTY_STATE)) {
-                state = new Integer(convertBluezSinkStringtoState(propValues[i+1]));
+                state = new Integer(convertBluezSinkStringToState(propValues[i+1]));
                 break;
             }
         }
@@ -226,7 +223,6 @@
 
     private synchronized void onBluetoothEnable() {
         String devices = mBluetoothService.getProperty("Devices");
-        mSinkCount = 0;
         if (devices != null) {
             String [] paths = devices.split(",");
             for (String path: paths) {
@@ -274,18 +270,18 @@
     private synchronized boolean isConnectSinkFeasible(BluetoothDevice device) {
         if (!mBluetoothService.isEnabled() || !isSinkDevice(device) ||
                 getPriority(device) == BluetoothA2dp.PRIORITY_OFF) {
-                return false;
-            }
+            return false;
+        }
 
-            if (mAudioDevices.get(device) == null && !addAudioSink(device)) {
-                return false;
-            }
+        if (mAudioDevices.get(device) == null && !addAudioSink(device)) {
+            return false;
+        }
 
-            String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-            if (path == null) {
-                return false;
-            }
-            return true;
+        String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
+        if (path == null) {
+            return false;
+        }
+        return true;
     }
 
     public synchronized boolean isA2dpPlaying(BluetoothDevice device) {
@@ -467,7 +463,15 @@
                 Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()), priority);
     }
 
-    private synchronized void onSinkPropertyChanged(String path, String []propValues) {
+    /**
+     * Called by native code on a PropertyChanged signal from
+     * org.bluez.AudioSink.
+     *
+     * @param path the object path for the changed device
+     * @param propValues a string array containing the key and one or more
+     *  values.
+     */
+    private synchronized void onSinkPropertyChanged(String path, String[] propValues) {
         if (!mBluetoothService.isEnabled()) {
             return;
         }
@@ -482,7 +486,7 @@
         BluetoothDevice device = mAdapter.getRemoteDevice(address);
 
         if (name.equals(PROPERTY_STATE)) {
-            int state = convertBluezSinkStringtoState(propValues[1]);
+            int state = convertBluezSinkStringToState(propValues[1]);
             log("A2DP: onSinkPropertyChanged newState is: " + state + "mPlayingA2dpDevice: " + mPlayingA2dpDevice);
 
             if (mAudioDevices.get(device) == null) {
@@ -508,12 +512,6 @@
 
     private void handleSinkStateChange(BluetoothDevice device, int prevState, int state) {
         if (state != prevState) {
-            if (state == BluetoothA2dp.STATE_DISCONNECTED ||
-                    state == BluetoothA2dp.STATE_DISCONNECTING) {
-                mSinkCount--;
-            } else if (state == BluetoothA2dp.STATE_CONNECTED) {
-                mSinkCount ++;
-            }
             mAudioDevices.put(device, state);
 
             checkSinkSuspendState(state);
@@ -577,6 +575,13 @@
         return result;
     }
 
+    /**
+     * Called by native code for the async response to a Connect
+     * method call to org.bluez.AudioSink.
+     *
+     * @param deviceObjectPath the object path for the connecting device
+     * @param result true on success; false on error
+     */
     private void onConnectSinkResult(String deviceObjectPath, boolean result) {
         // If the call was a success, ignore we will update the state
         // when we a Sink Property Change
diff --git a/core/java/android/server/BluetoothAdapterProperties.java b/core/java/android/server/BluetoothAdapterProperties.java
new file mode 100644
index 0000000..ae8104b
--- /dev/null
+++ b/core/java/android/server/BluetoothAdapterProperties.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2010 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.server;
+
+import android.content.Context;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class BluetoothAdapterProperties {
+
+    private static final String TAG = "BluetoothAdapterProperties";
+
+    private final Map<String, String> mPropertiesMap;
+    private final Context mContext;
+    private final BluetoothService mService;
+
+    BluetoothAdapterProperties(Context context, BluetoothService service) {
+        mPropertiesMap = new HashMap<String, String>();
+        mContext = context;
+        mService = service;
+    }
+
+    synchronized String getProperty(String name) {
+        if (mPropertiesMap.isEmpty()) {
+            getAllProperties();
+        }
+        return mPropertiesMap.get(name);
+    }
+
+    String getObjectPath() {
+        return getProperty("ObjectPath");
+    }
+
+    synchronized void clear() {
+        mPropertiesMap.clear();
+    }
+
+    synchronized boolean isEmpty() {
+        return mPropertiesMap.isEmpty();
+    }
+
+    synchronized void setProperty(String name, String value) {
+        mPropertiesMap.put(name, value);
+    }
+
+    synchronized void getAllProperties() {
+        mContext.enforceCallingOrSelfPermission(
+                BluetoothService.BLUETOOTH_PERM,
+                "Need BLUETOOTH permission");
+        mPropertiesMap.clear();
+
+        String properties[] = (String[]) mService
+                .getAdapterPropertiesNative();
+        // The String Array consists of key-value pairs.
+        if (properties == null) {
+            Log.e(TAG, "*Error*: GetAdapterProperties returned NULL");
+            return;
+        }
+
+        for (int i = 0; i < properties.length; i++) {
+            String name = properties[i];
+            String newValue = null;
+            int len;
+            if (name == null) {
+                Log.e(TAG, "Error:Adapter Property at index " + i + " is null");
+                continue;
+            }
+            if (name.equals("Devices") || name.equals("UUIDs")) {
+                StringBuilder str = new StringBuilder();
+                len = Integer.valueOf(properties[++i]);
+                for (int j = 0; j < len; j++) {
+                    str.append(properties[++i]);
+                    str.append(",");
+                }
+                if (len > 0) {
+                    newValue = str.toString();
+                }
+            } else {
+                newValue = properties[++i];
+            }
+            mPropertiesMap.put(name, newValue);
+        }
+
+        // Add adapter object path property.
+        String adapterPath = mService.getAdapterPathNative();
+        if (adapterPath != null) {
+            mPropertiesMap.put("ObjectPath", adapterPath + "/dev_");
+        }
+    }
+}
diff --git a/core/java/android/server/BluetoothBondState.java b/core/java/android/server/BluetoothBondState.java
new file mode 100644
index 0000000..2304a70
--- /dev/null
+++ b/core/java/android/server/BluetoothBondState.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2010 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.server;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Local cache of bonding state.
+ * We keep our own state to track the intermediate state BONDING, which
+ * bluez does not track.
+ * All addresses must be passed in upper case.
+ */
+class BluetoothBondState {
+    private static final String TAG = "BluetoothBondState";
+    private static final boolean DBG =  true;
+
+    private final HashMap<String, Integer> mState = new HashMap<String, Integer>();
+    private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();
+
+    private static final String AUTO_PAIRING_BLACKLIST =
+        "/etc/bluetooth/auto_pairing.conf";
+    private static final String DYNAMIC_AUTO_PAIRING_BLACKLIST =
+        "/data/misc/bluetooth/dynamic_auto_pairing.conf";
+    private ArrayList<String> mAutoPairingAddressBlacklist;
+    private ArrayList<String> mAutoPairingExactNameBlacklist;
+    private ArrayList<String> mAutoPairingPartialNameBlacklist;
+    private ArrayList<String> mAutoPairingFixedPinZerosKeyboardList;
+    // Addresses added to blacklist dynamically based on usage.
+    private ArrayList<String> mAutoPairingDynamicAddressBlacklist;
+
+    // If this is an outgoing connection, store the address.
+    // There can be only 1 pending outgoing connection at a time,
+    private String mPendingOutgoingBonding;
+
+    private final Context mContext;
+    private final BluetoothService mService;
+    private final BluetoothInputProfileHandler mBluetoothInputProfileHandler;
+
+    BluetoothBondState(Context context, BluetoothService service) {
+        mContext = context;
+        mService = service;
+        mBluetoothInputProfileHandler =
+            BluetoothInputProfileHandler.getInstance(mContext, mService);
+    }
+
+    synchronized void setPendingOutgoingBonding(String address) {
+        mPendingOutgoingBonding = address;
+    }
+
+    public synchronized String getPendingOutgoingBonding() {
+        return mPendingOutgoingBonding;
+    }
+
+    public synchronized void loadBondState() {
+        if (mService.getBluetoothStateInternal() !=
+                BluetoothAdapter.STATE_TURNING_ON) {
+            return;
+        }
+        String val = mService.getAdapterProperties().getProperty("Devices");
+        if (val == null) {
+            return;
+        }
+        String[] bonds = val.split(",");
+        if (bonds == null) {
+            return;
+        }
+        mState.clear();
+        if (DBG) Log.d(TAG, "found " + bonds.length + " bonded devices");
+        for (String device : bonds) {
+            mState.put(mService.getAddressFromObjectPath(device).toUpperCase(),
+                    BluetoothDevice.BOND_BONDED);
+        }
+    }
+
+    public synchronized void setBondState(String address, int state) {
+        setBondState(address, state, 0);
+    }
+
+    /** reason is ignored unless state == BOND_NOT_BONDED */
+    public synchronized void setBondState(String address, int state, int reason) {
+        int oldState = getBondState(address);
+        if (oldState == state) {
+            return;
+        }
+
+        // Check if this was an pending outgoing bonding.
+        // If yes, reset the state.
+        if (oldState == BluetoothDevice.BOND_BONDING) {
+            if (address.equals(mPendingOutgoingBonding)) {
+                mPendingOutgoingBonding = null;
+            }
+        }
+
+        if (state == BluetoothDevice.BOND_BONDED) {
+            mService.addProfileState(address);
+        } else if (state == BluetoothDevice.BOND_NONE) {
+            mService.removeProfileState(address);
+        }
+
+        // HID is handled by BluetoothService, other profiles
+        // will be handled by their respective services.
+        mBluetoothInputProfileHandler.setInitialInputDevicePriority(
+            mService.getRemoteDevice(address), state);
+
+        if (DBG) {
+            Log.d(TAG, address + " bond state " + oldState + " -> " + state
+                + " (" + reason + ")");
+        }
+        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mService.getRemoteDevice(address));
+        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, state);
+        intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
+        if (state == BluetoothDevice.BOND_NONE) {
+            if (reason <= 0) {
+                Log.w(TAG, "setBondState() called to unbond device, but reason code is " +
+                      "invalid. Overriding reason code with BOND_RESULT_REMOVED");
+                reason = BluetoothDevice.UNBOND_REASON_REMOVED;
+            }
+            intent.putExtra(BluetoothDevice.EXTRA_REASON, reason);
+            mState.remove(address);
+        } else {
+            mState.put(address, state);
+        }
+
+        mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
+    }
+
+    public boolean isAutoPairingBlacklisted(String address) {
+        if (mAutoPairingAddressBlacklist != null) {
+            for (String blacklistAddress : mAutoPairingAddressBlacklist) {
+                if (address.startsWith(blacklistAddress)) return true;
+            }
+        }
+
+        if (mAutoPairingDynamicAddressBlacklist != null) {
+            for (String blacklistAddress: mAutoPairingDynamicAddressBlacklist) {
+                if (address.equals(blacklistAddress)) return true;
+            }
+        }
+
+        String name = mService.getRemoteName(address);
+        if (name != null) {
+            if (mAutoPairingExactNameBlacklist != null) {
+                for (String blacklistName : mAutoPairingExactNameBlacklist) {
+                    if (name.equals(blacklistName)) return true;
+                }
+            }
+
+            if (mAutoPairingPartialNameBlacklist != null) {
+                for (String blacklistName : mAutoPairingPartialNameBlacklist) {
+                    if (name.startsWith(blacklistName)) return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public boolean isFixedPinZerosAutoPairKeyboard(String address) {
+        // Note: the meaning of blacklist is reversed in this case.
+        // If its in the list, we can go ahead and auto pair since
+        // by default keyboard should have a variable PIN that we don't
+        // auto pair using 0000.
+        if (mAutoPairingFixedPinZerosKeyboardList != null) {
+            for (String blacklistAddress : mAutoPairingFixedPinZerosKeyboardList) {
+                if (address.startsWith(blacklistAddress)) return true;
+            }
+        }
+        return false;
+    }
+
+    public synchronized int getBondState(String address) {
+        Integer state = mState.get(address);
+        if (state == null) {
+            return BluetoothDevice.BOND_NONE;
+        }
+        return state.intValue();
+    }
+
+    /*package*/ synchronized String[] listInState(int state) {
+        ArrayList<String> result = new ArrayList<String>(mState.size());
+        for (Map.Entry<String, Integer> e : mState.entrySet()) {
+            if (e.getValue().intValue() == state) {
+                result.add(e.getKey());
+            }
+        }
+        return result.toArray(new String[result.size()]);
+    }
+
+    public synchronized void addAutoPairingFailure(String address) {
+        if (mAutoPairingDynamicAddressBlacklist == null) {
+            mAutoPairingDynamicAddressBlacklist = new ArrayList<String>();
+        }
+
+        updateAutoPairingData(address);
+        mAutoPairingDynamicAddressBlacklist.add(address);
+    }
+
+    public synchronized boolean isAutoPairingAttemptsInProgress(String address) {
+        return getAttempt(address) != 0;
+    }
+
+    public synchronized void clearPinAttempts(String address) {
+        mPinAttempt.remove(address);
+    }
+
+    public synchronized boolean hasAutoPairingFailed(String address) {
+        if (mAutoPairingDynamicAddressBlacklist == null) return false;
+
+        return mAutoPairingDynamicAddressBlacklist.contains(address);
+    }
+
+    public synchronized int getAttempt(String address) {
+        Integer attempt = mPinAttempt.get(address);
+        if (attempt == null) {
+            return 0;
+        }
+        return attempt.intValue();
+    }
+
+    public synchronized void attempt(String address) {
+        Integer attempt = mPinAttempt.get(address);
+        int newAttempt;
+        if (attempt == null) {
+            newAttempt = 1;
+        } else {
+            newAttempt = attempt.intValue() + 1;
+        }
+        mPinAttempt.put(address, new Integer(newAttempt));
+    }
+
+    private void copyAutoPairingData() {
+        FileInputStream in = null;
+        FileOutputStream out = null;
+        try {
+            File file = new File(DYNAMIC_AUTO_PAIRING_BLACKLIST);
+            if (file.exists()) return;
+
+            in = new FileInputStream(AUTO_PAIRING_BLACKLIST);
+            out= new FileOutputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
+
+            byte[] buf = new byte[1024];
+            int len;
+            while ((len = in.read(buf)) > 0) {
+                out.write(buf, 0, len);
+            }
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "FileNotFoundException: copyAutoPairingData " + e);
+        } catch (IOException e) {
+            Log.e(TAG, "IOException: copyAutoPairingData " + e);
+        } finally {
+             try {
+                 if (in != null) in.close();
+                 if (out != null) out.close();
+             } catch (IOException e) {}
+        }
+    }
+
+    synchronized public void readAutoPairingData() {
+        if (mAutoPairingAddressBlacklist != null) return;
+        copyAutoPairingData();
+        FileInputStream fstream = null;
+        try {
+            fstream = new FileInputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
+            DataInputStream in = new DataInputStream(fstream);
+            BufferedReader file = new BufferedReader(new InputStreamReader(in));
+            String line;
+            while((line = file.readLine()) != null) {
+                line = line.trim();
+                if (line.length() == 0 || line.startsWith("//")) continue;
+                String[] value = line.split("=");
+                if (value != null && value.length == 2) {
+                    String[] val = value[1].split(",");
+                    if (value[0].equalsIgnoreCase("AddressBlacklist")) {
+                        mAutoPairingAddressBlacklist =
+                            new ArrayList<String>(Arrays.asList(val));
+                    } else if (value[0].equalsIgnoreCase("ExactNameBlacklist")) {
+                        mAutoPairingExactNameBlacklist =
+                            new ArrayList<String>(Arrays.asList(val));
+                    } else if (value[0].equalsIgnoreCase("PartialNameBlacklist")) {
+                        mAutoPairingPartialNameBlacklist =
+                            new ArrayList<String>(Arrays.asList(val));
+                    } else if (value[0].equalsIgnoreCase("FixedPinZerosKeyboardBlacklist")) {
+                        mAutoPairingFixedPinZerosKeyboardList =
+                            new ArrayList<String>(Arrays.asList(val));
+                    } else if (value[0].equalsIgnoreCase("DynamicAddressBlacklist")) {
+                        mAutoPairingDynamicAddressBlacklist =
+                            new ArrayList<String>(Arrays.asList(val));
+                    } else {
+                        Log.e(TAG, "Error parsing Auto pairing blacklist file");
+                    }
+                }
+            }
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "FileNotFoundException: readAutoPairingData " + e);
+        } catch (IOException e) {
+            Log.e(TAG, "IOException: readAutoPairingData " + e);
+        } finally {
+            if (fstream != null) {
+                try {
+                    fstream.close();
+                } catch (IOException e) {
+                    // Ignore
+                }
+            }
+        }
+    }
+
+    // This function adds a bluetooth address to the auto pairing blacklist
+    // file. These addresses are added to DynamicAddressBlacklistSection
+    private void updateAutoPairingData(String address) {
+        BufferedWriter out = null;
+        try {
+            out = new BufferedWriter(new FileWriter(DYNAMIC_AUTO_PAIRING_BLACKLIST, true));
+            StringBuilder str = new StringBuilder();
+            if (mAutoPairingDynamicAddressBlacklist.size() == 0) {
+                str.append("DynamicAddressBlacklist=");
+            }
+            str.append(address);
+            str.append(",");
+            out.write(str.toString());
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "FileNotFoundException: updateAutoPairingData " + e);
+        } catch (IOException e) {
+            Log.e(TAG, "IOException: updateAutoPairingData " + e);
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    // Ignore
+                }
+            }
+        }
+    }
+}
diff --git a/core/java/android/server/BluetoothDeviceProperties.java b/core/java/android/server/BluetoothDeviceProperties.java
new file mode 100644
index 0000000..3dc53d7
--- /dev/null
+++ b/core/java/android/server/BluetoothDeviceProperties.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010 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.server;
+
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+class BluetoothDeviceProperties {
+
+    private static final String TAG = "BluetoothDeviceProperties";
+
+    private final HashMap<String, Map<String, String>> mPropertiesMap;
+    private final BluetoothService mService;
+
+    BluetoothDeviceProperties(BluetoothService service) {
+        mPropertiesMap = new HashMap<String, Map<String, String>>();
+        mService = service;
+    }
+
+    synchronized Map<String, String> addProperties(String address,
+            String[] properties) {
+        /*
+         * We get a DeviceFound signal every time RSSI changes or name changes.
+         * Don't create a new Map object every time.
+         */
+        Map<String, String> propertyValues = mPropertiesMap.get(address);
+        if (propertyValues == null) {
+            propertyValues = new HashMap<String, String>();
+        }
+
+        for (int i = 0; i < properties.length; i++) {
+            String name = properties[i];
+            String newValue = null;
+            int len;
+            if (name == null) {
+                Log.e(TAG, "Error: Remote Device Property at index "
+                        + i + " is null");
+                continue;
+            }
+            if (name.equals("UUIDs") || name.equals("Nodes")) {
+                StringBuilder str = new StringBuilder();
+                len = Integer.valueOf(properties[++i]);
+                for (int j = 0; j < len; j++) {
+                    str.append(properties[++i]);
+                    str.append(",");
+                }
+                if (len > 0) {
+                    newValue = str.toString();
+                }
+            } else {
+                newValue = properties[++i];
+            }
+
+            propertyValues.put(name, newValue);
+        }
+        mPropertiesMap.put(address, propertyValues);
+
+        // We have added a new remote device or updated its properties.
+        // Also update the serviceChannel cache.
+        mService.updateDeviceServiceChannelCache(address);
+        return propertyValues;
+    }
+
+    synchronized void setProperty(String address, String name, String value) {
+        Map <String, String> propVal = mPropertiesMap.get(address);
+        if (propVal != null) {
+            propVal.put(name, value);
+            mPropertiesMap.put(address, propVal);
+        } else {
+            Log.e(TAG, "setRemoteDeviceProperty for a device not in cache:" + address);
+        }
+    }
+
+    synchronized boolean isInCache(String address) {
+        return (mPropertiesMap.get(address) != null);
+    }
+
+    synchronized boolean isEmpty() {
+        return mPropertiesMap.isEmpty();
+    }
+
+    synchronized Set<String> keySet() {
+        return mPropertiesMap.keySet();
+    }
+
+    synchronized String getProperty(String address, String property) {
+        Map<String, String> properties = mPropertiesMap.get(address);
+        if (properties != null) {
+            return properties.get(property);
+        } else {
+            // Query for remote device properties, again.
+            // We will need to reload the cache when we switch Bluetooth on / off
+            // or if we crash.
+            properties = updateCache(address);
+            if (properties != null) {
+                return properties.get(property);
+            }
+        }
+        Log.e(TAG, "getRemoteDeviceProperty: " + property + " not present: " + address);
+        return null;
+    }
+
+    synchronized Map<String, String> updateCache(String address) {
+        String[] propValues = mService.getRemoteDeviceProperties(address);
+        if (propValues != null) {
+            return addProperties(address, propValues);
+        }
+        return null;
+    }
+}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 578580a..e72aaa7 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -34,14 +34,9 @@
 
 import java.util.HashMap;
 import java.util.List;
-import java.util.Set;
 
 
 /**
- * TODO: Move this to
- * java/services/com/android/server/BluetoothEventLoop.java
- * and make the constructor package private again.
- *
  * @hide
  */
 class BluetoothEventLoop {
@@ -114,7 +109,7 @@
             BluetoothService bluetoothService) {
         mBluetoothService = bluetoothService;
         mContext = context;
-        mPasskeyAgentRequestData = new HashMap();
+        mPasskeyAgentRequestData = new HashMap<String, Integer>();
         mAdapter = adapter;
         //WakeLock instantiation in BluetoothEventLoop class
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
@@ -180,10 +175,12 @@
     }
 
     private void addDevice(String address, String[] properties) {
-        mBluetoothService.addRemoteDeviceProperties(address, properties);
-        String rssi = mBluetoothService.getRemoteDeviceProperty(address, "RSSI");
-        String classValue = mBluetoothService.getRemoteDeviceProperty(address, "Class");
-        String name = mBluetoothService.getRemoteDeviceProperty(address, "Name");
+        BluetoothDeviceProperties deviceProperties =
+                mBluetoothService.getDeviceProperties();
+        deviceProperties.addProperties(address, properties);
+        String rssi = deviceProperties.getProperty(address, "RSSI");
+        String classValue = deviceProperties.getProperty(address, "Class");
+        String name = deviceProperties.getProperty(address, "Name");
         short rssiValue;
         // For incoming connections, we don't get the RSSI value. Use a default of MIN_VALUE.
         // If we accept the pairing, we will automatically show it at the top of the list.
@@ -206,6 +203,14 @@
         }
     }
 
+    /**
+     * Called by native code on a DeviceFound signal from org.bluez.Adapter.
+     *
+     * @param address the MAC address of the new device
+     * @param properties an array of property keys and value strings
+     *
+     * @see BluetoothDeviceProperties#addProperties(String, String[])
+     */
     private void onDeviceFound(String address, String[] properties) {
         if (properties == null) {
             Log.e(TAG, "ERROR: Remote device properties are null");
@@ -214,12 +219,24 @@
         addDevice(address, properties);
     }
 
+    /**
+     * Called by native code on a DeviceDisappeared signal from
+     * org.bluez.Adapter.
+     *
+     * @param address the MAC address of the disappeared device
+     */
     private void onDeviceDisappeared(String address) {
         Intent intent = new Intent(BluetoothDevice.ACTION_DISAPPEARED);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         mContext.sendBroadcast(intent, BLUETOOTH_PERM);
     }
 
+    /**
+     * Called by native code on a DisconnectRequested signal from
+     * org.bluez.Device.
+     *
+     * @param deviceObjectPath the object path for the disconnecting device
+     */
     private void onDeviceDisconnectRequested(String deviceObjectPath) {
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
         if (address == null) {
@@ -231,11 +248,23 @@
         mContext.sendBroadcast(intent, BLUETOOTH_PERM);
     }
 
+    /**
+     * Called by native code for the async response to a CreatePairedDevice
+     * method call to org.bluez.Adapter.
+     *
+     * @param address the MAC address of the device to pair
+     * @param result success or error result for the pairing operation
+     */
     private void onCreatePairedDeviceResult(String address, int result) {
         address = address.toUpperCase();
         mBluetoothService.onCreatePairedDeviceResult(address, result);
     }
 
+    /**
+     * Called by native code on a DeviceCreated signal from org.bluez.Adapter.
+     *
+     * @param deviceObjectPath the object path for the created device
+     */
     private void onDeviceCreated(String deviceObjectPath) {
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
         if (!mBluetoothService.isRemoteDeviceInCache(address)) {
@@ -248,6 +277,11 @@
         return;
     }
 
+    /**
+     * Called by native code on a DeviceRemoved signal from org.bluez.Adapter.
+     *
+     * @param deviceObjectPath the object path for the removed device
+     */
     private void onDeviceRemoved(String deviceObjectPath) {
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
         if (address != null) {
@@ -257,31 +291,43 @@
         }
     }
 
+    /**
+     * Called by native code on a PropertyChanged signal from
+     * org.bluez.Adapter. This method is also called from Java at
+     * {@link BluetoothService.EnableThread#run()} to set the "Pairable"
+     * property when Bluetooth is enabled.
+     *
+     * @param propValues a string array containing the key and one or more
+     *  values.
+     */
     /*package*/ void onPropertyChanged(String[] propValues) {
-        if (mBluetoothService.isAdapterPropertiesEmpty()) {
+        BluetoothAdapterProperties adapterProperties =
+                mBluetoothService.getAdapterProperties();
+
+        if (adapterProperties.isEmpty()) {
             // We have got a property change before
             // we filled up our cache.
-            mBluetoothService.getAllProperties();
+            adapterProperties.getAllProperties();
         }
         log("Property Changed: " + propValues[0] + " : " + propValues[1]);
         String name = propValues[0];
         if (name.equals("Name")) {
-            mBluetoothService.setProperty(name, propValues[1]);
+            adapterProperties.setProperty(name, propValues[1]);
             Intent intent = new Intent(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
             intent.putExtra(BluetoothAdapter.EXTRA_LOCAL_NAME, propValues[1]);
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
         } else if (name.equals("Pairable") || name.equals("Discoverable")) {
             String pairable = name.equals("Pairable") ? propValues[1] :
-                mBluetoothService.getPropertyInternal("Pairable");
+                adapterProperties.getProperty("Pairable");
             String discoverable = name.equals("Discoverable") ? propValues[1] :
-                mBluetoothService.getPropertyInternal("Discoverable");
+                adapterProperties.getProperty("Discoverable");
 
             // This shouldn't happen, unless Adapter Properties are null.
             if (pairable == null || discoverable == null)
                 return;
 
-            mBluetoothService.setProperty(name, propValues[1]);
+            adapterProperties.setProperty(name, propValues[1]);
             int mode = BluetoothService.bluezStringToScanMode(
                     pairable.equals("true"),
                     discoverable.equals("true"));
@@ -293,7 +339,7 @@
             }
         } else if (name.equals("Discovering")) {
             Intent intent;
-            mBluetoothService.setProperty(name, propValues[1]);
+            adapterProperties.setProperty(name, propValues[1]);
             if (propValues[1].equals("true")) {
                 mBluetoothService.setIsDiscovering(true);
                 intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
@@ -315,7 +361,7 @@
                 }
                 value = str.toString();
             }
-            mBluetoothService.setProperty(name, value);
+            adapterProperties.setProperty(name, value);
             if (name.equals("UUIDs")) {
                 mBluetoothService.updateBluetoothState(value);
             }
@@ -325,10 +371,18 @@
             if (propValues[1].equals("true"))
                 onRestartRequired();
         } else if (name.equals("DiscoverableTimeout")) {
-            mBluetoothService.setProperty(name, propValues[1]);
+            adapterProperties.setProperty(name, propValues[1]);
         }
     }
 
+    /**
+     * Called by native code on a PropertyChanged signal from
+     * org.bluez.Device.
+     *
+     * @param deviceObjectPath the object path for the changed device
+     * @param propValues a string array containing the key and one or more
+     *  values.
+     */
     private void onDevicePropertyChanged(String deviceObjectPath, String[] propValues) {
         String name = propValues[0];
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
@@ -399,18 +453,26 @@
             }
         } else if (name.equals("Trusted")) {
             if (DBG)
-                log("set trust state succeded, value is  " + propValues[1]);
+                log("set trust state succeeded, value is: " + propValues[1]);
             mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
         }
     }
 
+    /**
+     * Called by native code on a PropertyChanged signal from
+     * org.bluez.Input.
+     *
+     * @param path the object path for the changed input device
+     * @param propValues a string array containing the key and one or more
+     *  values.
+     */
     private void onInputDevicePropertyChanged(String path, String[] propValues) {
         String address = mBluetoothService.getAddressFromObjectPath(path);
         if (address == null) {
-            Log.e(TAG, "onInputDevicePropertyChanged: Address of the remote device in null");
+            Log.e(TAG, "onInputDevicePropertyChanged: Address of the remote device is null");
             return;
         }
-        log(" Input Device : Name of Property is:" + propValues[0]);
+        log("Input Device : Name of Property is: " + propValues[0]);
         boolean state = false;
         if (propValues[1].equals("true")) {
             state = true;
@@ -418,6 +480,14 @@
         mBluetoothService.handleInputDevicePropertyChange(address, state);
     }
 
+    /**
+     * Called by native code on a PropertyChanged signal from
+     * org.bluez.Network.
+     *
+     * @param deviceObjectPath the object path for the changed PAN device
+     * @param propValues a string array containing the key and one or more
+     *  values.
+     */
     private void onPanDevicePropertyChanged(String deviceObjectPath, String[] propValues) {
         String name = propValues[0];
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
@@ -471,6 +541,13 @@
         return address;
     }
 
+    /**
+     * Called by native code on a RequestPairingConsent method call to
+     * org.bluez.Agent.
+     *
+     * @param objectPath the path of the device to request pairing consent for
+     * @param nativeData a native pointer to the original D-Bus message
+     */
     private void onRequestPairingConsent(String objectPath, int nativeData) {
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
@@ -494,11 +571,19 @@
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                         BluetoothDevice.PAIRING_VARIANT_CONSENT);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        // Release wakelock to allow the LCD to go off after the PIN popup notification.
         mWakeLock.release();
         return;
     }
 
+    /**
+     * Called by native code on a RequestConfirmation method call to
+     * org.bluez.Agent.
+     *
+     * @param objectPath the path of the device to confirm the passkey for
+     * @param passkey an integer containing the 6-digit passkey to confirm
+     * @param nativeData a native pointer to the original D-Bus message
+     */
     private void onRequestPasskeyConfirmation(String objectPath, int passkey, int nativeData) {
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
@@ -510,11 +595,18 @@
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                 BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        // Release wakelock to allow the LCD to go off after the PIN popup notification.
         mWakeLock.release();
         return;
     }
 
+    /**
+     * Called by native code on a RequestPasskey method call to
+     * org.bluez.Agent.
+     *
+     * @param objectPath the path of the device requesting a passkey
+     * @param nativeData a native pointer to the original D-Bus message
+     */
     private void onRequestPasskey(String objectPath, int nativeData) {
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
@@ -525,11 +617,18 @@
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                 BluetoothDevice.PAIRING_VARIANT_PASSKEY);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        // Release wakelock to allow the LCD to go off after the PIN popup notification.
         mWakeLock.release();
         return;
     }
 
+    /**
+     * Called by native code on a RequestPinCode method call to
+     * org.bluez.Agent.
+     *
+     * @param objectPath the path of the device requesting a PIN code
+     * @param nativeData a native pointer to the original D-Bus message
+     */
     private void onRequestPinCode(String objectPath, int nativeData) {
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
@@ -583,11 +682,19 @@
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        // Release wakelock to allow the LCD to go off after the PIN popup notification.
         mWakeLock.release();
         return;
     }
 
+    /**
+     * Called by native code on a DisplayPasskey method call to
+     * org.bluez.Agent.
+     *
+     * @param objectPath the path of the device to display the passkey for
+     * @param passkey an integer containing the 6-digit passkey
+     * @param nativeData a native pointer to the original D-Bus message
+     */
     private void onDisplayPasskey(String objectPath, int passkey, int nativeData) {
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
@@ -600,7 +707,7 @@
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                         BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        //Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        //Release wakelock to allow the LCD to go off after the PIN popup notification.
         mWakeLock.release();
     }
 
@@ -617,7 +724,14 @@
         mWakeLock.release();
     }
 
-    private void onRequestOobData(String objectPath , int nativeData) {
+    /**
+     * Called by native code on a RequestOobData method call to
+     * org.bluez.Agent.
+     *
+     * @param objectPath the path of the device requesting OOB data
+     * @param nativeData a native pointer to the original D-Bus message
+     */
+    private void onRequestOobData(String objectPath, int nativeData) {
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
 
@@ -628,6 +742,13 @@
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
     }
 
+    /**
+     * Called by native code on an Authorize method call to org.bluez.Agent.
+     *
+     * @param objectPath the path of the device requesting to be authorized
+     * @param deviceUuid the UUID of the requesting device
+     * @return true if the authorization is allowed; false if not allowed
+     */
     private boolean onAgentAuthorize(String objectPath, String deviceUuid) {
         if (!mBluetoothService.isEnabled()) return false;
 
@@ -704,6 +825,9 @@
         return false;
     }
 
+    /**
+     * Called by native code on a Cancel method call to org.bluez.Agent.
+     */
     private void onAgentCancel() {
         Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
@@ -714,6 +838,13 @@
         return;
     }
 
+    /**
+     * Called by native code for the async response to a DiscoverServices
+     * method call to org.bluez.Adapter.
+     *
+     * @param deviceObjectPath the path for the specified device
+     * @param result true for success; false on error
+     */
     private void onDiscoverServicesResult(String deviceObjectPath, boolean result) {
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
         if (address == null) return;
@@ -726,6 +857,14 @@
         mBluetoothService.makeServiceChannelCallbacks(address);
     }
 
+    /**
+     * Called by native code for the async response to a CreateDevice
+     * method call to org.bluez.Adapter.
+     *
+     * @param address the MAC address of the device to create
+     * @param result {@link #CREATE_DEVICE_SUCCESS},
+     *  {@link #CREATE_DEVICE_ALREADY_EXISTS} or {@link #CREATE_DEVICE_FAILED}}
+     */
     private void onCreateDeviceResult(String address, int result) {
         if (DBG) log("Result of onCreateDeviceResult:" + result);
 
@@ -736,7 +875,7 @@
                 mBluetoothService.discoverServicesNative(path, "");
                 break;
             }
-            Log.w(TAG, "Device exists, but we dont have the bluez path, failing");
+            Log.w(TAG, "Device exists, but we don't have the bluez path, failing");
             // fall-through
         case CREATE_DEVICE_FAILED:
             mBluetoothService.sendUuidIntent(address);
@@ -747,6 +886,13 @@
         }
     }
 
+    /**
+     * Called by native code for the async response to a Connect
+     * method call to org.bluez.Input.
+     *
+     * @param path the path of the specified input device
+     * @param result Result code of the operation.
+     */
     private void onInputDeviceConnectionResult(String path, int result) {
         // Success case gets handled by Property Change signal
         if (result != BluetoothInputDevice.INPUT_OPERATION_SUCCESS) {
@@ -776,6 +922,13 @@
         }
     }
 
+    /**
+     * Called by native code for the async response to a Connect
+     * method call to org.bluez.Network.
+     *
+     * @param path the path of the specified PAN device
+     * @param result Result code of the operation.
+     */
     private void onPanDeviceConnectionResult(String path, int result) {
         log ("onPanDeviceConnectionResult " + path + " " + result);
         // Success case gets handled by Property Change signal
@@ -810,12 +963,26 @@
         }
     }
 
+    /**
+     * Called by native code on a DeviceDisconnected signal from
+     * org.bluez.NetworkServer.
+     *
+     * @param address the MAC address of the disconnected device
+     */
     private void onNetworkDeviceDisconnected(String address) {
         BluetoothDevice device = mAdapter.getRemoteDevice(address);
         mBluetoothService.handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTED,
                                                       BluetoothPan.LOCAL_NAP_ROLE);
     }
 
+    /**
+     * Called by native code on a DeviceConnected signal from
+     * org.bluez.NetworkServer.
+     *
+     * @param address the MAC address of the connected device
+     * @param iface interface of remote network
+     * @param destUuid unused UUID parameter
+     */
     private void onNetworkDeviceConnected(String address, String iface, int destUuid) {
         BluetoothDevice device = mAdapter.getRemoteDevice(address);
         mBluetoothService.handlePanDeviceStateChange(device, iface, BluetoothPan.STATE_CONNECTED,
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index ebe3ef2..751a8d3 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -57,17 +57,12 @@
 import android.util.Pair;
 
 import java.io.BufferedInputStream;
-import java.io.BufferedReader;
 import java.io.BufferedWriter;
-import java.io.DataInputStream;
-import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
@@ -95,7 +90,7 @@
     private ParcelUuid[] mAdapterUuids;
 
     private BluetoothAdapter mAdapter;  // constant after init()
-    private final BondState mBondState = new BondState();  // local cache of bondings
+    private final BluetoothBondState mBondState;  // local cache of bondings
     private final IBatteryStats mBatteryStats;
     private final Context mContext;
 
@@ -129,9 +124,8 @@
             BluetoothUuid.HSP,
             BluetoothUuid.ObexObjectPush };
 
-    // TODO(): Optimize all these string handling
-    private final Map<String, String> mAdapterProperties;
-    private final HashMap<String, Map<String, String>> mDeviceProperties;
+    private final BluetoothAdapterProperties mAdapterProperties;
+    private final BluetoothDeviceProperties mDeviceProperties;
 
     private final HashMap<String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache;
     private final ArrayList<String> mUuidIntentTracker;
@@ -203,8 +197,9 @@
         mBluetoothState = BluetoothAdapter.STATE_OFF;
         mIsDiscovering = false;
 
-        mAdapterProperties = new HashMap<String, String>();
-        mDeviceProperties = new HashMap<String, Map<String,String>>();
+        mBondState = new BluetoothBondState(context, this);
+        mAdapterProperties = new BluetoothAdapterProperties(context, this);
+        mDeviceProperties = new BluetoothDeviceProperties(this);
 
         mDeviceServiceChannelCache = new HashMap<String, Map<ParcelUuid, Integer>>();
         mDeviceOobData = new HashMap<String, Pair<byte[], byte[]>>();
@@ -242,12 +237,13 @@
                 mDockAddress = dockAddress;
                 return mDockAddress;
             } else {
-                log("CheckBluetoothAddress failed for car dock address:" + dockAddress);
+                Log.e(TAG, "CheckBluetoothAddress failed for car dock address: "
+                        + dockAddress);
             }
         } catch (FileNotFoundException e) {
-            log("FileNotFoundException while trying to read dock address");
+            Log.e(TAG, "FileNotFoundException while trying to read dock address");
         } catch (IOException e) {
-            log("IOException while trying to read dock address");
+            Log.e(TAG, "IOException while trying to read dock address");
         } finally {
             if (file != null) {
                 try {
@@ -274,9 +270,9 @@
             out.write(mDockPin);
             return true;
         } catch (FileNotFoundException e) {
-            log("FileNotFoundException while trying to write dock pairing pin");
+            Log.e(TAG, "FileNotFoundException while trying to write dock pairing pin");
         } catch (IOException e) {
-            log("IOException while while trying to write dock pairing pin");
+            Log.e(TAG, "IOException while while trying to write dock pairing pin");
         } finally {
             if (out != null) {
                 try {
@@ -327,6 +323,9 @@
         return mBluetoothState;
     }
 
+    int getBluetoothStateInternal() {
+        return mBluetoothState;
+    }
 
     /**
      * Bring down bluetooth and disable BT in settings. Returns true on success.
@@ -486,7 +485,7 @@
             return;
         }
 
-        if (DBG) log("Bluetooth state " + mBluetoothState + " -> " + state);
+        if (DBG) Log.d(TAG, "Bluetooth state " + mBluetoothState + " -> " + state);
 
         Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
         intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, mBluetoothState);
@@ -537,7 +536,7 @@
                 boolean running = false;
                 while ((retryCount-- > 0) && !running) {
                     mEventLoop.start();
-                    // it may take a momement for the other thread to do its
+                    // it may take a moment for the other thread to do its
                     // thing.  Check periodically for a while.
                     int pollCount = 5;
                     while ((pollCount-- > 0) && !running) {
@@ -551,7 +550,7 @@
                     }
                 }
                 if (!running) {
-                    log("bt EnableThread giving up");
+                    Log.e(TAG, "bt EnableThread giving up");
                     res = false;
                     disableNative();
                 }
@@ -635,6 +634,7 @@
             if (mAdapterUuids != null &&
                     BluetoothUuid.containsAllUuids(adapterUuids, mAdapterUuids)) {
                 setBluetoothState(BluetoothAdapter.STATE_ON);
+                autoConnect();
                 String[] propVal = {"Pairable", getProperty("Pairable")};
                 mEventLoop.onPropertyChanged(propVal);
 
@@ -730,316 +730,8 @@
         mBondState.attempt(address);
     }
 
-    /** local cache of bonding state.
-    /* we keep our own state to track the intermediate state BONDING, which
-    /* bluez does not track.
-     * All addresses must be passed in upper case.
-     */
-    public class BondState {
-        private final HashMap<String, Integer> mState = new HashMap<String, Integer>();
-        private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();
-
-        private static final String AUTO_PAIRING_BLACKLIST =
-            "/etc/bluetooth/auto_pairing.conf";
-        private static final String DYNAMIC_AUTO_PAIRING_BLACKLIST =
-            "/data/misc/bluetooth/dynamic_auto_pairing.conf";
-        private ArrayList<String>  mAutoPairingAddressBlacklist;
-        private ArrayList<String> mAutoPairingExactNameBlacklist;
-        private ArrayList<String> mAutoPairingPartialNameBlacklist;
-        private ArrayList<String> mAutoPairingFixedPinZerosKeyboardList;
-        // Addresses added to blacklist dynamically based on usage.
-        private ArrayList<String> mAutoPairingDynamicAddressBlacklist;
-
-
-        // If this is an outgoing connection, store the address.
-        // There can be only 1 pending outgoing connection at a time,
-        private String mPendingOutgoingBonding;
-
-        private synchronized void setPendingOutgoingBonding(String address) {
-            mPendingOutgoingBonding = address;
-        }
-
-        public synchronized String getPendingOutgoingBonding() {
-            return mPendingOutgoingBonding;
-        }
-
-        public synchronized void loadBondState() {
-            if (mBluetoothState != BluetoothAdapter.STATE_TURNING_ON) {
-                return;
-            }
-            String []bonds = null;
-            String val = getPropertyInternal("Devices");
-            if (val != null) {
-                bonds = val.split(",");
-            }
-            if (bonds == null) {
-                return;
-            }
-            mState.clear();
-            if (DBG) log("found " + bonds.length + " bonded devices");
-            for (String device : bonds) {
-                mState.put(getAddressFromObjectPath(device).toUpperCase(),
-                        BluetoothDevice.BOND_BONDED);
-            }
-        }
-
-        public synchronized void setBondState(String address, int state) {
-            setBondState(address, state, 0);
-        }
-
-        /** reason is ignored unless state == BOND_NOT_BONDED */
-        public synchronized void setBondState(String address, int state, int reason) {
-            int oldState = getBondState(address);
-            if (oldState == state) {
-                return;
-            }
-
-            // Check if this was an pending outgoing bonding.
-            // If yes, reset the state.
-            if (oldState == BluetoothDevice.BOND_BONDING) {
-                if (address.equals(mPendingOutgoingBonding)) {
-                    mPendingOutgoingBonding = null;
-                }
-            }
-
-            if (state == BluetoothDevice.BOND_BONDED) {
-                addProfileState(address);
-            } else if (state == BluetoothDevice.BOND_NONE) {
-                removeProfileState(address);
-            }
-
-            // HID is handled by BluetoothService, other profiles
-            // will be handled by their respective services.
-            mBluetoothInputProfileHandler.setInitialInputDevicePriority(
-                    mAdapter.getRemoteDevice(address), state);
-
-            if (DBG) log(address + " bond state " + oldState + " -> " + state + " (" +
-                         reason + ")");
-            Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-            intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, state);
-            intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
-            if (state == BluetoothDevice.BOND_NONE) {
-                if (reason <= 0) {
-                    Log.w(TAG, "setBondState() called to unbond device, but reason code is " +
-                          "invalid. Overriding reason code with BOND_RESULT_REMOVED");
-                    reason = BluetoothDevice.UNBOND_REASON_REMOVED;
-                }
-                intent.putExtra(BluetoothDevice.EXTRA_REASON, reason);
-                mState.remove(address);
-            } else {
-                mState.put(address, state);
-            }
-
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        }
-
-        public boolean isAutoPairingBlacklisted(String address) {
-            if (mAutoPairingAddressBlacklist != null) {
-                for (String blacklistAddress : mAutoPairingAddressBlacklist) {
-                    if (address.startsWith(blacklistAddress)) return true;
-                }
-            }
-
-            if (mAutoPairingDynamicAddressBlacklist != null) {
-                for (String blacklistAddress: mAutoPairingDynamicAddressBlacklist) {
-                    if (address.equals(blacklistAddress)) return true;
-                }
-            }
-            String name = getRemoteName(address);
-            if (name != null) {
-                if (mAutoPairingExactNameBlacklist != null) {
-                    for (String blacklistName : mAutoPairingExactNameBlacklist) {
-                        if (name.equals(blacklistName)) return true;
-                    }
-                }
-
-                if (mAutoPairingPartialNameBlacklist != null) {
-                    for (String blacklistName : mAutoPairingPartialNameBlacklist) {
-                        if (name.startsWith(blacklistName)) return true;
-                    }
-                }
-            }
-            return false;
-        }
-
-        public boolean isFixedPinZerosAutoPairKeyboard(String address) {
-            // Note: the meaning of blacklist is reversed in this case.
-            // If its in the list, we can go ahead and auto pair since
-            // by default keyboard should have a variable PIN that we don't
-            // auto pair using 0000.
-            if (mAutoPairingFixedPinZerosKeyboardList != null) {
-                for (String blacklistAddress : mAutoPairingFixedPinZerosKeyboardList) {
-                    if (address.startsWith(blacklistAddress)) return true;
-                }
-            }
-            return false;
-        }
-
-        public synchronized int getBondState(String address) {
-            Integer state = mState.get(address);
-            if (state == null) {
-                return BluetoothDevice.BOND_NONE;
-            }
-            return state.intValue();
-        }
-
-        /*package*/ synchronized String[] listInState(int state) {
-            ArrayList<String> result = new ArrayList<String>(mState.size());
-            for (Map.Entry<String, Integer> e : mState.entrySet()) {
-                if (e.getValue().intValue() == state) {
-                    result.add(e.getKey());
-                }
-            }
-            return result.toArray(new String[result.size()]);
-        }
-
-        public synchronized void addAutoPairingFailure(String address) {
-            if (mAutoPairingDynamicAddressBlacklist == null) {
-                mAutoPairingDynamicAddressBlacklist = new ArrayList<String>();
-            }
-
-            updateAutoPairingData(address);
-            mAutoPairingDynamicAddressBlacklist.add(address);
-        }
-
-        public synchronized boolean isAutoPairingAttemptsInProgress(String address) {
-            return getAttempt(address) != 0;
-        }
-
-        public synchronized void clearPinAttempts(String address) {
-            mPinAttempt.remove(address);
-        }
-
-        public synchronized boolean hasAutoPairingFailed(String address) {
-            if (mAutoPairingDynamicAddressBlacklist == null) return false;
-
-            return mAutoPairingDynamicAddressBlacklist.contains(address);
-        }
-
-        public synchronized int getAttempt(String address) {
-            Integer attempt = mPinAttempt.get(address);
-            if (attempt == null) {
-                return 0;
-            }
-            return attempt.intValue();
-        }
-
-        public synchronized void attempt(String address) {
-            Integer attempt = mPinAttempt.get(address);
-            int newAttempt;
-            if (attempt == null) {
-                newAttempt = 1;
-            } else {
-                newAttempt = attempt.intValue() + 1;
-            }
-            mPinAttempt.put(address, new Integer(newAttempt));
-        }
-
-        private void copyAutoPairingData() {
-            File file = null;
-            FileInputStream in = null;
-            FileOutputStream out = null;
-            try {
-                file = new File(DYNAMIC_AUTO_PAIRING_BLACKLIST);
-
-                in = new FileInputStream(AUTO_PAIRING_BLACKLIST);
-                out= new FileOutputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
-
-                byte[] buf = new byte[1024];
-                int len;
-                while ((len = in.read(buf)) > 0) {
-                    out.write(buf, 0, len);
-                }
-            } catch (FileNotFoundException e) {
-                log("FileNotFoundException: in copyAutoPairingData");
-            } catch (IOException e) {
-                log("IOException: in copyAutoPairingData");
-            } finally {
-                 try {
-                     if (in != null) in.close();
-                     if (out != null) out.close();
-                 } catch (IOException e) {}
-            }
-        }
-
-        public void readAutoPairingData() {
-            if (mAutoPairingAddressBlacklist != null) return;
-            copyAutoPairingData();
-            FileInputStream fstream = null;
-            try {
-                fstream = new FileInputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
-                DataInputStream in = new DataInputStream(fstream);
-                BufferedReader file = new BufferedReader(new InputStreamReader(in));
-                String line;
-                while((line = file.readLine()) != null) {
-                    line = line.trim();
-                    if (line.length() == 0 || line.startsWith("//")) continue;
-                    String[] value = line.split("=");
-                    if (value != null && value.length == 2) {
-                        String[] val = value[1].split(",");
-                        if (value[0].equalsIgnoreCase("AddressBlacklist")) {
-                            mAutoPairingAddressBlacklist =
-                                new ArrayList<String>(Arrays.asList(val));
-                        } else if (value[0].equalsIgnoreCase("ExactNameBlacklist")) {
-                            mAutoPairingExactNameBlacklist =
-                                new ArrayList<String>(Arrays.asList(val));
-                        } else if (value[0].equalsIgnoreCase("PartialNameBlacklist")) {
-                            mAutoPairingPartialNameBlacklist =
-                                new ArrayList<String>(Arrays.asList(val));
-                        } else if (value[0].equalsIgnoreCase("FixedPinZerosKeyboardBlacklist")) {
-                            mAutoPairingFixedPinZerosKeyboardList =
-                                new ArrayList<String>(Arrays.asList(val));
-                        } else if (value[0].equalsIgnoreCase("DynamicAddressBlacklist")) {
-                            mAutoPairingDynamicAddressBlacklist =
-                                new ArrayList<String>(Arrays.asList(val));
-                        } else {
-                            Log.e(TAG, "Error parsing Auto pairing blacklist file");
-                        }
-                    }
-                }
-            } catch (FileNotFoundException e) {
-                log("FileNotFoundException: readAutoPairingData" + e.toString());
-            } catch (IOException e) {
-                log("IOException: readAutoPairingData" + e.toString());
-            } finally {
-                if (fstream != null) {
-                    try {
-                        fstream.close();
-                    } catch (IOException e) {
-                        // Ignore
-                    }
-                }
-            }
-        }
-
-        // This function adds a bluetooth address to the auto pairing blacklist
-        // file. These addresses are added to DynamicAddressBlacklistSection
-        private void updateAutoPairingData(String address) {
-            BufferedWriter out = null;
-            try {
-                out = new BufferedWriter(new FileWriter(DYNAMIC_AUTO_PAIRING_BLACKLIST, true));
-                StringBuilder str = new StringBuilder();
-                if (mAutoPairingDynamicAddressBlacklist.size() == 0) {
-                    str.append("DynamicAddressBlacklist=");
-                }
-                str.append(address);
-                str.append(",");
-                out.write(str.toString());
-            } catch (FileNotFoundException e) {
-                log("FileNotFoundException: updateAutoPairingData" + e.toString());
-            } catch (IOException e) {
-                log("IOException: updateAutoPairingData" + e.toString());
-            } finally {
-                if (out != null) {
-                    try {
-                        out.close();
-                    } catch (IOException e) {
-                        // Ignore
-                    }
-                }
-            }
-        }
+    /*package*/ BluetoothDevice getRemoteDevice(String address) {
+        return mAdapter.getRemoteDevice(address);
     }
 
     private static String toBondStateString(int bondState) {
@@ -1055,56 +747,6 @@
         }
     }
 
-    /*package*/ synchronized boolean isAdapterPropertiesEmpty() {
-        return mAdapterProperties.isEmpty();
-    }
-
-    /*package*/synchronized void getAllProperties() {
-
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        mAdapterProperties.clear();
-
-        String properties[] = (String [])getAdapterPropertiesNative();
-        // The String Array consists of key-value pairs.
-        if (properties == null) {
-            Log.e(TAG, "*Error*: GetAdapterProperties returned NULL");
-            return;
-        }
-
-        for (int i = 0; i < properties.length; i++) {
-            String name = properties[i];
-            String newValue = null;
-            int len;
-            if (name == null) {
-                Log.e(TAG, "Error:Adapter Property at index" + i + "is null");
-                continue;
-            }
-            if (name.equals("Devices") || name.equals("UUIDs")) {
-                StringBuilder str = new StringBuilder();
-                len = Integer.valueOf(properties[++i]);
-                for (int j = 0; j < len; j++) {
-                    str.append(properties[++i]);
-                    str.append(",");
-                }
-                if (len > 0) {
-                    newValue = str.toString();
-                }
-            } else {
-                newValue = properties[++i];
-            }
-            mAdapterProperties.put(name, newValue);
-        }
-
-        // Add adapter object path property.
-        String adapterPath = getAdapterPathNative();
-        if (adapterPath != null)
-            mAdapterProperties.put("ObjectPath", adapterPath + "/dev_");
-    }
-
-    /* package */ synchronized void setProperty(String name, String value) {
-        mAdapterProperties.put(name, value);
-    }
-
     public synchronized boolean setName(String name) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
@@ -1154,8 +796,8 @@
     public synchronized boolean setScanMode(int mode, int duration) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
                                                 "Need WRITE_SECURE_SETTINGS permission");
-        boolean pairable = false;
-        boolean discoverable = false;
+        boolean pairable;
+        boolean discoverable;
 
         switch (mode) {
         case BluetoothAdapter.SCAN_MODE_NONE:
@@ -1183,14 +825,27 @@
 
     /*package*/ synchronized String getProperty(String name) {
         if (!isEnabledInternal()) return null;
-        return getPropertyInternal(name);
+        return mAdapterProperties.getProperty(name);
     }
 
-    /*package*/ synchronized String getPropertyInternal(String name) {
-        if (!mAdapterProperties.isEmpty())
-            return mAdapterProperties.get(name);
-        getAllProperties();
-        return mAdapterProperties.get(name);
+    BluetoothAdapterProperties getAdapterProperties() {
+        return mAdapterProperties;
+    }
+
+    BluetoothDeviceProperties getDeviceProperties() {
+        return mDeviceProperties;
+    }
+
+    boolean isRemoteDeviceInCache(String address) {
+        return mDeviceProperties.isInCache(address);
+    }
+
+    void setRemoteDeviceProperty(String address, String name, String value) {
+        mDeviceProperties.setProperty(address, name, value);
+    }
+
+    void updateRemoteDevicePropertiesCache(String address) {
+        mDeviceProperties.updateCache(address);
     }
 
     public synchronized String getAddress() {
@@ -1239,7 +894,7 @@
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return null;
         }
-        return getRemoteDeviceProperty(address, "Name");
+        return mDeviceProperties.getProperty(address, "Name");
     }
 
     /**
@@ -1305,7 +960,7 @@
         address = address.toUpperCase();
 
         if (mBondState.getPendingOutgoingBonding() != null) {
-            log("Ignoring createBond(): another device is bonding");
+            Log.d(TAG, "Ignoring createBond(): another device is bonding");
             // a different device is currently bonding, fail
             return false;
         }
@@ -1314,13 +969,13 @@
         // pairing exponential back-off attempts.
         if (!mBondState.isAutoPairingAttemptsInProgress(address) &&
                 mBondState.getBondState(address) != BluetoothDevice.BOND_NONE) {
-            log("Ignoring createBond(): this device is already bonding or bonded");
+            Log.d(TAG, "Ignoring createBond(): this device is already bonding or bonded");
             return false;
         }
 
         if (address.equals(mDockAddress)) {
             if (!writeDockPin()) {
-                log("Error while writing Pin for the dock");
+                Log.e(TAG, "Error while writing Pin for the dock");
                 return false;
             }
         }
@@ -1364,8 +1019,8 @@
         Pair <byte[], byte[]> value = new Pair<byte[], byte[]>(hash, randomizer);
 
         if (DBG) {
-            log("Setting out of band data for:" + address + ":" +
-              Arrays.toString(hash) + ":" + Arrays.toString(randomizer));
+            Log.d(TAG, "Setting out of band data for: " + address + ":" +
+                  Arrays.toString(hash) + ":" + Arrays.toString(randomizer));
         }
 
         mDeviceOobData.put(address, value);
@@ -1453,7 +1108,7 @@
 
     public synchronized boolean isBluetoothDock(String address) {
         SharedPreferences sp = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME,
-                mContext.MODE_PRIVATE);
+                Context.MODE_PRIVATE);
 
         return sp.contains(SHARED_PREFERENCE_DOCK_ADDRESS + address);
     }
@@ -1465,85 +1120,6 @@
         return (String [])getDevicePropertiesNative(objectPath);
     }
 
-    /*package*/ synchronized String getRemoteDeviceProperty(String address, String property) {
-        Map<String, String> properties = mDeviceProperties.get(address);
-        if (properties != null) {
-            return properties.get(property);
-        } else {
-            // Query for remote device properties, again.
-            // We will need to reload the cache when we switch Bluetooth on / off
-            // or if we crash.
-            if (updateRemoteDevicePropertiesCache(address))
-                return getRemoteDeviceProperty(address, property);
-        }
-        Log.e(TAG, "getRemoteDeviceProperty: " + property + " not present: " + address);
-        return null;
-    }
-
-    /* package */ synchronized boolean updateRemoteDevicePropertiesCache(String address) {
-        String[] propValues = getRemoteDeviceProperties(address);
-        if (propValues != null) {
-            addRemoteDeviceProperties(address, propValues);
-            return true;
-        }
-        return false;
-    }
-
-    /* package */ synchronized void addRemoteDeviceProperties(String address, String[] properties) {
-        /*
-         * We get a DeviceFound signal every time RSSI changes or name changes.
-         * Don't create a new Map object every time */
-        Map<String, String> propertyValues = mDeviceProperties.get(address);
-        if (propertyValues == null) {
-            propertyValues = new HashMap<String, String>();
-        }
-
-        for (int i = 0; i < properties.length; i++) {
-            String name = properties[i];
-            String newValue = null;
-            int len;
-            if (name == null) {
-                Log.e(TAG, "Error: Remote Device Property at index" + i + "is null");
-                continue;
-            }
-            if (name.equals("UUIDs") || name.equals("Nodes")) {
-                StringBuilder str = new StringBuilder();
-                len = Integer.valueOf(properties[++i]);
-                for (int j = 0; j < len; j++) {
-                    str.append(properties[++i]);
-                    str.append(",");
-                }
-                if (len > 0) {
-                    newValue = str.toString();
-                }
-            } else {
-                newValue = properties[++i];
-            }
-
-            propertyValues.put(name, newValue);
-        }
-        mDeviceProperties.put(address, propertyValues);
-
-        // We have added a new remote device or updated its properties.
-        // Also update the serviceChannel cache.
-        updateDeviceServiceChannelCache(address);
-    }
-
-    /* package */ void removeRemoteDeviceProperties(String address) {
-        mDeviceProperties.remove(address);
-    }
-
-    /* package */ synchronized void setRemoteDeviceProperty(String address, String name,
-                                                              String value) {
-        Map <String, String> propVal = mDeviceProperties.get(address);
-        if (propVal != null) {
-            propVal.put(name, value);
-            mDeviceProperties.put(address, propVal);
-        } else {
-            Log.e(TAG, "setRemoteDeviceProperty for a device not in cache:" + address);
-        }
-    }
-
     /**
      * Sets the remote device trust state.
      *
@@ -1558,8 +1134,8 @@
 
         if (!isEnabledInternal()) return false;
 
-        return setDevicePropertyBooleanNative(getObjectPathFromAddress(address), "Trusted",
-                value ? 1 : 0);
+        return setDevicePropertyBooleanNative(
+                getObjectPathFromAddress(address), "Trusted", value ? 1 : 0);
     }
 
     /**
@@ -1567,7 +1143,7 @@
      * Note: this value may be
      * retrieved from cache if we retrieved the data before *
      *
-     * @return boolean to indicate trust or untrust state
+     * @return boolean to indicate trusted or untrusted state
      */
     public synchronized boolean getTrustState(String address) {
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
@@ -1575,11 +1151,11 @@
             return false;
         }
 
-        String val = getRemoteDeviceProperty(address, "Trusted");
+        String val = mDeviceProperties.getProperty(address, "Trusted");
         if (val == null) {
             return false;
         } else {
-            return val.equals("true") ? true : false;
+            return val.equals("true");
         }
     }
 
@@ -1598,7 +1174,7 @@
             mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
             return BluetoothClass.ERROR;
         }
-        String val = getRemoteDeviceProperty(address, "Class");
+        String val = mDeviceProperties.getProperty(address, "Class");
         if (val == null)
             return BluetoothClass.ERROR;
         else {
@@ -1620,8 +1196,8 @@
         return getUuidFromCache(address);
     }
 
-    private ParcelUuid[] getUuidFromCache(String address) {
-        String value = getRemoteDeviceProperty(address, "UUIDs");
+    ParcelUuid[] getUuidFromCache(String address) {
+        String value = mDeviceProperties.getProperty(address, "UUIDs");
         if (value == null) return null;
 
         String[] uuidStrings = null;
@@ -1672,7 +1248,7 @@
         boolean ret;
         // Just do the SDP if the device is already  created and UUIDs are not
         // NULL, else create the device and then do SDP.
-        if (isRemoteDeviceInCache(address) && getRemoteUuids(address) != null) {
+        if (mDeviceProperties.isInCache(address) && getRemoteUuids(address) != null) {
             String path = getObjectPathFromAddress(address);
             if (path == null) return false;
 
@@ -1712,7 +1288,7 @@
         }
         // Check if we are recovering from a crash.
         if (mDeviceProperties.isEmpty()) {
-            if (!updateRemoteDevicePropertiesCache(address))
+            if (mDeviceProperties.updateCache(address) == null)
                 return -1;
         }
 
@@ -1833,13 +1409,13 @@
     }
 
     /*package*/ void updateDeviceServiceChannelCache(String address) {
-        ParcelUuid[] deviceUuids = getRemoteUuids(address);
+        if (DBG) Log.d(TAG, "updateDeviceServiceChannelCache(" + address + ")");
+
         // We are storing the rfcomm channel numbers only for the uuids
         // we are interested in.
-        int channel;
-        if (DBG) log("updateDeviceServiceChannelCache(" + address + ")");
+        ParcelUuid[] deviceUuids = getRemoteUuids(address);
 
-        ArrayList<ParcelUuid> applicationUuids = new ArrayList();
+        ArrayList<ParcelUuid> applicationUuids = new ArrayList<ParcelUuid>();
 
         synchronized (this) {
             for (RemoteService service : mUuidCallbackTracker.keySet()) {
@@ -1849,24 +1425,22 @@
             }
         }
 
-        Map <ParcelUuid, Integer> value = new HashMap<ParcelUuid, Integer>();
+        Map <ParcelUuid, Integer> uuidToChannelMap = new HashMap<ParcelUuid, Integer>();
 
         // Retrieve RFCOMM channel for default uuids
         for (ParcelUuid uuid : RFCOMM_UUIDS) {
             if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
-                channel = getDeviceServiceChannelNative(getObjectPathFromAddress(address),
-                        uuid.toString(), 0x0004);
-                if (DBG) log("\tuuid(system): " + uuid + " " + channel);
-                value.put(uuid, channel);
+                int channel = getDeviceServiceChannelForUuid(address, uuid);
+                uuidToChannelMap.put(uuid, channel);
+                if (DBG) Log.d(TAG, "\tuuid(system): " + uuid + " " + channel);
             }
         }
         // Retrieve RFCOMM channel for application requested uuids
         for (ParcelUuid uuid : applicationUuids) {
             if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
-                channel = getDeviceServiceChannelNative(getObjectPathFromAddress(address),
-                        uuid.toString(), 0x0004);
-                if (DBG) log("\tuuid(application): " + uuid + " " + channel);
-                value.put(uuid, channel);
+                int channel = getDeviceServiceChannelForUuid(address, uuid);
+                uuidToChannelMap.put(uuid, channel);
+                if (DBG) Log.d(TAG, "\tuuid(application): " + uuid + " " + channel);
             }
         }
 
@@ -1876,13 +1450,11 @@
                     iter.hasNext();) {
                 RemoteService service = iter.next();
                 if (service.address.equals(address)) {
-                    channel = -1;
-                    if (value.get(service.uuid) != null) {
-                        channel = value.get(service.uuid);
-                    }
-                    if (channel != -1) {
-                        if (DBG) log("Making callback for " + service.uuid + " with result " +
-                                channel);
+                    if (uuidToChannelMap.containsKey(service.uuid)) {
+                        int channel = uuidToChannelMap.get(service.uuid);
+
+                        if (DBG) Log.d(TAG, "Making callback for " + service.uuid +
+                                    " with result " + channel);
                         IBluetoothCallback callback = mUuidCallbackTracker.get(service);
                         if (callback != null) {
                             try {
@@ -1896,10 +1468,16 @@
             }
 
             // Update cache
-            mDeviceServiceChannelCache.put(address, value);
+            mDeviceServiceChannelCache.put(address, uuidToChannelMap);
         }
     }
 
+    private int getDeviceServiceChannelForUuid(String address,
+            ParcelUuid uuid) {
+        return getDeviceServiceChannelNative(getObjectPathFromAddress(address),
+                uuid.toString(), 0x0004);
+    }
+
     /**
      * b is a handle to a Binder instance, so that this service can be notified
      * for Applications that terminate unexpectedly, to clean there service
@@ -1921,7 +1499,7 @@
         int handle = addRfcommServiceRecordNative(serviceName,
                 uuid.getUuid().getMostSignificantBits(), uuid.getUuid().getLeastSignificantBits(),
                 (short)channel);
-        if (DBG) log("new handle " + Integer.toHexString(handle));
+        if (DBG) Log.d(TAG, "new handle " + Integer.toHexString(handle));
         if (handle == -1) {
             return -1;
         }
@@ -1944,8 +1522,8 @@
         Integer handleInt = new Integer(handle);
         Integer owner = mServiceRecordToPid.get(handleInt);
         if (owner != null && pid == owner.intValue()) {
-            if (DBG) log("Removing service record " + Integer.toHexString(handle) + " for pid " +
-                    pid);
+            if (DBG) Log.d(TAG, "Removing service record " +
+                Integer.toHexString(handle) + " for pid " + pid);
             mServiceRecordToPid.remove(handleInt);
             removeServiceRecordNative(handle);
         }
@@ -1960,7 +1538,7 @@
         }
         public void binderDied() {
             synchronized (BluetoothService.this) {
-                if (DBG) log("Tracked app " + pid + " died");
+                if (DBG) Log.d(TAG, "Tracked app " + pid + " died");
                 checkAndRemoveRecord(handle, pid);
             }
         }
@@ -2033,10 +1611,7 @@
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         intent.putExtra(BluetoothDevice.EXTRA_UUID, uuid);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-
-        if (mUuidIntentTracker.contains(address))
-            mUuidIntentTracker.remove(address);
-
+        mUuidIntentTracker.remove(address);
     }
 
     /*package*/ synchronized void makeServiceChannelCallbacks(String address) {
@@ -2044,8 +1619,8 @@
                 iter.hasNext();) {
             RemoteService service = iter.next();
             if (service.address.equals(address)) {
-                if (DBG) log("Cleaning up failed UUID channel lookup: " + service.address +
-                        " " + service.uuid);
+                if (DBG) Log.d(TAG, "Cleaning up failed UUID channel lookup: "
+                    + service.address + " " + service.uuid);
                 IBluetoothCallback callback = mUuidCallbackTracker.get(service);
                 if (callback != null) {
                     try {
@@ -2060,18 +1635,9 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        switch(mBluetoothState) {
-        case BluetoothAdapter.STATE_OFF:
-            pw.println("Bluetooth OFF\n");
+        dumpBluetoothState(pw);
+        if (mBluetoothState != BluetoothAdapter.STATE_ON) {
             return;
-        case BluetoothAdapter.STATE_TURNING_ON:
-            pw.println("Bluetooth TURNING ON\n");
-            return;
-        case BluetoothAdapter.STATE_TURNING_OFF:
-            pw.println("Bluetooth TURNING OFF\n");
-            return;
-        case BluetoothAdapter.STATE_ON:
-            pw.println("Bluetooth ON\n");
         }
 
         pw.println("mIsAirplaneSensitive = " + mIsAirplaneSensitive);
@@ -2088,58 +1654,15 @@
         mAdapter.getProfileProxy(mContext,
                 mBluetoothProfileServiceListener, BluetoothProfile.PAN);
 
-        pw.println("\n--Known devices--");
-        for (String address : mDeviceProperties.keySet()) {
-            int bondState = mBondState.getBondState(address);
-            pw.printf("%s %10s (%d) %s\n", address,
-                       toBondStateString(bondState),
-                       mBondState.getAttempt(address),
-                       getRemoteName(address));
-
-            Map<ParcelUuid, Integer> uuidChannels = mDeviceServiceChannelCache.get(address);
-            if (uuidChannels == null) {
-                pw.println("\tuuids = null");
-            } else {
-                for (ParcelUuid uuid : uuidChannels.keySet()) {
-                    Integer channel = uuidChannels.get(uuid);
-                    if (channel == null) {
-                        pw.println("\t" + uuid);
-                    } else {
-                        pw.println("\t" + uuid + " RFCOMM channel = " + channel);
-                    }
-                }
-            }
-            for (RemoteService service : mUuidCallbackTracker.keySet()) {
-                if (service.address.equals(address)) {
-                    pw.println("\tPENDING CALLBACK: " + service.uuid);
-                }
-            }
-        }
-
-        String value = getProperty("Devices");
-        String[] devicesObjectPath = null;
-        if (value != null) {
-            devicesObjectPath = value.split(",");
-        }
-        pw.println("\n--ACL connected devices--");
-        if (devicesObjectPath != null) {
-            for (String device : devicesObjectPath) {
-                pw.println(getAddressFromObjectPath(device));
-            }
-        }
-
-        dumpHeadsetProfile(pw);
+        dumpKnownDevices(pw);
+        dumpAclConnectedDevices(pw);
+        dumpHeadsetService(pw);
         dumpInputDeviceProfile(pw);
         dumpPanProfile(pw);
-
-        pw.println("\n--Application Service Records--");
-        for (Integer handle : mServiceRecordToPid.keySet()) {
-            Integer pid = mServiceRecordToPid.get(handle);
-            pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
-        }
+        dumpApplicationServiceRecords(pw);
     }
 
-    private void dumpHeadsetProfile(PrintWriter pw) {
+    private void dumpHeadsetService(PrintWriter pw) {
         pw.println("\n--Headset Service--");
         if (mBluetoothHeadset != null) {
             List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
@@ -2147,22 +1670,8 @@
                 pw.println("No headsets connected");
             } else {
                 BluetoothDevice device = deviceList.get(0);
-                pw.println("getConnectedDevices[0] = " + device);
-
-                switch (mBluetoothHeadset.getConnectionState(device)) {
-                    case BluetoothHeadset.STATE_CONNECTING:
-                        pw.println("getConnectionState() = STATE_CONNECTING");
-                        break;
-                    case BluetoothHeadset.STATE_CONNECTED:
-                        pw.println("getConnectionState() = STATE_CONNECTED");
-                        break;
-                    case BluetoothHeadset.STATE_DISCONNECTING:
-                        pw.println("getConnectionState() = STATE_DISCONNECTING");
-                        break;
-                    case BluetoothHeadset.STATE_AUDIO_CONNECTED:
-                        pw.println("getConnectionState() = STATE_AUDIO_CONNECTED");
-                        break;
-                }
+                pw.println("\ngetConnectedDevices[0] = " + device);
+                dumpHeadsetConnectionState(pw, device);
                 pw.println("getBatteryUsageHint() = " +
                              mBluetoothHeadset.getBatteryUsageHint(device));
             }
@@ -2248,9 +1757,94 @@
                 pw.println(device);
             }
         }
+    }
+
+    private void dumpHeadsetConnectionState(PrintWriter pw,
+            BluetoothDevice device) {
+        switch (mBluetoothHeadset.getConnectionState(device)) {
+            case BluetoothHeadset.STATE_CONNECTING:
+                pw.println("getConnectionState() = STATE_CONNECTING");
+                break;
+            case BluetoothHeadset.STATE_CONNECTED:
+                pw.println("getConnectionState() = STATE_CONNECTED");
+                break;
+            case BluetoothHeadset.STATE_DISCONNECTING:
+                pw.println("getConnectionState() = STATE_DISCONNECTING");
+                break;
+            case BluetoothHeadset.STATE_AUDIO_CONNECTED:
+                pw.println("getConnectionState() = STATE_AUDIO_CONNECTED");
+                break;
+        }
+    }
+
+    private void dumpApplicationServiceRecords(PrintWriter pw) {
+        pw.println("\n--Application Service Records--");
+        for (Integer handle : mServiceRecordToPid.keySet()) {
+            Integer pid = mServiceRecordToPid.get(handle);
+            pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
+        }
         mAdapter.closeProfileProxy(BluetoothProfile.PAN, mBluetoothHeadset);
     }
 
+    private void dumpAclConnectedDevices(PrintWriter pw) {
+        String[] devicesObjectPath = getKnownDevices();
+        pw.println("\n--ACL connected devices--");
+        if (devicesObjectPath != null) {
+            for (String device : devicesObjectPath) {
+                pw.println(getAddressFromObjectPath(device));
+            }
+        }
+    }
+
+    private void dumpKnownDevices(PrintWriter pw) {
+        pw.println("\n--Known devices--");
+        for (String address : mDeviceProperties.keySet()) {
+            int bondState = mBondState.getBondState(address);
+            pw.printf("%s %10s (%d) %s\n", address,
+                       toBondStateString(bondState),
+                       mBondState.getAttempt(address),
+                       getRemoteName(address));
+
+            Map<ParcelUuid, Integer> uuidChannels = mDeviceServiceChannelCache.get(address);
+            if (uuidChannels == null) {
+                pw.println("\tuuids = null");
+            } else {
+                for (ParcelUuid uuid : uuidChannels.keySet()) {
+                    Integer channel = uuidChannels.get(uuid);
+                    if (channel == null) {
+                        pw.println("\t" + uuid);
+                    } else {
+                        pw.println("\t" + uuid + " RFCOMM channel = " + channel);
+                    }
+                }
+            }
+            for (RemoteService service : mUuidCallbackTracker.keySet()) {
+                if (service.address.equals(address)) {
+                    pw.println("\tPENDING CALLBACK: " + service.uuid);
+                }
+            }
+        }
+    }
+
+    private void dumpBluetoothState(PrintWriter pw) {
+        switch(mBluetoothState) {
+        case BluetoothAdapter.STATE_OFF:
+            pw.println("Bluetooth OFF\n");
+            break;
+        case BluetoothAdapter.STATE_TURNING_ON:
+            pw.println("Bluetooth TURNING ON\n");
+            break;
+        case BluetoothAdapter.STATE_TURNING_OFF:
+            pw.println("Bluetooth TURNING OFF\n");
+            break;
+        case BluetoothAdapter.STATE_ON:
+            pw.println("Bluetooth ON\n");
+            break;
+        default:
+            pw.println("Bluetooth UNKNOWN STATE " + mBluetoothState);
+        }
+    }
+
     private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
         new BluetoothProfile.ServiceListener() {
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
@@ -2295,7 +1889,7 @@
     }
 
     /*package*/ String getAddressFromObjectPath(String objectPath) {
-        String adapterObjectPath = getPropertyInternal("ObjectPath");
+        String adapterObjectPath = mAdapterProperties.getObjectPath();
         if (adapterObjectPath == null || objectPath == null) {
             Log.e(TAG, "getAddressFromObjectPath: AdapterObjectPath:" + adapterObjectPath +
                     "  or deviceObjectPath:" + objectPath + " is null");
@@ -2315,7 +1909,7 @@
     }
 
     /*package*/ String getObjectPathFromAddress(String address) {
-        String path = getPropertyInternal("ObjectPath");
+        String path = mAdapterProperties.getObjectPath();
         if (path == null) {
             Log.e(TAG, "Error: Object Path is null");
             return null;
@@ -2328,7 +1922,7 @@
         String path = getObjectPathFromAddress(address);
         boolean result = setLinkTimeoutNative(path, num_slots);
 
-        if (!result) log("Set Link Timeout to:" + num_slots + " slots failed");
+        if (!result) Log.d(TAG, "Set Link Timeout to " + num_slots + " slots failed");
     }
 
     /**** Handlers for PAN  Profile ****/
@@ -2448,10 +2042,6 @@
         mBluetoothInputProfileHandler.handleInputDevicePropertyChange(address, connected);
     }
 
-    /*package*/ boolean isRemoteDeviceInCache(String address) {
-        return (mDeviceProperties.get(address) != null);
-    }
-
     public boolean connectHeadset(String address) {
         if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
 
@@ -2508,7 +2098,7 @@
         return false;
     }
 
-    private BluetoothDeviceProfileState addProfileState(String address) {
+    BluetoothDeviceProfileState addProfileState(String address) {
         BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
         if (state != null) return state;
 
@@ -2518,26 +2108,47 @@
         return state;
     }
 
-    private void removeProfileState(String address) {
+    void removeProfileState(String address) {
         mDeviceProfileState.remove(address);
     }
 
+    synchronized String[] getKnownDevices() {
+        String[] bonds = null;
+        String val = getProperty("Devices");
+        if (val != null) {
+            bonds = val.split(",");
+        }
+        return bonds;
+    }
+
     private void initProfileState() {
-        String []bonds = null;
-        String val = getPropertyInternal("Devices");
+        String[] bonds = null;
+        String val = mAdapterProperties.getProperty("Devices");
         if (val != null) {
             bonds = val.split(",");
         }
         if (bonds == null) {
             return;
         }
-
         for (String path : bonds) {
             String address = getAddressFromObjectPath(path);
             BluetoothDeviceProfileState state = addProfileState(address);
-            Message msg = new Message();
-            msg.what = BluetoothDeviceProfileState.AUTO_CONNECT_PROFILES;
-            state.sendMessage(msg);
+        }
+    }
+
+    private void autoConnect() {
+        String[] bonds = getKnownDevices();
+        if (bonds == null) {
+            return;
+        }
+        for (String path : bonds) {
+            String address = getAddressFromObjectPath(path);
+            BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
+            if (state != null) {
+                Message msg = new Message();
+                msg.what = BluetoothDeviceProfileState.AUTO_CONNECT_PROFILES;
+                state.sendMessage(msg);
+            }
         }
     }
 
@@ -2585,78 +2196,91 @@
 
     public synchronized void sendConnectionStateChange(BluetoothDevice device, int state,
                                                         int prevState) {
-        if (updateCountersAndCheckForConnectionStateChange(device, state, prevState)) {
-            state = translateToAdapterConnectionState(state);
-            prevState = translateToAdapterConnectionState(prevState);
+        // Since this is a binder call check if Bluetooth is on still
+        if (mBluetoothState == BluetoothAdapter.STATE_OFF) return;
+
+        if (updateCountersAndCheckForConnectionStateChange(state, prevState)) {
+            if (!validateProfileConnectionState(state) ||
+                    !validateProfileConnectionState(prevState)) {
+                // Previously, an invalid state was broadcast anyway,
+                // with the invalid state converted to -1 in the intent.
+                // Better to log an error and not send an intent with
+                // invalid contents or set mAdapterConnectionState to -1.
+                Log.e(TAG, "Error in sendConnectionStateChange: "
+                        + "prevState " + prevState + " state " + state);
+                return;
+            }
 
             mAdapterConnectionState = state;
 
             Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
             intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-            intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, state);
-            intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, prevState);
+            intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
+                    convertToAdapterState(state));
+            intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE,
+                    convertToAdapterState(prevState));
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-            log("CONNECTION_STATE_CHANGE: " + device + ": " + prevState + "-> " + state);
+            Log.d(TAG, "CONNECTION_STATE_CHANGE: " + device + ": "
+                    + prevState + " -> " + state);
         }
     }
 
-    private int translateToAdapterConnectionState(int state) {
+    private boolean validateProfileConnectionState(int state) {
+        return (state == BluetoothProfile.STATE_DISCONNECTED ||
+                state == BluetoothProfile.STATE_CONNECTING ||
+                state == BluetoothProfile.STATE_CONNECTED ||
+                state == BluetoothProfile.STATE_DISCONNECTING);
+    }
+
+    private int convertToAdapterState(int state) {
         switch (state) {
+            case BluetoothProfile.STATE_DISCONNECTED:
+                return BluetoothAdapter.STATE_DISCONNECTED;
+            case BluetoothProfile.STATE_DISCONNECTING:
+                return BluetoothAdapter.STATE_DISCONNECTING;
+            case BluetoothProfile.STATE_CONNECTED:
+                return BluetoothAdapter.STATE_CONNECTED;
             case BluetoothProfile.STATE_CONNECTING:
                 return BluetoothAdapter.STATE_CONNECTING;
-            case BluetoothProfile.STATE_CONNECTED:
-              return BluetoothAdapter.STATE_CONNECTED;
-            case BluetoothProfile.STATE_DISCONNECTING:
-              return BluetoothAdapter.STATE_DISCONNECTING;
-            case BluetoothProfile.STATE_DISCONNECTED:
-              return BluetoothAdapter.STATE_DISCONNECTED;
-            default:
-              Log.e(TAG, "Error in getAdapterConnectionState");
-              return -1;
         }
+        Log.e(TAG, "Error in convertToAdapterState");
+        return -1;
     }
 
-    private boolean updateCountersAndCheckForConnectionStateChange(BluetoothDevice device,
-                                                                   int state,
-                                                                   int prevState) {
+    private boolean updateCountersAndCheckForConnectionStateChange(int state, int prevState) {
+        switch (prevState) {
+            case BluetoothProfile.STATE_CONNECTING:
+                mProfilesConnecting--;
+                break;
+
+            case BluetoothProfile.STATE_CONNECTED:
+                mProfilesConnected--;
+                break;
+
+            case BluetoothProfile.STATE_DISCONNECTING:
+                mProfilesDisconnecting--;
+                break;
+        }
+
         switch (state) {
             case BluetoothProfile.STATE_CONNECTING:
                 mProfilesConnecting++;
-                if (prevState == BluetoothAdapter.STATE_DISCONNECTING) mProfilesDisconnecting--;
-                if (mProfilesConnected > 0 || mProfilesConnecting > 1) return false;
+                return (mProfilesConnected == 0 && mProfilesConnecting == 1);
 
-                break;
             case BluetoothProfile.STATE_CONNECTED:
-                if (prevState == BluetoothAdapter.STATE_CONNECTING) mProfilesConnecting--;
-                if (prevState == BluetoothAdapter.STATE_DISCONNECTING) mProfilesDisconnecting--;
-
                 mProfilesConnected++;
+                return (mProfilesConnected == 1);
 
-                if (mProfilesConnected > 1) return false;
-                break;
             case BluetoothProfile.STATE_DISCONNECTING:
                 mProfilesDisconnecting++;
-                mProfilesConnected--;
+                return (mProfilesConnected == 0 && mProfilesDisconnecting == 1);
 
-                if (mProfilesConnected > 0 || mProfilesDisconnecting > 1) return false;
-
-                break;
             case BluetoothProfile.STATE_DISCONNECTED:
-                if (prevState == BluetoothAdapter.STATE_CONNECTING) mProfilesConnecting--;
-                if (prevState == BluetoothAdapter.STATE_DISCONNECTING) mProfilesDisconnecting--;
+                return (mProfilesConnected == 0 && mProfilesConnecting == 0);
 
-                if (prevState == BluetoothAdapter.STATE_CONNECTED) {
-                    mProfilesConnected--;
-                }
-
-                if (mProfilesConnected  > 0 || mProfilesConnecting > 0) return false;
-                break;
+            default:
+                return true;
         }
-        return true;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
     }
 
     private native static void classInitNative();
@@ -2664,13 +2288,13 @@
     private native boolean setupNativeDataNative();
     private native boolean tearDownNativeDataNative();
     private native void cleanupNativeDataNative();
-    private native String getAdapterPathNative();
+    /*package*/ native String getAdapterPathNative();
 
     private native int isEnabledNative();
     private native int enableNative();
     private native int disableNative();
 
-    private native Object[] getAdapterPropertiesNative();
+    /*package*/ native Object[] getAdapterPropertiesNative();
     private native Object[] getDevicePropertiesNative(String objectPath);
     private native boolean setAdapterPropertyStringNative(String key, String value);
     private native boolean setAdapterPropertyIntegerNative(String key, int value);
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 17b5dd7..218ee4f 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -154,6 +154,11 @@
     private float mBottomSlopEdge;
     private boolean mSloppyGesture;
 
+    // Pointer IDs currently responsible for the two fingers controlling the gesture
+    private int mActiveId0;
+    private int mActiveId1;
+    private boolean mActive0MostRecent;
+
     public ScaleGestureDetector(Context context, OnScaleGestureListener listener) {
         ViewConfiguration config = ViewConfiguration.get(context);
         mContext = context;
@@ -162,11 +167,21 @@
     }
 
     public boolean onTouchEvent(MotionEvent event) {
-        final int action = event.getAction();
+        final int action = event.getActionMasked();
         boolean handled = true;
 
         if (!mGestureInProgress) {
-            switch (action & MotionEvent.ACTION_MASK) {
+            switch (action) {
+            case MotionEvent.ACTION_DOWN: {
+                mActiveId0 = event.getPointerId(0);
+                mActive0MostRecent = true;
+            }
+            break;
+
+            case MotionEvent.ACTION_UP:
+                reset();
+                break;
+
             case MotionEvent.ACTION_POINTER_DOWN: {
                 // We have a new multi-finger gesture
 
@@ -175,12 +190,15 @@
                 mRightSlopEdge = metrics.widthPixels - mEdgeSlop;
                 mBottomSlopEdge = metrics.heightPixels - mEdgeSlop;
 
-                // Be paranoid in case we missed an event
-                reset();
-
+                if (mPrevEvent != null) mPrevEvent.recycle();
                 mPrevEvent = MotionEvent.obtain(event);
                 mTimeDelta = 0;
 
+                int index1 = event.getActionIndex();
+                int index0 = event.findPointerIndex(mActiveId0);
+                mActiveId1 = event.getPointerId(index1);
+                mActive0MostRecent = false;
+
                 setContext(event);
 
                 // Check if we have a sloppy gesture. If so, delay
@@ -190,10 +208,10 @@
                 final float edgeSlop = mEdgeSlop;
                 final float rightSlop = mRightSlopEdge;
                 final float bottomSlop = mBottomSlopEdge;
-                final float x0 = event.getRawX();
-                final float y0 = event.getRawY();
-                final float x1 = getRawX(event, 1);
-                final float y1 = getRawY(event, 1);
+                float x0 = getRawX(event, index0);
+                float y0 = getRawY(event, index0);
+                float x1 = getRawX(event, index1);
+                float y1 = getRawY(event, index1);
 
                 boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop
                         || x0 > rightSlop || y0 > bottomSlop;
@@ -205,14 +223,15 @@
                     mFocusY = -1;
                     mSloppyGesture = true;
                 } else if (p0sloppy) {
-                    mFocusX = event.getX(1);
-                    mFocusY = event.getY(1);
+                    mFocusX = event.getX(index1);
+                    mFocusY = event.getY(index1);
                     mSloppyGesture = true;
                 } else if (p1sloppy) {
-                    mFocusX = event.getX(0);
-                    mFocusY = event.getY(0);
+                    mFocusX = event.getX(index0);
+                    mFocusY = event.getY(index0);
                     mSloppyGesture = true;
                 } else {
+                    mSloppyGesture = false;
                     mGestureInProgress = mListener.onScaleBegin(this);
                 }
             }
@@ -224,25 +243,51 @@
                     final float edgeSlop = mEdgeSlop;
                     final float rightSlop = mRightSlopEdge;
                     final float bottomSlop = mBottomSlopEdge;
-                    final float x0 = event.getRawX();
-                    final float y0 = event.getRawY();
-                    final float x1 = getRawX(event, 1);
-                    final float y1 = getRawY(event, 1);
+                    int index0 = event.findPointerIndex(mActiveId0);
+                    int index1 = event.findPointerIndex(mActiveId1);
+                    float x0 = getRawX(event, index0);
+                    float y0 = getRawY(event, index0);
+                    float x1 = getRawX(event, index1);
+                    float y1 = getRawY(event, index1);
 
                     boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop
-                    || x0 > rightSlop || y0 > bottomSlop;
+                            || x0 > rightSlop || y0 > bottomSlop;
                     boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop
-                    || x1 > rightSlop || y1 > bottomSlop;
+                            || x1 > rightSlop || y1 > bottomSlop;
+
+                    if (p0sloppy) {
+                        // Do we have a different pointer that isn't sloppy?
+                        int index = findNewActiveIndex(event, mActiveId1, index0);
+                        if (index >= 0) {
+                            index0 = index;
+                            mActiveId0 = event.getPointerId(index);
+                            x0 = getRawX(event, index);
+                            y0 = getRawY(event, index);
+                            p0sloppy = false;
+                        }
+                    }
+
+                    if (p1sloppy) {
+                        // Do we have a different pointer that isn't sloppy?
+                        int index = findNewActiveIndex(event, mActiveId0, index1);
+                        if (index >= 0) {
+                            index1 = index;
+                            mActiveId1 = event.getPointerId(index);
+                            x1 = getRawX(event, index);
+                            y1 = getRawY(event, index);
+                            p1sloppy = false;
+                        }
+                    }
 
                     if(p0sloppy && p1sloppy) {
                         mFocusX = -1;
                         mFocusY = -1;
                     } else if (p0sloppy) {
-                        mFocusX = event.getX(1);
-                        mFocusY = event.getY(1);
+                        mFocusX = event.getX(index1);
+                        mFocusY = event.getY(index1);
                     } else if (p1sloppy) {
-                        mFocusX = event.getX(0);
-                        mFocusY = event.getY(0);
+                        mFocusX = event.getX(index0);
+                        mFocusY = event.getY(index0);
                     } else {
                         mSloppyGesture = false;
                         mGestureInProgress = mListener.onScaleBegin(this);
@@ -252,43 +297,109 @@
 
             case MotionEvent.ACTION_POINTER_UP:
                 if (mSloppyGesture) {
-                    // Set focus point to the remaining finger
-                    int id = (((action & MotionEvent.ACTION_POINTER_INDEX_MASK)
-                            >> MotionEvent.ACTION_POINTER_INDEX_SHIFT) == 0) ? 1 : 0;
-                    mFocusX = event.getX(id);
-                    mFocusY = event.getY(id);
+                    final int pointerCount = event.getPointerCount();
+                    final int actionIndex = event.getActionIndex();
+                    final int actionId = event.getPointerId(actionIndex);
+
+                    if (pointerCount > 2) {
+                        if (actionId == mActiveId0) {
+                            final int newIndex = findNewActiveIndex(event, mActiveId1, actionIndex);
+                            if (newIndex >= 0) mActiveId0 = event.getPointerId(newIndex);
+                        } else if (actionId == mActiveId1) {
+                            final int newIndex = findNewActiveIndex(event, mActiveId0, actionIndex);
+                            if (newIndex >= 0) mActiveId1 = event.getPointerId(newIndex);
+                        }
+                    } else {
+                        // Set focus point to the remaining finger
+                        final int index = event.findPointerIndex(actionId == mActiveId0 ?
+                                mActiveId1 : mActiveId0);
+                        mActiveId0 = event.getPointerId(index);
+                        mActive0MostRecent = true;
+                        mActiveId1 = -1;
+                        mFocusX = event.getX(index);
+                        mFocusY = event.getY(index);
+                    }
                 }
                 break;
             }
         } else {
             // Transform gesture in progress - attempt to handle it
-            switch (action & MotionEvent.ACTION_MASK) {
-                case MotionEvent.ACTION_POINTER_UP:
-                    // Gesture ended
+            switch (action) {
+                case MotionEvent.ACTION_POINTER_DOWN: {
+                    // End the old gesture and begin a new one with the most recent two fingers.
+                    mListener.onScaleEnd(this);
+                    final int oldActive0 = mActiveId0;
+                    final int oldActive1 = mActiveId1;
+                    reset();
+
+                    mPrevEvent = MotionEvent.obtain(event);
+                    mActiveId0 = mActive0MostRecent ? oldActive0 : oldActive1;
+                    mActiveId1 = event.getPointerId(event.getActionIndex());
+                    mActive0MostRecent = false;
+
                     setContext(event);
 
-                    // Set focus point to the remaining finger
-                    int id = (((action & MotionEvent.ACTION_POINTER_INDEX_MASK)
-                            >> MotionEvent.ACTION_POINTER_INDEX_SHIFT) == 0) ? 1 : 0;
-                    mFocusX = event.getX(id);
-                    mFocusY = event.getY(id);
+                    mGestureInProgress = mListener.onScaleBegin(this);
+                }
+                break;
 
-                    if (!mSloppyGesture) {
-                        mListener.onScaleEnd(this);
+                case MotionEvent.ACTION_POINTER_UP: {
+                    final int pointerCount = event.getPointerCount();
+                    final int actionIndex = event.getActionIndex();
+                    final int actionId = event.getPointerId(actionIndex);
+
+                    boolean gestureEnded = false;
+                    if (pointerCount > 2) {
+                        if (actionId == mActiveId0) {
+                            final int newIndex = findNewActiveIndex(event, mActiveId1, actionIndex);
+                            if (newIndex >= 0) {
+                                mActiveId0 = event.getPointerId(newIndex);
+                            } else {
+                                gestureEnded = true;
+                            }
+                        } else if (actionId == mActiveId1) {
+                            final int newIndex = findNewActiveIndex(event, mActiveId0, actionIndex);
+                            if (newIndex >= 0) {
+                                mActiveId1 = event.getPointerId(newIndex);
+                            } else {
+                                gestureEnded = true;
+                            }
+                        }
+                        mPrevEvent.recycle();
+                        mPrevEvent = MotionEvent.obtain(event);
+                        setContext(event);
+                    } else {
+                        gestureEnded = true;
                     }
 
-                    reset();
-                    break;
+                    if (gestureEnded) {
+                        // Gesture ended
+                        setContext(event);
+
+                        // Set focus point to the remaining finger
+                        final int activeId = actionId == mActiveId0 ? mActiveId1 : mActiveId0;
+                        final int index = event.findPointerIndex(activeId);
+                        mFocusX = event.getX(index);
+                        mFocusY = event.getY(index);
+
+                        mListener.onScaleEnd(this);
+                        reset();
+                        mActiveId0 = activeId;
+                        mActive0MostRecent = true;
+                    }
+                }
+                break;
 
                 case MotionEvent.ACTION_CANCEL:
-                    if (!mSloppyGesture) {
-                        mListener.onScaleEnd(this);
-                    }
-
+                    mListener.onScaleEnd(this);
                     reset();
                     break;
 
-                case MotionEvent.ACTION_MOVE:
+                case MotionEvent.ACTION_UP:
+                    reset();
+                    break;
+
+                case MotionEvent.ACTION_MOVE: {
                     setContext(event);
 
                     // Only accept the event if our relative pressure is within
@@ -302,16 +413,43 @@
                             mPrevEvent = MotionEvent.obtain(event);
                         }
                     }
-                    break;
+                }
+                break;
             }
         }
         return handled;
     }
 
+    private int findNewActiveIndex(MotionEvent ev, int otherActiveId, int oldIndex) {
+        final int pointerCount = ev.getPointerCount();
+
+        // It's ok if this isn't found and returns -1, it simply won't match.
+        final int otherActiveIndex = ev.findPointerIndex(otherActiveId);
+        int newActiveIndex = -1;
+
+        // Pick a new id and update tracking state. Only pick pointers not on the slop edges.
+        for (int i = 0; i < pointerCount; i++) {
+            if (i != oldIndex && i != otherActiveIndex) {
+                final float edgeSlop = mEdgeSlop;
+                final float rightSlop = mRightSlopEdge;
+                final float bottomSlop = mBottomSlopEdge;
+                float x = getRawX(ev, i);
+                float y = getRawY(ev, i);
+                if (x >= edgeSlop && y >= edgeSlop && x <= rightSlop && y <= bottomSlop) {
+                    newActiveIndex = i;
+                    break;
+                }
+            }
+        }
+
+        return newActiveIndex;
+    }
+
     /**
      * MotionEvent has no getRawX(int) method; simulate it pending future API approval.
      */
     private static float getRawX(MotionEvent event, int pointerIndex) {
+        if (pointerIndex == 0) return event.getRawX();
         float offset = event.getRawX() - event.getX();
         return event.getX(pointerIndex) + offset;
     }
@@ -320,6 +458,7 @@
      * MotionEvent has no getRawY(int) method; simulate it pending future API approval.
      */
     private static float getRawY(MotionEvent event, int pointerIndex) {
+        if (pointerIndex == 0) return event.getRawY();
         float offset = event.getRawY() - event.getY();
         return event.getY(pointerIndex) + offset;
     }
@@ -336,14 +475,19 @@
 
         final MotionEvent prev = mPrevEvent;
 
-        final float px0 = prev.getX(0);
-        final float py0 = prev.getY(0);
-        final float px1 = prev.getX(1);
-        final float py1 = prev.getY(1);
-        final float cx0 = curr.getX(0);
-        final float cy0 = curr.getY(0);
-        final float cx1 = curr.getX(1);
-        final float cy1 = curr.getY(1);
+        final int prevIndex0 = prev.findPointerIndex(mActiveId0);
+        final int prevIndex1 = prev.findPointerIndex(mActiveId1);
+        final int currIndex0 = curr.findPointerIndex(mActiveId0);
+        final int currIndex1 = curr.findPointerIndex(mActiveId1);
+
+        final float px0 = prev.getX(prevIndex0);
+        final float py0 = prev.getY(prevIndex0);
+        final float px1 = prev.getX(prevIndex1);
+        final float py1 = prev.getY(prevIndex1);
+        final float cx0 = curr.getX(currIndex0);
+        final float cy0 = curr.getY(currIndex0);
+        final float cx1 = curr.getX(currIndex1);
+        final float cy1 = curr.getY(currIndex1);
 
         final float pvx = px1 - px0;
         final float pvy = py1 - py0;
@@ -357,8 +501,8 @@
         mFocusX = cx0 + cvx * 0.5f;
         mFocusY = cy0 + cvy * 0.5f;
         mTimeDelta = curr.getEventTime() - prev.getEventTime();
-        mCurrPressure = curr.getPressure(0) + curr.getPressure(1);
-        mPrevPressure = prev.getPressure(0) + prev.getPressure(1);
+        mCurrPressure = curr.getPressure(currIndex0) + curr.getPressure(currIndex1);
+        mPrevPressure = prev.getPressure(prevIndex0) + prev.getPressure(prevIndex1);
     }
 
     private void reset() {
@@ -372,6 +516,8 @@
         }
         mSloppyGesture = false;
         mGestureInProgress = false;
+        mActiveId0 = -1;
+        mActiveId1 = -1;
     }
 
     /**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e00b9cd..e18c5e0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5781,10 +5781,67 @@
     }
 
     /**
+     * <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which
+     * views are drawn) from the camera to this view. The camera's distance
+     * affects 3D transformations, for instance rotations around the X and Y
+     * axis. If the rotationX or rotationY properties are changed and this view is
+     * large (more than half the size of the screen), it is recommended to always 
+     * use a camera distance that's greater than the height (X axis rotation) or
+     * the width (Y axis rotation) of this view.</p>
+     * 
+     * <p>The distance of the camera from the view plane can have an affect on the
+     * perspective distortion of the view when it is rotated around the x or y axis.
+     * For example, a large distance will result in a large viewing angle, and there
+     * will not be much perspective distortion of the view as it rotates. A short
+     * distance may cause much more perspective distortion upon rotation, and can 
+     * also result in some drawing artifacts if the rotated view ends up partially
+     * behind the camera (which is why the recommendation is to use a distance at
+     * least as far as the size of the view, if the view is to be rotated.)</p>
+     * 
+     * <p>The distance is expressed in "depth pixels." The default distance depends
+     * on the screen density. For instance, on a medium density display, the
+     * default distance is 1280. On a high density display, the default distance
+     * is 1920.</p>
+     * 
+     * <p>If you want to specify a distance that leads to visually consistent
+     * results across various densities, use the following formula:</p>
+     * <pre>
+     * float scale = context.getResources().getDisplayMetrics().density;
+     * view.setCameraDistance(distance * scale);
+     * </pre>
+     * 
+     * <p>The density scale factor of a high density display is 1.5,
+     * and 1920 = 1280 * 1.5.</p>
+     * 
+     * @param distance The distance in "depth pixels", if negative the opposite
+     *        value is used
+     * 
+     * @see #setRotationX(float) 
+     * @see #setRotationY(float) 
+     */
+    public void setCameraDistance(float distance) {
+        invalidateParentCaches();
+        invalidate(false);
+
+        final float dpi = mResources.getDisplayMetrics().densityDpi;
+        if (mCamera == null) {
+            mCamera = new Camera();
+            matrix3D = new Matrix();
+        }
+
+        mCamera.setLocation(0.0f, 0.0f, -Math.abs(distance) / dpi);
+        mMatrixDirty = true;
+
+        invalidate(false);
+    }
+
+    /**
      * The degrees that the view is rotated around the pivot point.
      *
+     * @see #setRotation(float) 
      * @see #getPivotX()
      * @see #getPivotY()
+     * 
      * @return The degrees of rotation.
      */
     public float getRotation() {
@@ -5796,8 +5853,12 @@
      * result in clockwise rotation.
      *
      * @param rotation The degrees of rotation.
+     * 
+     * @see #getRotation() 
      * @see #getPivotX()
      * @see #getPivotY()
+     * @see #setRotationX(float) 
+     * @see #setRotationY(float) 
      *
      * @attr ref android.R.styleable#View_rotation
      */
@@ -5818,6 +5879,8 @@
      *
      * @see #getPivotX()
      * @see #getPivotY()
+     * @see #setRotationY(float) 
+     * 
      * @return The degrees of Y rotation.
      */
     public float getRotationY() {
@@ -5828,10 +5891,18 @@
      * Sets the degrees that the view is rotated around the vertical axis through the pivot point.
      * Increasing values result in counter-clockwise rotation from the viewpoint of looking
      * down the y axis.
+     * 
+     * When rotating large views, it is recommended to adjust the camera distance
+     * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
      *
      * @param rotationY The degrees of Y rotation.
+     * 
+     * @see #getRotationY() 
      * @see #getPivotX()
      * @see #getPivotY()
+     * @see #setRotation(float)
+     * @see #setRotationX(float) 
+     * @see #setCameraDistance(float) 
      *
      * @attr ref android.R.styleable#View_rotationY
      */
@@ -5852,6 +5923,8 @@
      *
      * @see #getPivotX()
      * @see #getPivotY()
+     * @see #setRotationX(float) 
+     * 
      * @return The degrees of X rotation.
      */
     public float getRotationX() {
@@ -5862,10 +5935,18 @@
      * Sets the degrees that the view is rotated around the horizontal axis through the pivot point.
      * Increasing values result in clockwise rotation from the viewpoint of looking down the
      * x axis.
+     * 
+     * When rotating large views, it is recommended to adjust the camera distance
+     * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
      *
      * @param rotationX The degrees of X rotation.
+     * 
+     * @see #getRotationX() 
      * @see #getPivotX()
      * @see #getPivotY()
+     * @see #setRotation(float)
+     * @see #setRotationY(float) 
+     * @see #setCameraDistance(float) 
      *
      * @attr ref android.R.styleable#View_rotationX
      */
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 75d98ea..06cb64e8 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2272,6 +2272,17 @@
         }
         int contentX = viewToContentX(mLastTouchX + mScrollX);
         int contentY = viewToContentY(mLastTouchY + mScrollY);
+        if (nativeHasCursorNode()) {
+            Rect cursorBounds = nativeGetCursorRingBounds();
+            if (!cursorBounds.contains(contentX, contentY)) {
+                int slop = viewToContentDimension(mNavSlop);
+                cursorBounds.inset(-slop, -slop);
+                if (cursorBounds.contains(contentX, contentY)) {
+                    contentX = (int) cursorBounds.centerX();
+                    contentY = (int) cursorBounds.centerY();
+                }
+            }
+        }
         mWebViewCore.sendMessage(EventHub.REQUEST_CURSOR_HREF,
                 contentX, contentY, hrefMsg);
     }
@@ -5403,12 +5414,20 @@
 
             // If WebKit already showed no interests in this sequence of events,
             // WebView handles them directly.
-            if (mPreventDefault == PREVENT_DEFAULT_NO && action == MotionEvent.ACTION_MOVE) {
+            if (mPreventDefault == PREVENT_DEFAULT_NO) {
                 handleMultiTouchInWebView(ev);
             } else {
                 passMultiTouchToWebKit(ev);
             }
             return true;
+        } else {
+            final ScaleGestureDetector detector = mZoomManager.getMultiTouchGestureDetector();
+            if (detector != null) {
+                // ScaleGestureDetector needs a consistent event stream to operate properly.
+                // It won't take any action with fewer than two pointers, but it needs to
+                // update internal bookkeeping state.
+                detector.onTouchEvent(ev);
+            }
         }
 
         // Skip ACTION_MOVE for single touch if it's still handling multi-touch.
@@ -5948,23 +5967,6 @@
         float x = ev.getX();
         float y = ev.getY();
 
-        if (!detector.isInProgress() &&
-            ev.getActionMasked() != MotionEvent.ACTION_POINTER_DOWN) {
-            // Insert a fake pointer down event in order to start
-            // the zoom scale detector.
-            MotionEvent temp = MotionEvent.obtain(ev);
-            // Clear the original event and set it to
-            // ACTION_POINTER_DOWN.
-            try {
-                temp.setAction(temp.getAction() &
-                ~MotionEvent.ACTION_MASK |
-                MotionEvent.ACTION_POINTER_DOWN);
-                detector.onTouchEvent(temp);
-            } finally {
-                temp.recycle();
-            }
-        }
-
         detector.onTouchEvent(ev);
 
         if (detector.isInProgress()) {
@@ -8022,18 +8024,17 @@
     /*
      * Send a mouse move event to the webcore thread.
      *
-     * @param removeFocus Pass true if the "mouse" cursor is now over a node
-     *                    which wants key events, but it is not the focus. This
-     *                    will make the visual appear as though nothing is in
-     *                    focus.  Remove the WebTextView, if present, and stop
-     *                    drawing the blinking caret.
+     * @param removeFocus Pass true to remove the WebTextView, if present.
+     * @param stopPaintingCaret Stop drawing the blinking caret if true.
      * called by JNI
      */
-    private void sendMoveMouseIfLatest(boolean removeFocus) {
+    @SuppressWarnings("unused")
+    private void sendMoveMouseIfLatest(boolean removeFocus, boolean stopPaintingCaret) {
         if (removeFocus) {
             clearTextEntry();
         }
         mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE_IF_LATEST,
+                stopPaintingCaret ? 1 : 0, 0,
                 cursorData());
     }
 
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index fb0f61c..38288c5 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -558,7 +558,7 @@
     private native String nativeRetrieveHref(int x, int y);
     private native String nativeRetrieveAnchorText(int x, int y);
     private native String nativeRetrieveImageSource(int x, int y);
-
+    private native void nativeStopPaintingCaret();
     private native void nativeTouchUp(int touchGeneration,
             int framePtr, int nodePtr, int x, int y);
 
@@ -1381,6 +1381,9 @@
                             nativeMoveMouseIfLatest(cData.mMoveGeneration,
                                     cData.mFrame,
                                     cData.mX, cData.mY);
+                            if (msg.arg1 == 1) {
+                                nativeStopPaintingCaret();
+                            }
                             break;
 
                         case REQUEST_CURSOR_HREF: {
@@ -2369,15 +2372,42 @@
                 // mViewScale as 0 means it is in zoom overview mode. So we don't
                 // know the exact scale. If mRestoredScale is non-zero, use it;
                 // otherwise just use mTextWrapScale as the initial scale.
-                data.mScale = mInitialViewState.mViewScale == 0
-                        ? (mRestoredScale > 0 ? mRestoredScale
-                                : mInitialViewState.mTextWrapScale)
-                        : mInitialViewState.mViewScale;
+                float tentativeScale = mInitialViewState.mViewScale;
+                if (tentativeScale == 0) {
+                    // The following tries to figure out more correct view scale
+                    // and text wrap scale to be sent to webkit, by using some
+                    // knowledge from web settings and zoom manager.
+
+                    // Calculated window width will be used to guess the scale
+                    // in zoom overview mode.
+                    tentativeScale = mInitialViewState.mTextWrapScale;
+                    int tentativeViewWidth = Math.round(webViewWidth / tentativeScale);
+                    int windowWidth = calculateWindowWidth(tentativeViewWidth,
+                            tentativeViewWidth);
+                    // In viewport setup time, since no content width is known, we assume
+                    // the windowWidth will be the content width, to get a more likely
+                    // zoom overview scale.
+                    data.mScale = (float) webViewWidth / windowWidth;
+                    if (!mSettings.getLoadWithOverviewMode()) {
+                        // If user choose non-overview mode.
+                        data.mScale = Math.max(data.mScale, tentativeScale);
+                    }
+                    if (mSettings.isNarrowColumnLayout() &&
+                            mSettings.getUseFixedViewport()) {
+                        // In case of automatic text reflow in fixed view port mode.
+                        mInitialViewState.mTextWrapScale =
+                                ZoomManager.computeReadingLevelScale(data.mScale);
+                    }
+                } else {
+                    // Scale is given such as when page is restored, use it.
+                    data.mScale = tentativeScale;
+                }
                 if (DebugFlags.WEB_VIEW_CORE) {
                     Log.v(LOGTAG, "setupViewport"
                              + " mRestoredScale=" + mRestoredScale
                              + " mViewScale=" + mInitialViewState.mViewScale
                              + " mTextWrapScale=" + mInitialViewState.mTextWrapScale
+                             + " data.mScale= " + data.mScale
                              );
                 }
                 data.mWidth = Math.round(webViewWidth / data.mScale);
@@ -2396,8 +2426,9 @@
                 // send VIEW_SIZE_CHANGED to the front of the queue so that we
                 // can avoid pushing the wrong picture to the WebView side.
                 mEventHub.removeMessages(EventHub.VIEW_SIZE_CHANGED);
-                mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
-                        EventHub.VIEW_SIZE_CHANGED, data));
+                // Let webkit know the scale and inner width/height immediately
+                // in viewport setup time to avoid wrong information.
+                viewSizeChanged(data);
             }
         }
     }
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 86aef4c..74e6c40 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -282,11 +282,13 @@
     }
 
     public final float getReadingLevelScale() {
-        // The reading scale is at least 0.5f apart from the overview scale.
+        return computeScaleWithLimits(computeReadingLevelScale(getZoomOverviewScale()));
+    }
+
+    /* package */ final static float computeReadingLevelScale(float scale) {
+        // The reading scale is at least 0.5f apart from the input scale.
         final float MIN_SCALE_DIFF = 0.5f;
-        return computeScaleWithLimits(
-                   Math.max(getZoomOverviewScale() + MIN_SCALE_DIFF,
-                            DEFAULT_READING_LEVEL_SCALE));
+        return Math.max(scale + MIN_SCALE_DIFF, DEFAULT_READING_LEVEL_SCALE);
     }
 
     public final float getInvDefaultScale() {
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index cd3862f..df32c51 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -366,12 +366,23 @@
      * Gets whether the {@link CalendarView} is shown.
      *
      * @return True if the calendar view is shown.
+     * @see #getCalendarView()
      */
     public boolean getCalendarViewShown() {
         return mCalendarView.isShown();
     }
 
     /**
+     * Gets the {@link CalendarView}.
+     *
+     * @return The calendar view.
+     * @see #getCalendarViewShown()
+     */
+    public CalendarView getCalendarView () {
+        return mCalendarView;
+    }
+
+    /**
      * Sets whether the {@link CalendarView} is shown.
      *
      * @param shown True if the calendar view is to be shown.
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 8e660ff..7a59178 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -608,6 +608,7 @@
             case MotionEvent.ACTION_DOWN:
                 mLastMotionEventY = mLastDownEventY = event.getY();
                 removeAllCallbacks();
+                hideInputControls();
                 mBeginEditOnUpEvent = false;
                 mAdjustScrollerOnUpEvent = true;
                 if (mDrawSelectorWheel) {
@@ -620,7 +621,6 @@
                     }
                     mBeginEditOnUpEvent = scrollersFinished;
                     mAdjustScrollerOnUpEvent = true;
-                    hideInputControls();
                     return true;
                 }
                 if (isEventInViewHitRect(event, mInputText)
@@ -630,7 +630,6 @@
                                 && isEventInViewHitRect(event, mDecrementButton))) {
                     mAdjustScrollerOnUpEvent = false;
                     setDrawSelectorWheel(true);
-                    hideInputControls();
                     return true;
                 }
                 break;
@@ -641,7 +640,6 @@
                     mBeginEditOnUpEvent = false;
                     onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                     setDrawSelectorWheel(true);
-                    hideInputControls();
                     return true;
                 }
                 break;
@@ -1265,7 +1263,6 @@
             }
         }
 
-        postAdjustScrollerCommand(flingScroller.getDuration());
         invalidate();
     }
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 6791a1d..ce88c77 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4394,7 +4394,7 @@
                         }
                         mHighlightPaint.setStyle(Paint.Style.STROKE);
                         highlight = mHighlightPath;
-                        drawCursor = true;
+                        drawCursor = mCursorCount > 0;
                     }
                 } else {
                     if (mHighlightPathBogus) {
@@ -4503,7 +4503,10 @@
     }
 
     private void updateCursorsPositions() {
-        if (mCursorDrawableRes == 0) return;
+        if (mCursorDrawableRes == 0) {
+            mCursorCount = 0;
+            return; 
+        }
 
         final int offset = getSelectionStart();
         final int line = mLayout.getLineForOffset(offset);
@@ -8655,9 +8658,11 @@
         private float mTouchToWindowOffsetX;
         private float mTouchToWindowOffsetY;
         private float mHotspotX;
-        private float mHotspotY;
         private int mHeight;
+        // Offsets the hotspot point up, so that cursor is not hidden by the finger when moving up
         private float mTouchOffsetY;
+        // Where the touch position should be on the handle to ensure a maximum cursor visibility
+        private float mIdealVerticalOffset;
         private int mLastParentX;
         private int mLastParentY;
         private float mDownPositionX, mDownPositionY;
@@ -8767,7 +8772,7 @@
             final int handleHeight = mDrawable.getIntrinsicHeight();
 
             mTouchOffsetY = -handleHeight * 0.3f;
-            mHotspotY = 0;
+            mIdealVerticalOffset = 0.7f * handleHeight;
             mHeight = handleHeight;
             invalidate();
         }
@@ -8836,7 +8841,7 @@
             final int[] coords = mTempCoords;
             hostView.getLocationInWindow(coords);
             final int posX = coords[0] + mPositionX + (int) mHotspotX;
-            final int posY = coords[1] + mPositionY + (int) mHotspotY;
+            final int posY = coords[1] + mPositionY;
 
             // Offset by 1 to take into account 0.5 and int rounding around getPrimaryHorizontal.
             return posX >= clip.left - 1 && posX <= clip.right + 1 &&
@@ -8901,6 +8906,7 @@
                     mDownPositionY = ev.getRawY();
                     mTouchToWindowOffsetX = mDownPositionX - mPositionX;
                     mTouchToWindowOffsetY = mDownPositionY - mPositionY;
+
                     final int[] coords = mTempCoords;
                     TextView.this.getLocationInWindow(coords);
                     mLastParentX = coords[0];
@@ -8915,8 +8921,22 @@
                 case MotionEvent.ACTION_MOVE: {
                     final float rawX = ev.getRawX();
                     final float rawY = ev.getRawY();
+
+                    // Vertical hysteresis: vertical down movement tends to snap to ideal offset
+                    final float previousVerticalOffset = mTouchToWindowOffsetY - mLastParentY;
+                    final float currentVerticalOffset = rawY - mPositionY - mLastParentY;
+                    float newVerticalOffset;
+                    if (previousVerticalOffset < mIdealVerticalOffset) {
+                        newVerticalOffset = Math.min(currentVerticalOffset, mIdealVerticalOffset);
+                        newVerticalOffset = Math.max(newVerticalOffset, previousVerticalOffset);
+                    } else {
+                        newVerticalOffset = Math.max(currentVerticalOffset, mIdealVerticalOffset);
+                        newVerticalOffset = Math.min(newVerticalOffset, previousVerticalOffset);
+                    }
+                    mTouchToWindowOffsetY = newVerticalOffset + mLastParentY;
+
                     final float newPosX = rawX - mTouchToWindowOffsetX + mHotspotX;
-                    final float newPosY = rawY - mTouchToWindowOffsetY + mHotspotY + mTouchOffsetY;
+                    final float newPosY = rawY - mTouchToWindowOffsetY + mTouchOffsetY;
 
                     mController.updatePosition(this, Math.round(newPosX), Math.round(newPosY));
                     break;
@@ -8954,18 +8974,17 @@
             return mIsDragging;
         }
 
-        void positionAtCursor(final int offset, boolean bottom) {
+        void positionAtCursor(final int offset) {
             addPositionToTouchUpFilter(offset);
             final int width = mDrawable.getIntrinsicWidth();
             final int height = mDrawable.getIntrinsicHeight();
             final int line = mLayout.getLineForOffset(offset);
-            final int lineTop = mLayout.getLineTop(line);
             final int lineBottom = mLayout.getLineBottom(line);
 
             final Rect bounds = sCursorControllerTempRect;
             bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX) +
                     TextView.this.mScrollX;
-            bounds.top = (bottom ? lineBottom : lineTop - mHeight) + TextView.this.mScrollY;
+            bounds.top = lineBottom + TextView.this.mScrollY;
 
             bounds.right = bounds.left + width;
             bounds.bottom = bounds.top + height;
@@ -9107,10 +9126,10 @@
 
         public void updatePosition(HandleView handle, int x, int y) {
             final int previousOffset = getSelectionStart();
-            int offset = getHysteresisOffset(x, y, previousOffset);
+            final int newOffset = getOffset(x, y);
 
-            if (offset != previousOffset) {
-                updateOffset(handle, offset);
+            if (newOffset != previousOffset) {
+                updateOffset(handle, newOffset);
                 removePastePopupCallback();
             }
             hideDelayed();
@@ -9131,7 +9150,7 @@
                 return;
             }
 
-            getHandle().positionAtCursor(offset, true);
+            getHandle().positionAtCursor(offset);
         }
 
         public int getCurrentOffset(HandleView handle) {
@@ -9215,8 +9234,7 @@
             int selectionStart = getSelectionStart();
             int selectionEnd = getSelectionEnd();
 
-            final int previousOffset = handle == mStartHandle ? selectionStart : selectionEnd;
-            int offset = getHysteresisOffset(x, y, previousOffset);
+            int offset = getOffset(x, y);
 
             // Handle the case where start and end are swapped, making sure start <= end
             if (handle == mStartHandle) {
@@ -9275,8 +9293,8 @@
             }
 
             // The handles have been created since the controller isShowing().
-            mStartHandle.positionAtCursor(selectionStart, true);
-            mEndHandle.positionAtCursor(selectionEnd, true);
+            mStartHandle.positionAtCursor(selectionStart);
+            mEndHandle.positionAtCursor(selectionEnd);
         }
 
         public int getCurrentOffset(HandleView handle) {
@@ -9406,26 +9424,6 @@
         return offset;
     }
 
-    int getHysteresisOffset(int x, int y, int previousOffset) {
-        final Layout layout = getLayout();
-        if (layout == null) return -1;
-
-        int line = getLineAtCoordinate(y);
-        final int previousLine = layout.getLineForOffset(previousOffset);
-        final int previousLineTop = layout.getLineTop(previousLine);
-        final int previousLineBottom = layout.getLineBottom(previousLine);
-        final int hysteresisThreshold = (previousLineBottom - previousLineTop) / 8;
-
-        // If new line is just before or after previous line and y position is less than
-        // hysteresisThreshold away from previous line, keep cursor on previous line.
-        if (((line == previousLine + 1) && ((y - previousLineBottom) < hysteresisThreshold)) ||
-            ((line == previousLine - 1) && ((previousLineTop - y)    < hysteresisThreshold))) {
-            line = previousLine;
-        }
-
-        return getOffsetAtCoordinate(line, x);
-    }
-
     private int convertToLocalHorizontalCoordinate(int x) {
         x -= getTotalPaddingLeft();
         // Clamp the position to inside of the view.
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 4833df1..8064836 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -447,6 +447,13 @@
     JavaPixelAllocator allocator(env);

 

     src->extractAlpha(dst, paint, &allocator, &offset);

+    // If Skia can't allocate pixels for destination bitmap, it resets

+    // it, that is set its pixels buffer to NULL, and zero width and height.

+    if (dst->getPixels() == NULL && src->getPixels() != NULL) {

+        delete dst;

+        doThrowOOME(env, "failed to allocate pixels for alpha");

+        return NULL;

+    }

     if (offsetXY != 0 && env->GetArrayLength(offsetXY) >= 2) {

         int* array = env->GetIntArrayElements(offsetXY, NULL);

         array[0] = offset.fX;

@@ -651,4 +658,3 @@
     return android::AndroidRuntime::registerNativeMethods(env, kClassPathName,

                                 gBitmapMethods, SK_ARRAY_COUNT(gBitmapMethods));

 }

-

diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 7a53874..bd5305d 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -31,6 +31,8 @@
 #include <binder/IPCThreadState.h>
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
+#include <utils/List.h>
+#include <utils/KeyedVector.h>
 #include <cutils/logger.h>
 #include <binder/Parcel.h>
 #include <binder/ProcessState.h>
@@ -322,25 +324,15 @@
 class JavaBBinderHolder : public RefBase
 {
 public:
-    JavaBBinderHolder(JNIEnv* env, jobject object)
-        : mObject(object)
-    {
-        LOGV("Creating JavaBBinderHolder for Object %p\n", object);
-    }
-    ~JavaBBinderHolder()
-    {
-        LOGV("Destroying JavaBBinderHolder for Object %p\n", mObject);
-    }
-
-    sp<JavaBBinder> get(JNIEnv* env)
+    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
     {
         AutoMutex _l(mLock);
         sp<JavaBBinder> b = mBinder.promote();
         if (b == NULL) {
-            b = new JavaBBinder(env, mObject);
+            b = new JavaBBinder(env, obj);
             mBinder = b;
             LOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n",
-                 b.get(), b->getWeakRefs(), mObject, b->getWeakRefs()->getWeakCount());
+                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
         }
 
         return b;
@@ -354,20 +346,41 @@
 
 private:
     Mutex           mLock;
-    jobject         mObject;
     wp<JavaBBinder> mBinder;
 };
 
 // ----------------------------------------------------------------------------
 
+// Per-IBinder death recipient bookkeeping.  This is how we reconcile local jobject
+// death recipient references passed in through JNI with the permanent corresponding
+// JavaDeathRecipient objects.
+
+class JavaDeathRecipient;
+
+class DeathRecipientList : public RefBase {
+    List< sp<JavaDeathRecipient> > mList;
+    Mutex mLock;
+
+public:
+    ~DeathRecipientList();
+
+    void add(const sp<JavaDeathRecipient>& recipient);
+    void remove(const sp<JavaDeathRecipient>& recipient);
+    sp<JavaDeathRecipient> find(jobject recipient);
+};
+
+// ----------------------------------------------------------------------------
+
 class JavaDeathRecipient : public IBinder::DeathRecipient
 {
 public:
-    JavaDeathRecipient(JNIEnv* env, jobject object)
-        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
-          mHoldsRef(true)
+    JavaDeathRecipient(JNIEnv* env, jobject object, sp<DeathRecipientList>& list)
+        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), mList(list)
     {
-        incStrong(this);
+        // These objects manage their own lifetimes so are responsible for final bookkeeping.
+        // The list holds a strong reference to this object.
+        mList->add(this);
+
         android_atomic_inc(&gNumDeathRefs);
         incRefsCreated(env);
     }
@@ -391,16 +404,12 @@
 
     void clearReference()
     {
-        bool release = false;
-        mLock.lock();
-        if (mHoldsRef) {
-            mHoldsRef = false;
-            release = true;
-        }
-        mLock.unlock();
-        if (release) {
-            decStrong(this);
-        }
+        mList->remove(this);
+    }
+
+    bool matches(jobject obj) {
+        JNIEnv* env = javavm_to_jnienv(mVM);
+        return env->IsSameObject(obj, mObject);
     }
 
 protected:
@@ -415,12 +424,57 @@
 private:
     JavaVM* const   mVM;
     jobject const   mObject;
-    Mutex           mLock;
-    bool            mHoldsRef;
+    sp<DeathRecipientList> mList;
 };
 
 // ----------------------------------------------------------------------------
 
+DeathRecipientList::~DeathRecipientList() {
+    AutoMutex _l(mLock);
+
+    // Should never happen -- the JavaDeathRecipient objects that have added themselves
+    // to the list are holding references on the list object.  Only when they are torn
+    // down can the list header be destroyed.
+    if (mList.size() > 0) {
+        LOGE("Retiring binder %p with extant death recipients\n", this);
+    }
+}
+
+void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
+    AutoMutex _l(mLock);
+
+    mList.push_back(recipient);
+}
+
+void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
+    AutoMutex _l(mLock);
+
+    List< sp<JavaDeathRecipient> >::iterator iter;
+    for (iter = mList.begin(); iter != mList.end(); iter++) {
+        if (*iter == recipient) {
+            mList.erase(iter);
+            return;
+        }
+    }
+}
+
+sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) {
+    AutoMutex _l(mLock);
+
+    List< sp<JavaDeathRecipient> >::iterator iter;
+    for (iter = mList.begin(); iter != mList.end(); iter++) {
+        if ((*iter)->matches(recipient)) {
+            return *iter;
+        }
+    }
+    return NULL;
+}
+
+static KeyedVector<IBinder*, sp<DeathRecipientList> > gDeathRecipientsByIBinder;
+static Mutex gDeathRecipientMapLock;
+
+// ----------------------------------------------------------------------------
+
 namespace android {
 
 static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie)
@@ -490,7 +544,7 @@
     if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
         JavaBBinderHolder* jbh = (JavaBBinderHolder*)
             env->GetIntField(obj, gBinderOffsets.mObject);
-        return jbh != NULL ? jbh->get(env) : NULL;
+        return jbh != NULL ? jbh->get(env, obj) : NULL;
     }
 
     if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
@@ -621,26 +675,26 @@
     IPCThreadState::self()->flushCommands();
 }
 
-static void android_os_Binder_init(JNIEnv* env, jobject clazz)
+static void android_os_Binder_init(JNIEnv* env, jobject obj)
 {
-    JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz);
+    JavaBBinderHolder* jbh = new JavaBBinderHolder();
     if (jbh == NULL) {
         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
         return;
     }
-    LOGV("Java Binder %p: acquiring first ref on holder %p", clazz, jbh);
-    jbh->incStrong(clazz);
-    env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh);
+    LOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
+    jbh->incStrong((void*)android_os_Binder_init);
+    env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
 }
 
-static void android_os_Binder_destroy(JNIEnv* env, jobject clazz)
+static void android_os_Binder_destroy(JNIEnv* env, jobject obj)
 {
     JavaBBinderHolder* jbh = (JavaBBinderHolder*)
-        env->GetIntField(clazz, gBinderOffsets.mObject);
+        env->GetIntField(obj, gBinderOffsets.mObject);
     if (jbh != NULL) {
-        env->SetIntField(clazz, gBinderOffsets.mObject, 0);
-        LOGV("Java Binder %p: removing ref on holder %p", clazz, jbh);
-        jbh->decStrong(clazz);
+        env->SetIntField(obj, gBinderOffsets.mObject, 0);
+        LOGV("Java Binder %p: removing ref on holder %p", obj, jbh);
+        jbh->decStrong((void*)android_os_Binder_init);
     } else {
         // Encountering an uninitialized binder is harmless.  All it means is that
         // the Binder was only partially initialized when its finalizer ran and called
@@ -648,7 +702,7 @@
         // For example, a Binder subclass constructor might have thrown an exception before
         // it could delegate to its superclass's constructor.  Consequently init() would
         // not have been called and the holder pointer would remain NULL.
-        LOGV("Java Binder %p: ignoring uninitialized binder", clazz);
+        LOGV("Java Binder %p: ignoring uninitialized binder", obj);
     }
 }
 
@@ -973,8 +1027,25 @@
     LOGV("linkToDeath: binder=%p recipient=%p\n", target, recipient);
 
     if (!target->localBinder()) {
-        sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient);
-        status_t err = target->linkToDeath(jdr, recipient, flags);
+        sp<JavaDeathRecipient> jdr;
+
+        {
+            sp<DeathRecipientList> list;
+            AutoMutex _maplocker(gDeathRecipientMapLock);
+
+            ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(target);
+            if (listIndex < 0) {
+                // Set up the death notice bookkeeping for this binder lazily
+                list = new DeathRecipientList;
+                gDeathRecipientsByIBinder.add(target, list);
+            } else {
+                list = gDeathRecipientsByIBinder.valueAt(listIndex);
+            }
+
+            jdr = new JavaDeathRecipient(env, recipient, list);
+        }
+
+        status_t err = target->linkToDeath(jdr, NULL, flags);
         if (err != NO_ERROR) {
             // Failure adding the death recipient, so clear its reference
             // now.
@@ -1003,15 +1074,29 @@
     LOGV("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
 
     if (!target->localBinder()) {
-        wp<IBinder::DeathRecipient> dr;
-        status_t err = target->unlinkToDeath(NULL, recipient, flags, &dr);
-        if (err == NO_ERROR && dr != NULL) {
-            sp<IBinder::DeathRecipient> sdr = dr.promote();
-            JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
-            if (jdr != NULL) {
-                jdr->clearReference();
+        status_t err = NAME_NOT_FOUND;
+        sp<JavaDeathRecipient> origJDR;
+        {
+            AutoMutex _maplocker(gDeathRecipientMapLock);
+            ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(target);
+            if (listIndex >= 0) {
+                sp<DeathRecipientList> list = gDeathRecipientsByIBinder.valueAt(listIndex);
+                origJDR = list->find(recipient);
             }
         }
+        // If we found the matching recipient, proceed to unlink using that
+        if (origJDR != NULL) {
+            wp<IBinder::DeathRecipient> dr;
+            err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
+            if (err == NO_ERROR && dr != NULL) {
+                sp<IBinder::DeathRecipient> sdr = dr.promote();
+                JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get());
+                if (jdr != NULL) {
+                    jdr->clearReference();
+                }
+            }
+        }
+
         if (err == NO_ERROR || err == DEAD_OBJECT) {
             res = JNI_TRUE;
         } else {
@@ -1031,6 +1116,15 @@
     env->SetIntField(obj, gBinderProxyOffsets.mObject, 0);
     b->decStrong(obj);
     IPCThreadState::self()->flushCommands();
+
+    // tear down the death recipient bookkeeping
+    {
+        AutoMutex _maplocker(gDeathRecipientMapLock);
+        ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(b);
+        if (listIndex >= 0) {
+            gDeathRecipientsByIBinder.removeItemsAt((size_t)listIndex);
+        }
+    }
 }
 
 // ----------------------------------------------------------------------------
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index f8c6885..138936a 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"محو بيانات الهاتف بدون تحذير، وذلك عبر إجراء إعادة الضبط بحسب بيانات المصنع"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"تعيين الخادم الوكيل العمومي للجهاز"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"تعيين الخادم الوكيل العمومي للجهاز لكي يتم استخدامه أثناء تمكين السياسة. يعين مشرف الجهاز الأول فقط الخادم الوكيل العمومي الفعال."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"تعيين انتهاء صلاحية كلمة المرور"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"التحكم في الوقت المستغرق قبل الحاجة إلى تغيير كلمة مرور شاشة التوقف"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"تعيين انتهاء صلاحية كلمة المرور"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"التحكم في الوقت المستغرق قبل الحاجة إلى تغيير كلمة مرور شاشة التوقف"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"تعيين تشفير التخزين"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"طلب تشفير بيانات التطبيق المخزنة"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 039ead2..fbedfdc 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Изтриване на данните в телефона без предупреждение чрез възстановяване на фабричните настройки"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Задаване на глобален прокси сървър за устройството"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Задаване на глобалния прокси сървър, който да се използва, когато правилото е активирано. Само първият администратор на устройството задава действителния глобален прокси сървър."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Срок на валидност на паролата"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Контролирайте след колко време трябва да се променя паролата при заключване на екрана"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Срок на валидност на паролата"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Контролирайте след колко време трябва да се променя паролата при заключване на екрана"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Шифроване за хранилището"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Изисква съхраняваните данни за приложенията да бъдат шифровани"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index f88f5de..f9ef2bf 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Esborra les dades del telèfon sense advertiment mitjançant un restabliment de les dades de fàbrica"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Defineix el servidor intermediari global del dispositiu"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Defineix el servidor intermediari global del dispositiu que cal utilitzar mentre la política estigui activada. Només el primer administrador del dispositiu pot definir el servidor intermediari global efectiu."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Defineix la caducitat de la contrasenya"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controla quant de temps abans de la pantalla de bloqueig cal canviar la contrasenya"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Defineix la caducitat de la contrasenya"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Controla quant de temps abans de la pantalla de bloqueig cal canviar la contrasenya"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Encriptació d’emmagatzematge"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Requereix que les dades de l\'aplicació emmagatzemades estiguin encriptades"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index a7c74bc..0bfbd97 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Bez upozornění smazat všechna data telefonu obnovením továrních dat"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Nastavit globální proxy server zařízení"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globální proxy server, který se bude používat, když jsou zásady aktivní. Aktuální globální proxy server nastavuje pouze první správce zařízení."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Nastavit konec platnosti hesla"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ovládání doby, po jejímž uplynutí je nutné změnit heslo pro odemknutí obrazovky"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Nastavit konec platnosti hesla"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Ovládání doby, po jejímž uplynutí je nutné změnit heslo pro odemknutí obrazovky"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Nastavit šifrování úložiště"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Požadovat šifrování ukládaných dat"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index b29307d..02c3664 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Slet telefonens data uden varsel ved at gendanne fabriksindstillinger"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Angiv enhedens globale proxy"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angiv enhedens globale proxy, der skal bruges, mens politikken er aktiveret. Kun den første enhedsadministrator angiver den effektive globale proxy."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Indstil udløb for adgangskode"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontroller, hvor lang tid der skal gå, før adgangskoden til skærmlåsen skal ændres."</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Indstil udløb for adgangskode"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Kontroller, hvor lang tid der skal gå, før adgangskoden til skærmlåsen skal ændres."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Angiv kryptering af lager"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Kræv, at gemte programdata krypteres"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 3961b9f..e203a79 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Auf Werkseinstellungen zurücksetzen und Daten auf dem Telefon ohne Warnung löschen"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Den globalen Proxy des Geräts festlegen"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Den globalen Proxy des Geräts zur Verwendung während der Aktivierung der Richtlinie festlegen. Nur der erste Geräteadministrator kann den gültigen globalen Proxy festlegen."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Ablauf des Passworts festlegen"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Zeitraum bis zur Änderung des Passworts für die Bildschirmsperre festlegen"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Ablauf des Passworts festlegen"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Zeitraum bis zur Änderung des Passworts für die Bildschirmsperre festlegen"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Speicherverschlüsselung"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Anforderung, dass gespeicherte Anwendungsdaten verschlüsselt werden"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index e1c2c39..0e70acf 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Διαγραφή των δεδομένων του τηλεφώνου χωρίς προειδοποίηση με επαναφορά των εργοστασιακών δεδομένων"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Ρύθμιση του γενικού διακομιστή μεσολάβησης της συσκευής"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ορίστε τη χρήση του γενικού διακομιστή μεσολάβησης της συσκευής όταν είναι ενεργοποιημένη η πολιτική. Μόνο ο διαχειριστής της πρώτης συσκευής ορίζει τον ισχύοντα γενικό διακομιστή μεσολάβησης."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Ορισμός λήξης κωδ. πρόσβασης"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ελέγξτε πόσος χρόνος απομένει προτού πρέπει να αλλάξετε τον κωδικό πρόσβασης κλειδώματος της οθόνης"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Ορισμός λήξης κωδ. πρόσβασης"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Ελέγξτε πόσος χρόνος απομένει προτού πρέπει να αλλάξετε τον κωδικό πρόσβασης κλειδώματος της οθόνης"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Ορισμός κρυπτογρ. αποθ. χώρου"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Να απαιτείται η κρυπτογράφηση των αποθηκευμένων δεδομένων εφαρμογής"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 0ee0e50..51e9c80 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Erase the phone\'s data without warning by performing a factory data reset"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Set the device global proxy"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Set the device\'s global proxy to be used while policy is enabled. Only the first device admin sets the effective global proxy."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Set password expiry"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Control how long before lock-screen password needs to be changed"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Set password expiry"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Control how long before lock-screen password needs to be changed"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Set storage encryption"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Require that stored application data be encrypted"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index aac30d3..483f4b0 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Borrar los datos del teléfono sin advertencias al restablecer la configuración original"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Configura el proxy global de dispositivo"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configuración del proxy global de dispositivo que se utilizará mientras se habilita la política. Sólo la primera administración de dispositivo configura el proxy global efectivo."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Establecer la caducidad de la contraseña"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Verifica cuánto tiempo antes debes cambiar la contraseña de la pantalla de bloqueo"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Establecer la caducidad de la contraseña"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Verifica cuánto tiempo antes debes cambiar la contraseña de la pantalla de bloqueo"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Establecer la encriptación del almacenamiento"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Requiere que los datos almacenados de la aplicación estén encriptados"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 51bbd3c..95d7272 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Borrado de los datos del teléfono sin avisar restableciendo datos de fábrica"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir el servidor proxy global"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Define el servidor proxy global que se debe utilizar mientras la política esté habilitada. Solo el primer administrador de dispositivos define el servidor proxy global efectivo."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Definir caducidad contraseña"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Permite controlar cuándo se debe cambiar la contraseña de bloqueo de la pantalla."</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Definir caducidad contraseña"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Permite controlar cuándo se debe cambiar la contraseña de bloqueo de la pantalla."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Encriptación de almacenamiento"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Exige que se encripten los datos de la aplicación almacenados."</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index fe06a32..8a45f74 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"پاک کردن داده های گوشی بدون هشدار با انجام یک عملکرد بازنشانی داده های کارخانه"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"تنظیم پروکسی جهانی دستگاه"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"پروکسی جهانی دستگاه مورد نظر را جهت استفاده هنگام فعال بودن خط مشی تنظیم کنید. فقط اولین سرپرست دستگاه پروکسی جهانی مفید را تنظیم می کند."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"تنظیم زمان انقضای رمز ورود"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"کنترل مدت زمانی که رمز ورود صفحه قفل قبل از تغییر یافتن لازم دارد"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"تنظیم زمان انقضای رمز ورود"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"کنترل مدت زمانی که رمز ورود صفحه قفل قبل از تغییر یافتن لازم دارد"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"تنظیم رمزگذاری حافظه"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"نیاز به رمزگذاری داده های برنامه کاربردی ذخیره شده دارد"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index dc594db..7bc1db6 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Tyhjennä puhelimen tiedot varoituksetta palauttamalla tehdasasetukset."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Aseta laitteen yleinen välityspalvelin"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Aseta laitteen yleinen välityspalvelin käyttöön, kun käytäntö on käytössä. Vain ensimmäinen laitteen järjestelmänhallitsija voi asettaa käytettävän yleisen välityspalvelimen."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Aseta salasanan umpeutuminen"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Valitse, kuinka pian ruudunlukituksen poiston salasana tulee vaihtaa"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Aseta salasanan umpeutuminen"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Valitse, kuinka pian ruudunlukituksen poiston salasana tulee vaihtaa"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Aseta tallennustilan salaus"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Pakota tallennettujen sovellustietojen salaus"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 3e09691..bb6fa0e 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Effacer les données du téléphone sans avertissement, en restaurant les valeurs d\'usine"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Définir le proxy global du mobile"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Indiquez le proxy global à utiliser pour ce mobile lorsque les règles sont activées. Seul l\'administrateur principal du mobile peut définir le proxy global utilisé."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Définir date exp. mot de passe"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Définir la fréquence de changement du mot de passe de verrouillage d\'écran"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Définir date exp. mot de passe"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Définir la fréquence de changement du mot de passe de verrouillage d\'écran"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Définir cryptage du stockage"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Exiger que les données d\'application stockées soient cryptées"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index b9e2753..924d6fd 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Izbriši podatke telefona bez upozorenja vraćanjem u tvorničko stanje"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"postavi globalni proxy uređaja"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Postavi globalni proxy uređaja za upotrebu dok su pravila omogućena. Samo prvi administrator uređaja postavlja djelotvoran globalni proxy."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Postavi istek zaporke"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Nadzirite za koliko vremena zaporka za zaključani zaslon treba biti promijenjena"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Postavi istek zaporke"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Nadzirite za koliko vremena zaporka za zaključani zaslon treba biti promijenjena"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Postavi enkripciju za pohranu"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Zahtijevaj da pohranjeni podaci aplikacije budu kriptirani"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index a4ee0cb..f3d02f7 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Figyelmeztetés nélkül törli a telefon összes adatát, visszaállítva a gyári adatokat"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Az eszköz globális proxyjának beállítása"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Az eszköz globális proxyja lesz használatban, amíg az irányelv engedélyezve van. Csak az eszköz első rendszergazdája állíthatja be a tényleges globális proxyt."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Jelszó lejáratának beállítása"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Azt vezérli, mennyi időnként kell módosítani a képernyőt zároló jelszót"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Jelszó lejáratának beállítása"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Azt vezérli, mennyi időnként kell módosítani a képernyőt zároló jelszót"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Tárhelytitkosítás beállítása"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Megköveteli a tárolt alkalmazásadatok titkosítását"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index b6d0d43..a0e1dd4 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Hapus data ponsel tanpa peringatan, dengan menyetel ulang data pabrik"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Setel proxy global perangkat"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Setel proxy global perangkat yang akandigunakan ketika kebijakan diaktifkan. Hanya admin perangkat pertama yang menyetel procy global yang berlaku."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Setel kedaluwarsa sandi"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrol berapa lama sebelum sandi penguncian layar perlu diubah"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Setel kedaluwarsa sandi"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Kontrol berapa lama sebelum sandi penguncian layar perlu diubah"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Setel enkripsi penyimpanan"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Mengharuskan data aplikasi yang disimpan untuk dienkripsi"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 047f9b8..f10fbc2 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Cancella i dati del telefono senza preavviso eseguendo un ripristino dati di fabbrica"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Imposta il proxy globale del dispositivo"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Imposta il proxy globale del dispositivo in modo da utilizzarlo mentre la norma è attiva. Il proxy globale effettivo è impostabile solo dal primo amministratore del dispositivo."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Imposta scadenza password"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Stabilisci la scadenza della password di blocco dello schermo"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Imposta scadenza password"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Stabilisci la scadenza della password di blocco dello schermo"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Imposta crittografia archivio"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Richiede la crittografia dei dati applicazione memorizzati"</string>
   <string-array name="phoneTypes">
@@ -957,7 +957,7 @@
     <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Autorizzazione richiesta"\n"per l\'account <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Metodo inserimento"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sinc"</string>
-    <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesso facilitato"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilità"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Sfondo"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambia sfondo"</string>
     <string name="pptp_vpn_description" msgid="2688045385181439401">"Protocollo di tunneling Point-to-Point"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index f268fbf..f9073de 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"מחק את נתוני הטלפון ללא אזהרה, על ידי ביצוע איפוס נתוני יצרן"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"הגדר את שרת ה-proxy הגלובלי של ההתקן"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"הגדר את שרת proxy הגלובלי של ההתקן לשימוש כאשר המדיניות מופעלת. רק מנהל ההתקן הראשון מגדיר את שרת ה-proxy הגלובלי הפעיל."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"הגדר תפוגת תוקף של סיסמה"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"שלוט בפרק הזמן הדרוש לשינוי הסיסמה של נעילת המסך"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"הגדר תפוגת תוקף של סיסמה"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"שלוט בפרק הזמן הדרוש לשינוי הסיסמה של נעילת המסך"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"הגדר הצפנת אחסון"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"דורש שנתוני היישום המאוחסנים יהיו מוצפנים"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index ce6d13d..54a5e1b 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"警告せずにデータの初期化を実行して端末内のデータを消去します。"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"端末のグローバルプロキシを設定"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ポリシーが有効になっている場合は端末のグローバルプロキシが使用されるように設定します。有効なグローバルプロキシを設定できるのは最初のデバイス管理者だけです。"</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"パスワードの有効期限の設定"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"画面ロックパスワードの変更が必要になるまでの期間を指定します"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"パスワードの有効期限の設定"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"画面ロックパスワードの変更が必要になるまでの期間を指定します"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"ストレージ暗号化の設定"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"保存したアプリケーションデータが暗号化されるようにする"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 704f453..6b18422 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"공장 초기화를 수행하여 경고 없이 휴대전화 데이터를 지웁니다."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"기기 전체 프록시 설정"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"정책이 사용 설정되어 있는 동안 사용될 기기 전체 프록시를 설정합니다. 첫 번째 기기 관리자가 설정한 전체 프록시만 유효합니다."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"비밀번호 만료 설정"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"화면 잠금 비밀번호를 변경해야 하는 기간 변경"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"비밀번호 만료 설정"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"화면 잠금 비밀번호를 변경해야 하는 기간 변경"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"저장소 암호화 설정"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"저장한 애플리케이션 데이터를 암호화해야 합니다."</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f3de6dd..5c8cb87 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Be įspėjimo ištrinti telefono duomenis iš naujo nustatant gamyklinius duomenis"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Nustatyti įrenginio bendrąjį tarpinį serverį"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Nustatyti įrenginio bendrąjį tarpinį serverį, kad būtų naudojamas, kol įgalinta politika. Tik pirmasis įrenginio administratorius nustato efektyvų bendrąjį tarpinį serverį."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Nust. slaptaž. galiojimo pab."</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Valdyti, per kiek laiko iki ekrano užrakinimo turi būti pakeistas slaptažodis"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Nust. slaptaž. galiojimo pab."</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Valdyti, per kiek laiko iki ekrano užrakinimo turi būti pakeistas slaptažodis"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Nustatyti atmintinės šifruotę"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Saugomos programos duomenys turi būti šifruoti"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9756e91..265a446 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Dzēš tālruņa datus bez brīdinājuma, veicot rūpnīcas datu atiestatīšanu"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Iestatīt ierīces globālo starpniekserveri"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Iestatiet izmantojamo ierīces globālo starpniekserveri, kad ir iespējota politika. Spēkā esošo globālo starpniekserveri iestata tikai pirmās ierīces administrators."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Paroles termiņa izb. iest."</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrolē ekrāna bloķēšanas paroles maiņas intervālu"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Paroles termiņa izb. iest."</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Kontrolē ekrāna bloķēšanas paroles maiņas intervālu"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Skatīt atmiņas šifrējumu"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Pieprasīt, lai saglabātie lietojumprogrammas dati tiktu šifrēti"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 743c8df..34c8f7c 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Tilbakestill telefonens data uten advarsel ved å utføre tilbakestilling til fabrikkstandard"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Angi enhetens globale mellomtjener"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angir den globale mellomtjeneren på enheten som skal brukes når regelen er aktivert. Kun den opprinnelige administratoren av enheten kan angi den globale mellomtjeneren."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Angi utløpsdato for passordet"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Velg hvor lenge det skal gå før passordet til låseskjermen må byttes"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Angi utløpsdato for passordet"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Velg hvor lenge det skal gå før passordet til låseskjermen må byttes"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Angi lagringskryptering"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Krever at lagrede programdata krypteres"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index a149a53..12fd801a 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -179,78 +179,78 @@
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Toegang krijgen tot USB-opslag."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Toegang tot de SD-kaart."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"statusbalk uitschakelen of wijzigen"</string>
-    <string name="permdesc_statusBar" msgid="1365473595331989732">"Hiermee kan een toepassing de statusbalk uitschakelen of systeempictogrammen toevoegen en verwijderen."</string>
+    <string name="permdesc_statusBar" msgid="1365473595331989732">"Hiermee kan een app de statusbalk uitschakelen of systeempictogrammen toevoegen en verwijderen."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"statusbalk"</string>
-    <string name="permdesc_statusBarService" msgid="4097605867643520920">"Hiermee kan de toepassing de statusbalk zijn."</string>
+    <string name="permdesc_statusBarService" msgid="4097605867643520920">"Hiermee kan de app de statusbalk zijn."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"statusbalk uitvouwen/samenvouwen"</string>
-    <string name="permdesc_expandStatusBar" msgid="7088604400110768665">"Hiermee kan de toepassing de statusbalk uitvouwen of samenvouwen."</string>
+    <string name="permdesc_expandStatusBar" msgid="7088604400110768665">"Hiermee kan de app de statusbalk uitvouwen of samenvouwen."</string>
     <string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"uitgaande oproepen onderscheppen"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="2228988201852654461">"Hiermee kan een toepassing uitgaande oproepen verwerken en het nummer wijzigen dat wordt gebeld. Schadelijke toepassingen kunnen uitgaande oproepen bijhouden, omleiden of tegenhouden."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="2228988201852654461">"Hiermee kan een app uitgaande oproepen verwerken en het nummer wijzigen dat wordt gebeld. Schadelijke apps kunnen uitgaande oproepen bijhouden, omleiden of tegenhouden."</string>
     <string name="permlab_receiveSms" msgid="2697628268086208535">"SMS ontvangen"</string>
-    <string name="permdesc_receiveSms" msgid="6298292335965966117">"Hiermee kan een toepassing SMS-berichten ontvangen en verwerken. Schadelijke toepassingen kunnen uw berichten bijhouden of deze verwijderen zonder dat u ze te zien krijgt."</string>
+    <string name="permdesc_receiveSms" msgid="6298292335965966117">"Hiermee kan een app SMS-berichten ontvangen en verwerken. Schadelijke apps kunnen uw berichten bijhouden of deze verwijderen zonder dat u ze te zien krijgt."</string>
     <string name="permlab_receiveMms" msgid="8894700916188083287">"MMS ontvangen"</string>
-    <string name="permdesc_receiveMms" msgid="4563346832000174373">"Hiermee kan een toepassing MMS-berichten ontvangen en verwerken. Schadelijke toepassingen kunnen uw berichten bijhouden of deze verwijderen zonder dat u ze te zien krijgt."</string>
+    <string name="permdesc_receiveMms" msgid="4563346832000174373">"Hiermee kan een app MMS-berichten ontvangen en verwerken. Schadelijke apps kunnen uw berichten bijhouden of deze verwijderen zonder dat u ze te zien krijgt."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"SMS-berichten verzenden"</string>
-    <string name="permdesc_sendSms" msgid="1946540351763502120">"Hiermee kan de toepassing SMS-berichten verzenden. Schadelijke toepassingen kunnen u geld kosten door berichten te verzenden zonder uw toestemming."</string>
+    <string name="permdesc_sendSms" msgid="1946540351763502120">"Hiermee kan de app SMS-berichten verzenden. Schadelijke apps kunnen u geld kosten door berichten te verzenden zonder uw toestemming."</string>
     <string name="permlab_readSms" msgid="4085333708122372256">"SMS of MMS lezen"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="5836710350295631545">"Hiermee kan een toepassing de op uw tablet of SIM-kaart opgeslagen SMS-berichten lezen. Schadelijke toepassingen kunnen uw vertrouwelijke berichten mogelijk lezen."</string>
-    <string name="permdesc_readSms" product="default" msgid="3002170087197294591">"Hiermee kan een toepassing de op uw telefoon of SIM-kaart opgeslagen SMS-berichten lezen. Schadelijke toepassingen kunnen uw vertrouwelijke berichten mogelijk lezen."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="5836710350295631545">"Hiermee kan een app de op uw tablet of SIM-kaart opgeslagen SMS-berichten lezen. Schadelijke apps kunnen uw vertrouwelijke berichten mogelijk lezen."</string>
+    <string name="permdesc_readSms" product="default" msgid="3002170087197294591">"Hiermee kan een app de op uw telefoon of SIM-kaart opgeslagen SMS-berichten lezen. Schadelijke apps kunnen uw vertrouwelijke berichten mogelijk lezen."</string>
     <string name="permlab_writeSms" msgid="6881122575154940744">"SMS of MMS bewerken"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5332124772918835437">"Hiermee kan een toepassing naar de op uw tablet of SIM-kaart opgeslagen SMS-berichten schrijven. Schadelijke toepassingen kunnen uw berichten mogelijk verwijderen."</string>
-    <string name="permdesc_writeSms" product="default" msgid="6299398896177548095">"Hiermee kan een toepassing naar de op uw telefoon of SIM-kaart opgeslagen SMS-berichten schrijven. Schadelijke toepassingen kunnen uw berichten mogelijk verwijderen."</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5332124772918835437">"Hiermee kan een app naar de op uw tablet of SIM-kaart opgeslagen SMS-berichten schrijven. Schadelijke apps kunnen uw berichten mogelijk verwijderen."</string>
+    <string name="permdesc_writeSms" product="default" msgid="6299398896177548095">"Hiermee kan een app naar de op uw telefoon of SIM-kaart opgeslagen SMS-berichten schrijven. Schadelijke apps kunnen uw berichten mogelijk verwijderen."</string>
     <string name="permlab_receiveWapPush" msgid="8258226427716551388">"WAP ontvangen"</string>
-    <string name="permdesc_receiveWapPush" msgid="5979623826128082171">"Hiermee kan een toepassing WAP-berichten ontvangen en verwerken. Schadelijke toepassingen kunnen uw berichten bijhouden of deze verwijderen zonder dat u ze te zien krijgt."</string>
+    <string name="permdesc_receiveWapPush" msgid="5979623826128082171">"Hiermee kan een app WAP-berichten ontvangen en verwerken. Schadelijke apps kunnen uw berichten bijhouden of deze verwijderen zonder dat u ze te zien krijgt."</string>
     <string name="permlab_getTasks" msgid="5005277531132573353">"actieve toepassingen ophalen"</string>
-    <string name="permdesc_getTasks" msgid="7048711358713443341">"Hiermee kan een toepassing informatie over huidige en recent uitgevoerde taken ophalen. Schadelijke toepassingen kunnen op deze manier mogelijk privé-informatie over andere toepassingen achterhalen."</string>
+    <string name="permdesc_getTasks" msgid="7048711358713443341">"Hiermee kan een app informatie over huidige en recent uitgevoerde taken ophalen. Schadelijke apps kunnen op deze manier mogelijk privé-informatie over andere apps achterhalen."</string>
     <string name="permlab_reorderTasks" msgid="5669588525059921549">"actieve toepassingen opnieuw indelen"</string>
-    <string name="permdesc_reorderTasks" msgid="126252774270522835">"Hiermee kan een toepassing taken naar de voor- en achtergrond verplaatsen. Schadelijke toepassingen kunnen zichzelf op de voorgrond plaatsen zonder dat u hier iets aan kunt doen."</string>
+    <string name="permdesc_reorderTasks" msgid="126252774270522835">"Hiermee kan een app taken naar de voor- en achtergrond verplaatsen. Schadelijke apps kunnen zichzelf op de voorgrond plaatsen zonder dat u hier iets aan kunt doen."</string>
     <string name="permlab_setDebugApp" msgid="4339730312925176742">"foutopsporing in toepassingen inschakelen"</string>
-    <string name="permdesc_setDebugApp" msgid="5584310661711990702">"Hiermee kan een toepassing de foutopsporing voor een andere toepassing inschakelen. Schadelijke toepassingen kunnen dit gebruiken om andere toepassingen af te sluiten."</string>
+    <string name="permdesc_setDebugApp" msgid="5584310661711990702">"Hiermee kan een app de foutopsporing voor een andere app inschakelen. Schadelijke apps kunnen dit gebruiken om andere apps af te sluiten."</string>
     <string name="permlab_changeConfiguration" msgid="8214475779521218295">"uw UI-instellingen wijzigen"</string>
-    <string name="permdesc_changeConfiguration" msgid="3465121501528064399">"Hiermee kan een toepassing de huidige configuratie, zoals de landinstelling of de algemene lettergrootte, wijzigen."</string>
+    <string name="permdesc_changeConfiguration" msgid="3465121501528064399">"Hiermee kan een app de huidige configuratie, zoals de landinstelling of de algemene lettergrootte, wijzigen."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"automodus inschakelen"</string>
-    <string name="permdesc_enableCarMode" msgid="5673461159384850628">"Staat een toepassing toe de automodus in te schakelen."</string>
+    <string name="permdesc_enableCarMode" msgid="5673461159384850628">"Staat een app toe de automodus in te schakelen."</string>
     <string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"processen op de achtergrond beëindigen"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="2908829602869383753">"Staat een toepassing toe processen op de achtergrond te beëindigen, zelfs als er voldoende geheugen beschikbaar is."</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="2908829602869383753">"Staat een app toe processen op de achtergrond te beëindigen, zelfs als er voldoende geheugen beschikbaar is."</string>
     <string name="permlab_forceStopPackages" msgid="1447830113260156236">"andere toepassingen gedwongen stoppen"</string>
-    <string name="permdesc_forceStopPackages" msgid="7263036616161367402">"Staat een toepassing toe andere toepassingen te stoppen."</string>
-    <string name="permlab_forceBack" msgid="1804196839880393631">"toepassing nu sluiten"</string>
-    <string name="permdesc_forceBack" msgid="6534109744159919013">"Hiermee kan een toepassing elke willekeurige activiteit die op de voorgrond wordt uitgevoerd, sluiten en naar de achtergrond verplaatsen. Nooit vereist voor normale toepassingen."</string>
+    <string name="permdesc_forceStopPackages" msgid="7263036616161367402">"Staat een app toe andere apps te stoppen."</string>
+    <string name="permlab_forceBack" msgid="1804196839880393631">"app nu sluiten"</string>
+    <string name="permdesc_forceBack" msgid="6534109744159919013">"Hiermee kan een app elke willekeurige activiteit die op de voorgrond wordt uitgevoerd, sluiten en naar de achtergrond verplaatsen. Nooit vereist voor normale apps."</string>
     <string name="permlab_dump" msgid="1681799862438954752">"interne systeemstatus ophalen"</string>
-    <string name="permdesc_dump" msgid="2198776174276275220">"Hiermee kan een toepassing de interne status van het systeem ophalen. Schadelijke toepassingen kunnen privé- of veiligheidsgegevens ophalen die ze normaal niet nodig hebben."</string>
+    <string name="permdesc_dump" msgid="2198776174276275220">"Hiermee kan een app de interne status van het systeem ophalen. Schadelijke apps kunnen privé- of veiligheidsgegevens ophalen die ze normaal niet nodig hebben."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"gedeeltelijke uitschakeling"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Hiermee wordt activiteitenbeheer uitgeschakeld. Er wordt geen volledige uitschakeling uitgevoerd."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"schakelen tussen toepassingen voorkomen"</string>
-    <string name="permdesc_stopAppSwitches" msgid="3857886086919033794">"Hiermee wordt voorkomen dat de gebruiker overschakelt naar een andere toepassing."</string>
+    <string name="permdesc_stopAppSwitches" msgid="3857886086919033794">"Hiermee wordt voorkomen dat de gebruiker overschakelt naar een andere app."</string>
     <string name="permlab_runSetActivityWatcher" msgid="7811586187574696296">"alle startende toepassingen bijhouden en beheren"</string>
-    <string name="permdesc_runSetActivityWatcher" msgid="2149363027173451218">"Hiermee kan een toepassing de manier waarop het systeem activiteiten start, bijhouden en beheren. Schadelijke toepassingen kunnen het systeem volledig in gevaar brengen. Deze machtiging is alleen voor ontwikkeling vereist, nooit voor normaal gebruik."</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="2149363027173451218">"Hiermee kan een app de manier waarop het systeem activiteiten start, bijhouden en beheren. Schadelijke apps kunnen het systeem volledig in gevaar brengen. Deze machtiging is alleen voor ontwikkeling vereist, nooit voor normaal gebruik."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"melding verzenden dat pakket is verwijderd"</string>
-    <string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"Hiermee kan een toepassing een melding verzenden dat een toepassingspakket is verwijderd. Schadelijke toepassingen kunnen hiervan gebruik maken om alle andere actieve toepassingen af te sluiten."</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"Hiermee kan een app een melding verzenden dat een applicatiepakket (APK) is verwijderd. Schadelijke apps kunnen hiervan gebruik maken om alle andere actieve apps af te sluiten."</string>
     <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"melding over ontvangen SMS-bericht verzenden"</string>
-    <string name="permdesc_broadcastSmsReceived" msgid="9122419277306740155">"Hiermee kan een toepassing een melding verzenden dat een SMS-bericht is ontvangen. Schadelijke toepassingen kunnen hiervan gebruik maken om inkomende SMS-berichten te vervalsen."</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="9122419277306740155">"Hiermee kan een app een melding verzenden dat een SMS-bericht is ontvangen. Schadelijke apps kunnen hiervan gebruik maken om inkomende SMS-berichten te vervalsen."</string>
     <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"melding over ontvangen WAP-PUSH-bericht verzenden"</string>
-    <string name="permdesc_broadcastWapPush" msgid="3955303669461378091">"Hiermee kan een toepassing een melding verzenden dat een WAP PUSH-bericht is ontvangen. Schadelijke toepassingen kunnen hiervan gebruik maken om een valse MMS-ontvangst te melden of de inhoud van willekeurige webpagina\'s door schadelijke varianten te vervangen."</string>
+    <string name="permdesc_broadcastWapPush" msgid="3955303669461378091">"Hiermee kan een app een melding verzenden dat een WAP PUSH-bericht is ontvangen. Schadelijke apps kunnen hiervan gebruik maken om een valse MMS-ontvangst te melden of de inhoud van willekeurige webpagina\'s door schadelijke varianten te vervangen."</string>
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"aantal actieve processen beperken"</string>
-    <string name="permdesc_setProcessLimit" msgid="7824786028557379539">"Hiermee kan een toepassing het maximum aantal processen bepalen dat wordt uitgevoerd. Nooit vereist voor normale toepassingen."</string>
+    <string name="permdesc_setProcessLimit" msgid="7824786028557379539">"Hiermee kan een app het maximum aantal processen bepalen dat wordt uitgevoerd. Nooit vereist voor normale apps."</string>
     <string name="permlab_setAlwaysFinish" msgid="5342837862439543783">"alle achtergrondtoepassingen sluiten"</string>
-    <string name="permdesc_setAlwaysFinish" msgid="8773936403987091620">"Hiermee kan een toepassing bepalen of activiteiten altijd worden afgesloten zodra deze naar de achtergrond gaan. Nooit nodig voor normale toepassingen."</string>
+    <string name="permdesc_setAlwaysFinish" msgid="8773936403987091620">"Hiermee kan een app bepalen of activiteiten altijd worden afgesloten zodra deze naar de achtergrond gaan. Nooit nodig voor normale apps."</string>
     <string name="permlab_batteryStats" msgid="7863923071360031652">"accustatistieken aanpassen"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Hiermee kunnen verzamelde accustatistieken worden gewijzigd. Niet voor gebruik door normale toepassingen."</string>
     <string name="permlab_backup" msgid="470013022865453920">"systeemback-up en -herstel beheren"</string>
-    <string name="permdesc_backup" msgid="4837493065154256525">"Hiermee kan de toepassing het mechanisme voor systeemback-up en -herstel beheren. Niet voor gebruik door normale toepassingen."</string>
+    <string name="permdesc_backup" msgid="4837493065154256525">"Hiermee kan de app het mechanisme voor systeemback-up en -herstel beheren. Niet voor gebruik door normale apps."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"niet-geautoriseerde vensters weergeven"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Hiermee kunnen vensters worden gemaakt die door de interne systeemgebruikersinterface worden gebruikt. Niet voor gebruik door normale toepassingen."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"waarschuwingen op systeemniveau weergeven"</string>
-    <string name="permdesc_systemAlertWindow" msgid="2884149573672821318">"Hiermee kan een toepassing systeemwaarschuwingen weergeven. Schadelijke toepassingen kunnen op deze manier het hele scherm van de tablet overnemen."</string>
+    <string name="permdesc_systemAlertWindow" msgid="2884149573672821318">"Hiermee kan een app systeemwaarschuwingen weergeven. Schadelijke apps kunnen op deze manier het hele scherm van de tablet overnemen."</string>
     <string name="permlab_setAnimationScale" msgid="2805103241153907174">"algemene animatiesnelheid wijzigen"</string>
-    <string name="permdesc_setAnimationScale" msgid="7181522138912391988">"Hiermee kan een toepassing op elk gewenst moment de algemene animatiesnelheid wijzigen (snellere of tragere animaties)."</string>
+    <string name="permdesc_setAnimationScale" msgid="7181522138912391988">"Hiermee kan een app op elk gewenst moment de algemene animatiesnelheid wijzigen (snellere of tragere animaties)."</string>
     <string name="permlab_manageAppTokens" msgid="17124341698093865">"toepassingstokens beheren"</string>
     <string name="permdesc_manageAppTokens" msgid="977127907524195988">"Hiermee kunnen toepassingen hun eigen tokens maken en beheren, waarbij de normale Z-volgorde wordt overgeslagen. Nooit nodig voor normale toepassingen."</string>
     <string name="permlab_injectEvents" msgid="1378746584023586600">"drukken op toetsen en bedieningselementen"</string>
-    <string name="permdesc_injectEvents" product="tablet" msgid="7200014808195664505">"Hiermee kan een toepassing zijn eigen invoergebeurtenissen (toetsaanslagen, enzovoort) aan andere toepassingen doorgeven. Schadelijke toepassingen kunnen dit gebruiken om de tablet over te nemen."</string>
-    <string name="permdesc_injectEvents" product="default" msgid="3946098050410874715">"Hiermee kan een toepassing zijn eigen invoergebeurtenissen (toetsaanslagen, enzovoort) aan andere toepassingen doorgeven. Schadelijke toepassingen kunnen dit gebruiken om de telefoon over te nemen."</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="7200014808195664505">"Hiermee kan een app de eigen invoergebeurtenissen (toetsaanslagen, enzovoort) aan andere apps doorgeven. Schadelijke apps kunnen dit gebruiken om de tablet over te nemen."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="3946098050410874715">"Hiermee kan een app zijn de invoergebeurtenissen (toetsaanslagen, enzovoort) aan andere apps doorgeven. Schadelijke apps kunnen dit gebruiken om de telefoon over te nemen."</string>
     <string name="permlab_readInputState" msgid="469428900041249234">"uw invoer en acties vastleggen"</string>
-    <string name="permdesc_readInputState" msgid="5132879321450325445">"Hiermee kan een toepassing uw toetsaanslagen registreren, zelfs tijdens de interactie met een andere toepassing (zoals de invoer van een wachtwoord). Nooit vereist voor normale toepassingen."</string>
+    <string name="permdesc_readInputState" msgid="5132879321450325445">"Hiermee kan een app uw toetsaanslagen registreren, zelfs tijdens de interactie met een andere app (zoals de invoer van een wachtwoord). Nooit vereist voor normale apps."</string>
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"verbinden aan een invoermethode"</string>
     <string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Hiermee staat u de houder toe zich te verbinden met de hoofdinterface van een invoermethode. Nooit vereist voor normale toepassingen."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"verbinden met een achtergrond"</string>
@@ -260,59 +260,59 @@
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactie met apparaatbeheer"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Staat de houder toe intenties te verzenden naar een apparaatbeheerder. Nooit vereist voor normale toepassingen."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"schermstand wijzigen"</string>
-    <string name="permdesc_setOrientation" msgid="6335814461615851863">"Hiermee kan een toepassing op elk gewenst moment de oriëntatie van het scherm wijzigen. Nooit vereist voor normale toepassingen."</string>
+    <string name="permdesc_setOrientation" msgid="6335814461615851863">"Hiermee kan een app op elk gewenst moment de oriëntatie van het scherm wijzigen. Nooit vereist voor normale apps."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"Linux-signalen verzenden naar toepassingen"</string>
-    <string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"Hiermee kan de toepassing ervoor zorgen dat het geleverde signaal wordt verzonden naar alle persistente processen."</string>
-    <string name="permlab_persistentActivity" msgid="8659652042401085862">"toepassing altijd laten uitvoeren"</string>
-    <string name="permdesc_persistentActivity" msgid="5037199778265006008">"Hiermee kan een toepassing delen van zichzelf persistent maken, zodat het systeem dat deel niet voor andere toepassingen kan gebruiken."</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"Hiermee kan de app ervoor zorgen dat het geleverde signaal wordt verzonden naar alle persistente processen."</string>
+    <string name="permlab_persistentActivity" msgid="8659652042401085862">"app altijd laten uitvoeren"</string>
+    <string name="permdesc_persistentActivity" msgid="5037199778265006008">"Hiermee kan een app delen van zichzelf persistent maken, zodat het systeem dat deel niet voor andere apps kan gebruiken."</string>
     <string name="permlab_deletePackages" msgid="3343439331576348805">"toepassingen verwijderen"</string>
-    <string name="permdesc_deletePackages" msgid="3634943677518723314">"Hiermee kan een toepassing Android-pakketten verwijderen. Schadelijke toepassingen kunnen dit gebruiken om belangrijke toepassingen te verwijderen."</string>
+    <string name="permdesc_deletePackages" msgid="3634943677518723314">"Hiermee kan een app Android-pakketten verwijderen. Schadelijke apps kunnen dit gebruiken om belangrijke apps te verwijderen."</string>
     <string name="permlab_clearAppUserData" msgid="2192134353540277878">"gegevens van andere toepassingen verwijderen"</string>
-    <string name="permdesc_clearAppUserData" msgid="7546345080434325456">"Hiermee kan een toepassing gebruikersgegevens wissen."</string>
+    <string name="permdesc_clearAppUserData" msgid="7546345080434325456">"Hiermee kan een app gebruikersgegevens wissen."</string>
     <string name="permlab_deleteCacheFiles" msgid="1518556602634276725">"caches van andere toepassingen verwijderen"</string>
-    <string name="permdesc_deleteCacheFiles" msgid="2283074077168165971">"Hiermee kan een toepassing cachebestanden verwijderen."</string>
-    <string name="permlab_getPackageSize" msgid="4799785352306641460">"opslagruimte van toepassing bepalen"</string>
-    <string name="permdesc_getPackageSize" msgid="5557253039670753437">"Hiermee kan een toepassing de bijbehorende code, gegevens en cachegrootten ophalen."</string>
+    <string name="permdesc_deleteCacheFiles" msgid="2283074077168165971">"Hiermee kan een app cachebestanden verwijderen."</string>
+    <string name="permlab_getPackageSize" msgid="4799785352306641460">"opslagruimte van app bepalen"</string>
+    <string name="permdesc_getPackageSize" msgid="5557253039670753437">"Hiermee kan een app de bijbehorende code, gegevens en cachegrootten ophalen."</string>
     <string name="permlab_installPackages" msgid="335800214119051089">"toepassingen rechtstreeks installeren"</string>
-    <string name="permdesc_installPackages" msgid="526669220850066132">"Hiermee kan een toepassing nieuwe of bijgewerkte Android-pakketten installeren. Schadelijke toepassingen kunnen hiervan gebruik maken om nieuwe toepassingen met willekeurig krachtige machtigingen toe te voegen."</string>
-    <string name="permlab_clearAppCache" msgid="4747698311163766540">"alle cachegegevens van toepassing verwijderen"</string>
-    <string name="permdesc_clearAppCache" product="tablet" msgid="3097119797652477973">"Hiermee kan een toepassing opslagruimte op de tablet vrij maken door bestanden te verwijderen uit de cachemap van de toepassing. De toegang is doorgaans beperkt tot het systeemproces."</string>
-    <string name="permdesc_clearAppCache" product="default" msgid="7740465694193671402">"Hiermee kan een toepassing opslagruimte op de telefoon vrij maken door bestanden te verwijderen uit de cachemap van de toepassing. De toegang is doorgaans beperkt tot het systeemproces."</string>
+    <string name="permdesc_installPackages" msgid="526669220850066132">"Hiermee kan een app nieuwe of bijgewerkte Android-pakketten installeren. Schadelijke apps kunnen hiervan gebruik maken om nieuwe apps met willekeurig krachtige machtigingen toe te voegen."</string>
+    <string name="permlab_clearAppCache" msgid="4747698311163766540">"alle cachegegevens van app verwijderen"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="3097119797652477973">"Hiermee kan een app opslagruimte op de tablet vrij maken door bestanden te verwijderen uit de cachemap van de app. De toegang is doorgaans beperkt tot het systeemproces."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="7740465694193671402">"Hiermee kan een app opslagruimte op de telefoon vrij maken door bestanden te verwijderen uit de cachemap van de app. De toegang is doorgaans beperkt tot het systeemproces."</string>
     <string name="permlab_movePackage" msgid="728454979946503926">"Toepassingsbronnen verplaatsen"</string>
-    <string name="permdesc_movePackage" msgid="6323049291923925277">"Een toepassing toestaan toepassingsbronnen te verplaatsen van interne naar externe media en omgekeerd."</string>
+    <string name="permdesc_movePackage" msgid="6323049291923925277">"Een app toestaan app-bronnen te verplaatsen van interne naar externe media en omgekeerd."</string>
     <string name="permlab_readLogs" msgid="6615778543198967614">"gevoelige logbestandsgegevens lezen"</string>
-    <string name="permdesc_readLogs" product="tablet" msgid="4077356893924755294">"Hiermee kan een toepassing de verschillende logbestanden van het systeem lezen. De toepassing kan op deze manier algemene informatie achterhalen over uw tabletgebruik, mogelijk inclusief persoonlijke of privé-informatie."</string>
-    <string name="permdesc_readLogs" product="default" msgid="8896449437464867766">"Hiermee kan een toepassing de verschillende logbestanden van het systeem lezen. De toepassing kan op deze manier algemene informatie achterhalen over uw telefoongebruik, mogelijk inclusief persoonlijke of privé-informatie."</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="4077356893924755294">"Hiermee kan een app de verschillende logbestanden van het systeem lezen. De app kan op deze manier algemene informatie achterhalen over uw tabletgebruik, mogelijk inclusief persoonlijke of privé-informatie."</string>
+    <string name="permdesc_readLogs" product="default" msgid="8896449437464867766">"Hiermee kan een app de verschillende logbestanden van het systeem lezen. De app kan op deze manier algemene informatie achterhalen over uw telefoongebruik, mogelijk inclusief persoonlijke of privé-informatie."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lezen/schrijven naar bronnen van diag"</string>
-    <string name="permdesc_diagnostic" msgid="3121238373951637049">"Hiermee kan een toepassing lezen en schrijven naar elke bron die hoort bij de diagnostische groep, zoals bestanden in /dev. Hierdoor kan de systeemstabiliteit en -veiligheid worden beïnvloed. Dit mag ALLEEN worden gebruikt voor hardwarespecifieke diagnostiek door de fabrikant of operator."</string>
+    <string name="permdesc_diagnostic" msgid="3121238373951637049">"Hiermee kan een app lezen en schrijven naar elke bron die hoort bij de diagnostische groep, zoals bestanden in /dev. Hierdoor kan de systeemstabiliteit en -veiligheid worden beïnvloed. Dit mag ALLEEN worden gebruikt voor hardwarespecifieke diagnostiek door de fabrikant of operator."</string>
     <string name="permlab_changeComponentState" msgid="79425198834329406">"toepassingscomponenten in- of uitschakelen"</string>
-    <string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Hiermee kan een toepassing bepalen of een component van een andere toepassing is ingeschakeld. Schadelijke toepassingen kunnen hiervan gebruik maken om belangrijke tabletfuncties uit te schakelen. Een machtiging moet zorgvuldig worden overwogen, aangezien toepassingscomponenten onbruikbaar, inconsistent of instabiel kunnen worden."</string>
-    <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Hiermee kan een toepassing bepalen of een component van een andere toepassing is ingeschakeld. Schadelijke toepassingen kunnen dit gebruiken om belangrijke telefoonfuncties uit te schakelen. Een machtiging moet zorgvuldig worden overwogen, aangezien toepassingscomponenten onbruikbaar, inconsistent of instabiel kunnen worden."</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Hiermee kan een app bepalen of een component van een andere app is ingeschakeld. Schadelijke apps kunnen hiervan gebruik maken om belangrijke tabletfuncties uit te schakelen. Een machtiging moet zorgvuldig worden overwogen, aangezien app-componenten onbruikbaar, inconsistent of instabiel kunnen worden."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Hiermee kan een app bepalen of een component van een andere app is ingeschakeld. Schadelijke apps kunnen dit gebruiken om belangrijke telefoonfuncties uit te schakelen. Een machtiging moet zorgvuldig worden overwogen, aangezien app-componenten onbruikbaar, inconsistent of instabiel kunnen worden."</string>
     <string name="permlab_setPreferredApplications" msgid="3393305202145172005">"voorkeurstoepassingen instellen"</string>
-    <string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Hiermee kan een toepassing uw voorkeurstoepassingen wijzigen. Schadelijke toepassingen kunnen op deze manier de actieve toepassingen zonder uw medeweten wijzigen en uw bestaande toepassingen doorzoeken om privégegevens van u te verzamelen."</string>
+    <string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Hiermee kan een app uw voorkeurs-apps wijzigen. Schadelijke apps kunnen op deze manier de actieve apps zonder uw medeweten wijzigen en uw bestaande apps doorzoeken om privégegevens van u te verzamelen."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"algemene systeeminstellingen wijzigen"</string>
-    <string name="permdesc_writeSettings" msgid="838789419871034696">"Hiermee kan een toepassing de systeeminstellingen wijzigen. Schadelijke toepassingen kunnen hiermee uw systeemconfiguratie beschadigen."</string>
+    <string name="permdesc_writeSettings" msgid="838789419871034696">"Hiermee kan een app de systeeminstellingen wijzigen. Schadelijke apps kunnen hiermee uw systeemconfiguratie beschadigen."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"beveiligde systeeminstellingen wijzigen"</string>
-    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Hiermee kan een toepassing beveiligde systeeminstellingen wijzigen. Niet voor gebruik door normale toepassingen."</string>
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Hiermee kan een app beveiligde systeeminstellingen wijzigen. Niet voor gebruik door normale apps."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"de Google-serviceskaart wijzigen"</string>
-    <string name="permdesc_writeGservices" msgid="6602362746516676175">"Hiermee kan een toepassing de Google-serviceskaart wijzigen. Niet voor gebruik door normale toepassingen."</string>
+    <string name="permdesc_writeGservices" msgid="6602362746516676175">"Hiermee kan een app de Google-serviceskaart wijzigen. Niet voor gebruik door normale apps."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"automatisch starten bij opstarten"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7530977064379338199">"Hiermee kan een toepassing zichzelf starten zodra het systeem klaar is met opstarten. Hierdoor kan het langer duren voordat de tablet is opgestart en kan de toepassing de tabletprocessen vertragen door altijd actief te zijn."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="698336728415008796">"Hiermee kan een toepassing zichzelf starten zodra het systeem klaar is met opstarten. Hierdoor kan het langer duren voordat de telefoon is opgestart en kan de toepassing de telefoonprocessen vertragen door altijd actief te zijn."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7530977064379338199">"Hiermee kan een app zichzelf starten zodra het systeem klaar is met opstarten. Hierdoor kan het langer duren voordat de tablet is opgestart en kan de app de tabletprocessen vertragen door altijd actief te zijn."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="698336728415008796">"Hiermee kan een app zichzelf starten zodra het systeem klaar is met opstarten. Hierdoor kan het langer duren voordat de telefoon is opgestart en kan de app de telefoonprocessen vertragen door altijd actief te zijn."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"sticky broadcast verzenden"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="6322249605930062595">"Hiermee kan een toepassing sticky broadcasts verzenden die achterblijven als de broadcast eindigt. Schadelijke toepassingen kunnen hiermee de tablet traag of instabiel maken door ervoor te zorgen dat er te veel geheugenruimte wordt gebruikt."</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="1920045289234052219">"Hiermee kan een toepassing sticky broadcasts verzenden die achterblijven als de broadcast eindigt. Schadelijke toepassingen kunnen hiermee de telefoon traag of instabiel maken door ervoor te zorgen dat er te veel geheugenruimte wordt gebruikt."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="6322249605930062595">"Hiermee kan een app sticky broadcasts verzenden die achterblijven als de broadcast eindigt. Schadelijke apps kunnen hiermee de tablet traag of instabiel maken door ervoor te zorgen dat er te veel geheugenruimte wordt gebruikt."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="1920045289234052219">"Hiermee kan een app sticky broadcasts verzenden die achterblijven als de broadcast eindigt. Schadelijke apps kunnen hiermee de telefoon traag of instabiel maken door ervoor te zorgen dat er te veel geheugenruimte wordt gebruikt."</string>
     <string name="permlab_readContacts" msgid="6219652189510218240">"contactgegevens lezen"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="7596158687301157686">"Hiermee kan een toepassing alle contactgegevens (adresgegevens) zien die op uw tablet zijn opgeslagen. Schadelijke toepassingen kunnen hiervan gebruik maken om uw gegevens te verzenden naar andere personen."</string>
-    <string name="permdesc_readContacts" product="default" msgid="3371591512896545975">"Hiermee kan een toepassing alle contactgegevens (adresgegevens) zien die op uw telefoon zijn opgeslagen. Schadelijke toepassingen kunnen hiervan gebruik maken om uw gegevens te verzenden naar andere personen."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="7596158687301157686">"Hiermee kan een app alle contactgegevens (adresgegevens) zien die op uw tablet zijn opgeslagen. Schadelijke apps kunnen hiervan gebruik maken om uw gegevens te verzenden naar andere personen."</string>
+    <string name="permdesc_readContacts" product="default" msgid="3371591512896545975">"Hiermee kan een app alle contactgegevens (adresgegevens) zien die op uw telefoon zijn opgeslagen. Schadelijke apps kunnen hiervan gebruik maken om uw gegevens te verzenden naar andere personen."</string>
     <string name="permlab_writeContacts" msgid="644616215860933284">"contactgegevens schrijven"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="7782689510038568495">"Hiermee kan een toepassing de op uw tablet opgeslagen contactgegevens (adresgegevens) wijzigen. Schadelijke toepassingen kunnen hiermee uw contactgegevens verwijderen of wijzigen."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="3924383579108183601">"Hiermee kan een toepassing de op uw telefoon opgeslagen contactgegevens (adresgegevens) wijzigen. Schadelijke toepassingen kunnen hiermee uw contactgegevens verwijderen of wijzigen."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="7782689510038568495">"Hiermee kan een app de op uw tablet opgeslagen contactgegevens (adresgegevens) wijzigen. Schadelijke apps kunnen hiermee uw contactgegevens verwijderen of wijzigen."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="3924383579108183601">"Hiermee kan een app de op uw telefoon opgeslagen contactgegevens (adresgegevens) wijzigen. Schadelijke apps kunnen hiermee uw contactgegevens verwijderen of wijzigen."</string>
     <string name="permlab_readCalendar" msgid="6898987798303840534">"agendagebeurtenissen lezen"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="5905870265734599678">"Hiermee kan een toepassing alle agendagebeurtenissen lezen die zijn opgeslagen op uw tablet. Schadelijke toepassingen kunnen hiervan gebruik maken om uw agendagebeurtenissen te verzenden naar andere personen."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="5533029139652095734">"Hiermee kan een toepassing alle agendagebeurtenissen lezen die zijn opgeslagen op uw telefoon. Schadelijke toepassingen kunnen hiervan gebruik maken om uw agendagebeurtenissen te verzenden naar andere personen."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="5905870265734599678">"Hiermee kan een app alle agendagebeurtenissen lezen die zijn opgeslagen op uw tablet. Schadelijke apps kunnen hiervan gebruik maken om uw agendagebeurtenissen te verzenden naar andere personen."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="5533029139652095734">"Hiermee kan een app alle agendagebeurtenissen lezen die zijn opgeslagen op uw telefoon. Schadelijke apps kunnen hiervan gebruik maken om uw agendagebeurtenissen te verzenden naar andere personen."</string>
     <string name="permlab_writeCalendar" msgid="3894879352594904361">"agendagebeurtenissen toevoegen of aanpassen en e-mail verzenden naar gasten"</string>
-    <string name="permdesc_writeCalendar" msgid="2988871373544154221">"Een toepassing toestaan gebeurtenissen aan uw agenda toe te voegen of te wijzigen, wat inhoudt dat er e-mails kunnen worden verzonden naar gasten. Schadelijke toepassingen kunnen dit gebruiken om uw agendagebeurtenissen te wissen of aan te passen of om e-mail naar gasten te verzenden."</string>
+    <string name="permdesc_writeCalendar" msgid="2988871373544154221">"Een app toestaan gebeurtenissen aan uw agenda toe te voegen of te wijzigen, wat inhoudt dat er e-mails kunnen worden verzonden naar gasten. Schadelijke apps kunnen dit gebruiken om uw agendagebeurtenissen te wissen of aan te passen of om e-mail naar gasten te verzenden."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"neplocatiebronnen voor test"</string>
     <string name="permdesc_accessMockLocation" msgid="7648286063459727252">"Neplocatiebronnen voor testdoeleinden maken. Schadelijke toepassingen kunnen dit gebruiken om de locatie en/of status te overschrijven die door de echte locatiebronnen wordt aangegeven, zoals GPS of netwerkaanbieders."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"toegang tot extra opdrachten van locatieaanbieder"</string>
@@ -326,150 +326,150 @@
     <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3704633168985466045">"Toegang tot globale locatiebronnen, zoals de mobiele netwerkdatabase om een globale tabletlocatie te bepalen, indien beschikbaar. Schadelijke toepassingen kunnen hiervan gebruik maken om bij benadering te bepalen waar u zich bevindt."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="8235655958070862293">"Toegang tot globale locatiebronnen, zoals de mobiele netwerkdatabase om een globale telefoonlocatie te bepalen, indien beschikbaar. Schadelijke toepassingen kunnen hiervan gebruik maken om bij benadering te bepalen waar u zich bevindt."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"toegang tot SurfaceFlinger"</string>
-    <string name="permdesc_accessSurfaceFlinger" msgid="6805241830020733025">"Hiermee kan een toepassing SurfaceFlinger-functies op laag niveau gebruiken."</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="6805241830020733025">"Hiermee kan een app SurfaceFlinger-functies op laag niveau gebruiken."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"framebuffer lezen"</string>
-    <string name="permdesc_readFrameBuffer" msgid="7530020370469942528">"Hiermee kan een toepassing de inhoud van de framebuffer lezen."</string>
+    <string name="permdesc_readFrameBuffer" msgid="7530020370469942528">"Hiermee kan een app de inhoud van de framebuffer lezen."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"uw audio-instellingen wijzigen"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="5793461287365991922">"Hiermee kan een toepassing de algemene audio-instellingen, zoals volume en omleiding, wijzigen."</string>
+    <string name="permdesc_modifyAudioSettings" msgid="5793461287365991922">"Hiermee kan een app de algemene audio-instellingen, zoals volume en omleiding, wijzigen."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"audio opnemen"</string>
-    <string name="permdesc_recordAudio" msgid="6493228261176552356">"Hiermee krijgt de toepassing toegang tot het audio-opnamepad."</string>
+    <string name="permdesc_recordAudio" msgid="6493228261176552356">"Hiermee krijgt de app toegang tot het audio-opnamepad."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"foto\'s en video\'s maken"</string>
-    <string name="permdesc_camera" msgid="6004878235852154239">"Hiermee kan een toepassing foto\'s en video\'s maken met de camera. De toepassing kan op deze manier op elk gewenste moment beelden verzamelen van wat de camera ziet."</string>
+    <string name="permdesc_camera" msgid="6004878235852154239">"Hiermee kan een app foto\'s en video\'s maken met de camera. De app kan op deze manier op elk gewenste moment beelden verzamelen van wat de camera ziet."</string>
     <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"tablet permanent uitschakelen"</string>
     <string name="permlab_brick" product="default" msgid="8337817093326370537">"telefoon permanent uitschakelen"</string>
-    <string name="permdesc_brick" product="tablet" msgid="7379164636920817963">"Hiermee kan de toepassing de tablet permanent uitschakelen. Dit is erg gevaarlijk."</string>
-    <string name="permdesc_brick" product="default" msgid="5569526552607599221">"Hiermee kan de toepassing de telefoon permanent uitschakelen. Dit is erg gevaarlijk."</string>
+    <string name="permdesc_brick" product="tablet" msgid="7379164636920817963">"Hiermee kan de app de tablet permanent uitschakelen. Dit is erg gevaarlijk."</string>
+    <string name="permdesc_brick" product="default" msgid="5569526552607599221">"Hiermee kan de app de telefoon permanent uitschakelen. Dit is erg gevaarlijk."</string>
     <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"opnieuw opstarten van tablet afdwingen"</string>
     <string name="permlab_reboot" product="default" msgid="2898560872462638242">"telefoon nu opnieuw opstarten"</string>
-    <string name="permdesc_reboot" product="tablet" msgid="4555793623560701557">"Hiermee kan de toepassing de tablet nu opnieuw opstarten."</string>
-    <string name="permdesc_reboot" product="default" msgid="7914933292815491782">"Hiermee kan de toepassing de telefoon nu opnieuw opstarten."</string>
+    <string name="permdesc_reboot" product="tablet" msgid="4555793623560701557">"Hiermee kan de app de tablet opnieuw opstarten."</string>
+    <string name="permdesc_reboot" product="default" msgid="7914933292815491782">"Hiermee kan de app de telefoon nu opnieuw opstarten."</string>
     <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"bestandssystemen koppelen en ontkoppelen"</string>
-    <string name="permdesc_mount_unmount_filesystems" msgid="6253263792535859767">"Hiermee kan de toepassing bestandssystemen koppelen en ontkoppelen voor verwisselbare opslagruimte."</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="6253263792535859767">"Hiermee kan de app bestandssystemen koppelen en ontkoppelen voor verwisselbare opslagruimte."</string>
     <string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"externe opslag formatteren"</string>
-    <string name="permdesc_mount_format_filesystems" msgid="574060044906047386">"Hiermee kan de toepassing de externe opslag formatteren."</string>
+    <string name="permdesc_mount_format_filesystems" msgid="574060044906047386">"Hiermee kan de app de externe opslag formatteren."</string>
     <string name="permlab_asec_access" msgid="3411338632002193846">"informatie over de interne opslag verkrijgen"</string>
-    <string name="permdesc_asec_access" msgid="8820326551687285439">"Hiermee kan de toepassing informatie over de interne opslag verkrijgen."</string>
+    <string name="permdesc_asec_access" msgid="8820326551687285439">"Hiermee kan de app informatie over de interne opslag verkrijgen."</string>
     <string name="permlab_asec_create" msgid="6414757234789336327">"interne opslag maken"</string>
-    <string name="permdesc_asec_create" msgid="2621346764995731250">"Hiermee kan de toepassing interne opslag maken."</string>
+    <string name="permdesc_asec_create" msgid="2621346764995731250">"Hiermee kan de app interne opslag maken."</string>
     <string name="permlab_asec_destroy" msgid="526928328301618022">"interne opslag vernietigen"</string>
-    <string name="permdesc_asec_destroy" msgid="2746706889208066256">"Hiermee kan de toepassing de interne opslag vernietigen."</string>
+    <string name="permdesc_asec_destroy" msgid="2746706889208066256">"Hiermee kan de app de interne opslag vernietigen."</string>
     <string name="permlab_asec_mount_unmount" msgid="2456287623689029744">"interne opslag koppelen/ontkoppelen"</string>
-    <string name="permdesc_asec_mount_unmount" msgid="5934375590189368200">"Hiermee kan de toepassing de interne opslag koppelen/ontkoppelen."</string>
+    <string name="permdesc_asec_mount_unmount" msgid="5934375590189368200">"Hiermee kan de app de interne opslag koppelen/ontkoppelen."</string>
     <string name="permlab_asec_rename" msgid="7496633954080472417">"naam van interne opslag wijzigen"</string>
-    <string name="permdesc_asec_rename" msgid="2152829985238876790">"Hiermee kan de toepassing de naam van de interne opslag wijzigen."</string>
+    <string name="permdesc_asec_rename" msgid="2152829985238876790">"Hiermee kan de app de naam van de interne opslag wijzigen."</string>
     <string name="permlab_vibrate" msgid="7768356019980849603">"trilstand beheren"</string>
-    <string name="permdesc_vibrate" msgid="2886677177257789187">"Hiermee kan de toepassing de trilstand beheren."</string>
+    <string name="permdesc_vibrate" msgid="2886677177257789187">"Hiermee kan de app de trilstand beheren."</string>
     <string name="permlab_flashlight" msgid="2155920810121984215">"zaklamp bedienen"</string>
-    <string name="permdesc_flashlight" msgid="6433045942283802309">"Hiermee kan de toepassing de zaklamp bedienen."</string>
+    <string name="permdesc_flashlight" msgid="6433045942283802309">"Hiermee kan de app de zaklamp bedienen."</string>
     <string name="permlab_accessUsb" msgid="7362327818655760496">"toegang krijgen tot USB-apparaten"</string>
-    <string name="permdesc_accessUsb" msgid="2414271762914049292">"Hiermee kan de toepassing toegang krijgen tot USB-apparaten."</string>
+    <string name="permdesc_accessUsb" msgid="2414271762914049292">"Hiermee kan de app toegang krijgen tot USB-apparaten."</string>
     <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP-protocol implementeren"</string>
     <string name="permdesc_accessMtp" msgid="6532961200486791570">"Staat toegang tot de kernel van de MTP-driver toe voor het implementeren van het MTP-USB-protocol."</string>
     <string name="permlab_hardware_test" msgid="4148290860400659146">"hardware testen"</string>
-    <string name="permdesc_hardware_test" msgid="3668894686500081699">"Hiermee kan de toepassing verschillende randapparaten beheren om de hardware te testen."</string>
+    <string name="permdesc_hardware_test" msgid="3668894686500081699">"Hiermee kan de app verschillende randapparaten beheren om de hardware te testen."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"telefoonnummers rechtstreeks bellen"</string>
-    <string name="permdesc_callPhone" msgid="3369867353692722456">"Hiermee kan de toepassing telefoonnummers bellen zonder uw tussenkomst. Door schadelijke toepassingen kunnen onverwachte oproepen op uw telefoonrekening verschijnen. De toepassing kan hiermee geen alarmnummers bellen."</string>
+    <string name="permdesc_callPhone" msgid="3369867353692722456">"Hiermee kan de app telefoonnummers bellen zonder uw tussenkomst. Door schadelijke apps kunnen onverwachte oproepen op uw telefoonrekening verschijnen. De app kan hiermee geen alarmnummers bellen."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"alle telefoonnummers rechtstreeks bellen"</string>
-    <string name="permdesc_callPrivileged" msgid="244405067160028452">"Hiermee kan een toepassing elk telefoonnummer, inclusief alarmnummers, bellen zonder uw tussenkomst. Schadelijke toepassingen kunnen onnodige en illegale oproepen uitvoeren naar alarmdiensten."</string>
+    <string name="permdesc_callPrivileged" msgid="244405067160028452">"Hiermee kan een app elk telefoonnummer, inclusief alarmnummers, bellen zonder uw tussenkomst. Schadelijke apps kunnen onnodige en illegale oproepen uitvoeren naar alarmdiensten."</string>
     <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"meteen starten met CDMA-tabletinstelling"</string>
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"meteen starten met CDMA-telefooninstelling"</string>
-    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Hiermee kan de toepassing starten met CDMA-provisioning. Schadelijke applicaties kunnen de CDMA-provisioning onnodig starten"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Hiermee kan de app starten met CDMA-provisioning. Schadelijke apps kunnen de CDMA-provisioning onnodig starten"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"meldingen over locatie-updates beheren"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Hiermee kunnen updatemeldingen voor locaties van de radio worden ingeschakeld/uitgeschakeld. Niet voor gebruik door normale toepassingen."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"toegang tot checkin-eigenschappen"</string>
     <string name="permdesc_checkinProperties" msgid="7150307006141883832">"Hiermee wordt lees-/schrijftoegang gegeven tot eigenschappen die door de checkin-service zijn geüpload. Niet voor gebruik door normale toepassingen."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"widgets kiezen"</string>
-    <string name="permdesc_bindGadget" msgid="2098697834497452046">"Hiermee kan een toepassing het systeem melden welke widgets door welke toepassing kunnen worden gebruikt. Met deze toestemming kunnen toepassingen andere toepassingen toegang geven tot persoonlijke gegevens. Niet voor gebruik door normale toepassingen."</string>
+    <string name="permdesc_bindGadget" msgid="2098697834497452046">"Hiermee kan een app het systeem melden welke widgets door welke app kunnen worden gebruikt. Met deze toestemming kunnen apps andere apps toegang geven tot persoonlijke gegevens. Niet voor gebruik door normale apps."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"telefoonstatus wijzigen"</string>
-    <string name="permdesc_modifyPhoneState" msgid="3302284561346956587">"Hiermee kan de toepassing de telefoonfuncties van het apparaat beheren. Een toepassing met deze machtiging kan schakelen tussen netwerken, de radio van de telefoon in- of uitschakelen en dergelijke zonder dat u hiervan op de hoogte wordt gesteld."</string>
+    <string name="permdesc_modifyPhoneState" msgid="3302284561346956587">"Hiermee kan de app de telefoonfuncties van het apparaat beheren. Een app met deze machtiging kan schakelen tussen netwerken, de radio van de telefoon in- of uitschakelen en dergelijke zonder dat u hiervan op de hoogte wordt gesteld."</string>
     <string name="permlab_readPhoneState" msgid="2326172951448691631">"telefoonstatus en -identiteit lezen"</string>
-    <string name="permdesc_readPhoneState" msgid="188877305147626781">"Hiermee krijgt de toepassing toegang tot de telefoonfuncties van het apparaat. Een toepassing met de betreffende machtiging kan het telefoonnummer en serienummer van deze telefoon achterhalen, bepalen of een oproep actief is, het gekozen nummer achterhalen en dergelijke."</string>
+    <string name="permdesc_readPhoneState" msgid="188877305147626781">"Hiermee krijgt de app toegang tot de telefoonfuncties van het apparaat. Een app met de betreffende machtiging kan het telefoonnummer en serienummer van deze telefoon achterhalen, bepalen of een oproep actief is, het gekozen nummer achterhalen en dergelijke."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"voorkomen dat tablet overschakelt naar slaapmodus"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"voorkomen dat telefoon overschakelt naar slaapmodus"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="4032181488045338551">"Hiermee kan een toepassing voorkomen dat de tablet overschakelt naar de slaapmodus."</string>
-    <string name="permdesc_wakeLock" product="default" msgid="7584036471227467099">"Hiermee kan een toepassing voorkomen dat de telefoon overschakelt naar de slaapmodus."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="4032181488045338551">"Hiermee kan een app voorkomen dat de tablet overschakelt naar de slaapmodus."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="7584036471227467099">"Hiermee kan een app voorkomen dat de telefoon overschakelt naar de slaapmodus."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"tablet in- of uitschakelen"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefoon in- of uitschakelen"</string>
-    <string name="permdesc_devicePower" product="tablet" msgid="3853773100100451905">"Hiermee kan de toepassing de tablet in- of uitschakelen."</string>
-    <string name="permdesc_devicePower" product="default" msgid="4577331933252444818">"Hiermee kan de toepassing de telefoon in- of uitschakelen."</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="3853773100100451905">"Hiermee kan de app de tablet in- of uitschakelen."</string>
+    <string name="permdesc_devicePower" product="default" msgid="4577331933252444818">"Hiermee kan de app de telefoon in- of uitschakelen."</string>
     <string name="permlab_factoryTest" msgid="3715225492696416187">"uitvoeren in fabriekstestmodus"</string>
     <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Uitvoeren als fabrikanttest op laag niveau, waardoor toegang wordt gegeven tot de hardware van de tablet. Alleen beschikbaar als een tablet zich in de fabrikanttestmodus bevindt."</string>
     <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Uitvoeren als fabrikanttest op laag niveau, waardoor toegang wordt gegeven tot de hardware van de telefoon. Alleen beschikbaar als een telefoon zich in de fabrikanttestmodus bevindt."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"achtergrond instellen"</string>
-    <string name="permdesc_setWallpaper" msgid="6417041752170585837">"Hiermee kan de toepassing de systeemachtergrond instellen."</string>
+    <string name="permdesc_setWallpaper" msgid="6417041752170585837">"Hiermee kan de app de systeemachtergrond instellen."</string>
     <string name="permlab_setWallpaperHints" msgid="3600721069353106851">"grootte achtergrond instellen"</string>
-    <string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"Hiermee kan de toepassing de grootte van de achtergrond instellen."</string>
+    <string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"Hiermee kan de app de grootte van de achtergrond instellen."</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"systeem terugzetten op fabrieksinstellingen"</string>
-    <string name="permdesc_masterClear" msgid="5033465107545174514">"Hiermee kan een toepassing het systeem terugzetten op de fabrieksinstellingen, waarbij alle gegevens, configuraties en geïnstalleerde toepassingen worden verwijderd."</string>
+    <string name="permdesc_masterClear" msgid="5033465107545174514">"Hiermee kan een app het systeem terugzetten op de fabrieksinstellingen, waarbij alle gegevens, configuraties en geïnstalleerde apps worden verwijderd."</string>
     <string name="permlab_setTime" msgid="2021614829591775646">"tijd instellen"</string>
-    <string name="permdesc_setTime" product="tablet" msgid="209693136361006073">"Staat een toepassing toe de kloktijd van de tablet te wijzigen."</string>
-    <string name="permdesc_setTime" product="default" msgid="667294309287080045">"Staat een toepassing toe de kloktijd van de telefoon te wijzigen."</string>
+    <string name="permdesc_setTime" product="tablet" msgid="209693136361006073">"Staat een app toe de kloktijd van de tablet te wijzigen."</string>
+    <string name="permdesc_setTime" product="default" msgid="667294309287080045">"Staat een app toe de kloktijd van de telefoon te wijzigen."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"tijdzone instellen"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="2522877107613885139">"Hiermee kan een toepassing de tijdzone van de tablet wijzigen."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="1902540227418179364">"Hiermee kan een toepassing de tijdzone van de telefoon wijzigen."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="2522877107613885139">"Hiermee kan een app de tijdzone van de tablet wijzigen."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="1902540227418179364">"Hiermee kan een app de tijdzone van de telefoon wijzigen."</string>
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"fungeren als de AccountManagerService"</string>
-    <string name="permdesc_accountManagerService" msgid="6056903274106394752">"Hiermee kan een toepassing aanroepen plaatsen naar AccountAuthenticators"</string>
+    <string name="permdesc_accountManagerService" msgid="6056903274106394752">"Hiermee kan een app aanroepen plaatsen naar AccountAuthenticators"</string>
     <string name="permlab_getAccounts" msgid="4549918644233460103">"bekende accounts zoeken"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="857622793935544694">"Hiermee kan een toepassing de lijst met accounts van een tablet ophalen."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="6839262446413155394">"Hiermee kan een toepassing de lijst met accounts van een telefoon ophalen."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="857622793935544694">"Hiermee kan een app de lijst met accounts van een tablet ophalen."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="6839262446413155394">"Hiermee kan een app de lijst met accounts van een telefoon ophalen."</string>
     <string name="permlab_authenticateAccounts" msgid="3940505577982882450">"fungeren als verificatie-instantie voor het account"</string>
-    <string name="permdesc_authenticateAccounts" msgid="4006839406474208874">"Hiermee kan een toepassing de mogelijkheden voor verificatie-instanties voor het account van de AccountManager gebruiken, waaronder het maken van accounts en het ophalen en instellen van de bijbehorende wachtwoorden."</string>
+    <string name="permdesc_authenticateAccounts" msgid="4006839406474208874">"Hiermee kan een app de mogelijkheden voor verificatie-instanties voor het account van de AccountManager gebruiken, waaronder het maken van accounts en het ophalen en instellen van de bijbehorende wachtwoorden."</string>
     <string name="permlab_manageAccounts" msgid="4440380488312204365">"de lijst met accounts beheren"</string>
-    <string name="permdesc_manageAccounts" msgid="8804114016661104517">"Hiermee kan een toepassing bewerkingen uitvoeren, zoals het toevoegen en verwijderen van accounts en het verwijderen van de bijbehorende wachtwoorden."</string>
+    <string name="permdesc_manageAccounts" msgid="8804114016661104517">"Hiermee kan een app bewerkingen uitvoeren, zoals het toevoegen en verwijderen van accounts en het verwijderen van de bijbehorende wachtwoorden."</string>
     <string name="permlab_useCredentials" msgid="6401886092818819856">"de verificatiegegevens van een account gebruiken"</string>
-    <string name="permdesc_useCredentials" msgid="7416570544619546974">"Hiermee kan een toepassing verificatietokens aanvragen."</string>
+    <string name="permdesc_useCredentials" msgid="7416570544619546974">"Hiermee kan een app verificatietokens aanvragen."</string>
     <string name="permlab_accessNetworkState" msgid="6865575199464405769">"netwerkstatus bekijken"</string>
-    <string name="permdesc_accessNetworkState" msgid="558721128707712766">"Hiermee kan een toepassing de status van alle netwerken bekijken."</string>
+    <string name="permdesc_accessNetworkState" msgid="558721128707712766">"Hiermee kan een app de status van alle netwerken bekijken."</string>
     <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"volledige internettoegang"</string>
-    <string name="permdesc_createNetworkSockets" msgid="4593339106921772192">"Hiermee kan een toepassing netwerksockets maken."</string>
+    <string name="permdesc_createNetworkSockets" msgid="4593339106921772192">"Hiermee kan een app netwerksockets maken."</string>
     <string name="permlab_writeApnSettings" msgid="7823599210086622545">"instellingen voor toegangspuntnaam schrijven"</string>
-    <string name="permdesc_writeApnSettings" msgid="7443433457842966680">"Hiermee kan een toepassing de APN-instellingen, zoals proxy en poort, van elke APN wijzigen."</string>
+    <string name="permdesc_writeApnSettings" msgid="7443433457842966680">"Hiermee kan een app de APN-instellingen, zoals proxy en poort, van elke APN wijzigen."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"netwerkverbinding wijzigen"</string>
-    <string name="permdesc_changeNetworkState" msgid="4199958910396387075">"Staat een toepassing toe de status van de netwerkverbinding te wijzigen."</string>
+    <string name="permdesc_changeNetworkState" msgid="4199958910396387075">"Staat een app toe de status van de netwerkverbinding te wijzigen."</string>
     <string name="permlab_changeTetherState" msgid="2702121155761140799">"Getetherde verbinding wijzigen"</string>
-    <string name="permdesc_changeTetherState" msgid="8905815579146349568">"Staat een toepassing toe de status van de getetherde netwerkverbinding te wijzigen."</string>
+    <string name="permdesc_changeTetherState" msgid="8905815579146349568">"Staat een app toe de status van de getetherde netwerkverbinding te wijzigen."</string>
     <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"instelling voor gebruik van achtergrondgegevens van gegevens wijzigen"</string>
-    <string name="permdesc_changeBackgroundDataSetting" msgid="1001482853266638864">"Hiermee kan een toepassing de instelling voor gebruik van achtergrondgegevens wijzigen."</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="1001482853266638864">"Hiermee kan een app de instelling voor gebruik van achtergrondgegevens wijzigen."</string>
     <string name="permlab_accessWifiState" msgid="8100926650211034400">"Wi-Fi-status bekijken"</string>
-    <string name="permdesc_accessWifiState" msgid="485796529139236346">"Hiermee kan een toepassing informatie over de Wi-Fi-status bekijken."</string>
+    <string name="permdesc_accessWifiState" msgid="485796529139236346">"Hiermee kan een app informatie over de Wi-Fi-status bekijken."</string>
     <string name="permlab_changeWifiState" msgid="7280632711057112137">"Wi-Fi-status wijzigen"</string>
-    <string name="permdesc_changeWifiState" msgid="2950383153656873267">"Hiermee kan een toepassing zich koppelen aan en loskoppelen van Wi-Fi toegangspunten en wijzigingen aanbrengen in geconfigureerde Wi-Fi-netwerken."</string>
+    <string name="permdesc_changeWifiState" msgid="2950383153656873267">"Hiermee kan een app zich koppelen aan en loskoppelen van Wi-Fi toegangspunten en wijzigingen aanbrengen in geconfigureerde Wi-Fi-netwerken."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi Multicast-ontvangst toestaan"</string>
-    <string name="permdesc_changeWifiMulticastState" msgid="8199464507656067553">"Hiermee kan een toepassing pakketten ontvangen die niet rechtstreeks zijn geadresseerd aan uw apparaat. Dit kan handig zijn wanneer services in de buurt worden ontdekt. Dit verbruikt meer energie dan de niet-multicastmodus."</string>
+    <string name="permdesc_changeWifiMulticastState" msgid="8199464507656067553">"Hiermee kan een app pakketten ontvangen die niet rechtstreeks zijn geadresseerd aan uw apparaat. Dit kan handig zijn wanneer services in de buurt worden ontdekt. Dit verbruikt meer energie dan de niet-multicastmodus."</string>
     <string name="permlab_bluetoothAdmin" msgid="1092209628459341292">"bluetooth-beheer"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="3511795757324345837">"Hiermee kan een toepassing de lokale Bluetooth-tablet configureren en externe apparaten zoeken en aansluiten."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="7256289774667054555">"Hiermee kan een toepassing de lokale Bluetooth-telefoon configureren en externe apparaten zoeken en aansluiten."</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="3511795757324345837">"Hiermee kan een app de lokale Bluetooth-tablet configureren en externe apparaten zoeken en aansluiten."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="7256289774667054555">"Hiermee kan een app de lokale Bluetooth-telefoon configureren en externe apparaten zoeken en aansluiten."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"Bluetooth-verbindingen maken"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="4191941825910543803">"Hiermee kan een toepassing de configuratie van een lokale Bluetooth-tablet bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
-    <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Hiermee kan een toepassing de configuratie van een lokale Bluetooth-telefoon bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="4191941825910543803">"Hiermee kan een app de configuratie van een lokale Bluetooth-tablet bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Hiermee kan een app de configuratie van een lokale Bluetooth-telefoon bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"Near Field Communication regelen"</string>
-    <string name="permdesc_nfc" msgid="9171401851954407226">"Hiermee kan een toepassing communiceren met NFC-tags (Near Field Communication), kaarten en lezers."</string>
+    <string name="permdesc_nfc" msgid="9171401851954407226">"Hiermee kan een app communiceren met NFC-tags (Near Field Communication), kaarten en lezers."</string>
     <string name="permlab_disableKeyguard" msgid="4977406164311535092">"toetsvergrendeling uitschakelen"</string>
-    <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Hiermee kan een toepassing de toetsvergrendeling en bijbehorende wachtwoordbeveiliging uitschakelen. Een voorbeeld: de telefoon schakelt de toetsvergrendeling uit als er een oproep binnenkomt en schakelt de toetsvergrendeling weer in als de oproep is beëindigd."</string>
+    <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Hiermee kan een app de toetsvergrendeling en bijbehorende wachtwoordbeveiliging uitschakelen. Een voorbeeld: de telefoon schakelt de toetsvergrendeling uit wanneer een oproep binnenkomt en schakelt de toetsvergrendeling weer in zodra de oproep wordt beëindigd."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"synchronisatie-instellingen lezen"</string>
-    <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Hiermee kan een toepassing de synchronisatie-instellingen lezen, bijvoorbeeld of de synchronisatie van contacten is ingeschakeld."</string>
+    <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Hiermee kan een app de synchronisatie-instellingen lezen, bijvoorbeeld of de synchronisatie van contacten is ingeschakeld."</string>
     <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"synchronisatie-instellingen schrijven"</string>
-    <string name="permdesc_writeSyncSettings" msgid="2498201614431360044">"Hiermee kan een toepassing uw synchronisatie-instellingen wijzigen, bijvoorbeeld of de synchronisatie van contacten is ingeschakeld."</string>
+    <string name="permdesc_writeSyncSettings" msgid="2498201614431360044">"Hiermee kan een app uw synchronisatie-instellingen wijzigen, bijvoorbeeld of de synchronisatie van contacten is ingeschakeld."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"synchronisatiestatistieken lezen"</string>
-    <string name="permdesc_readSyncStats" msgid="7511448343374465000">"Hiermee kan een toepassing de synchronisatiestatistieken lezen, zoals de geschiedenis van uitgevoerde synchronisaties."</string>
+    <string name="permdesc_readSyncStats" msgid="7511448343374465000">"Hiermee kan een app de synchronisatiestatistieken lezen, zoals de geschiedenis van uitgevoerde synchronisaties."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"geabonneerde feeds lezen"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="3622200625634207660">"Hiermee kan een toepassing details over de huidige gesynchroniseerde feeds achterhalen."</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="3622200625634207660">"Hiermee kan een app details over de huidige gesynchroniseerde feeds achterhalen."</string>
     <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"geabonneerde feeds schrijven"</string>
-    <string name="permdesc_subscribedFeedsWrite" msgid="8121607099326533878">"Hiermee kan een toepassing uw huidige gesynchroniseerde feeds wijzigen. Een schadelijke toepassing kan op deze manier uw gesynchroniseerde feeds wijzigen."</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="8121607099326533878">"Hiermee kan een app uw huidige gesynchroniseerde feeds wijzigen. Een schadelijke app kan op deze manier uw gesynchroniseerde feeds wijzigen."</string>
     <string name="permlab_readDictionary" msgid="432535716804748781">"door gebruiker gedefinieerd woordenboek lezen"</string>
-    <string name="permdesc_readDictionary" msgid="1082972603576360690">"Hiermee kan een toepassing privéwoorden, namen en woordcombinaties lezen die de gebruiker heeft opgeslagen in het gebruikerswoordenboek."</string>
+    <string name="permdesc_readDictionary" msgid="1082972603576360690">"Hiermee kan een app privéwoorden, namen en woordcombinaties lezen die de gebruiker heeft opgeslagen in het gebruikerswoordenboek."</string>
     <string name="permlab_writeDictionary" msgid="6703109511836343341">"schrijven naar door gebruiker gedefinieerd woordenboek"</string>
-    <string name="permdesc_writeDictionary" msgid="2241256206524082880">"Hiermee kan een toepassing nieuwe woorden schrijven naar het gebruikerswoordenboek."</string>
+    <string name="permdesc_writeDictionary" msgid="2241256206524082880">"Hiermee kan een app nieuwe woorden schrijven naar het gebruikerswoordenboek."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"inhoud van USB-opslag aanpassen/verwijderen"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"inhoud op de SD-kaart aanpassen/verwijderen"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Hiermee kan een toepassing schrijven naar de USB-opslag."</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Hiermee kan een toepassing schrijven naar de SD-kaart."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Hiermee kan een app schrijven naar de USB-opslag."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Hiermee kan een app schrijven naar de SD-kaart."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"inh. mediaopsl. wijz./verw."</string>
-    <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Hiermee kan een toepassing de inhoud van interne mediaopslag aanpassen."</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Hiermee kan een app de inhoud van interne mediaopslag aanpassen."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"het cachebestandssysteem openen"</string>
-    <string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Staat een toepassing toe het cachebestandssysteem te lezen en te schrijven."</string>
+    <string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Staat een app toe het cachebestandssysteem te lezen en te schrijven."</string>
     <string name="permlab_use_sip" msgid="5986952362795870502">"internetoproepen starten/ontvangen"</string>
-    <string name="permdesc_use_sip" msgid="6320376185606661843">"Hiermee kan een toepassing de SIP-service gebruiken om internetoproepen te starten/te ontvangen."</string>
+    <string name="permdesc_use_sip" msgid="6320376185606661843">"Hiermee kan een app de SIP-service gebruiken om internetoproepen te starten/te ontvangen."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string>
     <string name="policydesc_limitPassword" msgid="9083400080861728056">"De lengte en tekens beheren die zijn toegestaan in wachtwoorden voor schermontgrendeling"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Pogingen voor schermontgrendeling bijhouden"</string>
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"De gegevens van de telefoon zonder waarschuwing wissen door de fabrieksinstellingen te herstellen"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Algemene proxy voor het apparaat instellen"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Stel de algemene proxy voor het apparaat in die moet worden gebruikt terwijl het beleid is geactiveerd. Alleen de eerste apparaatbeheerder stelt de algemene proxy in."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Verval wachtwoord instellen"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Beheren hoe lang het duurt voordat het wachtwoord voor schermvergrendeling moet worden gewijzigd"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Verval wachtwoord instellen"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Beheren hoe lang het duurt voordat het wachtwoord voor schermvergrendeling moet worden gewijzigd"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Codering voor opslag instellen"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Vereisen dat opgeslagen toepassingsgegevens kunnen worden gecodeerd"</string>
   <string-array name="phoneTypes">
@@ -672,14 +672,14 @@
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
     <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"browsergeschiedenis en bladwijzers lezen"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Hiermee kan een toepassing de URL\'s lezen die u via de browser heeft bezocht, evenals alle bladwijzers van de browser."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Hiermee kan een app de URL\'s lezen die u via de browser heeft bezocht, evenals alle bladwijzers van de browser."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"browsergeschiedenis en bladwijzers schrijven"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="7193514090469945307">"Hiermee kan een toepassing de op uw tablet opgeslagen browsergeschiedenis of bladwijzers wijzigen. Schadelijke toepassingen kunnen hiermee uw browsergegevens verwijderen of wijzigen."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Hiermee kan een toepassing de op uw telefoon opgeslagen browsergeschiedenis of bladwijzers wijzigen. Schadelijke toepassingen kunnen hiermee uw browsergegevens verwijderen of wijzigen."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="7193514090469945307">"Hiermee kan een app de op uw tablet opgeslagen browsergeschiedenis of bladwijzers wijzigen. Schadelijke apps kunnen hiermee uw browsergegevens verwijderen of wijzigen."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Hiermee kan een app de op uw telefoon opgeslagen browsergeschiedenis of bladwijzers wijzigen. Schadelijke apps kunnen hiermee uw browsergegevens verwijderen of wijzigen."</string>
     <string name="permlab_setAlarm" msgid="5924401328803615165">"alarm instellen in wekker"</string>
-    <string name="permdesc_setAlarm" msgid="5966966598149875082">"Hiermee kan de toepassing een alarm instellen in een geïnstalleerde wekkertoepassing. Deze functie wordt door sommige wekkertoepassingen niet geïmplementeerd."</string>
+    <string name="permdesc_setAlarm" msgid="5966966598149875082">"Hiermee kan de app een alarm instellen in een geïnstalleerde wekker-app. Deze functie wordt door sommige wekker-apps niet geïmplementeerd."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="4715212655598275532">"Geolocatierechten voor browser aanpassen"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Staat een toepassing toe de geolocatierechten van de browser aan te passen. Schadelijke toepassingen kunnen dit gebruiken om locatiegegevens te verzenden naar willekeurige websites."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="4011908282980861679">"Staat een app toe de geolocatierechten van de browser aan te passen. Schadelijke apps kunnen dit gebruiken om locatiegegevens te verzenden naar willekeurige websites."</string>
     <string name="save_password_message" msgid="767344687139195790">"Wilt u dat de browser dit wachtwoord onthoudt?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Niet nu"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Onthouden"</string>
@@ -814,31 +814,31 @@
     <string name="alwaysUse" msgid="4583018368000610438">"Standaard gebruiken voor deze actie."</string>
     <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Wis standaardinstelling via startscherm: \'Instellingen\' &gt; \'Toepassingen\' &gt; \'Toepassingen beheren\'."</string>
     <string name="chooseActivity" msgid="1009246475582238425">"Een actie selecteren"</string>
-    <string name="noApplications" msgid="1691104391758345586">"Geen enkele toepassing kan deze actie uitvoeren."</string>
+    <string name="noApplications" msgid="1691104391758345586">"Geen enkele app kan deze actie uitvoeren."</string>
     <string name="aerr_title" msgid="653922989522758100">"Helaas!"</string>
-    <string name="aerr_application" msgid="4683614104336409186">"De toepassing <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) is onverwachts gestopt. Probeer het opnieuw."</string>
+    <string name="aerr_application" msgid="4683614104336409186">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) is onverwachts gestopt. Probeer het opnieuw."</string>
     <string name="aerr_process" msgid="1551785535966089511">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> is onverwachts gestopt. Probeer het opnieuw."</string>
     <string name="anr_title" msgid="3100070910664756057">"Helaas!"</string>
-    <string name="anr_activity_application" msgid="3538242413112507636">"Activiteit <xliff:g id="ACTIVITY">%1$s</xliff:g> (in toepassing <xliff:g id="APPLICATION">%2$s</xliff:g>) reageert niet."</string>
+    <string name="anr_activity_application" msgid="3538242413112507636">"Activiteit <xliff:g id="ACTIVITY">%1$s</xliff:g> (in app <xliff:g id="APPLICATION">%2$s</xliff:g>) reageert niet."</string>
     <string name="anr_activity_process" msgid="5420826626009561014">"Activiteit <xliff:g id="ACTIVITY">%1$s</xliff:g> (in proces <xliff:g id="PROCESS">%2$s</xliff:g>) reageert niet."</string>
-    <string name="anr_application_process" msgid="4185842666452210193">"Toepassing <xliff:g id="APPLICATION">%1$s</xliff:g> (in proces <xliff:g id="PROCESS">%2$s</xliff:g>) reageert niet."</string>
+    <string name="anr_application_process" msgid="4185842666452210193">"App <xliff:g id="APPLICATION">%1$s</xliff:g> (in proces <xliff:g id="PROCESS">%2$s</xliff:g>) reageert niet."</string>
     <string name="anr_process" msgid="1246866008169975783">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> reageert niet."</string>
     <string name="force_close" msgid="3653416315450806396">"Nu sluiten"</string>
     <string name="report" msgid="4060218260984795706">"Rapport"</string>
     <string name="wait" msgid="7147118217226317732">"Wachten"</string>
-    <string name="launch_warning_title" msgid="8323761616052121936">"Toepassing omgeleid"</string>
+    <string name="launch_warning_title" msgid="8323761616052121936">"App omgeleid"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nu actief."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was het eerst gestart."</string>
-    <string name="smv_application" msgid="295583804361236288">"De toepassing <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
+    <string name="smv_application" msgid="295583804361236288">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
     <string name="smv_process" msgid="5120397012047462446">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> wordt uitgevoerd"</string>
-    <string name="heavy_weight_notification_detail" msgid="2423977499339403402">"Selecteren om over te schakelen naar toepassing"</string>
+    <string name="heavy_weight_notification_detail" msgid="2423977499339403402">"Selecteren om over te schakelen naar app"</string>
     <string name="heavy_weight_switcher_title" msgid="1135403633766694316">"Toepassingen wijzigen?"</string>
-    <string name="heavy_weight_switcher_text" msgid="4592075610079319667">"Er wordt al een andere toepassing uitgevoerd die moet worden gestopt voordat u een nieuwe toepassing kunt starten."</string>
+    <string name="heavy_weight_switcher_text" msgid="4592075610079319667">"Er wordt al een andere app uitgevoerd die moet worden gestopt voordat u een nieuwe app kunt starten."</string>
     <string name="old_app_action" msgid="493129172238566282">"Terug naar <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="942967900237208466">"De nieuwe toepassing niet starten."</string>
+    <string name="old_app_description" msgid="942967900237208466">"De nieuwe app niet starten."</string>
     <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> starten"</string>
-    <string name="new_app_description" msgid="6830398339826789493">"De oude toepassing stoppen zonder opslaan."</string>
+    <string name="new_app_description" msgid="6830398339826789493">"De oude app stoppen zonder opslaan."</string>
     <string name="sendText" msgid="5132506121645618310">"Selecteer een actie voor tekst"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Belvolume"</string>
     <string name="volume_music" msgid="5421651157138628171">"Mediavolume"</string>
@@ -863,7 +863,7 @@
     <item quantity="other" msgid="7915895323644292768">"Open Wi-Fi-netwerken beschikbaar"</item>
   </plurals>
     <string name="select_character" msgid="3365550120617701745">"Teken invoegen"</string>
-    <string name="sms_control_default_app_name" msgid="7630529934366549163">"Onbekende toepassing"</string>
+    <string name="sms_control_default_app_name" msgid="7630529934366549163">"Onbekende app"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"SMS-berichten verzenden"</string>
     <string name="sms_control_message" msgid="1289331457999236205">"Er wordt een groot aantal SMS-berichten verzonden. Selecteer \'OK\' om door te gaan of \'Annuleren\' om de verzending te stoppen."</string>
     <string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 3035e96..40e827f 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Wymazywanie danych z telefonu bez ostrzeżenia, przez przywrócenie danych fabrycznych"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Ustaw globalny serwer proxy urządzenia"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ustaw globalny serwer proxy urządzenia do wykorzystywania przy włączonych zasadach. Tylko pierwszy administrator urządzenia ustawia obowiązujący globalny serwer proxy."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Ustaw wygasanie hasła"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrola czasu, po którym należy zmienić hasło blokowania ekranu"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Ustaw wygasanie hasła"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Kontrola czasu, po którym należy zmienić hasło blokowania ekranu"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Ustaw szyfrowanie pamięci"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Wymaga szyfrowania danych zapisanych aplikacji"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index f6ab376..a616f4a 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Apagar os dados do telefone sem avisar, ao efectuar uma reposição de dados de fábrica"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir o proxy global do aparelho"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Definir o proxy global do aparelho a ser utilizado quando a política estiver activada. Só o primeiro administrador do aparelho define o proxy global efectivo."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Def. valid. da palavra-passe"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle com que antecedência é necessário alterar a palavra-passe de bloqueio do ecrã"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Def. valid. da palavra-passe"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Controle com que antecedência é necessário alterar a palavra-passe de bloqueio do ecrã"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Def. encriptação armazenamento"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Requerer encriptação dos dados da aplicação armazenados"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 6542cd3..cf27fb6 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Apaga os dados do telefone sem aviso, executando uma redefinição da configuração original"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir o proxy global do dispositivo"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configura o proxy global do dispositivo para ser usado enquanto a política estiver ativada. Somente o primeiro administrador do dispositivo pode configurar um verdadeiro proxy global."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Definir validade da senha"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle quanto tempo uma senha de bloqueio de tela deve ficar ativa antes de ser alterada"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Definir validade da senha"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Controle quanto tempo uma senha de bloqueio de tela deve ficar ativa antes de ser alterada"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Definir criptografia de armazenamento"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Exigir que os dados do aplicativo armazenado sejam criptografados"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index e28b304..f3073bd 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -498,9 +498,9 @@
     <!-- outdated translation 2314060933796396205 -->     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Restaurar ils parameters originals dal telefonin. Qua tras vegnan tut Vossas datas stizzadas senza dumonda da conferma."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir il proxy global da l\'apparat"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Definir il proxy global da l\'apparat che duai vegnir utilisà sche la directiva è activada. Mo l\'emprim administratur dad apparats definescha il vair proxy global."</string>
-    <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
+    <!-- no translation found for policylab_expirePassword (885279151847254056) -->
     <skip />
-    <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
+    <!-- no translation found for policydesc_expirePassword (4844430354224822074) -->
     <skip />
     <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
     <skip />
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5326a4c..68cb1b4 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Ştergeţi datele din telefon fără avertisment, efectuând resetarea configurării din fabrică"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Setaţi serverul proxy global pentru dispozitiv"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Setaţi serverul proxy global pentru dispozitiv care să fie utilizat cât timp politica este activă. Numai primul administrator al dispozitivului poate seta serverul proxy global activ."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Setaţi expirarea parolei"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controlarea duratei până când parola de blocare a ecranului trebuie modificată"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Setaţi expirarea parolei"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Controlarea duratei până când parola de blocare a ecranului trebuie modificată"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Setaţi criptarea stocării"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Necesită ca datele aplicaţiei stocate să fie criptate"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 436d09b..0161947 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Уничтожить все данные на телефоне без предупреждения путем сброса настроек"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Глобальный прокси-сервер"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Настройте глобальный прокси-сервер устройства, который будет использоваться при активной политике. Глобальный прокси-сервер должен настроить первый администратор устройства."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Задать время действия пароля"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Задать время действия пароля перед появлением экрана блокировки"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Задать время действия пароля"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Задать время действия пароля перед появлением экрана блокировки"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Настроить шифрование хранилища"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Требует шифровать данные приложений, находящиеся в хранилище."</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 0895aa1..fce5ccb 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Bez predchádzajúceho upozornenia zmazať všetky údaje tým, že sa obnovia továrenské nastavenia telefónu"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Nastaviť globálny server proxy zariadenia"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globálny server proxy, ktorý sa bude používať po aktivácii pravidiel. Platný globálny server proxy nastavuje iba prvý správca zariadenia."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Nastav. koniec platnosti hesla"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ovládanie doby, po uplynutí ktorej treba zmeniť heslo na odomknutie obrazovky"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Nastav. koniec platnosti hesla"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Ovládanie doby, po uplynutí ktorej treba zmeniť heslo na odomknutie obrazovky"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Nastaviť šifr. ukl. priestoru"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Vyžaduje šifrovanie uložených údajov aplikácií"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 486e266..0a06bef 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Brisanje (s tovarniško ponastavitvijo) vseh podatkov v telefonu brez opozorila"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Nastavitev globalnega strežnika proxy za napravo"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Nastavite globalni strežnik proxy naprave, ki bo v uporabi, ko je pravilnik omogočen. Samo skrbnik prve naprave lahko nastavi veljaven globalni strežnik proxy."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Nastavitev poteka gesla"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Nastavite, koliko časa prej je treba spremeniti geslo za odklepanje zaslona"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Nastavitev poteka gesla"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Nastavite, koliko časa prej je treba spremeniti geslo za odklepanje zaslona"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Nastavitev šifriranja shrambe"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Shranjeni podatki programa morajo biti šifrirani"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index aebd8e2..9df9270 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Брисање података на телефону без упозорења враћањем фабричких података"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Подесите глобални прокси сервер уређаја"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Подесите глобални прокси сервер уређаја који ће се користити док су омогућене смернице. Само први администратор уређаја поставља ефективни глобални прокси сервер."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Подеси време истека лозинке"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Контролишите време када лозинка за закључавање екрана треба да се промени"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Подеси време истека лозинке"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Контролишите време када лозинка за закључавање екрана треба да се промени"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Подешавање шифровања складишта"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Захтева да сачувани подаци апликације буду шифровани"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 296c2a3..22ee6cd 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -140,7 +140,7 @@
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Din telefon stängs av."</string>
     <string name="shutdown_confirm_question" msgid="6656441286856415014">"Vill du stänga av?"</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string>
-    <string name="no_recent_tasks" msgid="279702952298056674">"Inga nya program."</string>
+    <string name="no_recent_tasks" msgid="279702952298056674">"Inga nya appar."</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Alternativ för pekdatorn"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"Telefonalternativ"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Skärmlås"</string>
@@ -202,7 +202,7 @@
     <string name="permdesc_receiveWapPush" msgid="5979623826128082171">"Tillåter att program tar emot och bearbetar WAP-meddelanden. Skadliga program kan övervaka dina meddelanden eller ta bort dem utan att visa dem för dig."</string>
     <string name="permlab_getTasks" msgid="5005277531132573353">"hämta appar som körs"</string>
     <string name="permdesc_getTasks" msgid="7048711358713443341">"Tillåter att program hämtar information om uppgifter som körs och har körts. Skadliga program kan upptäcka privat information om andra program."</string>
-    <string name="permlab_reorderTasks" msgid="5669588525059921549">"byt ordning på program som körs"</string>
+    <string name="permlab_reorderTasks" msgid="5669588525059921549">"byt ordning på appar som körs"</string>
     <string name="permdesc_reorderTasks" msgid="126252774270522835">"Tillåter att ett program flyttar uppgifter till förgrunden eller bakgrunden. Skadliga program kan tvinga sig till förgrunden utan att du kan styra det."</string>
     <string name="permlab_setDebugApp" msgid="4339730312925176742">"aktivera felsökning av appar"</string>
     <string name="permdesc_setDebugApp" msgid="5584310661711990702">"Tillåter att ett program aktiverar felsökning för ett annat program. Skadliga program kan använda detta för att avsluta andra program."</string>
@@ -212,17 +212,17 @@
     <string name="permdesc_enableCarMode" msgid="5673461159384850628">"Tillåter att ett program aktiverar trafikläge."</string>
     <string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"avbryt bakgrundsprocesser"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="2908829602869383753">"Tillåter att ett program avslutar bakgrundsprocesser för andra program även om det inte finns för lite ledigt minne."</string>
-    <string name="permlab_forceStopPackages" msgid="1447830113260156236">"framtvinga avslutning av andra program"</string>
+    <string name="permlab_forceStopPackages" msgid="1447830113260156236">"framtvinga avslutning av andra appar"</string>
     <string name="permdesc_forceStopPackages" msgid="7263036616161367402">"Tillåter att ett program framtvingar avslutning av andra program."</string>
-    <string name="permlab_forceBack" msgid="1804196839880393631">"tvinga program att avsluta"</string>
+    <string name="permlab_forceBack" msgid="1804196839880393631">"tvinga appar att avsluta"</string>
     <string name="permdesc_forceBack" msgid="6534109744159919013">"Tillåter att ett program tvingar en aktivitet som finns i förgrunden att avsluta och gå tillbaka. Behövs inte för vanliga program."</string>
     <string name="permlab_dump" msgid="1681799862438954752">"hämta systemets interna status"</string>
     <string name="permdesc_dump" msgid="2198776174276275220">"Tillåter att ett program hämtar systemets interna status. Skadliga program kan hämta privat och skyddad information som de normalt aldrig ska behöva."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"avsluta delvis"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Sätter aktivitetshanteraren i avstängningsläge. Utför inte en fullständig avstängning."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"förhindrar programbyten"</string>
-    <string name="permdesc_stopAppSwitches" msgid="3857886086919033794">"Hindrar att användaren byter till ett annat program."</string>
-    <string name="permlab_runSetActivityWatcher" msgid="7811586187574696296">"övervaka och styra alla program som öppnas"</string>
+    <string name="permdesc_stopAppSwitches" msgid="3857886086919033794">"Hindrar att användaren byter till en annan app."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="7811586187574696296">"övervaka och styra alla appar som öppnas"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="2149363027173451218">"Tillåter att ett program övervakar och styr hur systemet startar aktiviteter. Skadliga program kan kompromettera systemet helt. Den här behörigheten behövs bara för programmering, aldrig för vanlig användning."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"skicka meddelande om borttaget paket"</string>
     <string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"Tillåter att ett program skickar ett meddelande om att ett programpaket har tagits bort. Skadliga program kan använda detta för att avsluta alla andra program som körs."</string>
@@ -254,7 +254,7 @@
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"binda till en metod för indata"</string>
     <string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en inmatningsmetod. Ska inte behövas för vanliga program."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"binda till en bakgrund"</string>
-    <string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en bakgrund. Ska inte behövas för vanliga program."</string>
+    <string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en bakgrund. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind till en widget"</string>
     <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en widget. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"arbeta med en enhetsadministratör"</string>
@@ -273,7 +273,7 @@
     <string name="permdesc_deleteCacheFiles" msgid="2283074077168165971">"Tillåter att ett program raderar cachefiler."</string>
     <string name="permlab_getPackageSize" msgid="4799785352306641460">"mäta telefonens lagringsutrymme"</string>
     <string name="permdesc_getPackageSize" msgid="5557253039670753437">"Tillåter att ett program hämtar kod, data och cachestorlekar"</string>
-    <string name="permlab_installPackages" msgid="335800214119051089">"installera program direkt"</string>
+    <string name="permlab_installPackages" msgid="335800214119051089">"installera appar direkt"</string>
     <string name="permdesc_installPackages" msgid="526669220850066132">"Tillåter att ett program installerar nya eller uppdaterade Android-paket. Skadliga program kan använda detta för att lägga till nya program med godtyckliga och starka behörigheter."</string>
     <string name="permlab_clearAppCache" msgid="4747698311163766540">"ta bort cacheinformation för alla appar"</string>
     <string name="permdesc_clearAppCache" product="tablet" msgid="3097119797652477973">"Tillåter att ett program frigör lagringsutrymme på pekdatorn genom att ta bort filer i programmets katalog för cachelagring. Mycket begränsad åtkomst, vanligtvis till systemprocesser."</string>
@@ -288,7 +288,7 @@
     <string name="permlab_changeComponentState" msgid="79425198834329406">"aktivera eller inaktivera programkomponenter"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Tillåter att ett program ändrar inställningen för om en komponent i ett annat program har aktiverats eller inte. Skadliga program kan använda detta för att inaktivera viktiga funktioner i pekdatorn. Var försiktig med behörigheten, eftersom programkomponenter kan bli oanvändbara, inkonsekventa eller instabila."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Tillåter att en app ändrar inställningen för om en komponent i en annan app ska aktiveras eller inte. Skadliga appar kan använda detta för att inaktivera viktiga funktioner i telefonen. Var försiktig med behörigheten, eftersom programkomponenter kan bli oanvändbara, inkonsekventa eller instabila."</string>
-    <string name="permlab_setPreferredApplications" msgid="3393305202145172005">"ange önskade program"</string>
+    <string name="permlab_setPreferredApplications" msgid="3393305202145172005">"ange önskade appar"</string>
     <string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Tillåter att ett program ändrar dina önskade program. Skadliga program kan utan varning ändra de program som körs och förfalska dina befintliga program så att de samlar privata data från dig."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"ändra globala systeminställningar"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Tillåter att ett program ändrar systemets inställningar. Skadliga program kan skada systemets konfiguration."</string>
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Ta bort data från telefonen utan förvarning genom att återställa standardinställningarna"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Ange global proxyserver"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ange vilken global proxyserver som ska användas när policyn är aktiverad. Endast den första enhetsadministratören anger den faktiska globala proxyservern."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Ange lösenordets utgångsdatum"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Se hur långt det är kvar till du måste ändra lösenordet till låsningsskärmen"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Ange lösenordets utgångsdatum"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Se hur långt det är kvar till du måste ändra lösenordet till låsningsskärmen"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Ange krypterad lagring"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Kräv att sparade applikationsdata krypteras."</string>
   <string-array name="phoneTypes">
@@ -814,7 +814,7 @@
     <string name="alwaysUse" msgid="4583018368000610438">"Använd som standard för denna åtgärd."</string>
     <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Rensa standardinställning i Startinställningar &gt; Appar &gt; Hantera appar."</string>
     <string name="chooseActivity" msgid="1009246475582238425">"Välj en åtgärd"</string>
-    <string name="noApplications" msgid="1691104391758345586">"Inga program kan utföra den här åtgärden."</string>
+    <string name="noApplications" msgid="1691104391758345586">"Inga appar kan utföra den här åtgärden."</string>
     <string name="aerr_title" msgid="653922989522758100">"Tyvärr!"</string>
     <string name="aerr_application" msgid="4683614104336409186">"Processen <xliff:g id="PROCESS">%2$s</xliff:g> för programmet <xliff:g id="APPLICATION">%1$s</xliff:g> stoppades oväntat. Försök igen."</string>
     <string name="aerr_process" msgid="1551785535966089511">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> avslutades oväntat. Försök igen."</string>
@@ -833,8 +833,8 @@
     <string name="smv_process" msgid="5120397012047462446">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> har brutit mot sin egen StrictMode-policy."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> körs"</string>
     <string name="heavy_weight_notification_detail" msgid="2423977499339403402">"Välj om du vill växla till programmet"</string>
-    <string name="heavy_weight_switcher_title" msgid="1135403633766694316">"Vill du byta program?"</string>
-    <string name="heavy_weight_switcher_text" msgid="4592075610079319667">"Ett annat program som körs måste avslutas innan du kan starta ett nytt."</string>
+    <string name="heavy_weight_switcher_title" msgid="1135403633766694316">"Vill du byta app?"</string>
+    <string name="heavy_weight_switcher_text" msgid="4592075610079319667">"En annan app som körs måste avslutas innan du kan starta en ny."</string>
     <string name="old_app_action" msgid="493129172238566282">"Gå tillbaka till <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
     <string name="old_app_description" msgid="942967900237208466">"Starta inte det nya programmet."</string>
     <string name="new_app_action" msgid="5472756926945440706">"Starta <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
@@ -892,7 +892,7 @@
     <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Inaktivera USB-lagring"</string>
     <string name="usb_storage_stop_error_message" msgid="143881914840412108">"Ett problem uppstod när USB-lagringsplatsen skulle inaktiveras. Kontrollera att USB-värden har demonterats och försök igen."</string>
     <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Aktivera USB-lagring"</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="3202838234780505886">"Om du aktiverar USB-lagring avbryts några av de program som körs och de kanske inte blir tillgängliga igen förrän du inaktiverar USB-lagring."</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="3202838234780505886">"Om du aktiverar USB-lagring avbryts några av de appar som körs och de kanske inte blir tillgängliga igen förrän du inaktiverar USB-lagring."</string>
     <string name="dlg_error_title" msgid="8048999973837339174">"USB-åtgärd misslyckades"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
     <string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"Formatera USB-enhet"</string>
@@ -933,8 +933,8 @@
     <string name="activity_list_empty" msgid="4168820609403385789">"Inga matchande aktiviteter hittades"</string>
     <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"uppdatera statistik över användning av komponenter"</string>
     <string name="permdesc_pkgUsageStats" msgid="891553695716752835">"Tillåter att samlad komponentstatistik ändras. Används inte av vanliga program."</string>
-    <string name="permlab_copyProtectedData" msgid="1660908117394854464">"Tillåter att innehåll kopieras genom att standardbehållartjänsten startas. Vanliga program behöver aldrig göra detta."</string>
-    <string name="permdesc_copyProtectedData" msgid="537780957633976401">"Tillåter att innehåll kopieras genom att standardbehållartjänsten startas. Vanliga program behöver aldrig göra detta."</string>
+    <string name="permlab_copyProtectedData" msgid="1660908117394854464">"Tillåter att innehåll kopieras genom att standardbehållartjänsten startas. Vanliga appar behöver aldrig göra detta."</string>
+    <string name="permdesc_copyProtectedData" msgid="537780957633976401">"Tillåter att innehåll kopieras genom att standardbehållartjänsten startas. Vanliga appar behöver aldrig göra detta."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Peka två gånger för zoomkontroll"</string>
     <string name="gadget_host_error_inflating" msgid="2613287218853846830">"Fel när widgeten expanderades"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Kör"</string>
@@ -948,7 +948,7 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Skapa kontakt"\n"med <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"markerad"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"inte markerad"</string>
-    <string name="grant_credentials_permission_message_header" msgid="6824538733852821001">"Följande program begär behörighet till konto, både nu och i framtiden."</string>
+    <string name="grant_credentials_permission_message_header" msgid="6824538733852821001">"Följande appar begär behörighet till konto, både nu och i framtiden."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Vill du tillåta den här begäran?"</string>
     <string name="grant_permissions_header_text" msgid="2722567482180797717">"Begäran om åtkomst"</string>
     <string name="allow" msgid="7225948811296386551">"Tillåt"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index ce9e131..b21447d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"ลบข้อมูลของโทรศัพท์โดยไม่มีการเตือน ด้วยการดำเนินการรีเซ็ตข้อมูลเป็นค่าเริ่มต้น"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ตั้งค่าพร็อกซีส่วนกลางของอุปกรณ์"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ตั้งค่าพร็อกซีส่วนกลางของอุปกรณ์ที่จะใช้ขณะเปิดการใช้งานนโยบาย เฉพาะผู้ดูแลอุปกรณ์คนแรกเท่านั้นที่ตั้งค่าพร็อกซีส่วนกลางที่มีผลบังคับ"</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"ตั้งค่าการหมดอายุของรหัสผ่าน"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"ควบคุมระยะเวลาก่อนที่จะต้องเปลี่ยนรหัสผ่านการล็อกหน้าจอ"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"ตั้งค่าการหมดอายุของรหัสผ่าน"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"ควบคุมระยะเวลาก่อนที่จะต้องเปลี่ยนรหัสผ่านการล็อกหน้าจอ"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"ตั้งค่าการเข้ารหัสที่เก็บข้อมูล"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"กำหนดว่าแอปพลิเคชันที่จัดเก็บต้องมีการเข้ารหัส"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index c26d789..e2231e2 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Burahin ang data ng telepono nang walang babala, sa pamamagitan ng pagsasagawa ng pag-reset sa data ng factory"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Itakda ang pandaigdigang proxy ng device"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Itakda ang pandaigdigang proxy ng device na gagamitin habang pinagana ang patakaran. Tanging ang unang admin ng device ang magtatakda sa may bisang pandaigdigang proxy."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Itakda pag-expire ng password"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrolin kung gaano katagal bago kailangang palitan ang password sa pag-lock ng screen"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Itakda pag-expire ng password"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Kontrolin kung gaano katagal bago kailangang palitan ang password sa pag-lock ng screen"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Itakda pag-encrypt ng imbakan"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Hinging naka-encrypt ang nakaimbak na data ng application"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 08e4e71..65b3bf8 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Fabrika verilerine sıfırlama işlemi gerçekleştirerek telefondaki verileri uyarıda bulunmadan silin"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Cihaz genelinde geçerli proxy\'i ayarla"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Politika etkin olduğunda kullanılacak cihaz genelinde geçerli proxy\'yi ayarlayın. Etkin genel proxy\'yi yalnızca ilk cihaz yöneticisi ayarlar."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Şifre süre sonu tarihi ayarla"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ekran kilitleme şifresinin ne kadar süre sonra değiştirilmesi gerekeceğini denetleyin."</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Şifre süre sonu tarihi ayarla"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Ekran kilitleme şifresinin ne kadar süre sonra değiştirilmesi gerekeceğini denetleyin."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Deplm şifrelemesini ayarla"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Depolanan uygulama verisinin şifrelenmiş olmasını gerektir"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 2a3624f..166291c 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Видаляє дані телефону без попередження, відновлюючи заводські налаштування"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Установ. глоб. проксі пристрою"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Устан. використ. глоб. проксі, коли ввімкнено політику. Лише адміністратор першого пристрою встановлює активний глоб. проксі."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Установити термін дії пароля"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Регулює, за скільки часу перед блокуванням екрана треба змінювати пароль"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Установити термін дії пароля"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Регулює, за скільки часу перед блокуванням екрана треба змінювати пароль"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Установити шифрування носія"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Потрібно, щоб дані збереженої програми були зашифровані"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 3306125..38ef264 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Xóa dữ liệu trên điện thoại mà không cần cảnh báo, bằng cách thực hiện đặt lại về dữ liệu gốc"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Đặt proxy chung của điện thoại"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Đặt proxy chung của điện thoại được sử dụng trong khi chính sách được bật. Chỉ quản trị viên đầu tiên của điện thoại mới có thể đặt proxy chung hiệu quả."</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"Đặt hết hạn mật khẩu"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kiểm soát thời lượng trước khi mật khẩu khóa màn hình cần được thay đổi"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"Đặt hết hạn mật khẩu"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Kiểm soát thời lượng trước khi mật khẩu khóa màn hình cần được thay đổi"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Đặt mã hóa dung lượng lưu trữ"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Yêu cầu dữ liệu ứng dụng được lưu trữ phải được mã hóa"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 40ae40f..874740f 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"恢复出厂设置时,将擦除手机上的数据而不发送警告"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"设置设备全局代理"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"请设置在启用政策的情况下要使用的设备全局代理。只有第一设备管理员才可设置有效的全局代理。"</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"设置密码有效期"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"控制屏幕锁定密码的使用期限"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"设置密码有效期"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"控制屏幕锁定密码的使用期限"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"设置存储设备加密"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"需要对存储的应用程序数据进行加密"</string>
   <string-array name="phoneTypes">
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 784d86f..246244a 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -484,8 +484,8 @@
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"執行重設為原廠設定時,系統會直接清除手機資料而不提出警告"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"設定裝置全域 Proxy"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"設定政策啟用時所要使用的裝置全域 Proxy,只有第一個裝置管理員所設定的全域 Proxy 具有效力。"</string>
-    <string name="policylab_expirePassword" msgid="2314569545488269564">"設定密碼到期日"</string>
-    <string name="policydesc_expirePassword" msgid="7276906351852798814">"控制螢幕鎖定密碼的使用期限"</string>
+    <!-- outdated translation 2314569545488269564 -->     <string name="policylab_expirePassword" msgid="885279151847254056">"設定密碼到期日"</string>
+    <!-- outdated translation 7276906351852798814 -->     <string name="policydesc_expirePassword" msgid="4844430354224822074">"控制螢幕鎖定密碼的使用期限"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"設定儲存裝置加密"</string>
     <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"必須為儲存的應用程式資料加密"</string>
   <string-array name="phoneTypes">
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 1fc2722..2d23fe9 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -24,11 +24,12 @@
 /**
  * Captures frames from an image stream as an OpenGL ES texture.
  *
- * <p>The image stream may come from either camera preview.  A SurfaceTexture may be used in place
- * of a SurfaceHolder when specifying the output destination of a {@link android.hardware.Camera}
+ * <p>The image stream may come from either camera preview or video decode.  A SurfaceTexture
+ * may be used in place of a SurfaceHolder when specifying the output destination of a
+ * {@link android.hardware.Camera} or {@link android.media.MediaPlayer}
  * object.  Doing so will cause all the frames from the image stream to be sent to the
  * SurfaceTexture object rather than to the device's display.  When {@link #updateTexImage} is
- * called, the contents of the texture object specified when the SurfaceTexture was created is
+ * called, the contents of the texture object specified when the SurfaceTexture was created are
  * updated to contain the most recent image from the image stream.  This may cause some frames of
  * the stream to be skipped.
  *
@@ -129,6 +130,8 @@
      *     16 elements.
      */
     public void getTransformMatrix(float[] mtx) {
+        // Note we intentionally don't check mtx for null, so this will result in a
+        // NullPointerException. But it's safe because it happens before the call to native.
         if (mtx.length != 16) {
             throw new IllegalArgumentException();
         }
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 749a977..81b56c2 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -98,7 +98,7 @@
      * Register the @a recipient for a notification if this binder
      * goes away.  If this binder object unexpectedly goes away
      * (typically because its hosting process has been killed),
-     * then DeathRecipient::binderDied() will be called with a referene
+     * then DeathRecipient::binderDied() will be called with a reference
      * to this.
      *
      * The @a cookie is optional -- if non-NULL, it should be a
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index bba7ed7..70519ef 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -26,6 +26,7 @@
 class Parcel;
 class ISurface;
 class Surface;
+class ISurfaceTexture;
 
 class IMediaPlayer: public IInterface
 {
@@ -35,6 +36,8 @@
     virtual void            disconnect() = 0;
 
     virtual status_t        setVideoSurface(const sp<Surface>& surface) = 0;
+    virtual status_t        setVideoSurfaceTexture(
+                                    const sp<ISurfaceTexture>& surfaceTexture) = 0;
     virtual status_t        prepareAsync() = 0;
     virtual status_t        start() = 0;
     virtual status_t        stop() = 0;
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 048f041..117d7eb 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -34,6 +34,7 @@
 class Parcel;
 class ISurface;
 class Surface;
+class ISurfaceTexture;
 
 template<typename T> class SortedVector;
 
@@ -112,7 +113,13 @@
         return INVALID_OPERATION;
     }
 
+    // pass the buffered Surface to the media player service
     virtual status_t    setVideoSurface(const sp<Surface>& surface) = 0;
+
+    // pass the buffered ISurfaceTexture to the media player service
+    virtual status_t    setVideoSurfaceTexture(
+                                const sp<ISurfaceTexture>& surfaceTexture) = 0;
+
     virtual status_t    prepare() = 0;
     virtual status_t    prepareAsync() = 0;
     virtual status_t    start() = 0;
@@ -177,7 +184,7 @@
     sp<AudioSink>       mAudioSink;
 };
 
-// Implement this class for media players that output directo to hardware
+// Implement this class for media players that output audio directly to hardware
 class MediaPlayerHWInterface : public MediaPlayerBase
 {
 public:
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 88b0c3e..528eeb9 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -28,6 +28,7 @@
 namespace android {
 
 class Surface;
+class ISurfaceTexture;
 
 enum media_event_type {
     MEDIA_NOP               = 0, // interface test message
@@ -146,6 +147,8 @@
 
             status_t        setDataSource(int fd, int64_t offset, int64_t length);
             status_t        setVideoSurface(const sp<Surface>& surface);
+            status_t        setVideoSurfaceTexture(
+                                    const sp<ISurfaceTexture>& surfaceTexture);
             status_t        setListener(const sp<MediaPlayerListener>& listener);
             status_t        prepare();
             status_t        prepareAsync();
diff --git a/include/media/stagefright/NativeWindowWrapper.h b/include/media/stagefright/NativeWindowWrapper.h
new file mode 100644
index 0000000..f323cbc
--- /dev/null
+++ b/include/media/stagefright/NativeWindowWrapper.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef NATIVE_WINDOW_WRAPPER_H_
+
+#define NATIVE_WINDOW_WRAPPER_H_
+
+#include <surfaceflinger/Surface.h>
+#include <gui/SurfaceTextureClient.h>
+
+namespace android {
+
+// Both Surface and SurfaceTextureClient are RefBase that implement the
+// ANativeWindow interface, but at different addresses. ANativeWindow is not
+// a RefBase but acts like one for use with sp<>.  This wrapper converts a
+// Surface or SurfaceTextureClient into a single reference-counted object
+// that holds an sp reference to the underlying Surface or SurfaceTextureClient,
+// It provides a method to get the ANativeWindow.
+
+struct NativeWindowWrapper : RefBase {
+    NativeWindowWrapper(
+            const sp<Surface> &surface) :
+        mSurface(surface) { }
+
+    NativeWindowWrapper(
+            const sp<SurfaceTextureClient> &surfaceTextureClient) :
+        mSurfaceTextureClient(surfaceTextureClient) { }
+
+    sp<ANativeWindow> getNativeWindow() const {
+        if (mSurface != NULL) {
+            return mSurface;
+        } else {
+            return mSurfaceTextureClient;
+        }
+    }
+
+    // If needed later we can provide a method to ask what kind of native window
+
+private:
+    // At most one of mSurface and mSurfaceTextureClient will be non-NULL
+    const sp<Surface> mSurface;
+    const sp<SurfaceTextureClient> mSurfaceTextureClient;
+
+    DISALLOW_EVIL_CONSTRUCTORS(NativeWindowWrapper);
+};
+
+}  // namespace android
+
+#endif  // NATIVE_WINDOW_WRAPPER_H_
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
index f8d96cf..f355087 100644
--- a/include/utils/RefBase.h
+++ b/include/utils/RefBase.h
@@ -22,16 +22,16 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <stdlib.h>
+#include <string.h>
+
+#include <utils/StrongPointer.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
 
 class TextOutput;
-TextOutput& printStrongPointer(TextOutput& to, const void* val);
 TextOutput& printWeakPointer(TextOutput& to, const void* val);
 
-template<typename T> class wp;
-
 // ---------------------------------------------------------------------------
 
 #define COMPARE_WEAK(_op_)                                      \
@@ -50,15 +50,15 @@
     return m_ptr _op_ o;                                        \
 }
 
-#define COMPARE(_op_)                                           \
-COMPARE_WEAK(_op_)                                              \
-inline bool operator _op_ (const wp<T>& o) const {              \
-    return m_ptr _op_ o.m_ptr;                                  \
-}                                                               \
-template<typename U>                                            \
-inline bool operator _op_ (const wp<U>& o) const {              \
-    return m_ptr _op_ o.m_ptr;                                  \
-}
+// ---------------------------------------------------------------------------
+
+class ReferenceMover;
+class ReferenceConverterBase {
+public:
+    virtual size_t getReferenceTypeSize() const = 0;
+    virtual void* getReferenceBase(void const*) const = 0;
+    inline virtual ~ReferenceConverterBase() { }
+};
 
 // ---------------------------------------------------------------------------
 
@@ -115,6 +115,8 @@
         getWeakRefs()->trackMe(enable, retain); 
     }
 
+    typedef RefBase basetype;
+
 protected:
                             RefBase();
     virtual                 ~RefBase();
@@ -138,6 +140,11 @@
     virtual void            onLastWeakRef(const void* id);
 
 private:
+    friend class ReferenceMover;
+    static void moveReferences(void* d, void const* s, size_t n,
+            const ReferenceConverterBase& caster);
+
+private:
     friend class weakref_type;
     class weakref_impl;
     
@@ -166,10 +173,17 @@
     inline int32_t getStrongCount() const {
         return mCount;
     }
-    
+
+    typedef LightRefBase<T> basetype;
+
 protected:
     inline ~LightRefBase() { }
-    
+
+private:
+    friend class ReferenceMover;
+    inline static void moveReferences(void* d, void const* s, size_t n,
+            const ReferenceConverterBase& caster) { }
+
 private:
     mutable volatile int32_t mCount;
 };
@@ -177,66 +191,6 @@
 // ---------------------------------------------------------------------------
 
 template <typename T>
-class sp
-{
-public:
-    typedef typename RefBase::weakref_type weakref_type;
-    
-    inline sp() : m_ptr(0) { }
-
-    sp(T* other);
-    sp(const sp<T>& other);
-    template<typename U> sp(U* other);
-    template<typename U> sp(const sp<U>& other);
-
-    ~sp();
-    
-    // Assignment
-
-    sp& operator = (T* other);
-    sp& operator = (const sp<T>& other);
-    
-    template<typename U> sp& operator = (const sp<U>& other);
-    template<typename U> sp& operator = (U* other);
-    
-    //! Special optimization for use by ProcessState (and nobody else).
-    void force_set(T* other);
-    
-    // Reset
-    
-    void clear();
-    
-    // Accessors
-
-    inline  T&      operator* () const  { return *m_ptr; }
-    inline  T*      operator-> () const { return m_ptr;  }
-    inline  T*      get() const         { return m_ptr; }
-
-    // Operators
-        
-    COMPARE(==)
-    COMPARE(!=)
-    COMPARE(>)
-    COMPARE(<)
-    COMPARE(<=)
-    COMPARE(>=)
-
-private:    
-    template<typename Y> friend class sp;
-    template<typename Y> friend class wp;
-
-    // Optimization for wp::promote().
-    sp(T* p, weakref_type* refs);
-    
-    T*              m_ptr;
-};
-
-template <typename T>
-TextOutput& operator<<(TextOutput& to, const sp<T>& val);
-
-// ---------------------------------------------------------------------------
-
-template <typename T>
 class wp
 {
 public:
@@ -329,113 +283,12 @@
 template <typename T>
 TextOutput& operator<<(TextOutput& to, const wp<T>& val);
 
-#undef COMPARE
 #undef COMPARE_WEAK
 
 // ---------------------------------------------------------------------------
 // No user serviceable parts below here.
 
 template<typename T>
-sp<T>::sp(T* other)
-    : m_ptr(other)
-{
-    if (other) other->incStrong(this);
-}
-
-template<typename T>
-sp<T>::sp(const sp<T>& other)
-    : m_ptr(other.m_ptr)
-{
-    if (m_ptr) m_ptr->incStrong(this);
-}
-
-template<typename T> template<typename U>
-sp<T>::sp(U* other) : m_ptr(other)
-{
-    if (other) other->incStrong(this);
-}
-
-template<typename T> template<typename U>
-sp<T>::sp(const sp<U>& other)
-    : m_ptr(other.m_ptr)
-{
-    if (m_ptr) m_ptr->incStrong(this);
-}
-
-template<typename T>
-sp<T>::~sp()
-{
-    if (m_ptr) m_ptr->decStrong(this);
-}
-
-template<typename T>
-sp<T>& sp<T>::operator = (const sp<T>& other) {
-    T* otherPtr(other.m_ptr);
-    if (otherPtr) otherPtr->incStrong(this);
-    if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = otherPtr;
-    return *this;
-}
-
-template<typename T>
-sp<T>& sp<T>::operator = (T* other)
-{
-    if (other) other->incStrong(this);
-    if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = other;
-    return *this;
-}
-
-template<typename T> template<typename U>
-sp<T>& sp<T>::operator = (const sp<U>& other)
-{
-    U* otherPtr(other.m_ptr);
-    if (otherPtr) otherPtr->incStrong(this);
-    if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = otherPtr;
-    return *this;
-}
-
-template<typename T> template<typename U>
-sp<T>& sp<T>::operator = (U* other)
-{
-    if (other) other->incStrong(this);
-    if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = other;
-    return *this;
-}
-
-template<typename T>    
-void sp<T>::force_set(T* other)
-{
-    other->forceIncStrong(this);
-    m_ptr = other;
-}
-
-template<typename T>
-void sp<T>::clear()
-{
-    if (m_ptr) {
-        m_ptr->decStrong(this);
-        m_ptr = 0;
-    }
-}
-
-template<typename T>
-sp<T>::sp(T* p, weakref_type* refs)
-    : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
-{
-}
-
-template <typename T>
-inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
-{
-   return printStrongPointer(to, val.get());
-}
-
-// ---------------------------------------------------------------------------
-
-template<typename T>
 wp<T>::wp(T* other)
     : m_ptr(other)
 {
@@ -572,7 +425,11 @@
 template<typename T>
 sp<T> wp<T>::promote() const
 {
-    return sp<T>(m_ptr, m_refs);
+    sp<T> result;
+    if (m_ptr && m_refs->attemptIncStrong(&result)) {
+        result.set_pointer(m_ptr);
+    }
+    return result;
 }
 
 template<typename T>
@@ -590,6 +447,77 @@
     return printWeakPointer(to, val.unsafe_get());
 }
 
+// ---------------------------------------------------------------------------
+
+// this class just serves as a namespace so TYPE::moveReferences can stay
+// private.
+
+class ReferenceMover {
+    // StrongReferenceCast and WeakReferenceCast do the impedance matching
+    // between the generic (void*) implementation in Refbase and the strongly typed
+    // template specializations below.
+
+    template <typename TYPE>
+    struct StrongReferenceCast : public ReferenceConverterBase {
+        virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); }
+        virtual void* getReferenceBase(void const* p) const {
+            sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p));
+            return static_cast<typename TYPE::basetype *>(sptr->get());
+        }
+    };
+
+    template <typename TYPE>
+    struct WeakReferenceCast : public ReferenceConverterBase {
+        virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); }
+        virtual void* getReferenceBase(void const* p) const {
+            wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p));
+            return static_cast<typename TYPE::basetype *>(sptr->unsafe_get());
+        }
+    };
+
+public:
+    template<typename TYPE> static inline
+    void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+        memmove(d, s, n*sizeof(sp<TYPE>));
+        StrongReferenceCast<TYPE> caster;
+        TYPE::moveReferences(d, s, n, caster);
+    }
+    template<typename TYPE> static inline
+    void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+        memmove(d, s, n*sizeof(wp<TYPE>));
+        WeakReferenceCast<TYPE> caster;
+        TYPE::moveReferences(d, s, n, caster);
+    }
+};
+
+// specialization for moving sp<> and wp<> types.
+// these are used by the [Sorted|Keyed]Vector<> implementations
+// sp<> and wp<> need to be handled specially, because they do not
+// have trivial copy operation in the general case (see RefBase.cpp
+// when DEBUG ops are enabled), but can be implemented very
+// efficiently in most cases.
+
+template<typename TYPE> inline
+void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+
 }; // namespace android
 
 // ---------------------------------------------------------------------------
diff --git a/include/utils/StrongPointer.h b/include/utils/StrongPointer.h
new file mode 100644
index 0000000..a8c9897
--- /dev/null
+++ b/include/utils/StrongPointer.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+#ifndef ANDROID_STRONG_POINTER_H
+#define ANDROID_STRONG_POINTER_H
+
+#include <cutils/atomic.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class TextOutput;
+TextOutput& printStrongPointer(TextOutput& to, const void* val);
+
+template<typename T> class wp;
+
+// ---------------------------------------------------------------------------
+
+#define COMPARE(_op_)                                           \
+inline bool operator _op_ (const sp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+inline bool operator _op_ (const T* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const sp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const U* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+inline bool operator _op_ (const wp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const wp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class sp
+{
+public:
+    inline sp() : m_ptr(0) { }
+
+    sp(T* other);
+    sp(const sp<T>& other);
+    template<typename U> sp(U* other);
+    template<typename U> sp(const sp<U>& other);
+
+    ~sp();
+
+    // Assignment
+
+    sp& operator = (T* other);
+    sp& operator = (const sp<T>& other);
+
+    template<typename U> sp& operator = (const sp<U>& other);
+    template<typename U> sp& operator = (U* other);
+
+    //! Special optimization for use by ProcessState (and nobody else).
+    void force_set(T* other);
+
+    // Reset
+
+    void clear();
+
+    // Accessors
+
+    inline  T&      operator* () const  { return *m_ptr; }
+    inline  T*      operator-> () const { return m_ptr;  }
+    inline  T*      get() const         { return m_ptr; }
+
+    // Operators
+
+    COMPARE(==)
+    COMPARE(!=)
+    COMPARE(>)
+    COMPARE(<)
+    COMPARE(<=)
+    COMPARE(>=)
+
+private:    
+    template<typename Y> friend class sp;
+    template<typename Y> friend class wp;
+    void set_pointer(T* ptr);
+    T* m_ptr;
+};
+
+#undef COMPARE
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const sp<T>& val);
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts below here.
+
+template<typename T>
+sp<T>::sp(T* other)
+: m_ptr(other)
+  {
+    if (other) other->incStrong(this);
+  }
+
+template<typename T>
+sp<T>::sp(const sp<T>& other)
+: m_ptr(other.m_ptr)
+  {
+    if (m_ptr) m_ptr->incStrong(this);
+  }
+
+template<typename T> template<typename U>
+sp<T>::sp(U* other) : m_ptr(other)
+{
+    if (other) other->incStrong(this);
+}
+
+template<typename T> template<typename U>
+sp<T>::sp(const sp<U>& other)
+: m_ptr(other.m_ptr)
+  {
+    if (m_ptr) m_ptr->incStrong(this);
+  }
+
+template<typename T>
+sp<T>::~sp()
+{
+    if (m_ptr) m_ptr->decStrong(this);
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (const sp<T>& other) {
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = otherPtr;
+    return *this;
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (T* other)
+{
+    if (other) other->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (const sp<U>& other)
+{
+    U* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = otherPtr;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (U* other)
+{
+    if (other) other->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T>    
+void sp<T>::force_set(T* other)
+{
+    other->forceIncStrong(this);
+    m_ptr = other;
+}
+
+template<typename T>
+void sp<T>::clear()
+{
+    if (m_ptr) {
+        m_ptr->decStrong(this);
+        m_ptr = 0;
+    }
+}
+
+template<typename T>
+void sp<T>::set_pointer(T* ptr) {
+    m_ptr = ptr;
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
+{
+    return printStrongPointer(to, val.get());
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_STRONG_POINTER_H
diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h
index 2ff2749..a1663f3 100644
--- a/include/utils/TypeHelpers.h
+++ b/include/utils/TypeHelpers.h
@@ -37,18 +37,6 @@
 template <typename T> struct trait_pointer      { enum { value = false }; };    
 template <typename T> struct trait_pointer<T*>  { enum { value = true }; };
 
-// sp<> can be trivially moved
-template <typename T> class sp;
-template <typename T> struct trait_trivial_move< sp<T> >{
-    enum { value = true }; 
-};
-
-// wp<> can be trivially moved
-template <typename T> class wp;
-template <typename T> struct trait_trivial_move< wp<T> >{ 
-    enum { value = true }; 
-};
-
 template <typename TYPE>
 struct traits {
     enum {
@@ -217,7 +205,6 @@
     }
 }
 
-
 // ---------------------------------------------------------------------------
 
 /*
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 1bcfaed..41e5766 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -527,9 +527,10 @@
     static  int             _threadLoop(void* user);
     const   bool            mCanCallJava;
             thread_id_t     mThread;
-            Mutex           mLock;
+    mutable Mutex           mLock;
             Condition       mThreadExitedCondition;
             status_t        mStatus;
+    // note that all accesses of mExitPending and mRunning need to hold mLock
     volatile bool           mExitPending;
     volatile bool           mRunning;
             sp<Thread>      mHoldSelf;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index a0aea00..cc88236 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1982,9 +1982,8 @@
 }
 
 SkXfermode::Mode OpenGLRenderer::getXfermode(SkXfermode* mode) {
-    /* In the future we should look at unifying the Porter-Duff modes and
-     * SkXferModes so that we can use SkXfermode::IsMode(xfer, &mode).
-     */
+    // In the future we should look at unifying the Porter-Duff modes and
+    // SkXferModes so that we can use SkXfermode::IsMode(xfer, &mode).
     if (mode == NULL) {
         return SkXfermode::kSrcOver_Mode;
     }
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index ffccfa2..1e065d1 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -58,6 +58,7 @@
     SkTypeface* typeface;
     String8 str;
 
+    // TODO: Should take into account fake bold and text skew
     bool operator<(const ShadowText& rhs) const {
         LTE_INT(len) {
             LTE_INT(radius) {
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index e560b8f..3752874 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -209,13 +209,10 @@
         // decoding happened
         texture->blend = !bitmap->isOpaque();
         break;
+    case SkBitmap::kARGB_4444_Config:
     case SkBitmap::kIndex8_Config:
         uploadLoFiTexture(resize, bitmap, texture->width, texture->height);
-        texture->blend = false;
-        break;
-    case SkBitmap::kARGB_4444_Config:
-        uploadLoFiTexture(resize, bitmap, texture->width, texture->height);
-        texture->blend = true;
+        texture->blend = !bitmap->isOpaque();
         break;
     default:
         LOGW("Unsupported bitmap config: %d", bitmap->getConfig());
@@ -235,6 +232,7 @@
     rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
     rgbaBitmap.allocPixels();
     rgbaBitmap.eraseColor(0);
+    rgbaBitmap.setIsOpaque(bitmap->isOpaque());
 
     SkCanvas canvas(rgbaBitmap);
     canvas.drawBitmap(*bitmap, 0.0f, 0.0f, NULL);
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index f934eec..0fd404d 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -20,7 +20,6 @@
 
 #include <utils/Atomic.h>
 #include <utils/CallStack.h>
-#include <utils/KeyedVector.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
 #include <utils/TextOutput.h>
@@ -35,6 +34,7 @@
 
 // compile with refcounting debugging enabled
 #define DEBUG_REFS                      0
+#define DEBUG_REFS_FATAL_SANITY_CHECKS  0
 #define DEBUG_REFS_ENABLED_BY_DEFAULT   1
 #define DEBUG_REFS_CALLSTACK_ENABLED    1
 
@@ -70,8 +70,10 @@
 
     void addStrongRef(const void* /*id*/) { }
     void removeStrongRef(const void* /*id*/) { }
+    void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
     void addWeakRef(const void* /*id*/) { }
     void removeWeakRef(const void* /*id*/) { }
+    void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
     void printRefs() const { }
     void trackMe(bool, bool) { }
 
@@ -87,39 +89,73 @@
         , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
         , mRetain(false)
     {
-        //LOGI("NEW weakref_impl %p for RefBase %p", this, base);
     }
     
     ~weakref_impl()
     {
-        LOG_ALWAYS_FATAL_IF(!mRetain && mStrongRefs != NULL, "Strong references remain!");
-        LOG_ALWAYS_FATAL_IF(!mRetain && mWeakRefs != NULL, "Weak references remain!");
+        bool dumpStack = false;
+        if (!mRetain && mStrongRefs != NULL) {
+            dumpStack = true;
+#if DEBUG_REFS_FATAL_SANITY_CHECKS
+            LOG_ALWAYS_FATAL("Strong references remain!");
+#else
+            LOGE("Strong references remain!");
+#endif
+        }
+
+        if (!mRetain && mWeakRefs != NULL) {
+            dumpStack = true;
+#if DEBUG_REFS_FATAL_SANITY_CHECKS
+            LOG_ALWAYS_FATAL("Weak references remain!");
+#else
+            LOGE("Weak references remain!");
+#endif
+        }
+
+        if (dumpStack) {
+            CallStack stack;
+            stack.update();
+            stack.dump();
+        }
     }
 
-    void addStrongRef(const void* id)
-    {
+    void addStrongRef(const void* id) {
+        //LOGD_IF(mTrackEnabled,
+        //        "addStrongRef: RefBase=%p, id=%p", mBase, id);
         addRef(&mStrongRefs, id, mStrong);
     }
 
-    void removeStrongRef(const void* id)
-    {
-        if (!mRetain)
+    void removeStrongRef(const void* id) {
+        //LOGD_IF(mTrackEnabled,
+        //        "removeStrongRef: RefBase=%p, id=%p", mBase, id);
+        if (!mRetain) {
             removeRef(&mStrongRefs, id);
-        else
+        } else {
             addRef(&mStrongRefs, id, -mStrong);
+        }
     }
 
-    void addWeakRef(const void* id)
-    {
+    void renameStrongRefId(const void* old_id, const void* new_id) {
+        //LOGD_IF(mTrackEnabled,
+        //        "renameStrongRefId: RefBase=%p, oid=%p, nid=%p",
+        //        mBase, old_id, new_id);
+        renameRefsId(mStrongRefs, old_id, new_id);
+    }
+
+    void addWeakRef(const void* id) {
         addRef(&mWeakRefs, id, mWeak);
     }
 
-    void removeWeakRef(const void* id)
-    {
-        if (!mRetain)
+    void removeWeakRef(const void* id) {
+        if (!mRetain) {
             removeRef(&mWeakRefs, id);
-        else
+        } else {
             addRef(&mWeakRefs, id, -mWeak);
+        }
+    }
+
+    void renameWeakRefId(const void* old_id, const void* new_id) {
+        renameRefsId(mWeakRefs, old_id, new_id);
     }
 
     void trackMe(bool track, bool retain)
@@ -133,8 +169,7 @@
         String8 text;
 
         {
-            AutoMutex _l(const_cast<weakref_impl*>(this)->mMutex);
-    
+            Mutex::Autolock _l(const_cast<weakref_impl*>(this)->mMutex);
             char buf[128];
             sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
             text.append(buf);
@@ -173,6 +208,7 @@
     {
         if (mTrackEnabled) {
             AutoMutex _l(mMutex);
+
             ref_entry* ref = new ref_entry;
             // Reference count at the time of the snapshot, but before the
             // update.  Positive value means we increment, negative--we
@@ -182,7 +218,6 @@
 #if DEBUG_REFS_CALLSTACK_ENABLED
             ref->stack.update(2);
 #endif
-            
             ref->next = *refs;
             *refs = ref;
         }
@@ -200,13 +235,37 @@
                     delete ref;
                     return;
                 }
-                
                 refs = &ref->next;
                 ref = *refs;
             }
-            
-            LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p (weakref_type %p) that doesn't exist!",
-                             id, mBase, this);
+
+#if DEBUG_REFS_FATAL_SANITY_CHECKS
+            LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p"
+                    "(weakref_type %p) that doesn't exist!",
+                    id, mBase, this);
+#endif
+
+            LOGE("RefBase: removing id %p on RefBase %p"
+                    "(weakref_type %p) that doesn't exist!",
+                    id, mBase, this);
+
+            CallStack stack;
+            stack.update();
+            stack.dump();
+        }
+    }
+
+    void renameRefsId(ref_entry* r, const void* old_id, const void* new_id)
+    {
+        if (mTrackEnabled) {
+            AutoMutex _l(mMutex);
+            ref_entry* ref = r;
+            while (ref != NULL) {
+                if (ref->id == old_id) {
+                    ref->id = new_id;
+                }
+                ref = ref->next;
+            }
         }
     }
 
@@ -236,44 +295,6 @@
     // on removeref that match the address ones.
     bool mRetain;
 
-#if 0
-    void addRef(KeyedVector<const void*, int32_t>* refs, const void* id)
-    {
-        AutoMutex _l(mMutex);
-        ssize_t i = refs->indexOfKey(id);
-        if (i >= 0) {
-            ++(refs->editValueAt(i));
-        } else {
-            i = refs->add(id, 1);
-        }
-    }
-
-    void removeRef(KeyedVector<const void*, int32_t>* refs, const void* id)
-    {
-        AutoMutex _l(mMutex);
-        ssize_t i = refs->indexOfKey(id);
-        LOG_ALWAYS_FATAL_IF(i < 0, "RefBase: removing id %p that doesn't exist!", id);
-        if (i >= 0) {
-            int32_t val = --(refs->editValueAt(i));
-            if (val == 0) {
-                refs->removeItemsAt(i);
-            }
-        }
-    }
-
-    void printRefs(const KeyedVector<const void*, int32_t>& refs)
-    {
-        const size_t N=refs.size();
-        for (size_t i=0; i<N; i++) {
-            printf("\tID %p: %d remain\n", refs.keyAt(i), refs.valueAt(i));
-        }
-    }
-
-    mutable Mutex mMutex;
-    KeyedVector<const void*, int32_t> mStrongRefs;
-    KeyedVector<const void*, int32_t> mWeakRefs;
-#endif
-
 #endif
 };
 
@@ -282,7 +303,6 @@
 void RefBase::incStrong(const void* id) const
 {
     weakref_impl* const refs = mRefs;
-    refs->addWeakRef(id);
     refs->incWeak(id);
     
     refs->addStrongRef(id);
@@ -314,14 +334,12 @@
             delete this;
         }
     }
-    refs->removeWeakRef(id);
     refs->decWeak(id);
 }
 
 void RefBase::forceIncStrong(const void* id) const
 {
     weakref_impl* const refs = mRefs;
-    refs->addWeakRef(id);
     refs->incWeak(id);
     
     refs->addStrongRef(id);
@@ -373,7 +391,7 @@
         if (impl->mStrong == INITIAL_STRONG_VALUE)
             delete impl->mBase;
         else {
-//            LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
+            // LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
             delete impl;
         }
     } else {
@@ -433,7 +451,6 @@
         }
     }
     
-    impl->addWeakRef(id);
     impl->addStrongRef(id);
 
 #if PRINT_REFS
@@ -451,7 +468,7 @@
 bool RefBase::weakref_type::attemptIncWeak(const void* id)
 {
     weakref_impl* const impl = static_cast<weakref_impl*>(this);
-    
+
     int32_t curCount = impl->mWeak;
     LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
                this);
@@ -498,14 +515,11 @@
 RefBase::RefBase()
     : mRefs(new weakref_impl(this))
 {
-//    LOGV("Creating refs %p with RefBase %p\n", mRefs, this);
 }
 
 RefBase::~RefBase()
 {
-//    LOGV("Destroying RefBase %p (refs %p)\n", this, mRefs);
     if (mRefs->mWeak == 0) {
-//        LOGV("Freeing refs %p of old RefBase %p\n", mRefs, this);
         delete mRefs;
     }
 }
@@ -534,6 +548,23 @@
 
 // ---------------------------------------------------------------------------
 
+void RefBase::moveReferences(void* dst, void const* src, size_t n,
+        const ReferenceConverterBase& caster)
+{
+#if DEBUG_REFS
+    const size_t itemSize = caster.getReferenceTypeSize();
+    for (size_t i=0 ; i<n ; i++) {
+        void*       d = reinterpret_cast<void      *>(intptr_t(dst) + i*itemSize);
+        void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize);
+        RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d)));
+        ref->mRefs->renameStrongRefId(s, d);
+        ref->mRefs->renameWeakRefId(s, d);
+    }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
 TextOutput& printStrongPointer(TextOutput& to, const void* val)
 {
     to << "sp<>(" << val << ")";
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 35dcbcb..8b5da0e 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -675,6 +675,9 @@
         mLock("Thread::mLock"),
         mStatus(NO_ERROR),
         mExitPending(false), mRunning(false)
+#ifdef HAVE_ANDROID_OS
+        , mTid(-1)
+#endif
 {
 }
 
@@ -715,6 +718,7 @@
         res = androidCreateRawThreadEtc(_threadLoop,
                 this, name, priority, stack, &mThread);
     }
+    // The new thread wakes up at _threadLoop, but immediately blocks on mLock
     
     if (res == false) {
         mStatus = UNKNOWN_ERROR;   // something happened!
@@ -730,11 +734,19 @@
     // here merely indicates successfully starting the thread and does not
     // imply successful termination/execution.
     return NO_ERROR;
+
+    // Exiting scope of mLock is a memory barrier and allows new thread to run
 }
 
 int Thread::_threadLoop(void* user)
 {
     Thread* const self = static_cast<Thread*>(user);
+
+    // force a memory barrier before reading any fields, in particular mHoldSelf
+    {
+    Mutex::Autolock _l(self->mLock);
+    }
+
     sp<Thread> strong(self->mHoldSelf);
     wp<Thread> weak(strong);
     self->mHoldSelf.clear();
@@ -753,7 +765,7 @@
             self->mStatus = self->readyToRun();
             result = (self->mStatus == NO_ERROR);
 
-            if (result && !self->mExitPending) {
+            if (result && !self->exitPending()) {
                 // Binder threads (and maybe others) rely on threadLoop
                 // running at least once after a successful ::readyToRun()
                 // (unless, of course, the thread has already been asked to exit
@@ -770,18 +782,21 @@
             result = self->threadLoop();
         }
 
+        // establish a scope for mLock
+        {
+        Mutex::Autolock _l(self->mLock);
         if (result == false || self->mExitPending) {
             self->mExitPending = true;
-            self->mLock.lock();
             self->mRunning = false;
             // clear thread ID so that requestExitAndWait() does not exit if
             // called by a new thread using the same thread ID as this one.
             self->mThread = thread_id_t(-1);
+            // note that interested observers blocked in requestExitAndWait are
+            // awoken by broadcast, but blocked on mLock until break exits scope
             self->mThreadExitedCondition.broadcast();
-            self->mThread = thread_id_t(-1); // thread id could be reused
-            self->mLock.unlock();
             break;
         }
+        }
         
         // Release our strong reference, to let a chance to the thread
         // to die a peaceful death.
@@ -795,6 +810,7 @@
 
 void Thread::requestExit()
 {
+    Mutex::Autolock _l(mLock);
     mExitPending = true;
 }
 
@@ -815,6 +831,8 @@
     while (mRunning == true) {
         mThreadExitedCondition.wait(mLock);
     }
+    // This next line is probably not needed any more, but is being left for
+    // historical reference. Note that each interested party will clear flag.
     mExitPending = false;
 
     return mStatus;
@@ -822,6 +840,7 @@
 
 bool Thread::exitPending() const
 {
+    Mutex::Autolock _l(mLock);
     return mExitPending;
 }
 
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 9c92ace..8b29ea84 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -30,6 +30,7 @@
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.graphics.Bitmap;
+import android.graphics.SurfaceTexture;
 import android.media.AudioManager;
 
 import java.io.FileDescriptor;
@@ -379,6 +380,11 @@
  *     <td>{} </p></td>
  *     <td>This method can be called in any state and calling it does not change
  *         the object state. </p></td></tr>
+ * <tr><td>setTexture </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
  * <tr><td>setLooping </p></td>
  *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
  *         PlaybackCompleted}</p></td>
@@ -503,6 +509,7 @@
     private int mListenerContext; // accessed by native methods
     private Surface mSurface; // accessed by native methods
     private SurfaceHolder  mSurfaceHolder;
+    private SurfaceTexture mSurfaceTexture; // accessed by native methods
     private EventHandler mEventHandler;
     private PowerManager.WakeLock mWakeLock = null;
     private boolean mScreenOnWhilePlaying;
@@ -533,9 +540,10 @@
     }
 
     /*
-     * Update the MediaPlayer ISurface. Call after updating mSurface.
+     * Update the MediaPlayer ISurface and ISurfaceTexture.
+     * Call after updating mSurface and/or mSurfaceTexture.
      */
-    private native void _setVideoSurface();
+    private native void _setVideoSurfaceOrSurfaceTexture();
 
     /**
      * Create a request parcel which can be routed to the native media
@@ -577,12 +585,21 @@
     }
 
     /**
-     * Sets the SurfaceHolder to use for displaying the video portion of the media.
-     * This call is optional. Not calling it when playing back a video will
+     * Sets the {@link SurfaceHolder} to use for displaying the video
+     * portion of the media.  A surface must be set if a display is
+     * needed.  Not calling this method when playing back a video will
      * result in only the audio track being played.
      *
      * @param sh the SurfaceHolder to use for video display
      */
+    /*
+     * This portion of comment has a non-Javadoc prefix so as not to refer to a
+     * hidden method. When unhidden, merge it with the previous javadoc comment.
+     *
+     * Either a surface or surface texture must be set if a display or video sink
+     * is needed.  Not calling this method or {@link #setTexture(SurfaceTexture)}
+     * when playing back a video will result in only the audio track being played.
+     */
     public void setDisplay(SurfaceHolder sh) {
         mSurfaceHolder = sh;
         if (sh != null) {
@@ -590,7 +607,29 @@
         } else {
             mSurface = null;
         }
-        _setVideoSurface();
+        mSurfaceTexture = null;
+        _setVideoSurfaceOrSurfaceTexture();
+        updateSurfaceScreenOn();
+    }
+
+    /**
+     * Sets the {@link SurfaceTexture} to be used as the sink for the
+     * video portion of the media. Either a surface or surface texture
+     * must be set if a video sink is needed.  The same surface texture
+     * can be re-set without harm. Setting a surface texture will un-set
+     * any surface that was set via {@link #setDisplay(SurfaceHolder)}.
+     * Not calling this method or {@link #setDisplay(SurfaceHolder)}
+     * when playing back a video will result in only the audio track
+     * being played. Note that if a SurfaceTexture is used, the value
+     * set via setScreenOnWhilePlaying has no effect.
+     *
+     * @hide
+     */
+    public void setTexture(SurfaceTexture st) {
+        mSurfaceHolder = null;
+        mSurface = null;
+        mSurfaceTexture = st;
+        _setVideoSurfaceOrSurfaceTexture();
         updateSurfaceScreenOn();
     }
 
@@ -645,6 +684,8 @@
         return null;
     }
 
+    // Note no convenience method to create a MediaPlayer with SurfaceTexture sink.
+
     /**
      * Convenience method to create a MediaPlayer for a given resource id.
      * On success, {@link #prepare()} will already have been called and must not be called again.
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
index 3019057..a6b4544 100755
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorImpl.java
@@ -928,6 +928,7 @@
             String name;
             MediaItem currentMediaItem = null;
             Overlay currentOverlay = null;
+            boolean regenerateProjectThumbnail = false;
             while (eventType != XmlPullParser.END_DOCUMENT) {
                 switch (eventType) {
                     case XmlPullParser.START_TAG: {
@@ -948,6 +949,11 @@
                             } catch (Exception ex) {
                                 Log.w(TAG, "Cannot load media item: " + mediaItemId, ex);
                                 currentMediaItem = null;
+
+                                // First media item is invalid, mark for project thumbnail removal
+                                if (mMediaItems.size() == 0) {
+                                    regenerateProjectThumbnail = true;
+                                }
                                 // Ignore the media item
                                 ignoredMediaItems.add(mediaItemId);
                             }
@@ -1043,6 +1049,11 @@
                 eventType = parser.next();
             }
             computeTimelineDuration();
+            // Regenerate project thumbnail
+            if (regenerateProjectThumbnail) {
+                generateProjectThumbnail();
+                regenerateProjectThumbnail = false;
+            }
         } finally {
             if (fis != null) {
                 fis.close();
diff --git a/media/java/android/mtp/MtpClient.java b/media/java/android/mtp/MtpClient.java
index 568ac94..a5ee77c 100644
--- a/media/java/android/mtp/MtpClient.java
+++ b/media/java/android/mtp/MtpClient.java
@@ -48,15 +48,14 @@
     private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            String deviceName = intent.getStringExtra(UsbManager.EXTRA_DEVICE_NAME);
+            UsbDevice usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+            String deviceName = usbDevice.getDeviceName();
 
             synchronized (mDeviceList) {
                 MtpDevice mtpDevice = getDeviceLocked(deviceName);
 
                 if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
                     if (mtpDevice == null) {
-                        UsbDevice usbDevice =
-                                (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                         mtpDevice = openDevice(usbDevice);
                     }
                     if (mtpDevice != null) {
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index ca54432..6d074e9 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -35,6 +35,8 @@
 #include "utils/String8.h"
 #include "android_util_Binder.h"
 #include <binder/Parcel.h>
+#include <gui/SurfaceTexture.h>
+#include <gui/ISurfaceTexture.h>
 #include <surfaceflinger/Surface.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -48,8 +50,11 @@
 struct fields_t {
     jfieldID    context;
     jfieldID    surface;
+    jfieldID    surfaceTexture;
     /* actually in android.view.Surface XXX */
     jfieldID    surface_native;
+    // actually in android.graphics.SurfaceTexture
+    jfieldID    surfaceTexture_native;
 
     jmethodID   post_event;
 };
@@ -110,6 +115,13 @@
     return (Surface*)env->GetIntField(clazz, fields.surface_native);
 }
 
+sp<ISurfaceTexture> getSurfaceTexture(JNIEnv* env, jobject clazz)
+{
+    sp<ISurfaceTexture> surfaceTexture(
+        (ISurfaceTexture*)env->GetIntField(clazz, fields.surfaceTexture_native));
+    return surfaceTexture;
+}
+
 static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)
 {
     Mutex::Autolock l(sLock);
@@ -288,26 +300,40 @@
     process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
 }
 
-static void setVideoSurface(const sp<MediaPlayer>& mp, JNIEnv *env, jobject thiz)
+static void setVideoSurfaceOrSurfaceTexture(
+        const sp<MediaPlayer>& mp, JNIEnv *env, jobject thiz, const char *prefix)
 {
+    // The Java MediaPlayer class makes sure that at most one of mSurface and
+    // mSurfaceTexture is non-null.  But just in case, we give priority to
+    // mSurface over mSurfaceTexture.
     jobject surface = env->GetObjectField(thiz, fields.surface);
     if (surface != NULL) {
-        const sp<Surface> native_surface = get_surface(env, surface);
-        LOGV("prepare: surface=%p (id=%d)",
+        sp<Surface> native_surface(get_surface(env, surface));
+        LOGV("%s: surface=%p (id=%d)", prefix,
              native_surface.get(), native_surface->getIdentity());
         mp->setVideoSurface(native_surface);
+    } else {
+        jobject surfaceTexture = env->GetObjectField(thiz, fields.surfaceTexture);
+        if (surfaceTexture != NULL) {
+            sp<ISurfaceTexture> native_surfaceTexture(
+                    getSurfaceTexture(env, surfaceTexture));
+            LOGV("%s: texture=%p (id=%d)", prefix,
+                 native_surfaceTexture.get(), native_surfaceTexture->getIdentity());
+            mp->setVideoSurfaceTexture(native_surfaceTexture);
+        }
     }
 }
 
 static void
-android_media_MediaPlayer_setVideoSurface(JNIEnv *env, jobject thiz)
+android_media_MediaPlayer_setVideoSurfaceOrSurfaceTexture(JNIEnv *env, jobject thiz)
 {
     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
     if (mp == NULL ) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
-    setVideoSurface(mp, env, thiz);
+    setVideoSurfaceOrSurfaceTexture(mp, env, thiz,
+            "_setVideoSurfaceOrSurfaceTexture");
 }
 
 static void
@@ -318,7 +344,7 @@
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
-    setVideoSurface(mp, env, thiz);
+    setVideoSurfaceOrSurfaceTexture(mp, env, thiz, "prepare");
     process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
 }
 
@@ -330,13 +356,7 @@
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
-    jobject surface = env->GetObjectField(thiz, fields.surface);
-    if (surface != NULL) {
-        const sp<Surface> native_surface = get_surface(env, surface);
-        LOGV("prepareAsync: surface=%p (id=%d)",
-             native_surface.get(), native_surface->getIdentity());
-        mp->setVideoSurface(native_surface);
-    }
+    setVideoSurfaceOrSurfaceTexture(mp, env, thiz, "prepareAsync");
     process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
 }
 
@@ -640,9 +660,34 @@
 
     fields.surface_native = env->GetFieldID(surface, ANDROID_VIEW_SURFACE_JNI_ID, "I");
     if (fields.surface_native == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Can't find Surface.mSurface");
+        jniThrowException(env, "java/lang/RuntimeException",
+                "Can't find Surface." ANDROID_VIEW_SURFACE_JNI_ID);
         return;
     }
+
+    fields.surfaceTexture = env->GetFieldID(clazz, "mSurfaceTexture",
+            "Landroid/graphics/SurfaceTexture;");
+    if (fields.surfaceTexture == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException",
+                "Can't find MediaPlayer.mSurfaceTexture");
+        return;
+    }
+
+    jclass surfaceTexture = env->FindClass("android/graphics/SurfaceTexture");
+    if (surfaceTexture == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException",
+                "Can't find android/graphics/SurfaceTexture");
+        return;
+    }
+
+    fields.surfaceTexture_native = env->GetFieldID(surfaceTexture,
+            ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I");
+    if (fields.surfaceTexture_native == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException",
+                "Can't find SurfaceTexture." ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
+        return;
+    }
+
 }
 
 static void
@@ -746,7 +791,7 @@
     {"setDataSource",       "(Ljava/lang/String;)V",            (void *)android_media_MediaPlayer_setDataSource},
     {"setDataSource",       "(Ljava/lang/String;Ljava/util/Map;)V",(void *)android_media_MediaPlayer_setDataSourceAndHeaders},
     {"setDataSource",       "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},
-    {"_setVideoSurface",    "()V",                              (void *)android_media_MediaPlayer_setVideoSurface},
+    {"_setVideoSurfaceOrSurfaceTexture", "()V",                 (void *)android_media_MediaPlayer_setVideoSurfaceOrSurfaceTexture},
     {"prepare",             "()V",                              (void *)android_media_MediaPlayer_prepare},
     {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer_prepareAsync},
     {"_start",              "()V",                              (void *)android_media_MediaPlayer_start},
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 74fb531..fd4c6c6 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -37,7 +37,8 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libui libcutils libutils libbinder libsonivox libicuuc libexpat \
-        libsurfaceflinger_client libcamera_client libstagefright_foundation
+        libsurfaceflinger_client libcamera_client libstagefright_foundation \
+        libgui
 
 LOCAL_MODULE:= libmedia
 
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index c287c0a..2399216 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -23,6 +23,7 @@
 #include <media/IMediaPlayer.h>
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/Surface.h>
+#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
@@ -45,7 +46,8 @@
     SET_METADATA_FILTER,
     GET_METADATA,
     SET_AUX_EFFECT_SEND_LEVEL,
-    ATTACH_AUX_EFFECT
+    ATTACH_AUX_EFFECT,
+    SET_VIDEO_SURFACETEXTURE,
 };
 
 class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -64,6 +66,7 @@
         remote()->transact(DISCONNECT, data, &reply);
     }
 
+    // pass the buffered Surface to the media player service
     status_t setVideoSurface(const sp<Surface>& surface)
     {
         Parcel data, reply;
@@ -73,6 +76,17 @@
         return reply.readInt32();
     }
 
+    // pass the buffered ISurfaceTexture to the media player service
+    status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+        sp<IBinder> b(surfaceTexture->asBinder());
+        data.writeStrongBinder(b);
+        remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply);
+        return reply.readInt32();
+    }
+
     status_t prepareAsync()
     {
         Parcel data, reply;
@@ -220,6 +234,7 @@
         remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
         return reply.readInt32();
     }
+
 };
 
 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -241,6 +256,13 @@
             reply->writeInt32(setVideoSurface(surface));
             return NO_ERROR;
         } break;
+        case SET_VIDEO_SURFACETEXTURE: {
+            CHECK_INTERFACE(IMediaPlayer, data, reply);
+            sp<ISurfaceTexture> surfaceTexture =
+                    interface_cast<ISurfaceTexture>(data.readStrongBinder());
+            reply->writeInt32(setVideoSurfaceTexture(surfaceTexture));
+            return NO_ERROR;
+        } break;
         case PREPARE_ASYNC: {
             CHECK_INTERFACE(IMediaPlayer, data, reply);
             reply->writeInt32(prepareAsync());
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 87c8fe4..0ee0249a 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -201,6 +201,16 @@
     return mPlayer->setVideoSurface(surface);
 }
 
+status_t MediaPlayer::setVideoSurfaceTexture(
+        const sp<ISurfaceTexture>& surfaceTexture)
+{
+    LOGV("setVideoSurfaceTexture");
+    Mutex::Autolock _l(mLock);
+    if (mPlayer == 0) return NO_INIT;
+
+    return mPlayer->setVideoSurfaceTexture(surfaceTexture);
+}
+
 // must call with lock held
 status_t MediaPlayer::prepareAsync_l()
 {
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index f7f0d95..e65f6d8 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -32,7 +32,8 @@
 	libstagefright        			\
 	libstagefright_omx    			\
 	libstagefright_foundation               \
-	libsurfaceflinger_client
+	libsurfaceflinger_client                \
+	libgui
 
 LOCAL_STATIC_LIBRARIES := \
         libstagefright_rtsp                     \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 8c6f76b..ec6188f 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -935,6 +935,15 @@
     return p->setVideoSurface(surface);
 }
 
+status_t MediaPlayerService::Client::setVideoSurfaceTexture(
+        const sp<ISurfaceTexture>& surfaceTexture)
+{
+    LOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
+    sp<MediaPlayerBase> p = getPlayer();
+    if (p == 0) return UNKNOWN_ERROR;
+    return p->setVideoSurfaceTexture(surfaceTexture);
+}
+
 status_t MediaPlayerService::Client::invoke(const Parcel& request,
                                             Parcel *reply)
 {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 9f41db0..1175ed0 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -236,6 +236,8 @@
         // IMediaPlayer interface
         virtual void            disconnect();
         virtual status_t        setVideoSurface(const sp<Surface>& surface);
+        virtual status_t        setVideoSurfaceTexture(
+                                        const sp<ISurfaceTexture>& surfaceTexture);
         virtual status_t        prepareAsync();
         virtual status_t        start();
         virtual status_t        stop();
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index aa8f3f0e..a98231c 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -36,6 +36,9 @@
 
     virtual status_t    setDataSource(int fd, int64_t offset, int64_t length);
     virtual status_t    setVideoSurface(const sp<Surface>& surface) { return UNKNOWN_ERROR; }
+    virtual status_t    setVideoSurfaceTexture(
+                                const sp<ISurfaceTexture>& surfaceTexture)
+                            { return UNKNOWN_ERROR; }
     virtual status_t    prepare();
     virtual status_t    prepareAsync();
     virtual status_t    start();
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index da564dc..e277121 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -33,7 +33,6 @@
 
 status_t StagefrightPlayer::setDataSource(
         const char *url, const KeyedVector<String8, String8> *headers) {
-    LOGI("setDataSource('%s')", url);
     return mPlayer->setDataSource(url, headers);
 }
 
@@ -55,6 +54,14 @@
     return OK;
 }
 
+status_t StagefrightPlayer::setVideoSurfaceTexture(
+        const sp<ISurfaceTexture> &surfaceTexture) {
+    LOGV("setVideoSurfaceTexture");
+
+    mPlayer->setSurfaceTexture(surfaceTexture);
+    return OK;
+}
+
 status_t StagefrightPlayer::prepare() {
     return mPlayer->prepare();
 }
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index fc72bfb..e2796d2 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -39,6 +39,8 @@
     virtual status_t setDataSource(const sp<IStreamSource> &source);
 
     virtual status_t setVideoSurface(const sp<Surface> &surface);
+    virtual status_t setVideoSurfaceTexture(
+            const sp<ISurfaceTexture> &surfaceTexture);
     virtual status_t prepare();
     virtual status_t prepareAsync();
     virtual status_t start();
diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h
index 6abd8e3..d9c3db3 100644
--- a/media/libmediaplayerservice/TestPlayerStub.h
+++ b/media/libmediaplayerservice/TestPlayerStub.h
@@ -78,6 +78,10 @@
     virtual status_t setVideoSurface(const android::sp<android::Surface>& s)  {
         return mPlayer->setVideoSurface(s);
     }
+    virtual status_t setVideoSurfaceTexture(
+            const android::sp<android::ISurfaceTexture>& st)  {
+        return mPlayer->setVideoSurfaceTexture(st);
+    }
     virtual status_t prepare() {return mPlayer->prepare();}
     virtual status_t prepareAsync()  {return mPlayer->prepareAsync();}
     virtual status_t start()  {return mPlayer->start();}
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index 6bf6dd3..b3314be 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -33,8 +33,9 @@
 
 namespace android {
 
-NuPlayer::HTTPLiveSource::HTTPLiveSource(const char *url)
+NuPlayer::HTTPLiveSource::HTTPLiveSource(const char *url, uint32_t flags)
     : mURL(url),
+      mFlags(flags),
       mEOS(false),
       mOffset(0) {
 }
@@ -49,7 +50,9 @@
     mLiveLooper->setName("http live");
     mLiveLooper->start();
 
-    mLiveSession = new LiveSession;
+    mLiveSession = new LiveSession(
+            (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0);
+
     mLiveLooper->registerHandler(mLiveSession);
 
     mLiveSession->connect(mURL.c_str());
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index f3f539a..a8ce7f4 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -27,7 +27,11 @@
 struct LiveSession;
 
 struct NuPlayer::HTTPLiveSource : public NuPlayer::Source {
-    HTTPLiveSource(const char *url);
+    enum Flags {
+        // Don't log any URLs.
+        kFlagIncognito = 1,
+    };
+    HTTPLiveSource(const char *url, uint32_t flags = 0);
 
     virtual void start();
 
@@ -46,6 +50,7 @@
 
 private:
     AString mURL;
+    uint32_t mFlags;
     bool mEOS;
     off64_t mOffset;
     sp<ALooper> mLiveLooper;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 1fcf92b..474c056 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -37,6 +37,7 @@
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 #include <surfaceflinger/Surface.h>
+#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
@@ -71,13 +72,31 @@
         const char *url, const KeyedVector<String8, String8> *headers) {
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
 
-    msg->setObject("source", new HTTPLiveSource(url));
+    uint32_t flags = 0;
+
+    if (headers) {
+        ssize_t index = headers->indexOfKey(String8("x-hide-urls-from-log"));
+
+        if (index >= 0) {
+            flags |= HTTPLiveSource::kFlagIncognito;
+        }
+    }
+
+    msg->setObject("source", new HTTPLiveSource(url, flags));
     msg->post();
 }
 
 void NuPlayer::setVideoSurface(const sp<Surface> &surface) {
-    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, id());
-    msg->setObject("surface", surface);
+    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
+    msg->setObject("native-window", new NativeWindowWrapper(surface));
+    msg->post();
+}
+
+void NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
+    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
+    sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
+                new SurfaceTextureClient(surfaceTexture) : NULL);
+    msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient));
     msg->post();
 }
 
@@ -144,14 +163,14 @@
             break;
         }
 
-        case kWhatSetVideoSurface:
+        case kWhatSetVideoNativeWindow:
         {
-            LOGV("kWhatSetVideoSurface");
+            LOGV("kWhatSetVideoNativeWindow");
 
             sp<RefBase> obj;
-            CHECK(msg->findObject("surface", &obj));
+            CHECK(msg->findObject("native-window", &obj));
 
-            mSurface = static_cast<Surface *>(obj.get());
+            mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
             break;
         }
 
@@ -529,7 +548,8 @@
         new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
                      id());
 
-    *decoder = new Decoder(notify, audio ? NULL : mSurface);
+    *decoder = audio ? new Decoder(notify) :
+                       new Decoder(notify, mNativeWindow);
     looper()->registerHandler(*decoder);
 
     (*decoder)->configure(meta);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index bb65162..e7c6a42 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -20,6 +20,9 @@
 
 #include <media/MediaPlayerInterface.h>
 #include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/NativeWindowWrapper.h>
+#include <gui/SurfaceTextureClient.h>
+#include <surfaceflinger/Surface.h>
 
 namespace android {
 
@@ -38,6 +41,7 @@
             const char *url, const KeyedVector<String8, String8> *headers);
 
     void setVideoSurface(const sp<Surface> &surface);
+    void setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
     void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink);
     void start();
 
@@ -65,7 +69,7 @@
 
     enum {
         kWhatSetDataSource,
-        kWhatSetVideoSurface,
+        kWhatSetVideoNativeWindow,
         kWhatSetAudioSink,
         kWhatMoreDataQueued,
         kWhatStart,
@@ -81,7 +85,7 @@
 
     wp<NuPlayerDriver> mDriver;
     sp<Source> mSource;
-    sp<Surface> mSurface;
+    sp<NativeWindowWrapper> mNativeWindow;
     sp<MediaPlayerBase::AudioSink> mAudioSink;
     sp<Decoder> mVideoDecoder;
     sp<Decoder> mAudioDecoder;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 761dfa4..517acc9 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -31,13 +31,15 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
 #include <surfaceflinger/Surface.h>
+#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
 NuPlayer::Decoder::Decoder(
-        const sp<AMessage> &notify, const sp<Surface> &surface)
+        const sp<AMessage> &notify,
+        const sp<NativeWindowWrapper> &nativeWindow)
     : mNotify(notify),
-      mSurface(surface) {
+      mNativeWindow(nativeWindow) {
 }
 
 NuPlayer::Decoder::~Decoder() {
@@ -55,8 +57,8 @@
 
     sp<AMessage> format = makeFormat(meta);
 
-    if (mSurface != NULL) {
-        format->setObject("surface", mSurface);
+    if (mNativeWindow != NULL) {
+        format->setObject("native-window", mNativeWindow);
     }
 
     if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index 3874cfe..732f090 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -28,7 +28,8 @@
 struct DecoderWrapper;
 
 struct NuPlayer::Decoder : public AHandler {
-    Decoder(const sp<AMessage> &notify, const sp<Surface> &surface = NULL);
+    Decoder(const sp<AMessage> &notify,
+            const sp<NativeWindowWrapper> &nativeWindow = NULL);
 
     void configure(const sp<MetaData> &meta);
 
@@ -47,7 +48,7 @@
     };
 
     sp<AMessage> mNotify;
-    sp<Surface> mSurface;
+    sp<NativeWindowWrapper> mNativeWindow;
 
     sp<ACodec> mCodec;
     sp<DecoderWrapper> mWrapper;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index ac19a2f..0eca958 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -86,6 +86,13 @@
     return OK;
 }
 
+status_t NuPlayerDriver::setVideoSurfaceTexture(
+        const sp<ISurfaceTexture> &surfaceTexture) {
+    mPlayer->setVideoSurfaceTexture(surfaceTexture);
+
+    return OK;
+}
+
 status_t NuPlayerDriver::prepare() {
     return OK;
 }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index e3a5de4..67d0f3e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -36,6 +36,8 @@
     virtual status_t setDataSource(const sp<IStreamSource> &source);
 
     virtual status_t setVideoSurface(const sp<Surface> &surface);
+    virtual status_t setVideoSurfaceTexture(
+            const sp<ISurfaceTexture> &surfaceTexture);
     virtual status_t prepare();
     virtual status_t prepareAsync();
     virtual status_t start();
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 505d9d4..b0ae3d8 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -11,9 +11,11 @@
 #include <media/stagefright/foundation/AMessage.h>
 
 #include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/NativeWindowWrapper.h>
 #include <media/stagefright/OMXClient.h>
 
 #include <surfaceflinger/Surface.h>
+#include <gui/SurfaceTextureClient.h>
 
 #include <OMX_Component.h>
 
@@ -1633,8 +1635,11 @@
     mCodec->configureCodec(mime.c_str(), msg);
 
     sp<RefBase> obj;
-    if (msg->findObject("surface", &obj)) {
-        mCodec->mNativeWindow = static_cast<Surface *>(obj.get());
+    if (msg->findObject("native-window", &obj)) {
+        sp<NativeWindowWrapper> nativeWindow(
+                static_cast<NativeWindowWrapper *>(obj.get()));
+        CHECK(nativeWindow != NULL);
+        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
     }
 
     CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 80eb59f..88069e9 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -74,7 +74,8 @@
         libcamera_client \
         libdrmframework  \
         libcrypto        \
-        libssl
+        libssl           \
+        libgui
 
 LOCAL_STATIC_LIBRARIES := \
         libstagefright_color_conversion \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 1b63ab2..4c744bd 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -43,12 +43,14 @@
 #include <media/stagefright/OMXCodec.h>
 
 #include <surfaceflinger/Surface.h>
+#include <gui/ISurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
 
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
 
 #define USE_SURFACE_ALLOC 1
-#define FRAME_DROP_FREQ 7
+#define FRAME_DROP_FREQ 0
 
 namespace android {
 
@@ -83,8 +85,8 @@
 
 struct AwesomeLocalRenderer : public AwesomeRenderer {
     AwesomeLocalRenderer(
-            const sp<Surface> &surface, const sp<MetaData> &meta)
-        : mTarget(new SoftwareRenderer(surface, meta)) {
+            const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
+        : mTarget(new SoftwareRenderer(nativeWindow, meta)) {
     }
 
     virtual void render(MediaBuffer *buffer) {
@@ -245,6 +247,22 @@
 
     if (headers) {
         mUriHeaders = *headers;
+
+        ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log"));
+        if (index >= 0) {
+            // Browser is in "incognito" mode, suppress logging URLs.
+
+            // This isn't something that should be passed to the server.
+            mUriHeaders.removeItemsAt(index);
+
+            mFlags |= INCOGNITO;
+        }
+    }
+
+    if (!(mFlags & INCOGNITO)) {
+        LOGI("setDataSource_l('%s')", mUri.string());
+    } else {
+        LOGI("setDataSource_l(URL suppressed)");
     }
 
     // The actual work will be done during preparation in the call to
@@ -478,7 +496,7 @@
     mTimeSourceDeltaUs = 0;
     mVideoTimeUs = 0;
 
-    mSeeking = false;
+    mSeeking = NO_SEEK;
     mSeekNotificationSent = false;
     mSeekTimeUs = 0;
 
@@ -889,7 +907,7 @@
 }
 
 void AwesomePlayer::initRenderer_l() {
-    if (mSurface == NULL) {
+    if (mNativeWindow == NULL) {
         return;
     }
 
@@ -920,13 +938,13 @@
         // directly to ANativeBuffers, so we must use a renderer that
         // just pushes those buffers to the ANativeWindow.
         mVideoRenderer =
-            new AwesomeNativeWindowRenderer(mSurface, rotationDegrees);
+            new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);
     } else {
         // Other decoders are instantiated locally and as a consequence
         // allocate their buffers in local address space.  This renderer
         // then performs a color conversion and copy to get the data
         // into the ANativeBuffer.
-        mVideoRenderer = new AwesomeLocalRenderer(mSurface, meta);
+        mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, meta);
     }
 }
 
@@ -986,6 +1004,17 @@
     Mutex::Autolock autoLock(mLock);
 
     mSurface = surface;
+    mNativeWindow = surface;
+}
+
+void AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
+    Mutex::Autolock autoLock(mLock);
+
+    mSurface.clear();
+    if (surfaceTexture != NULL) {
+        mNativeWindow = new SurfaceTextureClient(surfaceTexture);
+    }
+
 }
 
 void AwesomePlayer::setAudioSink(
@@ -1023,7 +1052,7 @@
     if (mRTSPController != NULL) {
         *positionUs = mRTSPController->getNormalPlayTimeUs();
     }
-    else if (mSeeking) {
+    else if (mSeeking != NO_SEEK) {
         *positionUs = mSeekTimeUs;
     } else if (mVideoSource != NULL) {
         Mutex::Autolock autoLock(mMiscStateLock);
@@ -1067,7 +1096,7 @@
         play_l();
     }
 
-    mSeeking = true;
+    mSeeking = SEEK;
     mSeekNotificationSent = false;
     mSeekTimeUs = timeUs;
     mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
@@ -1091,7 +1120,7 @@
 }
 
 void AwesomePlayer::seekAudioIfNecessary_l() {
-    if (mSeeking && mVideoSource == NULL && mAudioPlayer != NULL) {
+    if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
         mAudioPlayer->seekTo(mSeekTimeUs);
 
         mWatchForAudioSeekComplete = true;
@@ -1164,7 +1193,7 @@
             mClient.interface(), mVideoTrack->getFormat(),
             false, // createEncoder
             mVideoTrack,
-            NULL, flags, USE_SURFACE_ALLOC ? mSurface : NULL);
+            NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);
 
     if (mVideoSource != NULL) {
         int64_t durationUs;
@@ -1187,7 +1216,12 @@
 }
 
 void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
-    if (!mSeeking || (mFlags & SEEK_PREVIEW)) {
+    if (mSeeking == SEEK_VIDEO_ONLY) {
+        mSeeking = NO_SEEK;
+        return;
+    }
+
+    if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
         return;
     }
 
@@ -1206,7 +1240,7 @@
     }
 
     mFlags |= FIRST_FRAME;
-    mSeeking = false;
+    mSeeking = NO_SEEK;
     mSeekNotificationSent = false;
 
     if (mDecryptHandle != NULL) {
@@ -1226,13 +1260,13 @@
     }
     mVideoEventPending = false;
 
-    if (mSeeking) {
+    if (mSeeking != NO_SEEK) {
         if (mVideoBuffer) {
             mVideoBuffer->release();
             mVideoBuffer = NULL;
         }
 
-        if (mCachedSource != NULL && mAudioSource != NULL
+        if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL
                 && !(mFlags & SEEK_PREVIEW)) {
             // We're going to seek the video source first, followed by
             // the audio source.
@@ -1253,11 +1287,14 @@
 
     if (!mVideoBuffer) {
         MediaSource::ReadOptions options;
-        if (mSeeking) {
+        if (mSeeking != NO_SEEK) {
             LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
 
             options.setSeekTo(
-                    mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
+                    mSeekTimeUs,
+                    mSeeking == SEEK_VIDEO_ONLY
+                        ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
+                        : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
         }
         for (;;) {
             status_t err = mVideoSource->read(&mVideoBuffer, &options);
@@ -1281,7 +1318,7 @@
                 // So video playback is complete, but we may still have
                 // a seek request pending that needs to be applied
                 // to the audio track.
-                if (mSeeking) {
+                if (mSeeking != NO_SEEK) {
                     LOGV("video stream ended while seeking!");
                 }
                 finishSeekIfNecessary(-1);
@@ -1307,12 +1344,19 @@
     int64_t timeUs;
     CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
 
+    if (mSeeking == SEEK_VIDEO_ONLY) {
+        if (mSeekTimeUs > timeUs) {
+            LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
+                 mSeekTimeUs, timeUs);
+        }
+    }
+
     {
         Mutex::Autolock autoLock(mMiscStateLock);
         mVideoTimeUs = timeUs;
     }
 
-    bool wasSeeking = mSeeking;
+    SeekType wasSeeking = mSeeking;
     finishSeekIfNecessary(timeUs);
 
     if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
@@ -1337,13 +1381,41 @@
         mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
     }
 
-    if (!wasSeeking) {
+    if (wasSeeking == SEEK_VIDEO_ONLY) {
+        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
+
+        int64_t latenessUs = nowUs - timeUs;
+
+        if (latenessUs > 0) {
+            LOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
+        }
+    }
+
+    if (wasSeeking == NO_SEEK) {
         // Let's display the first frame after seeking right away.
 
         int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
 
         int64_t latenessUs = nowUs - timeUs;
 
+        if (latenessUs > 500000ll
+                && mRTSPController == NULL
+                && mAudioPlayer != NULL
+                && mAudioPlayer->getMediaTimeMapping(
+                    &realTimeUs, &mediaTimeUs)) {
+            LOGI("we're much too late (%.2f secs), video skipping ahead",
+                 latenessUs / 1E6);
+
+            mVideoBuffer->release();
+            mVideoBuffer = NULL;
+
+            mSeeking = SEEK_VIDEO_ONLY;
+            mSeekTimeUs = mediaTimeUs;
+
+            postVideoEvent_l();
+            return;
+        }
+
         if (latenessUs > 40000) {
             // We're more than 40ms late.
             LOGV("we're late by %lld us (%.2f secs)", latenessUs, latenessUs / 1E6);
@@ -1381,7 +1453,7 @@
     mVideoBuffer->release();
     mVideoBuffer = NULL;
 
-    if (wasSeeking && (mFlags & SEEK_PREVIEW)) {
+    if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
         mFlags &= ~SEEK_PREVIEW;
         return;
     }
@@ -1450,7 +1522,7 @@
             mSeekNotificationSent = true;
         }
 
-        mSeeking = false;
+        mSeeking = NO_SEEK;
     }
 
     status_t finalStatus;
@@ -1525,7 +1597,8 @@
 
     if (!strncasecmp("http://", mUri.string(), 7)
             || !strncasecmp("https://", mUri.string(), 8)) {
-        mConnectingDataSource = new NuHTTPDataSource;
+        mConnectingDataSource = new NuHTTPDataSource(
+                (mFlags & INCOGNITO) ? NuHTTPDataSource::kFlagIncognito : 0);
 
         mLock.unlock();
         status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 00a4dd5e..eb4c68d 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -217,7 +217,7 @@
 
             *inout_pos += len;
 
-            LOGV("skipped ID3 tag, new starting offset is %ld (0x%08lx)",
+            LOGV("skipped ID3 tag, new starting offset is %lld (0x%016llx)",
                  *inout_pos, *inout_pos);
         }
 
@@ -241,7 +241,7 @@
     do {
         if (pos >= *inout_pos + kMaxBytesChecked) {
             // Don't scan forever.
-            LOGV("giving up at offset %ld", pos);
+            LOGV("giving up at offset %lld", pos);
             break;
         }
 
@@ -251,7 +251,15 @@
             } else {
                 memcpy(buf, tmp, remainingBytes);
                 bytesToRead = kMaxReadBytes - remainingBytes;
-                totalBytesRead = source->readAt(pos, buf + remainingBytes, bytesToRead);
+
+                /*
+                 * The next read position should start from the end of
+                 * the last buffer, and thus should include the remaining
+                 * bytes in the buffer.
+                 */
+                totalBytesRead = source->readAt(pos + remainingBytes,
+                                                buf + remainingBytes,
+                                                bytesToRead);
                 if (totalBytesRead <= 0) {
                     break;
                 }
@@ -283,7 +291,7 @@
             continue;
         }
 
-        LOGV("found possible 1st frame at %ld (header = 0x%08x)", pos, header);
+        LOGV("found possible 1st frame at %lld (header = 0x%08x)", pos, header);
 
         // We found what looks like a valid frame,
         // now find its successors.
@@ -314,7 +322,7 @@
                 break;
             }
 
-            LOGV("found subsequent frame #%d at %ld", j + 2, test_pos);
+            LOGV("found subsequent frame #%d at %lld", j + 2, test_pos);
 
             test_pos += test_frame_size;
         }
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index e39fab3..dbbf3b4 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -71,8 +71,9 @@
     return true;
 }
 
-NuHTTPDataSource::NuHTTPDataSource()
-    : mState(DISCONNECTED),
+NuHTTPDataSource::NuHTTPDataSource(uint32_t flags)
+    : mFlags(flags),
+      mState(DISCONNECTED),
       mPort(0),
       mHTTPS(false),
       mOffset(0),
@@ -138,7 +139,11 @@
         bool https,
         const String8 &headers,
         off64_t offset) {
-    LOGI("connect to %s:%u%s @%lld", host, port, path, offset);
+    if (!(mFlags & kFlagIncognito)) {
+        LOGI("connect to %s:%u%s @%lld", host, port, path, offset);
+    } else {
+        LOGI("connect to <URL suppressed> @%lld", offset);
+    }
 
     bool needsToReconnect = true;
 
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 70408d7..31afc43 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -26,14 +26,15 @@
 #include <surfaceflinger/Surface.h>
 #include <ui/android_native_buffer.h>
 #include <ui/GraphicBufferMapper.h>
+#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
 SoftwareRenderer::SoftwareRenderer(
-        const sp<Surface> &surface, const sp<MetaData> &meta)
+        const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
     : mConverter(NULL),
       mYUVMode(None),
-      mSurface(surface) {
+      mNativeWindow(nativeWindow) {
     int32_t tmp;
     CHECK(meta->findInt32(kKeyColorFormat, &tmp));
     mColorFormat = (OMX_COLOR_FORMATTYPE)tmp;
@@ -65,22 +66,22 @@
             break;
     }
 
-    CHECK(mSurface.get() != NULL);
+    CHECK(mNativeWindow != NULL);
     CHECK(mWidth > 0);
     CHECK(mHeight > 0);
     CHECK(mConverter == NULL || mConverter->isValid());
 
     CHECK_EQ(0,
             native_window_set_usage(
-            mSurface.get(),
+            mNativeWindow.get(),
             GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
             | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));
 
-    CHECK_EQ(0, native_window_set_buffer_count(mSurface.get(), 2));
+    CHECK_EQ(0, native_window_set_buffer_count(mNativeWindow.get(), 2));
 
     // Width must be multiple of 32???
     CHECK_EQ(0, native_window_set_buffers_geometry(
-                mSurface.get(),
+                mNativeWindow.get(),
                 mCropRight - mCropLeft + 1,
                 mCropBottom - mCropTop + 1,
                 halFormat));
@@ -96,7 +97,7 @@
 
     if (transform) {
         CHECK_EQ(0, native_window_set_buffers_transform(
-                    mSurface.get(), transform));
+                    mNativeWindow.get(), transform));
     }
 }
 
@@ -109,12 +110,12 @@
         const void *data, size_t size, void *platformPrivate) {
     android_native_buffer_t *buf;
     int err;
-    if ((err = mSurface->dequeueBuffer(mSurface.get(), &buf)) != 0) {
+    if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0) {
         LOGW("Surface::dequeueBuffer returned error %d", err);
         return;
     }
 
-    CHECK_EQ(0, mSurface->lockBuffer(mSurface.get(), buf));
+    CHECK_EQ(0, mNativeWindow->lockBuffer(mNativeWindow.get(), buf));
 
     GraphicBufferMapper &mapper = GraphicBufferMapper::get();
 
@@ -140,7 +141,7 @@
 
     CHECK_EQ(0, mapper.unlock(buf->handle));
 
-    if ((err = mSurface->queueBuffer(mSurface.get(), buf)) != 0) {
+    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf)) != 0) {
         LOGW("Surface::queueBuffer returned error %d", err);
     }
     buf = NULL;
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index ee845a3..f0cd6a0 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -41,9 +41,14 @@
 
 const int64_t LiveSession::kMaxPlaylistAgeUs = 15000000ll;
 
-LiveSession::LiveSession()
-    : mDataSource(new LiveDataSource),
-      mHTTPDataSource(new NuHTTPDataSource),
+LiveSession::LiveSession(uint32_t flags)
+    : mFlags(flags),
+      mDataSource(new LiveDataSource),
+      mHTTPDataSource(
+              new NuHTTPDataSource(
+                  (mFlags & kFlagIncognito)
+                    ? NuHTTPDataSource::kFlagIncognito
+                    : 0)),
       mPrevBandwidthIndex(-1),
       mLastPlaylistFetchTimeUs(-1),
       mSeqNumber(-1),
@@ -139,7 +144,11 @@
     AString url;
     CHECK(msg->findString("url", &url));
 
-    LOGI("onConnect '%s'", url.c_str());
+    if (!(mFlags & kFlagIncognito)) {
+        LOGI("onConnect '%s'", url.c_str());
+    } else {
+        LOGI("onConnect <URL suppressed>");
+    }
 
     mMasterURL = url;
 
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 1497732..4e6f75c 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -36,6 +36,7 @@
 struct MediaExtractor;
 struct MediaSource;
 struct NuCachedSource2;
+struct ISurfaceTexture;
 
 struct ALooper;
 struct ARTSPController;
@@ -80,6 +81,7 @@
     bool isPlaying() const;
 
     void setSurface(const sp<Surface> &surface);
+    void setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
     void setAudioSink(const sp<MediaPlayerBase::AudioSink> &audioSink);
     status_t setLooping(bool shouldLoop);
 
@@ -122,6 +124,8 @@
 
         AUDIO_RUNNING       = 8192,
         AUDIOPLAYER_STARTED = 16384,
+
+        INCOGNITO           = 32768,
     };
 
     mutable Mutex mLock;
@@ -133,6 +137,7 @@
     wp<MediaPlayerBase> mListener;
 
     sp<Surface> mSurface;
+    sp<ANativeWindow> mNativeWindow;
     sp<MediaPlayerBase::AudioSink> mAudioSink;
 
     SystemTimeSource mSystemTimeSource;
@@ -163,7 +168,13 @@
     int64_t mTimeSourceDeltaUs;
     int64_t mVideoTimeUs;
 
-    bool mSeeking;
+    enum SeekType {
+        NO_SEEK,
+        SEEK,
+        SEEK_VIDEO_ONLY
+    };
+    SeekType mSeeking;
+
     bool mSeekNotificationSent;
     int64_t mSeekTimeUs;
 
diff --git a/media/libstagefright/include/LiveSession.h b/media/libstagefright/include/LiveSession.h
index f1188c4..3fe5d4e 100644
--- a/media/libstagefright/include/LiveSession.h
+++ b/media/libstagefright/include/LiveSession.h
@@ -29,7 +29,11 @@
 struct NuHTTPDataSource;
 
 struct LiveSession : public AHandler {
-    LiveSession();
+    enum Flags {
+        // Don't log any URLs.
+        kFlagIncognito = 1,
+    };
+    LiveSession(uint32_t flags = 0);
 
     sp<DataSource> getDataSource();
 
@@ -67,6 +71,8 @@
         unsigned long mBandwidth;
     };
 
+    uint32_t mFlags;
+
     sp<LiveDataSource> mDataSource;
 
     sp<NuHTTPDataSource> mHTTPDataSource;
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
index 3918434..082b589 100644
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ b/media/libstagefright/include/NuHTTPDataSource.h
@@ -12,7 +12,11 @@
 namespace android {
 
 struct NuHTTPDataSource : public DataSource {
-    NuHTTPDataSource();
+    enum Flags {
+        // Don't log any URLs.
+        kFlagIncognito = 1
+    };
+    NuHTTPDataSource(uint32_t flags = 0);
 
     status_t connect(
             const char *uri,
@@ -52,6 +56,8 @@
 
     Mutex mLock;
 
+    uint32_t mFlags;
+
     State mState;
 
     String8 mHost;
diff --git a/media/libstagefright/include/SoftwareRenderer.h b/media/libstagefright/include/SoftwareRenderer.h
index 90d3fe1..78037b97 100644
--- a/media/libstagefright/include/SoftwareRenderer.h
+++ b/media/libstagefright/include/SoftwareRenderer.h
@@ -20,16 +20,16 @@
 
 #include <media/stagefright/ColorConverter.h>
 #include <utils/RefBase.h>
+#include <ui/android_native_buffer.h>
 
 namespace android {
 
 struct MetaData;
-class Surface;
 
 class SoftwareRenderer {
 public:
     SoftwareRenderer(
-            const sp<Surface> &surface, const sp<MetaData> &meta);
+            const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta);
 
     ~SoftwareRenderer();
 
@@ -44,7 +44,7 @@
     OMX_COLOR_FORMATTYPE mColorFormat;
     ColorConverter *mConverter;
     YUVMode mYUVMode;
-    sp<Surface> mSurface;
+    sp<ANativeWindow> mNativeWindow;
     int32_t mWidth, mHeight;
     int32_t mCropLeft, mCropTop, mCropRight, mCropBottom;
 
diff --git a/media/tests/CameraBrowser/src/com/android/camerabrowser/DeviceDisconnectedReceiver.java b/media/tests/CameraBrowser/src/com/android/camerabrowser/DeviceDisconnectedReceiver.java
index 736af1f..1155807 100644
--- a/media/tests/CameraBrowser/src/com/android/camerabrowser/DeviceDisconnectedReceiver.java
+++ b/media/tests/CameraBrowser/src/com/android/camerabrowser/DeviceDisconnectedReceiver.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.hardware.UsbDevice;
 import android.hardware.UsbManager;
 import android.util.Log;
 
@@ -41,7 +42,8 @@
 
     @Override
     public void onReceive(Context context, Intent intent) {
-        String deviceName = intent.getStringExtra(UsbManager.EXTRA_DEVICE_NAME);
+        UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+        String deviceName = device.getDeviceName();
         Log.d(TAG, "ACTION_USB_DEVICE_DETACHED " + deviceName);
 
         // close our activity if the device it is displaying is disconnected
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
index 4481d00..4c66a2d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
@@ -217,21 +217,21 @@
             videoItemStartTime, videoItemEndTime);
 
         timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Time taken to Create Media Video Item\t" +
+        loggingInfo[0] = "Time taken to Create Media Video Item :" +
             timeTaken;
 
         /** Time Take for Addition of Media Video Item */
         startTime = SystemClock.uptimeMillis();
         addVideoItems(mediaVideoItem);
         timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
-        loggingInfo[1] = "\n\tTime taken to Add  Media Video Item\t"
+        loggingInfo[1] = "\n\tTime taken to Add  Media Video Item :"
             + timeTaken;
 
         /** Time Take for Removal of Media Video Item */
         startTime = SystemClock.uptimeMillis();
         removeVideoItems(mediaVideoItem);
         timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
-        loggingInfo[2] = "\n\tTime taken to remove  Media Video Item\t"
+        loggingInfo[2] = "\n\tTime taken to remove  Media Video Item :"
             + timeTaken;
 
         writeTimingInfo("testPerformanceAddRemoveVideoItem (in mSec)", loggingInfo);
@@ -257,19 +257,19 @@
         createImageItems(mediaImageItem, imageItemFileName, renderingMode,
             imageItemDuration);
         timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Time taken to Create  Media Image Item\t" +
+        loggingInfo[0] = "Time taken to Create  Media Image Item :" +
             timeTaken;
 
         beginTime = SystemClock.uptimeMillis();
         addImageItems(mediaImageItem);
         timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[1] = "\n\tTime taken to add  Media Image Item\t" +
+        loggingInfo[1] = "\n\tTime taken to add  Media Image Item :" +
             timeTaken;
 
         beginTime = SystemClock.uptimeMillis();
         removeImageItems(mediaImageItem);
         timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[2] = "\n\tTime taken to remove  Media Image Item\t"
+        loggingInfo[2] = "\n\tTime taken to remove  Media Image Item :"
             + timeTaken;
 
         writeTimingInfo("testPerformanceAddRemoveImageItem (in mSec)",
@@ -333,7 +333,7 @@
                 transitionBehavior);
         }
         timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
-        loggingInfo[0] = "Time taken to Create CrossFade Transition\t" +
+        loggingInfo[0] = "Time taken to Create CrossFade Transition :" +
             timeTaken;
 
         beginTime = SystemClock.uptimeMillis();
@@ -341,7 +341,7 @@
             mVideoEditor.addTransition(tranCrossfade[i]);
         }
         timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
-        loggingInfo[1] = "\n\tTime taken to add CrossFade Transition\t" +
+        loggingInfo[1] = "\n\tTime taken to add CrossFade Transition :" +
             timeTaken;
 
         beginTime = SystemClock.uptimeMillis();
@@ -350,7 +350,7 @@
                 .removeTransition(tranCrossfade[i].getId()));
         }
         timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
-        loggingInfo[2] = "\n\tTime taken to remove CrossFade Transition\t" +
+        loggingInfo[2] = "\n\tTime taken to remove CrossFade Transition :" +
             timeTaken;
 
         writeTimingInfo("testPerformanceAddRemoveTransition (in mSec)", loggingInfo);
@@ -529,8 +529,8 @@
         mVideoEditorHelper.checkDeleteExistingFile(outFilename);
 
         timeTaken = calculateTimeTaken(beginTime, 1);
-        loggingInfo[0] = "Time taken to do ONE export of storyboard duration\t"
-            + mVideoEditor.getDuration() + "   is   :\t" + timeTaken;
+        loggingInfo[0] = "Time taken to do ONE export of storyboard duration "
+            + mVideoEditor.getDuration() + " is :" + timeTaken;
 
         writeTimingInfo("testPerformanceExport (in mSec)", loggingInfo);
         mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
@@ -564,7 +564,7 @@
                 mediaVideoItem.getHeight() / 2, i);
         }
         timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Duration taken to get Video Thumbnails\t" +
+        loggingInfo[0] = "Duration taken to get Video Thumbnails :" +
             timeTaken;
 
         writeTimingInfo("testPerformanceThumbnailVideoItem (in mSec)", loggingInfo);
@@ -611,7 +611,7 @@
             mediaVideoItem.addOverlay(overlayFrame[i]);
         }
         timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Time taken to add & create Overlay\t" + timeTaken;
+        loggingInfo[0] = "Time taken to add & create Overlay :" + timeTaken;
 
         beginTime = SystemClock.uptimeMillis();
         for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
@@ -619,7 +619,7 @@
                 mediaVideoItem.removeOverlay((overlayFrame[i].getId())));
         }
         timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[1] = "\n\tTime taken to remove  Overlay\t" +
+        loggingInfo[1] = "\n\tTime taken to remove  Overlay :" +
             timeTaken;
 
         writeTimingInfo("testPerformanceOverlayVideoItem (in mSec)", loggingInfo);
@@ -676,7 +676,7 @@
             }
         }
         timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS*10));
-        loggingInfo[0] = "Time taken to get Media Properties\t"
+        loggingInfo[0] = "Time taken to get Media Properties :"
             + timeTaken;
         writeTimingInfo("testPerformanceVideoItemProperties:", loggingInfo);
     }
@@ -727,7 +727,7 @@
         final long durationToAddObjects = averageTime;
         final float timeTaken = (float)durationToAddObjects *
             1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken to Generate Preview with transition\t"
+        loggingInfo[0] = "Time taken to Generate Preview with transition :"
             + timeTaken;
         writeTimingInfo("testPerformanceGeneratePreviewWithTransitions:",
             loggingInfo);
@@ -782,7 +782,7 @@
         final long durationToAddObjects = (averageTime);
         final float timeTaken = (float)durationToAddObjects *
             1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken to Generate KenBurn Effect \t"
+        loggingInfo[0] = "Time taken to Generate KenBurn Effect :"
             + timeTaken;
         writeTimingInfo("testPerformanceWithKenBurn", loggingInfo);
     }
@@ -850,7 +850,7 @@
         final float timeTaken = (float)durationToAddObjects *
             1.0f/(float)NUM_OF_ITERATIONS;
         loggingInfo[0] =
-            "Time taken to testPerformanceEffectOverlappingTransition\t"
+            "Time taken to testPerformanceEffectOverlappingTransition :"
             + timeTaken;
         writeTimingInfo("testPerformanceEffectOverlappingTransition:",
             loggingInfo);
@@ -920,7 +920,7 @@
         final long durationToAddObjects = (averageTime);
         final float timeTaken = (float)durationToAddObjects *
             1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken to TransitionWithEffectOverlapping\t"
+        loggingInfo[0] = "Time taken to TransitionWithEffectOverlapping :"
             + timeTaken;
         writeTimingInfo("testPerformanceTransitionWithEffectOverlapping",
             loggingInfo);
@@ -952,7 +952,7 @@
         }
         final float timeTaken = (float)durationToAddObjects *
             1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken for Thumbnail generation \t"
+        loggingInfo[0] = "Time taken for Thumbnail generation :"
             + timeTaken;
         writeTimingInfo("testThumbnailH264NonIFrame", loggingInfo);
     }
@@ -984,7 +984,7 @@
         }
         final float timeTaken = (float)durationToAddObjects *
             1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken Thumbnail generation \t"
+        loggingInfo[0] = "Time taken Thumbnail generation :"
             + timeTaken;
         writeTimingInfo("testThumbnailH264AnIFrame", loggingInfo);
     }
@@ -1024,7 +1024,7 @@
             }
         });
         timeTaken = calculateTimeTaken(beginTime, 1);
-        loggingInfo[0] = "Time taken for 1st Audio Track (AACLC)\t"
+        loggingInfo[0] = "Time taken for 1st Audio Track (AACLC) :"
             + timeTaken;
 
         final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
@@ -1037,7 +1037,7 @@
             }
         });
         timeTaken = calculateTimeTaken(beginTime, 1);
-        loggingInfo[1] = "\n\tTime taken for 2nd Audio Track(AMRNB)\t"
+        loggingInfo[1] = "\n\tTime taken for 2nd Audio Track(AMRNB) :"
             + timeTaken;
 
         writeTimingInfo("testPerformanceWithAudioTrack", loggingInfo);
@@ -1065,19 +1065,19 @@
         createImageItems(mediaImageItem, imageItemFileName, renderingMode,
             imageItemDuration);
         timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Time taken to Create  Media Image Item (640x480)\t"
+        loggingInfo[0] = "Time taken to Create  Media Image Item (640x480) :"
             + timeTaken;
 
         beginTime = SystemClock.uptimeMillis();
         addImageItems(mediaImageItem);
         timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[1] = "\n\tTime taken to add  Media Image Item (640x480)\t"
+        loggingInfo[1] = "\n\tTime taken to add  Media Image Item (640x480) :"
             + timeTaken;
 
         beginTime = SystemClock.uptimeMillis();
         removeImageItems(mediaImageItem);
         timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[2] = "\n\tTime taken to remove  Media Image Item (640x480)\t"
+        loggingInfo[2] = "\n\tTime taken to remove  Media Image Item (640x480) :"
             + timeTaken;
         writeTimingInfo("testPerformanceAddRemoveImageItem640x480 (in mSec)", loggingInfo);
     }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
index 0e70dd3..432fb43 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
@@ -597,7 +597,7 @@
             if (i % 4 == 0) {
                 final Bitmap[] thumbNails =
                     mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()*3,
-                        mediaVideoItem.getHeight()*2, i, 5000, 2);
+                        mediaVideoItem.getHeight()/2, i, 5000, 2);
                 // Recycle this Bitmap array
                 for (int i1 = 0; i1 < thumbNails.length; i1++) {
                     thumbNails[i1].recycle();
diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp
index 1e3731e..d571106 100644
--- a/media/tests/players/invoke_mock_media_player.cpp
+++ b/media/tests/players/invoke_mock_media_player.cpp
@@ -25,8 +25,8 @@
 #include <utils/Errors.h>
 
 using android::INVALID_OPERATION;
-using android::ISurface;
 using android::Surface;
+using android::ISurfaceTexture;
 using android::MediaPlayerBase;
 using android::OK;
 using android::Parcel;
@@ -69,6 +69,8 @@
 
     virtual status_t    setDataSource(int fd, int64_t offset, int64_t length) {return OK;}
     virtual status_t    setVideoSurface(const sp<Surface>& surface) {return OK;}
+    virtual status_t    setVideoSurfaceTexture(
+                                const sp<ISurfaceTexture>& surfaceTexture) {return OK;}
     virtual status_t    prepare() {return OK;}
     virtual status_t    prepareAsync() {return OK;}
     virtual status_t    start() {return OK;}
diff --git a/packages/SystemUI/res/values-ar-xlarge/strings.xml b/packages/SystemUI/res/values-ar-xlarge/strings.xml
index d689df6..af0eed0 100644
--- a/packages/SystemUI/res/values-ar-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ar-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"محو الكل"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"لا اتصال بالإنترنت"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi متصل"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"جارٍ البحث عن GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"تم تعيين الموقع بواسطة GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg-xlarge/strings.xml b/packages/SystemUI/res/values-bg-xlarge/strings.xml
index ec632ec..d44366d 100644
--- a/packages/SystemUI/res/values-bg-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-bg-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Изчистване"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Няма връзка с интернет"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: има връзка"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Търси се GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Местоположението е зададено от GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca-xlarge/strings.xml b/packages/SystemUI/res/values-ca-xlarge/strings.xml
index 950d845..a0ace2c 100644
--- a/packages/SystemUI/res/values-ca-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ca-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Esborra-ho"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"No connexió Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: connectat"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"S\'està cercant un GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"S\'ha establert la ubicació per GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs-xlarge/strings.xml b/packages/SystemUI/res/values-cs-xlarge/strings.xml
index c3cdd9a..5fe365c 100644
--- a/packages/SystemUI/res/values-cs-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-cs-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Vymazat vše"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Žádné připojení"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: připojeno"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Vyhledávání satelitů GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Poloha nastavena pomocí GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da-xlarge/strings.xml b/packages/SystemUI/res/values-da-xlarge/strings.xml
index 7712a41..ae430b3 100644
--- a/packages/SystemUI/res/values-da-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-da-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Ryd alt"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ingen internetforb."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi er forbundet"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Søger efter GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Placeringen er angivet ved hjælp af GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de-xlarge/strings.xml b/packages/SystemUI/res/values-de-xlarge/strings.xml
index bc5dca2..825cd0d 100644
--- a/packages/SystemUI/res/values-de-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-de-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Alle löschen"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Keine Internetverbindung"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Mit WLAN verbunden"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Suche nach GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Standort durch GPS festgelegt"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el-xlarge/strings.xml b/packages/SystemUI/res/values-el-xlarge/strings.xml
index ab72f4a..4902bb5 100644
--- a/packages/SystemUI/res/values-el-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-el-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Διαγ. όλων"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Χωρίς σύνδ. σε Διαδ."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: συνδέθηκε"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Αναζήτηση για GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Ρύθμιση τοποθεσίας με GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml b/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml
index f31c829..de1eb52 100644
--- a/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Clear all"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"No Internet connection"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi connected"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Searching for GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Location set by GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
index 15a602f..2ace144 100644
--- a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Eliminar todos"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sin conexión a Int."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"WiFi conectado"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Buscando GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"La ubicación se estableció por GPS."</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es-xlarge/strings.xml b/packages/SystemUI/res/values-es-xlarge/strings.xml
index e0451ba..dd490fb 100644
--- a/packages/SystemUI/res/values-es-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-es-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Borrar todo"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sin conexión a Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Con conexión WiFi"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Buscando GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Ubicación definida por GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa-xlarge/strings.xml b/packages/SystemUI/res/values-fa-xlarge/strings.xml
index 5c5f62f..6e0654d 100644
--- a/packages/SystemUI/res/values-fa-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-fa-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"پاک کردن همه"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"اتصال اینترنت موجود نیست"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi متصل شد"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"جستجوی GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"مکان تنظیم شده توسط GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi-xlarge/strings.xml b/packages/SystemUI/res/values-fi-xlarge/strings.xml
index 9ae24d0..7d49e9b 100644
--- a/packages/SystemUI/res/values-fi-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-fi-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Poista kaikki"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ei internetyhteyttä"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wifi yhdistetty"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Haetaan GPS-yhteyttä"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Sijainti määritetty GPS:n avulla"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-xlarge/strings.xml b/packages/SystemUI/res/values-fr-xlarge/strings.xml
index 2bee46a..98dc6c0 100644
--- a/packages/SystemUI/res/values-fr-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-fr-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Tout effacer"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Aucune connexion Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Connecté au Wi-Fi"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Recherche de GPS en cours"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Position définie par GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr-xlarge/strings.xml b/packages/SystemUI/res/values-hr-xlarge/strings.xml
index 4830f81..08adaf0 100644
--- a/packages/SystemUI/res/values-hr-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-hr-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Izbriši sve"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nema int. veze"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: povezano"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Pretraživanje GPS-a"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokaciju utvrdio GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu-xlarge/strings.xml b/packages/SystemUI/res/values-hu-xlarge/strings.xml
index 6643436..41d60fc 100644
--- a/packages/SystemUI/res/values-hu-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-hu-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Össz.törl."</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nincs internetkapcs."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi csatlakozva"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"GPS keresése"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"A GPS beállította a helyet"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in-xlarge/strings.xml b/packages/SystemUI/res/values-in-xlarge/strings.xml
index 8fb9372..8d95060 100644
--- a/packages/SystemUI/res/values-in-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-in-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Hapus semua"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Tidak ada sambungan internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi tersambung"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Menelusuri GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokasi yang disetel oleh GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it-xlarge/strings.xml b/packages/SystemUI/res/values-it-xlarge/strings.xml
index 66718bc..68393fb 100644
--- a/packages/SystemUI/res/values-it-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-it-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Canc. tutto"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"No connessione Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: connesso"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Ricerca del GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Posizione stabilita dal GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw-xlarge/strings.xml b/packages/SystemUI/res/values-iw-xlarge/strings.xml
index 5115c7d..fd3ce0e 100644
--- a/packages/SystemUI/res/values-iw-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-iw-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"נקה הכל"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"אין חיבור לאינטרנט"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi מחובר"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"מחפש GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"מיקום מוגדר על ידי GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja-xlarge/strings.xml b/packages/SystemUI/res/values-ja-xlarge/strings.xml
index 9aac398..c7c0824 100644
--- a/packages/SystemUI/res/values-ja-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ja-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"すべて消去"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"インターネット未接続"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi接続済み"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"GPSで検索中"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPSにより現在地が設定されました"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko-xlarge/strings.xml b/packages/SystemUI/res/values-ko-xlarge/strings.xml
index 21b6845..3777154 100644
--- a/packages/SystemUI/res/values-ko-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ko-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"모두 지우기"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"인터넷에 연결되지 않음"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi 연결됨"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"GPS 검색"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS에서 설정한 위치"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lt-xlarge/strings.xml b/packages/SystemUI/res/values-lt-xlarge/strings.xml
index ba6f97e..90dd501 100644
--- a/packages/SystemUI/res/values-lt-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-lt-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Išv. viską"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nėra interneto ryšio"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Prisijungta prie „Wi-Fi“"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Ieškoma GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS nustatyta vieta"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv-xlarge/strings.xml b/packages/SystemUI/res/values-lv-xlarge/strings.xml
index d5352b9..c533ecb 100644
--- a/packages/SystemUI/res/values-lv-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-lv-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Notīr.visu"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nav interneta sav."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Izv. sav. ar Wi-Fi"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Notiek GPS meklēšana..."</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS iestatītā atrašanās vieta"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb-xlarge/strings.xml b/packages/SystemUI/res/values-nb-xlarge/strings.xml
index d749062..2bf63e8 100644
--- a/packages/SystemUI/res/values-nb-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-nb-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Tøm alt"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ingen Int.-tilkobl."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: tilkoblet"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Søker etter GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Posisjon angitt av GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl-xlarge/strings.xml b/packages/SystemUI/res/values-nl-xlarge/strings.xml
index c079f22..7a63401 100644
--- a/packages/SystemUI/res/values-nl-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-nl-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Wissen"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Geen internetverb."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Verbonden via Wi-Fi"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Zoeken naar GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Locatie bepaald met GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl-xlarge/strings.xml b/packages/SystemUI/res/values-pl-xlarge/strings.xml
index 4280773..1334b70 100644
--- a/packages/SystemUI/res/values-pl-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-pl-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Wyczyść wszystko"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Brak połączenia internetowego"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: połączono"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Wyszukiwanie sygnału GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokalizacja ustawiona wg GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml b/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml
index f807ae9..a5d6bac 100644
--- a/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Limpar tudo"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sem ligação internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi ligado"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"A procurar GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Localização definida por GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-xlarge/strings.xml b/packages/SystemUI/res/values-pt-xlarge/strings.xml
index d47a8db..5209ab9 100644
--- a/packages/SystemUI/res/values-pt-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-pt-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Limpar tudo"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sem conex. à inter."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi conectado"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Procurando GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Localização definida por GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro-xlarge/strings.xml b/packages/SystemUI/res/values-ro-xlarge/strings.xml
index c308e42..2dedd3b 100644
--- a/packages/SystemUI/res/values-ro-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ro-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Şterg. tot"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Fără conex. internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi conectat"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Se caută dispozitivul GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Locaţie setată prin GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru-xlarge/strings.xml b/packages/SystemUI/res/values-ru-xlarge/strings.xml
index dc4dd68..212fa83 100644
--- a/packages/SystemUI/res/values-ru-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ru-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Удалить все"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Нет подключения"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi подкл."</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Выполняется поиск при помощи GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Местоположение установлено при помощи GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk-xlarge/strings.xml b/packages/SystemUI/res/values-sk-xlarge/strings.xml
index 7fe27c8..0fcdd4a 100644
--- a/packages/SystemUI/res/values-sk-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-sk-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Vymazať všetky"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nepripoj. k Intern."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: pripojené"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Hľadanie signálu GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Poloha určená pomocou GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sl-xlarge/strings.xml b/packages/SystemUI/res/values-sl-xlarge/strings.xml
index 8c8fd56..615c565 100644
--- a/packages/SystemUI/res/values-sl-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-sl-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Izbriši vse"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Brez inter. povez."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi – povezano"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Iskanje GPS-a"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokacija nastavljena z GPS-om"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr-xlarge/strings.xml b/packages/SystemUI/res/values-sr-xlarge/strings.xml
index b127757..d66765b 100644
--- a/packages/SystemUI/res/values-sr-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-sr-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Обриши све"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Нема интернет везе"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi је повезан"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Тражи се GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Локацију је подесио GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv-xlarge/strings.xml b/packages/SystemUI/res/values-sv-xlarge/strings.xml
index 0294198..b53269e 100644
--- a/packages/SystemUI/res/values-sv-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-sv-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Ta bort alla"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ingen Internetansl."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi-ansluten"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Sökning efter GPS pågår"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Platsen har identifierats av GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 0537c94..3d8f3c9 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -39,7 +39,7 @@
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Aviseringar"</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string>
-    <string name="recent_tasks_empty" msgid="1905484479067697884">"Inga nya program."</string>
+    <string name="recent_tasks_empty" msgid="1905484479067697884">"Inga nya appar."</string>
     <string name="recent_tasks_app_label" msgid="3796483981246752469">"Appar"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Internetdelning via Bluetooth"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurera inmatningsmetoder"</string>
diff --git a/packages/SystemUI/res/values-th-xlarge/strings.xml b/packages/SystemUI/res/values-th-xlarge/strings.xml
index 73fc2fc..8222140 100644
--- a/packages/SystemUI/res/values-th-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-th-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"ล้างหมด"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"ไม่มีการเชื่อมต่ออินเทอร์เน็ต"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"เชื่อมต่อ Wi-Fi แล้ว"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"การค้นหาสำหรับ GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"ตำแหน่งที่กำหนดโดย GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl-xlarge/strings.xml b/packages/SystemUI/res/values-tl-xlarge/strings.xml
index 90f434e..0eef090 100644
--- a/packages/SystemUI/res/values-tl-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-tl-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"I-clear lahat"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Wala net connection"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Konektado ang WiFi"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Naghahanap ng GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Lokasyon na itinatakda ng GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr-xlarge/strings.xml b/packages/SystemUI/res/values-tr-xlarge/strings.xml
index e15d4d1..8c382fb 100644
--- a/packages/SystemUI/res/values-tr-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-tr-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Tümünü temizle"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"İnternet bağlnts yok"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Kablosuz bağlandı"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"GPS aranıyor"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Konum GPS ile belirlendi"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk-xlarge/strings.xml b/packages/SystemUI/res/values-uk-xlarge/strings.xml
index 9495bc0..6b1b193 100644
--- a/packages/SystemUI/res/values-uk-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-uk-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Очист. все"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Інтернет не під\'єдн."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi під\'єднано"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Виконується пошук за допомогою GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Місцезнаходження встановлено за допомогою GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-vi-xlarge/strings.xml b/packages/SystemUI/res/values-vi-xlarge/strings.xml
index 76d8a8da..b44e1c3 100644
--- a/packages/SystemUI/res/values-vi-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-vi-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Xóa tất cả"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Không có kết nối Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Đã kết nối Wi-Fi"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"Tìm kiếm GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"Vị trí đặt bởi GPS"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml b/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml
index bb70d48..f599dca 100644
--- a/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"全部清除"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"未连接至互联网"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi 已连接"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"正在搜索 GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS 设置的位置"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml b/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml
index 67adbab..2191db7 100644
--- a/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml
@@ -22,8 +22,10 @@
     <string name="status_bar_clear_all_button" msgid="4722520806446512408">"全部清除"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"沒有網路連線"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi 已連線"</string>
-    <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+    <string name="gps_notification_searching_text" msgid="894185519046488403">"正在搜尋 GPS"</string>
+    <string name="gps_notification_found_text" msgid="5306445324124275852">"GPS 已定位"</string>
+    <!-- no translation found for notifications_off_title (2297252328026582111) -->
     <skip />
-    <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+    <!-- no translation found for notifications_off_text (3754847213329718358) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index e80e37d..8ab231b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -42,13 +42,12 @@
 
     IWindowManager mWindowManager;
     long mDownTime;
-    boolean mSending, mLongPressed;
+    boolean mSending;
     int mCode;
     int mRepeat;
     Runnable mCheckLongPress = new Runnable() {
         public void run() {
             if (isPressed()) {
-                mLongPressed = true;
                 mRepeat++;
                 sendEvent(KeyEvent.ACTION_DOWN,
                         KeyEvent.FLAG_FROM_SYSTEM
@@ -91,7 +90,6 @@
                 mDownTime = SystemClock.uptimeMillis();
                 mRepeat = 0;
                 mSending = true;
-                mLongPressed = false;
                 sendEvent(KeyEvent.ACTION_DOWN,
                         KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime);
                 setPressed(true);
@@ -107,7 +105,7 @@
                 break;
             case MotionEvent.ACTION_CANCEL:
                 setPressed(false);
-                if (mSending && !mLongPressed) {
+                if (mSending) {
                     mSending = false;
                     sendEvent(KeyEvent.ACTION_UP,
                             KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
@@ -117,7 +115,7 @@
                 break;
             case MotionEvent.ACTION_UP:
                 setPressed(false);
-                if (mSending && !mLongPressed) {
+                if (mSending) {
                     mSending = false;
                     sendEvent(KeyEvent.ACTION_UP,
                             KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 60fb61d..233d601 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -93,7 +93,7 @@
     public static final int MSG_CLOSE_INPUT_METHODS_PANEL = 1041;
     public static final int MSG_STOP_TICKER = 2000;
 
-    // Fitts' Law assistance for LatinIME; TODO: replace with a more general approach
+    // Fitts' Law assistance for LatinIME; see policy.EventHole
     private static final boolean FAKE_SPACE_BAR = true;
 
     // The height of the bar, as definied by the build.  It may be taller if we're plugged
@@ -159,7 +159,6 @@
     // for disabling the status bar
     int mDisabled = 0;
 
-    boolean mNotificationsOn = true;
     private RecentAppsPanel mRecentsPanel;
     private InputMethodsPanel mInputMethodsPanel;
 
@@ -350,7 +349,7 @@
 
         // the button to open the notification area
         mNotificationTrigger = sb.findViewById(R.id.notificationTrigger);
-        mNotificationTrigger.setOnClickListener(mOnClickListener);
+        mNotificationTrigger.setOnTouchListener(new NotificationTriggerTouchListener());
 
         // the more notifications icon
         mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
@@ -767,7 +766,7 @@
     }
 
     public void removeNotification(IBinder key) {
-        if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ") // TODO");
+        if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ")");
         removeNotificationViews(key);
         mTicker.remove(key);
         setAreThereNotifications();
@@ -882,6 +881,9 @@
     }
 
     public void animateExpand() {
+        mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK);
+        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
+        mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
         mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
         mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
     }
@@ -893,6 +895,8 @@
         mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
         mHandler.removeMessages(MSG_CLOSE_INPUT_METHODS_PANEL);
         mHandler.sendEmptyMessage(MSG_CLOSE_INPUT_METHODS_PANEL);
+        mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK);
+        mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
     }
 
     // called by StatusBar
@@ -1015,16 +1019,11 @@
     public void onClickNotificationTrigger() {
         if (DEBUG) Slog.d(TAG, "clicked notification icons; disabled=" + mDisabled);
         if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
-            if (!mNotificationsOn) {
-                mNotificationsOn = true;
-                mIconLayout.setVisibility(View.VISIBLE); // TODO: animation
-            } else {
-                int msg = !mNotificationPanel.isShowing()
-                    ? MSG_OPEN_NOTIFICATION_PANEL
-                    : MSG_CLOSE_NOTIFICATION_PANEL;
-                mHandler.removeMessages(msg);
-                mHandler.sendEmptyMessage(msg);
-            }
+            int msg = !mNotificationPanel.isShowing()
+                ? MSG_OPEN_NOTIFICATION_PANEL
+                : MSG_CLOSE_NOTIFICATION_PANEL;
+            mHandler.removeMessages(msg);
+            mHandler.sendEmptyMessage(msg);
         }
     }
 
@@ -1132,10 +1131,74 @@
         return entry.notification;
     }
 
-    private class NotificationIconTouchListener implements View.OnTouchListener {
+    private class NotificationTriggerTouchListener implements View.OnTouchListener {
         VelocityTracker mVT;
+        float mInitialTouchX, mInitialTouchY;
+        int mTouchSlop;
+
+        public NotificationTriggerTouchListener() {
+            mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
+        }
+
+        public boolean onTouch(View v, MotionEvent event) {
+//            Slog.d(TAG, String.format("touch: (%.1f, %.1f) initial: (%.1f, %.1f)",
+//                        event.getX(),
+//                        event.getY(),
+//                        mInitialTouchX,
+//                        mInitialTouchY));
+            final int action = event.getAction();
+            switch (action) {
+                case MotionEvent.ACTION_DOWN:
+                    mVT = VelocityTracker.obtain();
+                    mInitialTouchX = event.getX();
+                    mInitialTouchY = event.getY();
+                    // fall through
+                case MotionEvent.ACTION_OUTSIDE:
+                case MotionEvent.ACTION_MOVE:
+                    // check for fling
+                    if (mVT != null) {
+                        mVT.addMovement(event);
+                        mVT.computeCurrentVelocity(1000); // pixels per second
+                        // require a little more oomph once we're already in peekaboo mode
+                        if (mVT.getYVelocity() < -mNotificationFlingVelocity) {
+                            animateExpand();
+                            mVT.recycle();
+                            mVT = null;
+                        }
+                    }
+                    return true;
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL:
+                    if (mVT != null) {
+                        if (action == MotionEvent.ACTION_UP
+                         // was this a sloppy tap?
+                         && Math.abs(event.getX() - mInitialTouchX) < mTouchSlop 
+                         && Math.abs(event.getY() - mInitialTouchY) < (mTouchSlop / 3)
+                         // dragging off the bottom doesn't count
+                         && (int)event.getY() < v.getBottom()) {
+                            animateExpand();
+                        }
+
+                        mVT.recycle();
+                        mVT = null;
+                        return true;
+                    }
+            }
+            return false;
+        }
+    }
+
+    private class NotificationIconTouchListener implements View.OnTouchListener {
+        final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms
+        final static int NOTIFICATION_PEEK_FADE_DELAY = 5000; // ms
+
+        VelocityTracker mVT;
+        int mPeekIndex;
+        float mInitialTouchX, mInitialTouchY;
+        int mTouchSlop;
 
         public NotificationIconTouchListener() {
+            mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
         }
 
         public boolean onTouch(View v, MotionEvent event) {
@@ -1143,34 +1206,46 @@
             boolean panelShowing = mNotificationPanel.isShowing();
             if (panelShowing) return false;
 
-            switch (event.getAction()) {
+            int numIcons = mIconLayout.getChildCount();
+            int newPeekIndex = (int)(event.getX() * numIcons / mIconLayout.getWidth());
+            if (newPeekIndex > numIcons - 1) newPeekIndex = numIcons - 1;
+            else if (newPeekIndex < 0) newPeekIndex = 0;
+
+            final int action = event.getAction();
+            switch (action) {
                 case MotionEvent.ACTION_DOWN:
                     mVT = VelocityTracker.obtain();
+                    mInitialTouchX = event.getX();
+                    mInitialTouchY = event.getY();
+                    mPeekIndex = -1;
 
                     // fall through
                 case MotionEvent.ACTION_OUTSIDE:
                 case MotionEvent.ACTION_MOVE:
                     // peek and switch icons if necessary
-                    int numIcons = mIconLayout.getChildCount();
-                    int peekIndex = (int)((float)event.getX() * numIcons / mIconLayout.getWidth());
-                    if (peekIndex > numIcons - 1) peekIndex = numIcons - 1;
-                    else if (peekIndex < 0) peekIndex = 0;
 
-                    if (!peeking || mNotificationPeekIndex != peekIndex) {
-                        if (DEBUG) Slog.d(TAG, "will peek at notification #" + peekIndex);
+                    if (newPeekIndex != mPeekIndex) {
+                        mPeekIndex = newPeekIndex;
+
+                        if (DEBUG) Slog.d(TAG, "will peek at notification #" + mPeekIndex);
                         Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
-                        peekMsg.arg1 = peekIndex;
+                        peekMsg.arg1 = mPeekIndex;
 
                         mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
 
-                        // no delay if we're scrubbing left-right
-                        mHandler.sendMessage(peekMsg);
+                        if (peeking) {
+                            // no delay if we're scrubbing left-right
+                            mHandler.sendMessage(peekMsg);
+                        } else {
+                            // wait for fling
+                            mHandler.sendMessageDelayed(peekMsg, NOTIFICATION_PEEK_HOLD_THRESH);
+                        }
                     }
 
                     // check for fling
                     if (mVT != null) {
                         mVT.addMovement(event);
-                        mVT.computeCurrentVelocity(1000);
+                        mVT.computeCurrentVelocity(1000); // pixels per second
                         // require a little more oomph once we're already in peekaboo mode
                         if (!panelShowing && (
                                (peeking && mVT.getYVelocity() < -mNotificationFlingVelocity*3)
@@ -1185,9 +1260,24 @@
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL:
                     mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
-                    if (peeking) {
-                        mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK, 5000);
+                    if (action == MotionEvent.ACTION_UP
+                            // was this a sloppy tap?
+                            && Math.abs(event.getX() - mInitialTouchX) < mTouchSlop 
+                            && Math.abs(event.getY() - mInitialTouchY) < (mTouchSlop / 3)
+                            // dragging off the bottom doesn't count
+                            && (int)event.getY() < v.getBottom()) {
+                        Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
+                        peekMsg.arg1 = mPeekIndex;
+                        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
+                        mHandler.sendMessage(peekMsg);
+                        peeking = true; // not technically true yet, but the next line will run
                     }
+
+                    if (peeking) {
+                        mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK,
+                                NOTIFICATION_PEEK_FADE_DELAY);
+                    }
+
                     mVT.recycle();
                     mVT = null;
                     return true;
@@ -1435,155 +1525,6 @@
         return true;
     }
 
-/*
-    public class ShadowController {
-        boolean mShowShadows;
-        Map<View, View> mShadowsForElements = new IdentityHashMap<View, View>(7);
-        Map<View, View> mElementsForShadows = new IdentityHashMap<View, View>(7);
-        LayoutTransition mElementTransition, mShadowTransition;
-
-        View mTouchTarget;
-
-        ShadowController(boolean showShadows) {
-            mShowShadows = showShadows;
-            mTouchTarget = null;
-
-            mElementTransition = new LayoutTransition();
-//            AnimatorSet s = new AnimatorSet();
-//            s.play(ObjectAnimator.ofInt(null, "top", 48, 0))
-//                .with(ObjectAnimator.ofFloat(null, "scaleY", 0.5f, 1f))
-//                .with(ObjectAnimator.ofFloat(null, "alpha", 0.5f, 1f))
-//                ;
-            mElementTransition.setAnimator(LayoutTransition.APPEARING, //s);
-                   ObjectAnimator.ofInt(null, "top", 48, 0));
-            mElementTransition.setDuration(LayoutTransition.APPEARING, 100);
-            mElementTransition.setStartDelay(LayoutTransition.APPEARING, 0);
-
-//            s = new AnimatorSet();
-//            s.play(ObjectAnimator.ofInt(null, "top", 0, 48))
-//                .with(ObjectAnimator.ofFloat(null, "scaleY", 1f, 0.5f))
-//                .with(ObjectAnimator.ofFloat(null, "alpha", 1f, 0.5f))
-//                ;
-            mElementTransition.setAnimator(LayoutTransition.DISAPPEARING, //s);
-                    ObjectAnimator.ofInt(null, "top", 0, 48));
-            mElementTransition.setDuration(LayoutTransition.DISAPPEARING, 400);
-
-            mShadowTransition = new LayoutTransition();
-            mShadowTransition.setAnimator(LayoutTransition.APPEARING,
-                    ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
-            mShadowTransition.setDuration(LayoutTransition.APPEARING, 200);
-            mShadowTransition.setStartDelay(LayoutTransition.APPEARING, 100);
-            mShadowTransition.setAnimator(LayoutTransition.DISAPPEARING,
-                    ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
-            mShadowTransition.setDuration(LayoutTransition.DISAPPEARING, 100);
-
-            ViewGroup bar = (ViewGroup) TabletStatusBar.this.mBarContents;
-            bar.setLayoutTransition(mElementTransition);
-            ViewGroup nav = (ViewGroup) TabletStatusBar.this.mNavigationArea;
-            nav.setLayoutTransition(mElementTransition);
-            ViewGroup shadowGroup = (ViewGroup) bar.findViewById(R.id.shadows);
-            shadowGroup.setLayoutTransition(mShadowTransition);
-        }
-
-        public void add(View element, View shadow) {
-            shadow.setOnTouchListener(makeTouchListener());
-            mShadowsForElements.put(element, shadow);
-            mElementsForShadows.put(shadow, element);
-        }
-
-        public boolean getShadowState() {
-            return mShowShadows;
-        }
-
-        public View.OnTouchListener makeTouchListener() {
-            return new View.OnTouchListener() {
-                public boolean onTouch(View v, MotionEvent ev) {
-                    final int action = ev.getAction();
-
-                    if (DEBUG) Slog.d(TAG, "ShadowController: v=" + v + ", ev=" + ev);
-
-                    // currently redirecting events?
-                    if (mTouchTarget == null) {
-                        mTouchTarget = mElementsForShadows.get(v);
-                    }
-
-                    if (mTouchTarget != null && mTouchTarget.getVisibility() != View.GONE) {
-                        boolean last = false;
-                        switch (action) {
-                            case MotionEvent.ACTION_CANCEL:
-                            case MotionEvent.ACTION_UP:
-                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
-                                if (mShowShadows) {
-                                    mHandler.sendEmptyMessageDelayed(MSG_RESTORE_SHADOWS,
-                                            v == mNotificationShadow ? 5000 : 500);
-                                }
-                                last = true;
-                                break;
-                            case MotionEvent.ACTION_DOWN:
-                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
-                                setElementShadow(mTouchTarget, false);
-                                break;
-                        }
-                        mTouchTarget.dispatchTouchEvent(ev);
-                        if (last) mTouchTarget = null;
-                        return true;
-                    }
-
-                    return false;
-                }
-            };
-        }
-
-        public void refresh() {
-            for (View element : mShadowsForElements.keySet()) {
-                setElementShadow(element, mShowShadows);
-            }
-        }
-
-        public void showAllShadows() {
-            mShowShadows = true;
-            refresh();
-        }
-
-        public void hideAllShadows() {
-            mShowShadows = false;
-            refresh();
-        }
-
-        // Use View.INVISIBLE for things hidden due to shadowing, and View.GONE for things that are
-        // disabled (and should not be shadowed or re-shown)
-        public void setElementShadow(View button, boolean shade) {
-            View shadow = mShadowsForElements.get(button);
-            if (shadow != null) {
-                if (button.getVisibility() != View.GONE) {
-                    shadow.setVisibility(shade ? View.VISIBLE : View.INVISIBLE);
-                    button.setVisibility(shade ? View.INVISIBLE : View.VISIBLE);
-                }
-            }
-        }
-
-        // Hide both element and shadow, using default layout animations.
-        public void hideElement(View button) {
-            Slog.d(TAG, "hiding: " + button);
-            View shadow = mShadowsForElements.get(button);
-            if (shadow != null) {
-                shadow.setVisibility(View.GONE);
-            }
-            button.setVisibility(View.GONE);
-        }
-
-        // Honoring the current shadow state.
-        public void showElement(View button) {
-            Slog.d(TAG, "showing: " + button);
-            View shadow = mShadowsForElements.get(button);
-            if (shadow != null) {
-                shadow.setVisibility(mShowShadows ? View.VISIBLE : View.INVISIBLE);
-            }
-            button.setVisibility(mShowShadows ? View.INVISIBLE : View.VISIBLE);
-        }
-    }
-    */
-
     public class TouchOutsideListener implements View.OnTouchListener {
         private int mMsg;
         private StatusBarPanel mPanel;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 79b5ced..b746c37 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -143,7 +143,6 @@
      * this is 0, there is no key held down.
      */
     private int mPanelChordingKey;
-    private boolean mPanelMayLongPress;
 
     private ImageView mLeftIconView;
 
@@ -658,22 +657,11 @@
         if (event.getRepeatCount() == 0) {
             // The panel key was pushed, so set the chording key
             mPanelChordingKey = keyCode;
-            mPanelMayLongPress = false;
 
             PanelFeatureState st = getPanelState(featureId, true);
             if (!st.isOpen) {
-                if (getContext().getResources().getConfiguration().keyboard
-                        == Configuration.KEYBOARD_NOKEYS) {
-                    mPanelMayLongPress = true;
-                }
                 return preparePanel(st, event);
             }
-        } else if (mPanelMayLongPress && mPanelChordingKey == keyCode
-                && (event.getFlags()&KeyEvent.FLAG_LONG_PRESS) != 0) {
-            // We have had a long press while in a state where this
-            // should be executed...  do it!
-            mPanelChordingKey = 0;
-            mPanelMayLongPress = false;
         }
 
         return false;
@@ -688,7 +676,6 @@
         // The panel key was released, so clear the chording key
         if (mPanelChordingKey != 0) {
             mPanelChordingKey = 0;
-            mPanelMayLongPress = false;
 
             if (event.isCanceled()) {
                 return;
@@ -2140,8 +2127,6 @@
         public void onWindowFocusChanged(boolean hasWindowFocus) {
             super.onWindowFocusChanged(hasWindowFocus);
 
-            mPanelMayLongPress = false;
-
             // If the user is chording a menu shortcut, release the chord since
             // this window lost focus
             if (!hasWindowFocus && mPanelChordingKey != 0) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index f6649fd..f5f4c6e 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -601,19 +601,11 @@
      */
     Runnable mHomeLongPress = new Runnable() {
         public void run() {
-            /*
-             * Eat the longpress so it won't dismiss the recent apps dialog when
-             * the user lets go of the home key
-             */
-            mHomePressed = false;
-            showRecentAppsDialog();
+            handleLongPressOnHome();
         }
     };
 
-    /**
-     * Create (if necessary) and launch the recent apps dialog
-     */
-    void showRecentAppsDialog() {
+    private void handleLongPressOnHome() {
         // We can't initialize this in init() since the configuration hasn't been loaded yet.
         if (mLongPressOnHomeBehavior < 0) {
             mLongPressOnHomeBehavior
@@ -627,14 +619,14 @@
         if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
             performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
             sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
+
+            // Eat the longpress so it won't dismiss the recent apps dialog when
+            // the user lets go of the home key
+            mHomePressed = false;
         }
-        
+
         if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
-            // Fallback to dialog if we fail to launch the above.
-            if (mRecentAppsDialog == null) {
-                mRecentAppsDialog = new RecentApplicationsDialog(mContext);
-            }
-            mRecentAppsDialog.show();
+            showRecentAppsDialog();
         } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) {
             try {
                 Intent intent = new Intent();
@@ -649,6 +641,16 @@
             }
         }
     }
+
+    /**
+     * Create (if necessary) and launch the recent apps dialog
+     */
+    void showRecentAppsDialog() {
+        if (mRecentAppsDialog == null) {
+            mRecentAppsDialog = new RecentApplicationsDialog(mContext);
+        }
+        mRecentAppsDialog.show();
+    }
     
     /** {@inheritDoc} */
     public void init(Context context, IWindowManager windowManager,
diff --git a/services/java/com/android/server/UsbService.java b/services/java/com/android/server/UsbService.java
index 1bc203e..2f84713 100644
--- a/services/java/com/android/server/UsbService.java
+++ b/services/java/com/android/server/UsbService.java
@@ -143,19 +143,6 @@
                 mCurrentAccessory = new UsbAccessory(strings);
                 Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
                 intent.putExtra(UsbManager.EXTRA_ACCESSORY, mCurrentAccessory);
-                // add strings as separate extras to allow filtering
-                if (strings[0] != null) {
-                    intent.putExtra(UsbManager.EXTRA_ACCESSORY_MANUFACTURER, strings[0]);
-                }
-                if (strings[1] != null) {
-                    intent.putExtra(UsbManager.EXTRA_ACCESSORY_PRODUCT, strings[1]);
-                }
-                if (strings[2] != null) {
-                    intent.putExtra(UsbManager.EXTRA_ACCESSORY_TYPE, strings[2]);
-                }
-                if (strings[3] != null) {
-                    intent.putExtra(UsbManager.EXTRA_ACCESSORY_VERSION, strings[3]);
-                }
                 mContext.sendBroadcast(intent);
             } else {
                 Log.e(TAG, "nativeGetAccessoryStrings failed");
@@ -360,12 +347,6 @@
             mDevices.put(deviceName, device);
 
             Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
-            intent.putExtra(UsbManager.EXTRA_DEVICE_NAME, deviceName);
-            intent.putExtra(UsbManager.EXTRA_VENDOR_ID, vendorID);
-            intent.putExtra(UsbManager.EXTRA_PRODUCT_ID, productID);
-            intent.putExtra(UsbManager.EXTRA_DEVICE_CLASS, deviceClass);
-            intent.putExtra(UsbManager.EXTRA_DEVICE_SUBCLASS, deviceSubclass);
-            intent.putExtra(UsbManager.EXTRA_DEVICE_PROTOCOL, deviceProtocol);
             intent.putExtra(UsbManager.EXTRA_DEVICE, device);
             Log.d(TAG, "usbDeviceAdded, sending " + intent);
             mContext.sendBroadcast(intent);
@@ -378,7 +359,7 @@
             UsbDevice device = mDevices.remove(deviceName);
             if (device != null) {
                 Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED);
-                intent.putExtra(UsbManager.EXTRA_DEVICE_NAME, deviceName);
+                intent.putExtra(UsbManager.EXTRA_DEVICE, device);
                 Log.d(TAG, "usbDeviceRemoved, sending " + intent);
                 mContext.sendBroadcast(intent);
             }
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index bccb219..804ace4 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -244,6 +244,8 @@
 
     Object     mLastNITZTimeInfo;
 
+    private static final String WIFI_ONLY_CARRIER = "wifi-only";
+
     //***** Events
 
     static final int EVENT_SEND                 = 1;
@@ -654,14 +656,22 @@
         Looper looper = mSenderThread.getLooper();
         mSender = new RILSender(looper);
 
-        mReceiver = new RILReceiver();
-        mReceiverThread = new Thread(mReceiver, "RILReceiver");
-        mReceiverThread.start();
+        // TODO: Provide a common API for determining if a
+        // device is wifi-only. bug: 3480713
+        String carrier = SystemProperties.get("ro.carrier");
+        if (WIFI_ONLY_CARRIER.equals(carrier)) {
+            riljLog("Not starting RILReceiver: wifi-only");
+        } else {
+            riljLog("Starting RILReceiver");
+            mReceiver = new RILReceiver();
+            mReceiverThread = new Thread(mReceiver, "RILReceiver");
+            mReceiverThread.start();
 
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_SCREEN_ON);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        context.registerReceiver(mIntentReceiver, filter);
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_SCREEN_ON);
+            filter.addAction(Intent.ACTION_SCREEN_OFF);
+            context.registerReceiver(mIntentReceiver, filter);
+        }
     }
 
     //***** CommandsInterface implementation
diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore
index 0ec5000..c5e82d7 100644
--- a/tools/layoutlib/.gitignore
+++ b/tools/layoutlib/.gitignore
@@ -1,2 +1 @@
-bridge/bin
-create/bin
+bin
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 5cfda29..9fb000e 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -1,9 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
-	<classpathentry kind="src" path="tests"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
index 7e70f33..687a91f 100644
--- a/tools/layoutlib/bridge/Android.mk
+++ b/tools/layoutlib/bridge/Android.mk
@@ -33,3 +33,6 @@
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
+# Build all sub-directories
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/tools/layoutlib/bridge/tests/.classpath b/tools/layoutlib/bridge/tests/.classpath
new file mode 100644
index 0000000..9cc2433
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/layoutlib/bridge/tests/.project b/tools/layoutlib/bridge/tests/.project
new file mode 100644
index 0000000..2325eed
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>layoutlib_bridge-tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
new file mode 100644
index 0000000..e303638
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2011 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Only compile source java files in this lib.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := layoutlib-tests
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_JAVA_LIBRARIES := layoutlib kxml2-2.3.0 junit
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+# Build all sub-directories
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
deleted file mode 100644
index a3219e7..0000000
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.android.layoutlib.bridge;
-
-import com.android.ninepatch.NinePatch;
-
-import java.net.URL;
-
-import junit.framework.TestCase;
-
-public class NinePatchTest extends TestCase {
-
-    private NinePatch mPatch;
-
-    @Override
-    protected void setUp() throws Exception {
-        URL url = this.getClass().getClassLoader().getResource(
-                "com/android/layoutlib/testdata/button.9.png");
-
-        mPatch = NinePatch.load(url, false /* convert */);
-    }
-
-    public void test9PatchLoad() throws Exception {
-        assertNotNull(mPatch);
-    }
-
-    public void test9PatchMinSize() {
-        int[] padding = new int[4];
-        mPatch.getPadding(padding);
-        assertEquals(13, padding[0]);
-        assertEquals(3, padding[1]);
-        assertEquals(13, padding[2]);
-        assertEquals(4, padding[3]);
-        assertEquals(36, mPatch.getWidth());
-        assertEquals(25, mPatch.getHeight());
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/button.9.png b/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/button.9.png
deleted file mode 100644
index 9d52f40..0000000
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/button.9.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
similarity index 81%
rename from tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java
rename to tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
index ba3c51a..ec4edac 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java
+++ b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
@@ -14,17 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
-
-import android.graphics.Matrix;
-import android.text.TextPaint;
+package android.graphics;
 
 import junit.framework.TestCase;
 
 /**
  *
  */
-public class AndroidGraphicsTests extends TestCase {
+public class Matrix_DelegateTest extends TestCase {
 
     @Override
     protected void setUp() throws Exception {
@@ -36,14 +33,17 @@
         super.tearDown();
     }
 
-    public void testMatrix() {
+    public void testIdentity() {
         Matrix m1 = new Matrix();
 
         assertTrue(m1.isIdentity());
 
         m1.setValues(new float[] { 1,0,0, 0,1,0, 0,0,1 });
         assertTrue(m1.isIdentity());
+    }
 
+    public void testCopyConstructor() {
+        Matrix m1 = new Matrix();
         Matrix m2 = new Matrix(m1);
 
         float[] v1 = new float[9];
@@ -55,9 +55,4 @@
             assertEquals(v1[i], v2[i]);
         }
     }
-
-    public void textTextPaint() {
-        TextPaint p = new TextPaint();
-        assertNotNull(p);
-    }
 }
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
similarity index 100%
rename from tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java
rename to tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
similarity index 100%
rename from tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
rename to tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/layout1.xml b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/testdata/layout1.xml
similarity index 100%
rename from tools/layoutlib/bridge/tests/com/android/layoutlib/testdata/layout1.xml
rename to tools/layoutlib/bridge/tests/src/com/android/layoutlib/testdata/layout1.xml
diff --git a/voip/java/android/net/sip/SipAudioCall.java b/voip/java/android/net/sip/SipAudioCall.java
index 90d286d..b46f826 100644
--- a/voip/java/android/net/sip/SipAudioCall.java
+++ b/voip/java/android/net/sip/SipAudioCall.java
@@ -754,7 +754,6 @@
     }
 
     private void grabWifiHighPerfLock() {
-        /* not available in master yet
         if (mWifiHighPerfLock == null) {
             Log.v(TAG, "acquire wifi high perf lock");
             mWifiHighPerfLock = ((WifiManager)
@@ -762,7 +761,6 @@
                     .createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, TAG);
             mWifiHighPerfLock.acquire();
         }
-        */
     }
 
     private void releaseWifiHighPerfLock() {