Merge change 25412 into eclair

* changes:
  Make ParcelUuid helper functions consistent.
diff --git a/Android.mk b/Android.mk
index 138ff09..90f2acb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -126,6 +126,8 @@
 	core/java/android/view/IWindow.aidl \
 	core/java/android/view/IWindowManager.aidl \
 	core/java/android/view/IWindowSession.aidl \
+	core/java/android/speech/IRecognitionListener.aidl \
+	core/java/android/speech/IRecognitionService.aidl \
 	core/java/android/speech/tts/ITts.aidl \
 	core/java/android/speech/tts/ITtsCallback.aidl \
 	core/java/com/android/internal/app/IBatteryStats.aidl \
@@ -339,6 +341,7 @@
     -since ./frameworks/base/api/2.xml 2 \
     -since ./frameworks/base/api/3.xml 3 \
     -since ./frameworks/base/api/4.xml 4 \
+    -since ./frameworks/base/api/current.xml Eclair \
 		-error 1 -error 2 -warning 3 -error 4 -error 6 -error 8 \
 		-overview $(LOCAL_PATH)/core/java/overview.html
 
diff --git a/api/current.xml b/api/current.xml
index d6db119..efeecb6 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -7841,6 +7841,28 @@
  visibility="public"
 >
 </field>
+<field name="textAppearanceSearchResultSubtitle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843424"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="textAppearanceSearchResultTitle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843425"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="textAppearanceSmall"
  type="int"
  transient="false"
@@ -17165,27 +17187,6 @@
 <parameter name="id" type="int">
 </parameter>
 </method>
-<method name="startActivity"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="intent" type="android.app.PendingIntent">
-</parameter>
-<parameter name="fillInIntent" type="android.content.Intent">
-</parameter>
-<parameter name="flagsMask" type="int">
-</parameter>
-<parameter name="flagsValues" type="int">
-</parameter>
-<exception name="PendingIntent.CanceledException" type="android.app.PendingIntent.CanceledException">
-</exception>
-</method>
 <method name="startActivityForResult"
  return="void"
  abstract="false"
@@ -17201,29 +17202,6 @@
 <parameter name="requestCode" type="int">
 </parameter>
 </method>
-<method name="startActivityForResult"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="intent" type="android.app.PendingIntent">
-</parameter>
-<parameter name="requestCode" type="int">
-</parameter>
-<parameter name="fillInIntent" type="android.content.Intent">
-</parameter>
-<parameter name="flagsMask" type="int">
-</parameter>
-<parameter name="flagsValues" type="int">
-</parameter>
-<exception name="PendingIntent.CanceledException" type="android.app.PendingIntent.CanceledException">
-</exception>
-</method>
 <method name="startActivityFromChild"
  return="void"
  abstract="false"
@@ -17241,31 +17219,6 @@
 <parameter name="requestCode" type="int">
 </parameter>
 </method>
-<method name="startActivityFromChild"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="child" type="android.app.Activity">
-</parameter>
-<parameter name="intent" type="android.app.PendingIntent">
-</parameter>
-<parameter name="requestCode" type="int">
-</parameter>
-<parameter name="fillInIntent" type="android.content.Intent">
-</parameter>
-<parameter name="flagsMask" type="int">
-</parameter>
-<parameter name="flagsValues" type="int">
-</parameter>
-<exception name="PendingIntent.CanceledException" type="android.app.PendingIntent.CanceledException">
-</exception>
-</method>
 <method name="startActivityIfNeeded"
  return="boolean"
  abstract="false"
@@ -17281,6 +17234,58 @@
 <parameter name="requestCode" type="int">
 </parameter>
 </method>
+<method name="startIntentSenderForResult"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.IntentSender">
+</parameter>
+<parameter name="requestCode" type="int">
+</parameter>
+<parameter name="fillInIntent" type="android.content.Intent">
+</parameter>
+<parameter name="flagsMask" type="int">
+</parameter>
+<parameter name="flagsValues" type="int">
+</parameter>
+<parameter name="extraFlags" type="int">
+</parameter>
+<exception name="IntentSender.SendIntentException" type="android.content.IntentSender.SendIntentException">
+</exception>
+</method>
+<method name="startIntentSenderFromChild"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="child" type="android.app.Activity">
+</parameter>
+<parameter name="intent" type="android.content.IntentSender">
+</parameter>
+<parameter name="requestCode" type="int">
+</parameter>
+<parameter name="fillInIntent" type="android.content.Intent">
+</parameter>
+<parameter name="flagsMask" type="int">
+</parameter>
+<parameter name="flagsValues" type="int">
+</parameter>
+<parameter name="extraFlags" type="int">
+</parameter>
+<exception name="IntentSender.SendIntentException" type="android.content.IntentSender.SendIntentException">
+</exception>
+</method>
 <method name="startManagingCursor"
  return="void"
  abstract="false"
@@ -17563,6 +17568,19 @@
 <parameter name="outInfo" type="android.app.ActivityManager.MemoryInfo">
 </parameter>
 </method>
+<method name="getProcessMemoryInfo"
+ return="android.os.Debug.MemoryInfo[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="pids" type="int[]">
+</parameter>
+</method>
 <method name="getProcessesInErrorState"
  return="java.util.List&lt;android.app.ActivityManager.ProcessErrorStateInfo&gt;"
  abstract="false"
@@ -26137,6 +26155,16 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="BluetoothClass.Device"
  extends="java.lang.Object"
@@ -27197,6 +27225,16 @@
  visibility="public"
 >
 </field>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ERROR"
  type="int"
  transient="false"
@@ -31676,6 +31714,29 @@
 <parameter name="intent" type="android.content.Intent">
 </parameter>
 </method>
+<method name="sendStickyOrderedBroadcast"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultReceiver" type="android.content.BroadcastReceiver">
+</parameter>
+<parameter name="scheduler" type="android.os.Handler">
+</parameter>
+<parameter name="initialCode" type="int">
+</parameter>
+<parameter name="initialData" type="java.lang.String">
+</parameter>
+<parameter name="initialExtras" type="android.os.Bundle">
+</parameter>
+</method>
 <method name="setTheme"
  return="void"
  abstract="true"
@@ -31749,6 +31810,29 @@
 <parameter name="arguments" type="android.os.Bundle">
 </parameter>
 </method>
+<method name="startIntentSender"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.IntentSender">
+</parameter>
+<parameter name="fillInIntent" type="android.content.Intent">
+</parameter>
+<parameter name="flagsMask" type="int">
+</parameter>
+<parameter name="flagsValues" type="int">
+</parameter>
+<parameter name="extraFlags" type="int">
+</parameter>
+<exception name="IntentSender.SendIntentException" type="android.content.IntentSender.SendIntentException">
+</exception>
+</method>
 <method name="startService"
  return="android.content.ComponentName"
  abstract="true"
@@ -32989,6 +33073,29 @@
 <parameter name="intent" type="android.content.Intent">
 </parameter>
 </method>
+<method name="sendStickyOrderedBroadcast"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultReceiver" type="android.content.BroadcastReceiver">
+</parameter>
+<parameter name="scheduler" type="android.os.Handler">
+</parameter>
+<parameter name="initialCode" type="int">
+</parameter>
+<parameter name="initialData" type="java.lang.String">
+</parameter>
+<parameter name="initialExtras" type="android.os.Bundle">
+</parameter>
+</method>
 <method name="setTheme"
  return="void"
  abstract="false"
@@ -33062,6 +33169,29 @@
 <parameter name="arguments" type="android.os.Bundle">
 </parameter>
 </method>
+<method name="startIntentSender"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.IntentSender">
+</parameter>
+<parameter name="fillInIntent" type="android.content.Intent">
+</parameter>
+<parameter name="flagsMask" type="int">
+</parameter>
+<parameter name="flagsValues" type="int">
+</parameter>
+<parameter name="extraFlags" type="int">
+</parameter>
+<exception name="IntentSender.SendIntentException" type="android.content.IntentSender.SendIntentException">
+</exception>
+</method>
 <method name="startService"
  return="android.content.ComponentName"
  abstract="false"
@@ -35699,17 +35829,6 @@
  visibility="public"
 >
 </field>
-<field name="ACTION_REMOTE_INTENT"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.intent.action.REMOTE_INTENT&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="ACTION_RUN"
  type="java.lang.String"
  transient="false"
@@ -42539,6 +42658,25 @@
 >
 </field>
 </class>
+<interface name="RegisteredServicesCacheListener"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onRegisteredServicesCacheChanged"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</interface>
 <class name="ResolveInfo"
  extends="java.lang.Object"
  abstract="false"
@@ -60997,6 +61135,17 @@
  visibility="public"
 >
 </field>
+<field name="YCbCr_422_I"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="20"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="YCbCr_422_SP"
  type="int"
  transient="false"
@@ -67179,6 +67328,17 @@
  visibility="public"
 >
 </method>
+<method name="lock"
+ return="void"
+ abstract="false"
+ native="true"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="open"
  return="android.hardware.Camera"
  abstract="false"
@@ -67339,6 +67499,17 @@
 <parameter name="jpeg" type="android.hardware.Camera.PictureCallback">
 </parameter>
 </method>
+<method name="unlock"
+ return="void"
+ abstract="false"
+ native="true"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <field name="CAMERA_ERROR_SERVER_DIED"
  type="int"
  transient="false"
@@ -77559,8 +77730,8 @@
 <parameter name="tag" type="java.lang.String">
 </parameter>
 </method>
-<method name="getDateTime"
- return="long"
+<method name="getAttributeInt"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -77569,9 +77740,13 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="tag" type="java.lang.String">
+</parameter>
+<parameter name="defaultValue" type="int">
+</parameter>
 </method>
 <method name="getLatLong"
- return="float[]"
+ return="boolean"
  abstract="false"
  native="false"
  synchronized="false"
@@ -77580,17 +77755,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
-</method>
-<method name="getOrientationString"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
+<parameter name="output" type="float[]">
+</parameter>
 </method>
 <method name="getThumbnail"
  return="byte[]"
@@ -77603,17 +77769,6 @@
  visibility="public"
 >
 </method>
-<method name="getWhiteBalanceString"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="hasThumbnail"
  return="boolean"
  abstract="false"
@@ -98630,6 +98785,116 @@
  visibility="public"
 >
 </field>
+<field name="EXTRA_HEALTH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;health&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ICON_SMALL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;icon-small&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_LEVEL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;level&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PLUGGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;plugged&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PRESENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;present&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_SCALE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;scale&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_STATUS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;status&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_TECHNOLOGY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;technology&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_TEMPERATURE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;temperature&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_VOLTAGE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;voltage&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="Binder"
  extends="java.lang.Object"
@@ -101281,6 +101546,39 @@
  visibility="public"
 >
 </method>
+<method name="getTotalPrivateDirty"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalPss"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalSharedDirty"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="readFromParcel"
  return="void"
  abstract="false"
@@ -121528,6 +121826,153 @@
 </field>
 </class>
 </package>
+<package name="android.telephony.cdma"
+>
+<class name="CdmaCellLocation"
+ extends="android.telephony.CellLocation"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="CdmaCellLocation"
+ type="android.telephony.cdma.CdmaCellLocation"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<constructor name="CdmaCellLocation"
+ type="android.telephony.cdma.CdmaCellLocation"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="bundleWithValues" type="android.os.Bundle">
+</parameter>
+</constructor>
+<method name="fillInNotifierBundle"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="bundleToFill" type="android.os.Bundle">
+</parameter>
+</method>
+<method name="getBaseStationId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getBaseStationLatitude"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getBaseStationLongitude"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getNetworkId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSystemId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setCellLocationData"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="baseStationId" type="int">
+</parameter>
+<parameter name="baseStationLatitude" type="int">
+</parameter>
+<parameter name="baseStationLongitude" type="int">
+</parameter>
+</method>
+<method name="setCellLocationData"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="baseStationId" type="int">
+</parameter>
+<parameter name="baseStationLatitude" type="int">
+</parameter>
+<parameter name="baseStationLongitude" type="int">
+</parameter>
+<parameter name="systemId" type="int">
+</parameter>
+<parameter name="networkId" type="int">
+</parameter>
+</method>
+<method name="setStateInvalid"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
+</package>
 <package name="android.telephony.gsm"
 >
 <class name="GsmCellLocation"
@@ -126439,6 +126884,29 @@
 <parameter name="intent" type="android.content.Intent">
 </parameter>
 </method>
+<method name="sendStickyOrderedBroadcast"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultReceiver" type="android.content.BroadcastReceiver">
+</parameter>
+<parameter name="scheduler" type="android.os.Handler">
+</parameter>
+<parameter name="initialCode" type="int">
+</parameter>
+<parameter name="initialData" type="java.lang.String">
+</parameter>
+<parameter name="initialExtras" type="android.os.Bundle">
+</parameter>
+</method>
 <method name="setTheme"
  return="void"
  abstract="false"
@@ -126512,6 +126980,29 @@
 <parameter name="arguments" type="android.os.Bundle">
 </parameter>
 </method>
+<method name="startIntentSender"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.IntentSender">
+</parameter>
+<parameter name="fillInIntent" type="android.content.Intent">
+</parameter>
+<parameter name="flagsMask" type="int">
+</parameter>
+<parameter name="flagsValues" type="int">
+</parameter>
+<parameter name="extraFlags" type="int">
+</parameter>
+<exception name="IntentSender.SendIntentException" type="android.content.IntentSender.SendIntentException">
+</exception>
+</method>
 <method name="startService"
  return="android.content.ComponentName"
  abstract="false"
@@ -129444,6 +129935,17 @@
  visibility="public"
 >
 </field>
+<field name="TYPE_TEXT_FLAG_NO_SUGGESTIONS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="524288"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TYPE_TEXT_VARIATION_EMAIL_ADDRESS"
  type="int"
  transient="false"
diff --git a/cmds/keystore/Android.mk b/cmds/keystore/Android.mk
index 8804636..15a199f 100644
--- a/cmds/keystore/Android.mk
+++ b/cmds/keystore/Android.mk
@@ -1,22 +1,36 @@
+#
+# Copyright (C) 2009 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.
+#
+
 ifneq ($(TARGET_SIMULATOR),true)
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    netkeystore.c netkeystore_main.c keymgmt.c
-
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, system-core)/cutils \
-    external/openssl/include
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils libssl
-
-LOCAL_STATIC_LIBRARIES :=
-
+LOCAL_SRC_FILES := keystore.c
+LOCAL_C_INCLUDES := external/openssl/include
+LOCAL_SHARED_LIBRARIES := libcutils libcrypto
 LOCAL_MODULE:= keystore
-
 include $(BUILD_EXECUTABLE)
 
-endif # !simulator))
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := keystore_cli.c
+LOCAL_C_INCLUDES := external/openssl/include
+LOCAL_SHARED_LIBRARIES := libcutils libcrypto
+LOCAL_MODULE:= keystore_cli
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_EXECUTABLE)
+
+endif
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
new file mode 100644
index 0000000..ba74c78
--- /dev/null
+++ b/cmds/keystore/keystore.c
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+
+#define LOG_TAG "keystore"
+#include <cutils/log.h>
+#include <cutils/sockets.h>
+#include <private/android_filesystem_config.h>
+
+#include "keystore.h"
+
+/* KeyStore is a secured storage for key-value pairs. In this implementation,
+ * each file stores one key-value pair. Keys are encoded in file names, and
+ * values are encrypted with checksums. The encryption key is protected by a
+ * user-defined password. To keep things simple, buffers are always larger than
+ * the maximum space we needed, so boundary checks on buffers are omitted. */
+
+#define KEY_SIZE        120
+#define VALUE_SIZE      32768
+#define PASSWORD_SIZE   VALUE_SIZE
+
+/* Here is the encoding of keys. This is necessary in order to allow arbitrary
+ * characters in keys. Characters in [0-~] are not encoded. Others are encoded
+ * into two bytes. The first byte is one of [+-.] which represents the first
+ * two bits of the character. The second byte encodes the rest of the bits into
+ * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
+ * that Base64 cannot be used here due to the need of prefix match on keys. */
+
+static int encode_key(char *out, uint8_t *in, int length)
+{
+    int i;
+    for (i = length; i > 0; --i, ++in, ++out) {
+        if (*in >= '0' && *in <= '~') {
+            *out = *in;
+        } else {
+            *out = '+' + (*in >> 6);
+            *++out = '0' + (*in & 0x3F);
+            ++length;
+        }
+    }
+    *out = 0;
+    return length;
+}
+
+static int decode_key(uint8_t *out, char *in, int length)
+{
+    int i;
+    for (i = 0; i < length; ++i, ++in, ++out) {
+        if (*in >= '0' && *in <= '~') {
+            *out = *in;
+        } else {
+            *out = (*in - '+') << 6;
+            *out |= (*++in - '0') & 0x3F;
+            --length;
+        }
+    }
+    *out = 0;
+    return length;
+}
+
+/* Here is the protocol used in both requests and responses:
+ *     code [length_1 message_1 ... length_n message_n] end-of-file
+ * where code is one byte long and lengths are unsigned 16-bit integers in
+ * network order. Thus the maximum length of a message is 65535 bytes. */
+
+static int the_socket = -1;
+
+static int recv_code(int8_t *code)
+{
+    return recv(the_socket, code, 1, 0) == 1;
+}
+
+static int recv_message(uint8_t *message, int length)
+{
+    uint8_t bytes[2];
+    if (recv(the_socket, &bytes[0], 1, 0) != 1 ||
+        recv(the_socket, &bytes[1], 1, 0) != 1) {
+        return -1;
+    } else {
+        int offset = bytes[0] << 8 | bytes[1];
+        if (length < offset) {
+            return -1;
+        }
+        length = offset;
+        offset = 0;
+        while (offset < length) {
+            int n = recv(the_socket, &message[offset], length - offset, 0);
+            if (n <= 0) {
+                return -1;
+            }
+            offset += n;
+        }
+    }
+    return length;
+}
+
+static int recv_end_of_file()
+{
+    uint8_t byte;
+    return recv(the_socket, &byte, 1, 0) == 0;
+}
+
+static void send_code(int8_t code)
+{
+    send(the_socket, &code, 1, 0);
+}
+
+static void send_message(uint8_t *message, int length)
+{
+    uint16_t bytes = htons(length);
+    send(the_socket, &bytes, 2, 0);
+    send(the_socket, message, length, 0);
+}
+
+/* Here is the file format. Values are encrypted by AES CBC, and MD5 is used to
+ * compute their checksums. To make the files portable, the length is stored in
+ * network order. Note that the first four bytes are reserved for future use and
+ * are always set to zero in this implementation. */
+
+static int the_entropy = -1;
+
+static struct __attribute__((packed)) {
+    uint32_t reserved;
+    uint8_t vector[AES_BLOCK_SIZE];
+    uint8_t encrypted[0];
+    uint8_t digest[MD5_DIGEST_LENGTH];
+    uint8_t digested[0];
+    int32_t length;
+    uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
+} blob;
+
+static int8_t encrypt_blob(char *name, AES_KEY *aes_key)
+{
+    uint8_t vector[AES_BLOCK_SIZE];
+    int length = blob.length;
+    int fd;
+
+    if (read(the_entropy, vector, AES_BLOCK_SIZE) != AES_BLOCK_SIZE) {
+        return SYSTEM_ERROR;
+    }
+
+    length += blob.value - blob.digested;
+    blob.length = htonl(blob.length);
+    MD5(blob.digested, length, blob.digest);
+
+    length += blob.digested - blob.encrypted;
+    length = (length + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE * AES_BLOCK_SIZE;
+    memcpy(vector, blob.vector, AES_BLOCK_SIZE);
+    AES_cbc_encrypt(blob.encrypted, blob.encrypted, length, aes_key, vector,
+                    AES_ENCRYPT);
+
+    blob.reserved = 0;
+    length += blob.encrypted - (uint8_t *)&blob;
+
+    fd = open(".tmp", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
+    if (fd == -1 || write(fd, &blob, length) != length) {
+        return SYSTEM_ERROR;
+    }
+    close(fd);
+    return rename(".tmp", name) ? SYSTEM_ERROR : NO_ERROR;
+}
+
+static int8_t decrypt_blob(char *name, AES_KEY *aes_key)
+{
+    int fd = open(name, O_RDONLY);
+    int length;
+
+    if (fd == -1) {
+        return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
+    }
+    length = read(fd, &blob, sizeof(blob));
+    close(fd);
+
+    length -= blob.encrypted - (uint8_t *)&blob;
+    if (length < blob.value - blob.encrypted || length % AES_BLOCK_SIZE != 0) {
+        return VALUE_CORRUPTED;
+    }
+
+    AES_cbc_encrypt(blob.encrypted, blob.encrypted, length, aes_key,
+                    blob.vector, AES_DECRYPT);
+    length -= blob.digested - blob.encrypted;
+    if (!memcmp(blob.digest, MD5(blob.digested, length, NULL),
+                MD5_DIGEST_LENGTH)) {
+        return VALUE_CORRUPTED;
+    }
+
+    length -= blob.value - blob.digested;
+    blob.length = ntohl(blob.length);
+    return (length < blob.length) ? VALUE_CORRUPTED : NO_ERROR;
+}
+
+/* Here are the actions. Each of them is a function without arguments. All
+ * information is defined in global variables, which are set properly before
+ * performing an action. The number of parameters required by each action is
+ * fixed and defined in a table. If the return value of an action is positive,
+ * it will be treated as a response code and transmitted to the client. Note
+ * that the lengths of parameters are checked when they are received, so
+ * boundary checks on parameters are omitted. */
+
+#define MAX_PARAM   2
+#define MAX_RETRY   4
+
+static uid_t uid = -1;
+static int8_t state = UNINITIALIZED;
+static int8_t retry = MAX_RETRY;
+
+static struct {
+    int length;
+    uint8_t value[VALUE_SIZE];
+} params[MAX_PARAM];
+
+static AES_KEY encryption_key;
+static AES_KEY decryption_key;
+
+static int8_t test()
+{
+    return state;
+}
+
+static int8_t get()
+{
+    char name[NAME_MAX];
+    int n = sprintf(name, "%u_", uid);
+    encode_key(&name[n], params[0].value, params[0].length);
+    n = decrypt_blob(name, &decryption_key);
+    if (n != NO_ERROR) {
+        return n;
+    }
+    send_code(NO_ERROR);
+    send_message(blob.value, blob.length);
+    return -NO_ERROR;
+}
+
+static int8_t insert()
+{
+    char name[NAME_MAX];
+    int n = sprintf(name, "%u_", uid);
+    encode_key(&name[n], params[0].value, params[0].length);
+    blob.length = params[1].length;
+    memcpy(blob.value, params[1].value, params[1].length);
+    return encrypt_blob(name, &encryption_key);
+}
+
+static int8_t delete()
+{
+    char name[NAME_MAX];
+    int n = sprintf(name, "%u_", uid);
+    encode_key(&name[n], params[0].value, params[0].length);
+    return (unlink(name) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR;
+}
+
+static int8_t exist()
+{
+    char name[NAME_MAX];
+    int n = sprintf(name, "%u_", uid);
+    encode_key(&name[n], params[0].value, params[0].length);
+    if (access(name, R_OK) == -1) {
+        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
+    }
+    return NO_ERROR;
+}
+
+static int8_t saw()
+{
+    DIR *dir = opendir(".");
+    struct dirent *file;
+    char name[NAME_MAX];
+    int n;
+
+    if (!dir) {
+        return SYSTEM_ERROR;
+    }
+    n = sprintf(name, "%u_", uid);
+    n += encode_key(&name[n], params[0].value, params[0].length);
+    send_code(NO_ERROR);
+    while ((file = readdir(dir)) != NULL) {
+        if (!strncmp(name, file->d_name, n)) {
+            char *p = &file->d_name[n];
+            params[0].length = decode_key(params[0].value, p, strlen(p));
+            send_message(params[0].value, params[0].length);
+        }
+    }
+    closedir(dir);
+    return -NO_ERROR;
+}
+
+static int8_t reset()
+{
+    DIR *dir = opendir(".");
+    struct dirent *file;
+
+    memset(&encryption_key, 0, sizeof(encryption_key));
+    memset(&decryption_key, 0, sizeof(decryption_key));
+    state = UNINITIALIZED;
+    retry = MAX_RETRY;
+
+    if (!dir) {
+        return SYSTEM_ERROR;
+    }
+    while ((file = readdir(dir)) != NULL) {
+        unlink(file->d_name);
+    }
+    closedir(dir);
+    return NO_ERROR;
+}
+
+#define MASTER_KEY_FILE ".masterkey"
+#define MASTER_KEY_SIZE 16
+
+static void generate_key(uint8_t *key, uint8_t *password, int length)
+{
+    PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, (uint8_t *)"keystore",
+                           sizeof("keystore"), 1024, MASTER_KEY_SIZE, key);
+}
+
+static int8_t password()
+{
+    uint8_t key[MASTER_KEY_SIZE];
+    AES_KEY aes_key;
+    int n;
+
+    if (state == UNINITIALIZED) {
+        blob.length = MASTER_KEY_SIZE;
+        if (read(the_entropy, blob.value, MASTER_KEY_SIZE) != MASTER_KEY_SIZE) {
+           return SYSTEM_ERROR;
+        }
+    } else {
+        generate_key(key, params[0].value, params[0].length);
+        AES_set_decrypt_key(key, MASTER_KEY_SIZE * 8, &aes_key);
+        n = decrypt_blob(MASTER_KEY_FILE, &aes_key);
+        if (n == SYSTEM_ERROR) {
+            return SYSTEM_ERROR;
+        }
+        if (n != NO_ERROR || blob.length != MASTER_KEY_SIZE) {
+            if (retry <= 0) {
+                reset();
+                return UNINITIALIZED;
+            }
+            return WRONG_PASSWORD + --retry;
+        }
+    }
+
+    if (params[1].length == -1) {
+        memcpy(key, blob.value, MASTER_KEY_SIZE);
+    } else {
+        generate_key(key, params[1].value, params[1].length);
+        AES_set_encrypt_key(key, MASTER_KEY_SIZE * 8, &aes_key);
+        memcpy(key, blob.value, MASTER_KEY_SIZE);
+        n = encrypt_blob(MASTER_KEY_FILE, &aes_key);
+    }
+
+    if (n == NO_ERROR) {
+        AES_set_encrypt_key(key, MASTER_KEY_SIZE * 8, &encryption_key);
+        AES_set_decrypt_key(key, MASTER_KEY_SIZE * 8, &decryption_key);
+        state = NO_ERROR;
+        retry = MAX_RETRY;
+    }
+    return n;
+}
+
+static int8_t lock()
+{
+    memset(&encryption_key, 0, sizeof(encryption_key));
+    memset(&decryption_key, 0, sizeof(decryption_key));
+    state = LOCKED;
+    return NO_ERROR;
+}
+
+static int8_t unlock()
+{
+    params[1].length = -1;
+    return password();
+}
+
+/* Here are the permissions, actions, users, and the main function. */
+
+enum perm {
+    TEST     =   1,
+    GET      =   2,
+    INSERT   =   4,
+    DELETE   =   8,
+    EXIST    =  16,
+    SAW      =  32,
+    RESET    =  64,
+    PASSWORD = 128,
+    LOCK     = 256,
+    UNLOCK   = 512,
+};
+
+static struct action {
+    int8_t (*run)();
+    int8_t code;
+    int8_t state;
+    uint32_t perm;
+    int lengths[MAX_PARAM];
+} actions[] = {
+    {test,     't', 0,        TEST,     {0}},
+    {get,      'g', NO_ERROR, GET,      {KEY_SIZE}},
+    {insert,   'i', NO_ERROR, INSERT,   {KEY_SIZE, VALUE_SIZE}},
+    {delete,   'd', 0,        DELETE,   {KEY_SIZE}},
+    {exist,    'e', 0,        EXIST,    {KEY_SIZE}},
+    {saw,      's', 0,        SAW,      {KEY_SIZE}},
+    {reset,    'r', 0,        RESET,    {0}},
+    {password, 'p', 0,        PASSWORD, {PASSWORD_SIZE, PASSWORD_SIZE}},
+    {lock,     'l', NO_ERROR, LOCK,     {0}},
+    {unlock,   'u', LOCKED,   UNLOCK,   {PASSWORD_SIZE}},
+    {NULL,      0 , 0,        0,        {0}},
+};
+
+static struct user {
+    uid_t uid;
+    uid_t euid;
+    uint32_t perms;
+} users[] = {
+    {AID_SYSTEM,   0,          ~GET},
+    {AID_VPN,      AID_SYSTEM, GET},
+    {AID_WIFI,     AID_SYSTEM, GET},
+    {0,            0,          TEST | GET | INSERT | DELETE | EXIST | SAW},
+};
+
+static int8_t process(int8_t code) {
+    struct user *user = users;
+    struct action *action = actions;
+    int i;
+
+    while (user->uid && user->uid != uid) {
+        ++user;
+    }
+    while (action->code && action->code != code) {
+        ++action;
+    }
+    if (!action->code) {
+        return UNDEFINED_ACTION;
+    }
+    if (!(action->perm & user->perms)) {
+        return PERMISSION_DENIED;
+    }
+    if (action->state && action->state != state) {
+        return state;
+    }
+    if (user->euid) {
+        uid = user->euid;
+    }
+    for (i = 0; i < MAX_PARAM && action->lengths[i]; ++i) {
+        params[i].length = recv_message(params[i].value, action->lengths[i]);
+        if (params[i].length == -1) {
+            return PROTOCOL_ERROR;
+        }
+    }
+    if (!recv_end_of_file()) {
+        return PROTOCOL_ERROR;
+    }
+    return action->run();
+}
+
+#define RANDOM_DEVICE   "/dev/urandom"
+
+int main(int argc, char **argv)
+{
+    int control_socket = android_get_control_socket("keystore");
+    if (argc < 2) {
+        LOGE("A directory must be specified!");
+        return 1;
+    }
+    if (chdir(argv[1]) == -1) {
+        LOGE("chdir: %s: %s", argv[1], strerror(errno));
+        return 1;
+    }
+    if ((the_entropy = open(RANDOM_DEVICE, O_RDONLY)) == -1) {
+        LOGE("open: %s: %s", RANDOM_DEVICE, strerror(errno));
+        return 1;
+    }
+    if (listen(control_socket, 3) == -1) {
+        LOGE("listen: %s", strerror(errno));
+        return 1;
+    }
+
+    signal(SIGPIPE, SIG_IGN);
+    if (access(MASTER_KEY_FILE, R_OK) == 0) {
+        state = LOCKED;
+    }
+
+    while ((the_socket = accept(control_socket, NULL, 0)) != -1) {
+        struct timeval tv = {.tv_sec = 3};
+        struct ucred cred;
+        socklen_t size = sizeof(cred);
+        int8_t request;
+
+        setsockopt(the_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+        setsockopt(the_socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
+
+        if (getsockopt(the_socket, SOL_SOCKET, SO_PEERCRED, &cred, &size)) {
+            LOGW("getsockopt: %s", strerror(errno));
+        } else if (recv_code(&request)) {
+            int8_t old_state = state;
+            int8_t response;
+            uid = cred.uid;
+
+            if ((response = process(request)) > 0) {
+                send_code(response);
+                response = -response;
+            }
+
+            LOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d",
+                 cred.uid, request, -response, old_state, state, retry);
+        }
+        close(the_socket);
+    }
+    LOGE("accept: %s", strerror(errno));
+    return 1;
+}
diff --git a/cmds/keystore/keystore.h b/cmds/keystore/keystore.h
new file mode 100644
index 0000000..5ef51e9
--- /dev/null
+++ b/cmds/keystore/keystore.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2009 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 __KEYSTORE_H__
+#define __KEYSTORE_H__
+
+enum response_code {
+    NO_ERROR          =  1,
+    LOCKED            =  2,
+    UNINITIALIZED     =  3,
+    SYSTEM_ERROR      =  4,
+    PROTOCOL_ERROR    =  5,
+    PERMISSION_DENIED =  6,
+    KEY_NOT_FOUND     =  7,
+    VALUE_CORRUPTED   =  8,
+    UNDEFINED_ACTION  =  9,
+    WRONG_PASSWORD    = 10,
+};
+
+#endif
diff --git a/cmds/keystore/keystore_cli.c b/cmds/keystore/keystore_cli.c
new file mode 100644
index 0000000..e8afb5a
--- /dev/null
+++ b/cmds/keystore/keystore_cli.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <cutils/sockets.h>
+
+#include "keystore.h"
+
+char *responses[256] = {
+    [NO_ERROR]           = "No error",
+    [LOCKED]             = "Locked",
+    [UNINITIALIZED]      = "Uninitialized",
+    [SYSTEM_ERROR]       = "System error",
+    [PROTOCOL_ERROR]     = "Protocol error",
+    [PERMISSION_DENIED]  = "Permission denied",
+    [KEY_NOT_FOUND]      = "Key not found",
+    [VALUE_CORRUPTED]    = "Value corrupted",
+    [UNDEFINED_ACTION]   = "Undefined action",
+    [WRONG_PASSWORD]     = "Wrong password (last chance)",
+    [WRONG_PASSWORD + 1] = "Wrong password (2 tries left)",
+    [WRONG_PASSWORD + 2] = "Wrong password (3 tries left)",
+    [WRONG_PASSWORD + 3] = "Wrong password (4 tries left)",
+};
+
+#define MAX_RESPONSE (WRONG_PASSWORD + 3)
+
+int main(int argc, char **argv)
+{
+    uint8_t bytes[65536];
+    uint8_t code;
+    int sock, i;
+
+    if (argc < 2) {
+        printf("Usage: %s action [parameter ...]\n", argv[0]);
+        return 0;
+    }
+
+    sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
+                               SOCK_STREAM);
+    if (sock == -1) {
+        puts("Failed to connect");
+        return 1;
+    }
+
+    send(sock, argv[1], 1, 0);
+    for (i = 2; i < argc; ++i) {
+        uint16_t length = strlen(argv[i]);
+        bytes[0] = length >> 8;
+        bytes[1] = length;
+        send(sock, &bytes, 2, 0);
+        send(sock, argv[i], length, 0);
+    }
+    shutdown(sock, SHUT_WR);
+
+    if (recv(sock, &code, 1, 0) != 1) {
+        puts("Failed to receive");
+        return 1;
+    }
+    printf("%d %s\n", code , responses[code] ? responses[code] : "Unknown");
+    while ((i = recv(sock, &bytes[0], 1, 0)) == 1) {
+        int length;
+        int offset;
+        if ((i = recv(sock, &bytes[1], 1, 0)) != 1) {
+            puts("Failed to receive");
+            return 1;
+        }
+        length = bytes[0] << 8 | bytes[1];
+        for (offset = 0; offset < length; offset += i) {
+            i = recv(sock, &bytes[offset], length - offset, 0);
+            if (i <= 0) {
+                puts("Failed to receive");
+                return 1;
+            }
+        }
+        fwrite(bytes, 1, length, stdout);
+        puts("");
+    }
+    return 0;
+}
diff --git a/cmds/keystore/keystore_get.h b/cmds/keystore/keystore_get.h
index 7665e81..0e7e1ae 100644
--- a/cmds/keystore/keystore_get.h
+++ b/cmds/keystore/keystore_get.h
@@ -1,53 +1,69 @@
 /*
-**
-** Copyright 2009, 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.
-*/
+ * Copyright (C) 2009 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 __KEYSTORE_GET_H__
 #define __KEYSTORE_GET_H__
 
 #include <stdio.h>
-#include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 
-#include "certtool.h"
+#include <cutils/sockets.h>
 
-/* This function is provided to native components to get values from keystore.
- * Users are required to link against libcutils. If something goes wrong, NULL
- * is returned. Otherwise it returns the value in dynamically allocated memory
- * and sets the size if the pointer is not NULL. One can release the memory by
- * calling free(). */
-static char *keystore_get(const char *key, int *size)
+#define KEYSTORE_MESSAGE_SIZE 65535
+
+/* This function is provided for native components to get values from keystore.
+ * Users are required to link against libcutils. The lengths of keys and values
+ * are limited to KEYSTORE_MESSAGE_SIZE. This function returns the length of
+ * the requested value or -1 if something goes wrong. */
+static int keystore_get(const char *key, char *value)
 {
-    char buffer[MAX_KEY_VALUE_LENGTH];
-    char *value;
-    int length;
+    int length = strlen(key);
+    uint8_t bytes[2] = {length >> 8, length};
+    uint8_t code = 'g';
+    int sock;
 
-    if (get_cert(key, (unsigned char *)buffer, &length) != 0) {
-        return NULL;
+    if (length > KEYSTORE_MESSAGE_SIZE) {
+        return -1;
     }
-    value = malloc(length + 1);
-    if (!value) {
-        return NULL;
+    sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
+                               SOCK_STREAM);
+    if (sock == -1) {
+        return -1;
     }
-    memcpy(value, buffer, length);
-    value[length] = 0;
-    if (size) {
-        *size = length;
+    if (send(sock, &code, 1, 0) == 1 && send(sock, bytes, 2, 0) == 2 &&
+        send(sock, key, length, 0) == length && shutdown(sock, SHUT_WR) == 0 &&
+        recv(sock, &code, 1, 0) == 1 && code == /* NO_ERROR */ 1 &&
+        recv(sock, &bytes[0], 1, 0) == 1 && recv(sock, &bytes[1], 1, 0) == 1) {
+        int offset = 0;
+        length = bytes[0] << 8 | bytes[1];
+        while (offset < length) {
+            int n = recv(sock, &value[offset], length - offset, 0);
+            if (n <= 0) {
+                length = -1;
+                break;
+            }
+            offset += n;
+        }
     }
-    return value;
+    close(sock);
+    return length;
 }
 
 #endif
diff --git a/cmds/keystore/netkeystore.c b/cmds/keystore/netkeystore.c
index 83c7871..87fdc80 100644
--- a/cmds/keystore/netkeystore.c
+++ b/cmds/keystore/netkeystore.c
@@ -116,10 +116,13 @@
 
 static int is_alnum_string(char *s)
 {
+    char *s0 = s;
     while (*s != 0) {
-        if (!isalnum(*s++)) return 0;
+        if (!isalnum(*s++)) {
+            LOGE("The string '%s' is not an alphanumeric string\n", s0);
+            return 0;
+        }
     }
-    LOGE("The string %s is not an alphanumeric string\n", s);
     return 1;
 }
 
@@ -159,7 +162,9 @@
 // no argument
 static void do_get_state(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
 {
-    reply->retcode = get_state();
+    int s = get_state();
+    if (DBG) LOGD("keystore state = %d\n", s);
+    reply->retcode = s;
 }
 
 // args of listkeys():
@@ -413,12 +418,10 @@
 
         // read the command, execute and send the result back.
         if(read_marshal(s, &cmd)) goto err;
-        if (DBG) LOGD("new connection\n");
         execute(&cmd, &reply);
         write_marshal(s, &reply);
 err:
         memset(&reply, 0, sizeof(LPC_MARSHAL));
-        if (DBG) LOGD("closing connection\n");
         close(s);
     }
 
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 73215d3..5397a69 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -61,6 +61,66 @@
 
     decoder->start();
 
+    if (gReproduceBug == 3) {
+        status_t err;
+        MediaBuffer *buffer;
+        MediaSource::ReadOptions options;
+        int64_t seekTimeUs = -1;
+        for (;;) {
+            err = decoder->read(&buffer, &options);
+            options.clearSeekTo();
+
+            bool shouldSeek = false;
+            if (err != OK) {
+                printf("reached EOF.\n");
+
+                shouldSeek = true;
+            } else {
+                int32_t units, scale;
+                CHECK(buffer->meta_data()->findInt32(kKeyTimeUnits, &units));
+                CHECK(buffer->meta_data()->findInt32(kKeyTimeScale, &scale));
+                int64_t timestamp = ((OMX_TICKS)units * 1000000) / scale;
+
+                bool failed = false;
+                if (seekTimeUs >= 0) {
+                    int64_t diff = timestamp - seekTimeUs;
+
+                    if (diff > 500000) {
+                        printf("ERROR: ");
+                        failed = true;
+                    }
+                }
+
+                printf("buffer has timestamp %lld us (%.2f secs)\n",
+                       timestamp, timestamp / 1E6);
+
+                buffer->release();
+                buffer = NULL;
+
+                if (failed) {
+                    break;
+                }
+
+                shouldSeek = ((double)rand() / RAND_MAX) < 0.1;
+                shouldSeek = false;
+            }
+
+            seekTimeUs = -1;
+
+            if (shouldSeek) {
+                seekTimeUs = (rand() * 30E6) / RAND_MAX;
+                options.setSeekTo(seekTimeUs);
+
+                printf("seeking to %lld us (%.2f secs)\n",
+                       seekTimeUs, seekTimeUs / 1E6);
+            }
+        }
+
+        decoder->stop();
+
+        return;
+    }
+
     int n = 0;
     int64_t startTime = getNowUs();
 
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 0bdcc1d..32a2997 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -25,6 +25,7 @@
 import android.content.pm.RegisteredServicesCache;
 import android.content.pm.PackageInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.RegisteredServicesCacheListener;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteDatabase;
@@ -46,7 +47,6 @@
 import android.app.PendingIntent;
 import android.app.NotificationManager;
 import android.app.Notification;
-import android.app.Activity;
 import android.Manifest;
 
 import java.io.FileDescriptor;
@@ -70,7 +70,9 @@
  *      (AccountManager)context.getSystemService(Context.ACCOUNT_SERVICE)
  * @hide
  */
-public class AccountManagerService extends IAccountManager.Stub {
+public class AccountManagerService
+        extends IAccountManager.Stub
+        implements RegisteredServicesCacheListener {
     private static final String TAG = "AccountManagerService";
 
     private static final int TIMEOUT_DELAY_MS = 1000 * 60;
@@ -210,11 +212,41 @@
         mMessageHandler = new MessageHandler(mMessageThread.getLooper());
 
         mAuthenticatorCache = new AccountAuthenticatorCache(mContext);
+        mAuthenticatorCache.setListener(this);
         mBindHelper = new AuthenticatorBindHelper(mContext, mAuthenticatorCache, mMessageHandler,
                 MESSAGE_CONNECTED, MESSAGE_DISCONNECTED);
 
         mSimWatcher = new SimWatcher(mContext);
         sThis.set(this);
+
+        onRegisteredServicesCacheChanged();
+    }
+
+    public void onRegisteredServicesCacheChanged() {
+        boolean accountDeleted = false;
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        Cursor cursor = db.query(TABLE_ACCOUNTS,
+                new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME},
+                null, null, null, null, null);
+        try {
+            while (cursor.moveToNext()) {
+                final long accountId = cursor.getLong(0);
+                final String accountType = cursor.getString(1);
+                final String accountName = cursor.getString(2);
+                if (mAuthenticatorCache.getServiceInfo(AuthenticatorDescription.newKey(accountType))
+                        == null) {
+                    Log.d(TAG, "deleting account " + accountName + " because type "
+                            + accountType + " no longer has a registered authenticator");
+                    db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null);
+                    accountDeleted= true;
+                }
+            }
+        } finally {
+            cursor.close();
+            if (accountDeleted) {
+                sendAccountsChangedBroadcast();
+            }
+        }
     }
 
     public String getPassword(Account account) {
@@ -255,25 +287,18 @@
 
     private String readUserDataFromDatabase(Account account, String key) {
         SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        db.beginTransaction();
+        Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE},
+                EXTRAS_ACCOUNTS_ID
+                        + "=(select _id FROM accounts WHERE name=? AND type=?) AND "
+                        + EXTRAS_KEY + "=?",
+                new String[]{account.name, account.type, key}, null, null, null);
         try {
-            long accountId = getAccountId(db, account);
-            if (accountId < 0) {
-                return null;
+            if (cursor.moveToNext()) {
+                return cursor.getString(0);
             }
-            Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE},
-                    EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
-                    new String[]{key}, null, null, null);
-            try {
-                if (cursor.moveToNext()) {
-                    return cursor.getString(0);
-                }
-                return null;
-            } finally {
-                cursor.close();
-            }
+            return null;
         } finally {
-            db.endTransaction();
+            cursor.close();
         }
     }
 
@@ -471,6 +496,7 @@
     }
 
     private boolean saveAuthTokenToDatabase(Account account, String type, String authToken) {
+        cancelNotification(getSigninRequiredNotificationId(account));
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         db.beginTransaction();
         try {
@@ -497,15 +523,18 @@
 
     public String readAuthTokenFromDatabase(Account account, String authTokenType) {
         SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        db.beginTransaction();
+        Cursor cursor = db.query(TABLE_AUTHTOKENS, new String[]{AUTHTOKENS_AUTHTOKEN},
+                AUTHTOKENS_ACCOUNTS_ID + "=(select _id FROM accounts WHERE name=? AND type=?) AND "
+                        + AUTHTOKENS_TYPE + "=?",
+                new String[]{account.name, account.type, authTokenType},
+                null, null, null);
         try {
-            long accountId = getAccountId(db, account);
-            if (accountId < 0) {
-                return null;
+            if (cursor.moveToNext()) {
+                return cursor.getString(0);
             }
-            return getAuthToken(db, accountId, authTokenType);
+            return null;
         } finally {
-            db.endTransaction();
+            cursor.close();
         }
     }
 
@@ -523,7 +552,7 @@
         checkAuthenticateAccountsPermission(account);
         long identityToken = clearCallingIdentity();
         try {
-            cacheAuthToken(account, authTokenType, authToken);
+            saveAuthTokenToDatabase(account, authTokenType, authToken);
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -533,17 +562,21 @@
         checkAuthenticateAccountsPermission(account);
         long identityToken = clearCallingIdentity();
         try {
-            ContentValues values = new ContentValues();
-            values.put(ACCOUNTS_PASSWORD, password);
-            mOpenHelper.getWritableDatabase().update(TABLE_ACCOUNTS, values,
-                    ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
-                    new String[]{account.name, account.type});
-            sendAccountsChangedBroadcast();
+            setPasswordInDB(account, password);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    private void setPasswordInDB(Account account, String password) {
+        ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_PASSWORD, password);
+        mOpenHelper.getWritableDatabase().update(TABLE_ACCOUNTS, values,
+                ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+                new String[]{account.name, account.type});
+        sendAccountsChangedBroadcast();
+    }
+
     private void sendAccountsChangedBroadcast() {
         mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT);
     }
@@ -552,7 +585,7 @@
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            setPassword(account, null);
+            setPasswordInDB(account, null);
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -686,7 +719,8 @@
                                         "the type and name should not be empty");
                                 return;
                             }
-                            cacheAuthToken(new Account(name, type), authTokenType, authToken);
+                            saveAuthTokenToDatabase(new Account(name, type),
+                                    authTokenType, authToken);
                         }
 
                         Intent intent = result.getParcelable(Constants.INTENT_KEY);
@@ -1004,10 +1038,6 @@
         }
     }
 
-    private boolean cacheAuthToken(Account account, String authTokenType, String authToken) {
-        return saveAuthTokenToDatabase(account, authTokenType, authToken);
-    }
-
     private long getAccountId(SQLiteDatabase db, Account account) {
         Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
                 "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
@@ -1035,21 +1065,6 @@
         }
     }
 
-    private String getAuthToken(SQLiteDatabase db, long accountId, String authTokenType) {
-        Cursor cursor = db.query(TABLE_AUTHTOKENS, new String[]{AUTHTOKENS_AUTHTOKEN},
-                AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
-                new String[]{authTokenType},
-                null, null, null);
-        try {
-            if (cursor.moveToNext()) {
-                return cursor.getString(0);
-            }
-            return null;
-        } finally {
-            cursor.close();
-        }
-    }
-
     private abstract class Session extends IAccountAuthenticatorResponse.Stub
             implements AuthenticatorBindHelper.Callback, IBinder.DeathRecipient {
         IAccountManagerResponse mResponse;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 545db17..a86fe90 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IIntentSender;
+import android.content.IntentSender;
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
@@ -2774,48 +2775,50 @@
 
     /**
      * Like {@link #startActivityForResult(Intent, int)}, but allowing you
-     * to use a PendingIntent to describe the activity to be started.  Note
-     * that the given PendingIntent <em>must</em> have been created with
-     * {@link PendingIntent#getActivity PendingIntent.getActivity}; all other
-     * types will result in an IllegalArgumentException being thrown.
+     * to use a IntentSender to describe the activity to be started.  If
+     * the IntentSender is for an activity, that activity will be started
+     * as if you had called the regular {@link #startActivityForResult(Intent, int)}
+     * here; otherwise, its associated action will be executed (such as
+     * sending a broadcast) as if you had called
+     * {@link IntentSender#sendIntent IntentSender.sendIntent} on it.
      * 
-     * @param intent The PendingIntent to launch.
+     * @param intent The IntentSender to launch.
      * @param requestCode If >= 0, this code will be returned in
      *                    onActivityResult() when the activity exits.
      * @param fillInIntent If non-null, this will be provided as the
-     * intent parameter to {@link PendingIntent#send(Context, int, Intent)
-     * PendingIntent.send(Context, int, Intent)}.
-     * @param flagsMask Intent flags in the original PendingIntent that you
+     * intent parameter to {@link IntentSender#sendIntent}.
+     * @param flagsMask Intent flags in the original IntentSender that you
      * would like to change.
      * @param flagsValues Desired values for any bits set in
      * <var>flagsMask</var>
+     * @param extraFlags Always set to 0.
      */
-    public void startActivityForResult(PendingIntent intent, int requestCode,
-            Intent fillInIntent, int flagsMask, int flagsValues)
-            throws PendingIntent.CanceledException {
+    public void startIntentSenderForResult(IntentSender intent, int requestCode,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            throws IntentSender.SendIntentException {
         if (mParent == null) {
-            startActivityForResultInner(intent, requestCode, fillInIntent,
+            startIntentSenderForResultInner(intent, requestCode, fillInIntent,
                     flagsMask, flagsValues, this);
         } else {
-            mParent.startActivityFromChild(this, intent, requestCode,
-                    fillInIntent, flagsMask, flagsValues);
+            mParent.startIntentSenderFromChild(this, intent, requestCode,
+                    fillInIntent, flagsMask, flagsValues, extraFlags);
         }
     }
 
-    private void startActivityForResultInner(PendingIntent intent, int requestCode,
+    private void startIntentSenderForResultInner(IntentSender intent, int requestCode,
             Intent fillInIntent, int flagsMask, int flagsValues, Activity activity)
-            throws PendingIntent.CanceledException {
+            throws IntentSender.SendIntentException {
         try {
             String resolvedType = null;
             if (fillInIntent != null) {
                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
             }
             int result = ActivityManagerNative.getDefault()
-                .startActivityPendingIntent(mMainThread.getApplicationThread(), intent,
+                .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
                         fillInIntent, resolvedType, mToken, activity.mEmbeddedID,
                         requestCode, flagsMask, flagsValues);
             if (result == IActivityManager.START_CANCELED) {
-                throw new PendingIntent.CanceledException();
+                throw new IntentSender.SendIntentException();
             }
             Instrumentation.checkStartActivityResult(result, null);
         } catch (RemoteException e) {
@@ -2856,24 +2859,25 @@
     }
 
     /**
-     * Like {@link #startActivity(Intent)}, but taking a PendingIntent
+     * Like {@link #startActivity(Intent)}, but taking a IntentSender
      * to start; see
-     * {@link #startActivityForResult(PendingIntent, int, Intent, int, int)}
+     * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int)}
      * for more information.
      * 
-     * @param intent The PendingIntent to launch.
+     * @param intent The IntentSender to launch.
      * @param fillInIntent If non-null, this will be provided as the
-     * intent parameter to {@link PendingIntent#send(Context, int, Intent)
-     * PendingIntent.send(Context, int, Intent)}.
-     * @param flagsMask Intent flags in the original PendingIntent that you
+     * intent parameter to {@link IntentSender#sendIntent}.
+     * @param flagsMask Intent flags in the original IntentSender that you
      * would like to change.
      * @param flagsValues Desired values for any bits set in
      * <var>flagsMask</var>
+     * @param extraFlags Always set to 0.
      */
-    public void startActivity(PendingIntent intent,
-            Intent fillInIntent, int flagsMask, int flagsValues)
-            throws PendingIntent.CanceledException {
-        startActivityForResult(intent, -1, fillInIntent, flagsMask, flagsValues);
+    public void startIntentSender(IntentSender intent,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            throws IntentSender.SendIntentException {
+        startIntentSenderForResult(intent, -1, fillInIntent, flagsMask,
+                flagsValues, extraFlags);
     }
 
     /**
@@ -2998,14 +3002,15 @@
 
     /**
      * Like {@link #startActivityFromChild(Activity, Intent, int)}, but
-     * taking a PendingIntent; see
-     * {@link #startActivityForResult(PendingIntent, int, Intent, int, int)}
+     * taking a IntentSender; see
+     * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int)}
      * for more information.
      */
-    public void startActivityFromChild(Activity child, PendingIntent intent,
-            int requestCode, Intent fillInIntent, int flagsMask, int flagsValues)
-            throws PendingIntent.CanceledException {
-        startActivityForResultInner(intent, requestCode, fillInIntent,
+    public void startIntentSenderFromChild(Activity child, IntentSender intent,
+            int requestCode, Intent fillInIntent, int flagsMask, int flagsValues,
+            int extraFlags)
+            throws IntentSender.SendIntentException {
+        startIntentSenderForResultInner(intent, requestCode, fillInIntent,
                 flagsMask, flagsValues, child);
     }
 
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index e96de07..be89ee6 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -22,6 +22,7 @@
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageDataObserver;
 import android.graphics.Bitmap;
+import android.os.Debug;
 import android.os.RemoteException;
 import android.os.Handler;
 import android.os.Parcel;
@@ -854,6 +855,22 @@
     }
     
     /**
+     * Return information about the memory usage of one or more processes.
+     * 
+     * @param pids The pids of the processes whose memory usage is to be
+     * retrieved.
+     * @return Returns an array of memory information, one for each
+     * requested pid.
+     */
+    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
+        try {
+            return ActivityManagerNative.getDefault().getProcessMemoryInfo(pids);
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+    
+    /**
      * Have the system perform a force stop of everything associated with
      * the given application package.  All processes that share its uid
      * will be killed, all services it has running stopped, all activities
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 4796e49..82d49e3 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -21,6 +21,7 @@
 import android.content.IntentFilter;
 import android.content.IIntentSender;
 import android.content.IIntentReceiver;
+import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageDataObserver;
@@ -145,12 +146,12 @@
             return true;
         }
 
-        case START_ACTIVITY_PENDING_INTENT_TRANSACTION:
+        case START_ACTIVITY_INTENT_SENDER_TRANSACTION:
         {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
-            PendingIntent intent = PendingIntent.CREATOR.createFromParcel(data);
+            IntentSender intent = IntentSender.CREATOR.createFromParcel(data);
             Intent fillInIntent = null;
             if (data.readInt() != 0) {
                 fillInIntent = Intent.CREATOR.createFromParcel(data);
@@ -161,7 +162,7 @@
             int requestCode = data.readInt();
             int flagsMask = data.readInt();
             int flagsValues = data.readInt();
-            int result = startActivityPendingIntent(app, intent,
+            int result = startActivityIntentSender(app, intent,
                     fillInIntent, resolvedType, resultTo, resultWho,
                     requestCode, flagsMask, flagsValues);
             reply.writeNoException();
@@ -1137,11 +1138,10 @@
         
         case GET_PROCESS_MEMORY_INFO_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            int pid = data.readInt();
-            Debug.MemoryInfo mi = new Debug.MemoryInfo();
-            getProcessMemoryInfo(pid, mi);
+            int[] pids = data.createIntArray();
+            Debug.MemoryInfo[] res =  getProcessMemoryInfo(pids);
             reply.writeNoException();
-            mi.writeToParcel(reply, 0);
+            reply.writeTypedArray(res, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
             return true;
         }
 
@@ -1203,8 +1203,8 @@
         data.recycle();
         return result;
     }
-    public int startActivityPendingIntent(IApplicationThread caller,
-            PendingIntent intent, Intent fillInIntent, String resolvedType,
+    public int startActivityIntentSender(IApplicationThread caller,
+            IntentSender intent, Intent fillInIntent, String resolvedType,
             IBinder resultTo, String resultWho, int requestCode,
             int flagsMask, int flagsValues) throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -1224,7 +1224,7 @@
         data.writeInt(requestCode);
         data.writeInt(flagsMask);
         data.writeInt(flagsValues);
-        mRemote.transact(START_ACTIVITY_PENDING_INTENT_TRANSACTION, data, reply, 0);
+        mRemote.transact(START_ACTIVITY_INTENT_SENDER_TRANSACTION, data, reply, 0);
         reply.readException();
         int result = reply.readInt();
         reply.recycle();
@@ -2504,17 +2504,18 @@
         reply.recycle();
     }
     
-    public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo)
+    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(pid);
+        data.writeIntArray(pids);
         mRemote.transact(GET_PROCESS_MEMORY_INFO_TRANSACTION, data, reply, 0);
         reply.readException();
-        outInfo.readFromParcel(reply);
+        Debug.MemoryInfo[] res = reply.createTypedArray(Debug.MemoryInfo.CREATOR);
         data.recycle();
         reply.recycle();
+        return res;
     }
 
     public void killApplicationProcess(String processName, int uid) throws RemoteException {
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 487cfda..afafe64 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -561,6 +561,27 @@
     }
 
     @Override
+    public void startIntentSender(IntentSender intent,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            throws IntentSender.SendIntentException {
+        try {
+            String resolvedType = null;
+            if (fillInIntent != null) {
+                resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
+            }
+            int result = ActivityManagerNative.getDefault()
+                .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
+                        fillInIntent, resolvedType, null, null,
+                        0, flagsMask, flagsValues);
+            if (result == IActivityManager.START_CANCELED) {
+                throw new IntentSender.SendIntentException();
+            }
+            Instrumentation.checkStartActivityResult(result, null);
+        } catch (RemoteException e) {
+        }
+    }
+    
+    @Override
     public void sendBroadcast(Intent intent) {
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
@@ -638,6 +659,38 @@
     }
 
     @Override
+    public void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData,
+            Bundle initialExtras) {
+        IIntentReceiver rd = null;
+        if (resultReceiver != null) {
+            if (mPackageInfo != null) {
+                if (scheduler == null) {
+                    scheduler = mMainThread.getHandler();
+                }
+                rd = mPackageInfo.getReceiverDispatcher(
+                    resultReceiver, getOuterContext(), scheduler,
+                    mMainThread.getInstrumentation(), false);
+            } else {
+                if (scheduler == null) {
+                    scheduler = mMainThread.getHandler();
+                }
+                rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
+                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
+            }
+        }
+        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+        try {
+            ActivityManagerNative.getDefault().broadcastIntent(
+                mMainThread.getApplicationThread(), intent, resolvedType, rd,
+                initialCode, initialData, initialExtras, null,
+                true, true);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
     public void removeStickyBroadcast(Intent intent) {
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         if (resolvedType != null) {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8244645..110b72d 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -23,6 +23,7 @@
 import android.content.IntentFilter;
 import android.content.IIntentSender;
 import android.content.IIntentReceiver;
+import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageDataObserver;
@@ -83,8 +84,8 @@
             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
             int grantedMode, IBinder resultTo, String resultWho, int requestCode,
             boolean onlyIfNeeded, boolean debug) throws RemoteException;
-    public int startActivityPendingIntent(IApplicationThread caller,
-            PendingIntent intent, Intent fillInIntent, String resolvedType,
+    public int startActivityIntentSender(IApplicationThread caller,
+            IntentSender intent, Intent fillInIntent, String resolvedType,
             IBinder resultTo, String resultWho, int requestCode,
             int flagsMask, int flagsValues) throws RemoteException;
     public boolean startNextMatchingActivity(IBinder callingActivity,
@@ -281,7 +282,7 @@
     
     public void closeSystemDialogs(String reason) throws RemoteException;
     
-    public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo)
+    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
             throws RemoteException;
     
     /*
@@ -442,5 +443,5 @@
     int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
     int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
     int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98;
-    int START_ACTIVITY_PENDING_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+99;
+    int START_ACTIVITY_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+99;
 }
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 75a90c4..caf72af 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -191,7 +191,10 @@
         mSearchPlate = findViewById(com.android.internal.R.id.search_plate);
         mWorkingSpinner = getContext().getResources().
                 getDrawable(com.android.internal.R.drawable.search_spinner);
-        
+        mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
+                null, null, mWorkingSpinner, null);
+        setWorking(false);
+
         // attach listeners
         mSearchAutoComplete.addTextChangedListener(mTextWatcher);
         mSearchAutoComplete.setOnKeyListener(mTextKeyListener);
@@ -407,15 +410,9 @@
      * @param working true to show spinner, false to hide spinner
      */
     public void setWorking(boolean working) {
-        if (working) {
-            mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
-                    null, null, mWorkingSpinner, null);
-            ((Animatable) mWorkingSpinner).start();
-        } else {
-            mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
-                    null, null, null, null);
-            ((Animatable) mWorkingSpinner).stop();
-        }
+        mWorkingSpinner.setAlpha(working ? 255 : 0);
+        mWorkingSpinner.setVisible(working, false);
+        mWorkingSpinner.invalidateSelf();
     }
     
     /**
@@ -739,12 +736,8 @@
             return false;
         }
 
-        // handle back key to go back to previous searchable, etc.
-        if (handleBackKey(keyCode, event)) {
-            return true;
-        }
-        
-        if (keyCode == KeyEvent.KEYCODE_SEARCH) {
+        if (keyCode == KeyEvent.KEYCODE_SEARCH && event.getRepeatCount() == 0) {
+            event.startTracking();
             // Consume search key for later use.
             return true;
         }
@@ -756,8 +749,8 @@
             launchQuerySearch(keyCode, actionKey.getQueryActionMsg());
             return true;
         }
-        
-        return false;
+
+        return super.onKeyDown(keyCode, event);
     }
     
     @Override
@@ -767,11 +760,6 @@
             return false;
         }
 
-        // handle back key to go back to previous searchable, etc.
-        if (handleBackKey(keyCode, event)) {
-            return true;
-        }
-        
         if (keyCode == KeyEvent.KEYCODE_SEARCH && event.isTracking()
                 && !event.isCanceled()) {
             // If the search key is pressed, toggle between global and in-app search. If we are
@@ -779,8 +767,8 @@
             // just don't do anything.
             return toggleGlobalSearch();
         }
-        
-        return false;
+
+        return super.onKeyUp(keyCode, event);
     }
     
     /**
@@ -1194,7 +1182,7 @@
             // report back about the click
             if (mGlobalSearchMode) {
                 // in global search mode, do it via cursor
-                mSuggestionsAdapter.callCursorOnClick(c, position);
+                mSuggestionsAdapter.callCursorOnClick(c, position, actionKey, actionMsg);
             } else if (intent != null
                     && mPreviousComponents != null
                     && !mPreviousComponents.isEmpty()) {
@@ -1231,7 +1219,7 @@
         cv.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION, intent.getAction());
         cv.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, intent.getDataString());
         cv.put(SearchManager.SUGGEST_COLUMN_INTENT_COMPONENT_NAME,
-                        intent.getStringExtra(SearchManager.COMPONENT_NAME_KEY));
+                intent.getComponent().flattenToShortString());
 
         // ensure the icons will work for global search
         cv.put(SearchManager.SUGGEST_COLUMN_ICON_1,
@@ -1488,6 +1476,13 @@
     }
 
     /**
+     * Checks if there are any previous searchable components in the history stack.
+     */
+    private boolean hasPreviousComponent() {
+        return mPreviousComponents != null && !mPreviousComponents.isEmpty();
+    }
+
+    /**
      * Saves the previous component that was searched, so that we can go
      * back to it.
      */
@@ -1505,14 +1500,10 @@
      *         no previous component.
      */
     private ComponentName popPreviousComponent() {
-        if (mPreviousComponents == null) {
+        if (!hasPreviousComponent()) {
             return null;
         }
-        int size = mPreviousComponents.size();
-        if (size == 0) {
-            return null;
-        }
-        return mPreviousComponents.remove(size - 1);
+        return mPreviousComponents.remove(mPreviousComponents.size() - 1);
     }
     
     /**
@@ -1520,25 +1511,22 @@
      * 
      * @return <code>true</code> if there was a previous component that we could go back to.
      */
-    private boolean backToPreviousComponent(boolean doIt) {
+    private boolean backToPreviousComponent() {
         ComponentName previous = popPreviousComponent();
         if (previous == null) {
             return false;
         }
-        
-        if (doIt) {
-            if (!show(previous, mAppSearchData, false)) {
-                Log.w(LOG_TAG, "Failed to switch to source " + previous);
-                return false;
-            }
-            
-            // must touch text to trigger suggestions
-            // TODO: should this be the text as it was when the user left
-            // the source that we are now going back to?
-            String query = mSearchAutoComplete.getText().toString();
-            setUserQuery(query);
+
+        if (!show(previous, mAppSearchData, false)) {
+            Log.w(LOG_TAG, "Failed to switch to source " + previous);
+            return false;
         }
-        
+
+        // must touch text to trigger suggestions
+        // TODO: should this be the text as it was when the user left
+        // the source that we are now going back to?
+        String query = mSearchAutoComplete.getText().toString();
+        setUserQuery(query);
         return true;
     }
     
@@ -1763,74 +1751,49 @@
          */
         @Override
         public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+            if (DBG) Log.d(LOG_TAG, "onKeyPreIme(" + keyCode + "," + event + ")");
             if (mSearchDialog.mSearchable == null) {
                 return false;
             }
             if (keyCode == KeyEvent.KEYCODE_BACK) {
                 if (event.getAction() == KeyEvent.ACTION_DOWN
                         && event.getRepeatCount() == 0) {
-                    // We release the back key, might we want to do
-                    // something before the IME?
-                    if (mSearchDialog.backToPreviousComponent(false)) {
+                    if (mSearchDialog.hasPreviousComponent() || isDismissingKeyboardPointless()) {
                         getKeyDispatcherState().startTracking(event, this);
                         return true;
                     }
-                    if (isInputMethodNotNeeded() ||
-                            (isEmpty() && getDropDownChildCount() >= getAdapterCount())) {
-                        getKeyDispatcherState().startTracking(event, this);
-                        return true;
-                    }
-                    return false; // will dismiss soft keyboard if necessary
                 } else if (event.getAction() == KeyEvent.ACTION_UP
                         && event.isTracking() && !event.isCanceled()) {
-                    if (mSearchDialog.backToPreviousComponent(true)) {
+                    if (mSearchDialog.backToPreviousComponent()) {
                         return true;
-                    }
-                    // If the drop-down obscures the keyboard, the user wouldn't see anything
-                    // happening when pressing back, so we dismiss the entire dialog instead.
-                    //
-                    // also: if there is no text entered, we also want to dismiss the whole dialog,
-                    // not just the soft keyboard.  the exception to this is if there are shortcuts
-                    // that aren't displayed (e.g are being obscured by the soft keyboard); in that
-                    // case we want to dismiss the soft keyboard so the user can see the rest of the
-                    // shortcuts.
-                    if (isInputMethodNotNeeded() ||
-                            (isEmpty() && getDropDownChildCount() >= getAdapterCount())) {
+                    } else if (isDismissingKeyboardPointless()) {
                         mSearchDialog.cancel();
                         return true;
                     }
-                    return false; // will dismiss soft keyboard if necessary
                 }
             }
             return false;
         }
 
+        // If the drop-down obscures the keyboard, or if the drop-down shows all suggestions,
+        // dismissing the keyboard is pointless, so we dismiss the entire dialog instead.
+        private boolean isDismissingKeyboardPointless() {
+            return (isInputMethodNotNeeded() || getDropDownChildCount() >= getAdapterCount());
+        }
+
         private int getAdapterCount() {
             final ListAdapter adapter = getAdapter();
             return adapter == null ? 0 : adapter.getCount();
         }
     }
-    
-    protected boolean handleBackKey(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_BACK) {
-            if (event.getAction() == KeyEvent.ACTION_DOWN
-                    && event.getRepeatCount() == 0) {
-                // Consume the event, to get an up at which point we execute.
-                event.startTracking();
-                return true;
-            }
-            if (event.getAction() == KeyEvent.ACTION_UP && event.isTracking()
-                    && !event.isCanceled()) {
-                if (backToPreviousComponent(true)) {
-                    return true;
-                }
-                cancel();
-            }
-            return true;
+
+    @Override
+    public void onBackPressed() {
+        if (!backToPreviousComponent()) {
+            cancel();
         }
-        return false;
     }
-    
+
     /**
      * Implements OnItemClickListener
      */
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 3a14f6f..6a0285d 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1343,6 +1343,10 @@
                 = "DialogCursorProtocol.CLICK.sendPosition";
         public final static String CLICK_SEND_MAX_DISPLAY_POS
                 = "DialogCursorProtocol.CLICK.sendDisplayPosition";
+        public final static String CLICK_SEND_ACTION_KEY
+                = "DialogCursorProtocol.CLICK.sendActionKey";
+        public final static String CLICK_SEND_ACTION_MSG
+                = "DialogCursorProtocol.CLICK.sendActionMsg";
         public final static String CLICK_RECEIVE_SELECTED_POS
                 = "DialogCursorProtocol.CLICK.receiveSelectedPosition";
 
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index 4f9531e..9234a9c 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -26,7 +26,6 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.database.Cursor;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
@@ -37,6 +36,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Filter;
@@ -47,7 +47,6 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.List;
 import java.util.WeakHashMap;
 
 /**
@@ -290,12 +289,16 @@
      * @param cursor The cursor
      * @param position The position that was clicked.
      */
-    void callCursorOnClick(Cursor cursor, int position) {
+    void callCursorOnClick(Cursor cursor, int position, int actionKey, String actionMsg) {
         if (!mGlobalSearchMode) return;
-        final Bundle request = new Bundle(3);
+        final Bundle request = new Bundle(5);
         request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.CLICK);
         request.putInt(DialogCursorProtocol.CLICK_SEND_POSITION, position);
         request.putInt(DialogCursorProtocol.CLICK_SEND_MAX_DISPLAY_POS, mMaxDisplayed);
+        if (actionKey != KeyEvent.KEYCODE_UNKNOWN) {
+            request.putInt(DialogCursorProtocol.CLICK_SEND_ACTION_KEY, actionKey);
+            request.putString(DialogCursorProtocol.CLICK_SEND_ACTION_MSG, actionMsg);
+        }
         final Bundle response = cursor.respond(request);
         mMaxDisplayed = -1;
         mListItemToSelect = response.getInt(
@@ -569,69 +572,91 @@
         if (drawableId == null || drawableId.length() == 0 || "0".equals(drawableId)) {
             return null;
         }
-
-        // First, check the cache.
-        Drawable.ConstantState cached = mOutsideDrawablesCache.get(drawableId);
-        if (cached != null) {
-            if (DBG) Log.d(LOG_TAG, "Found icon in cache: " + drawableId);
-            return cached.newDrawable(mProviderContext.getResources());
-        }
-
-        Drawable drawable = null;
         try {
-            // Not cached, try using it as a plain resource ID in the provider's context.
+            // First, see if it's just an integer
             int resourceId = Integer.parseInt(drawableId);
+            // It's an int, look for it in the cache
+            String drawableUri = ContentResolver.SCHEME_ANDROID_RESOURCE
+                    + "://" + mProviderContext.getPackageName() + "/" + resourceId;
+            // Must use URI as cache key, since ints are app-specific
+            Drawable drawable = checkIconCache(drawableUri);
+            if (drawable != null) {
+                return drawable;
+            }
+            // Not cached, find it by resource ID
             drawable = mProviderContext.getResources().getDrawable(resourceId);
+            // Stick it in the cache, using the URI as key
+            storeInIconCache(drawableUri, drawable);
+            return drawable;
         } catch (NumberFormatException nfe) {
-            // The id was not an integer resource id, use it as a URI
-            try {
-                Uri uri = Uri.parse(drawableId);
-                String scheme = uri.getScheme();
-                if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
-                    // Load drawables through Resources, to get the source density information
-                    OpenResourceIdResult r =
-                            mProviderContext.getContentResolver().getResourceId(uri);
+            // It's not an integer, use it as a URI
+            Drawable drawable = checkIconCache(drawableId);
+            if (drawable != null) {
+                return drawable;
+            }
+            Uri uri = Uri.parse(drawableId);
+            drawable = getDrawable(uri);
+            storeInIconCache(drawableId, drawable);
+            return drawable;
+        } catch (Resources.NotFoundException nfe) {
+            // It was an integer, but it couldn't be found, bail out
+            Log.w(LOG_TAG, "Icon resource not found: " + drawableId);
+            return null;
+        }
+    }
+
+    /**
+     * Gets a drawable by URI, without using the cache.
+     *
+     * @return A drawable, or {@code null} if the drawable could not be loaded.
+     */
+    private Drawable getDrawable(Uri uri) {
+        try {
+            String scheme = uri.getScheme();
+            if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
+                // Load drawables through Resources, to get the source density information
+                OpenResourceIdResult r =
+                    mProviderContext.getContentResolver().getResourceId(uri);
+                try {
+                    return r.r.getDrawable(r.id);
+                } catch (Resources.NotFoundException ex) {
+                    throw new FileNotFoundException("Resource does not exist: " + uri);
+                }
+            } else {
+                // Let the ContentResolver handle content and file URIs.
+                InputStream stream = mProviderContext.getContentResolver().openInputStream(uri);
+                if (stream == null) {
+                    throw new FileNotFoundException("Failed to open " + uri);
+                }
+                try {
+                    return Drawable.createFromStream(stream, null);
+                } finally {
                     try {
-                        drawable = r.r.getDrawable(r.id);
-                    } catch (Resources.NotFoundException ex) {
-                        throw new FileNotFoundException("Resource does not exist: " + uri);
-                    }
-                } else {
-                    // Let the ContentResolver handle content and file URIs.
-                    InputStream stream = mProviderContext.getContentResolver().openInputStream(uri);
-                    if (stream == null) {
-                        throw new FileNotFoundException("Failed to open " + uri);
-                    }
-                    try {
-                        drawable = Drawable.createFromStream(stream, null);
-                    } finally {
-                        try {
-                            stream.close();
-                        } catch (IOException ex) {
-                            Log.e(LOG_TAG, "Error closing icon stream for " + uri, ex);
-                        }
+                        stream.close();
+                    } catch (IOException ex) {
+                        Log.e(LOG_TAG, "Error closing icon stream for " + uri, ex);
                     }
                 }
-            } catch (FileNotFoundException fnfe) {
-                Log.w(LOG_TAG, "Icon not found: " + drawableId + ", " + fnfe.getMessage());
-                // drawable = null;
             }
-        } catch (Resources.NotFoundException nfe) {
-            Log.w(LOG_TAG, "Icon resource not found: " + drawableId);
-            // drawable = null;
+        } catch (FileNotFoundException fnfe) {
+            Log.w(LOG_TAG, "Icon not found: " + uri + ", " + fnfe.getMessage());
+            return null;
         }
+    }
 
-        if (drawable == null) {
-            if (DBG) Log.d(LOG_TAG, "Didn't find icon: " + drawableId);
-        } else {
-            if (DBG) {
-                Log.d(LOG_TAG, "Found icon: " + drawableId);
-            }
-            // Cache it so we don't do this lookup again
-            mOutsideDrawablesCache.put(drawableId, drawable.getConstantState());
+    private Drawable checkIconCache(String resourceUri) {
+        Drawable.ConstantState cached = mOutsideDrawablesCache.get(resourceUri);
+        if (cached == null) {
+            return null;
         }
+        if (DBG) Log.d(LOG_TAG, "Found icon in cache: " + resourceUri);
+        return cached.newDrawable();
+    }
 
-        return drawable;
+    private void storeInIconCache(String resourceUri, Drawable drawable) {
+        if (drawable != null) {
+            mOutsideDrawablesCache.put(resourceUri, drawable.getConstantState());
+        }
     }
 
     /**
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 96a927b..1fc22fe 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -573,6 +573,7 @@
 
     /**
      * Validate a Bluetooth address, such as "00:43:A8:23:10:F0"
+     * <p>Alphabetic characters must be uppercase to be valid.
      *
      * @param address Bluetooth address as string
      * @return true if the address is valid, false otherwise
@@ -586,8 +587,9 @@
             switch (i % 3) {
             case 0:
             case 1:
-                if (Character.digit(c, 16) != -1) {
-                    break;  // hex character, OK
+                if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
+                    // hex character, OK
+                    break;
                 }
                 return false;
             case 2:
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 1fbbf78..6210380 100644
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -72,12 +72,10 @@
         return Integer.toHexString(mClass);
     }
 
-    /** @hide */
     public int describeContents() {
         return 0;
     }
 
-    /** @hide */
     public static final Parcelable.Creator<BluetoothClass> CREATOR =
             new Parcelable.Creator<BluetoothClass>() {
         public BluetoothClass createFromParcel(Parcel in) {
@@ -88,7 +86,6 @@
         }
     };
 
-    /** @hide */
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mClass);
     }
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 0b3f3c7..b52a822 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -28,6 +28,7 @@
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
+import java.util.UUID;
 
 /**
  * Represents a remote Bluetooth device.
@@ -226,6 +227,20 @@
     public static final String EXTRA_PASSKEY = "android.bluetooth.device.extra.PASSKEY";
 
     /**
+     * Broadcast Action: This intent is used to broadcast the {@link UUID}
+     * wrapped as a {@link ParcelUuid} of the remote device after it has been
+     * fetched. This intent is sent only when the UUIDs of the remote device
+     * are requested to be fetched using Service Discovery Protocol
+     * <p> Always contains the extra field {@link #EXTRA_DEVICE}
+     * <p> Always contains the extra filed {@link #EXTRA_UUID}
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_UUID =
+            "android.bleutooth.device.action.UUID";
+
+    /**
      * Broadcast Action: Indicates a failure to retrieve the name of a remote
      * device.
      * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
@@ -292,6 +307,15 @@
      * @hide */
     public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
 
+    /**
+     * Used as an extra field in {@link #ACTION_UUID} intents,
+     * Contains the {@link ParcelUuid}s of the remote device which is a parcelable
+     * version of {@link UUID}.
+     * @hide
+     */
+    public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
+
+
     private static IBluetooth sService;  /* Guarenteed constant after first object constructed */
 
     private final String mAddress;
@@ -349,12 +373,10 @@
         return mAddress;
     }
 
-    /** @hide */
     public int describeContents() {
         return 0;
     }
 
-    /** @hide */
     public static final Parcelable.Creator<BluetoothDevice> CREATOR =
             new Parcelable.Creator<BluetoothDevice>() {
         public BluetoothDevice createFromParcel(Parcel in) {
@@ -365,7 +387,6 @@
         }
     };
 
-    /** @hide */
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(mAddress);
     }
@@ -510,6 +531,27 @@
         return null;
     }
 
+     /**
+      *  Perform a SDP query on the remote device to get the UUIDs
+      *  supported. This API is asynchronous and an Intent is sent,
+      *  with the UUIDs supported by the remote end. If there is an error
+      *  in getting the SDP records or if the process takes a long time,
+      *  an Intent is sent with the UUIDs that is currently present in the
+      *  cache. Clients should use the {@link getUuids} to get UUIDs
+      *  is SDP is not to be performed.
+      *
+      *  @return False if the sanity check fails, True if the process
+      *               of initiating an ACL connection to the remote device
+      *               was started.
+      *  @hide
+      */
+     public boolean fetchUuidsWithSdp() {
+        try {
+            return sService.fetchRemoteUuidsWithSdp(mAddress);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return false;
+    }
+
     /** @hide */
     public int getServiceChannel(ParcelUuid uuid) {
          try {
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 04c8ec9..203a61d 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -53,6 +53,7 @@
     String getRemoteName(in String address);
     int getRemoteClass(in String address);
     ParcelUuid[] getRemoteUuids(in String address);
+    boolean fetchRemoteUuidsWithSdp(in String address);
     int getRemoteServiceChannel(in String address,in ParcelUuid uuid);
 
     boolean setPin(in String address, in byte[] pin);
diff --git a/core/java/android/bluetooth/ScoSocket.java b/core/java/android/bluetooth/ScoSocket.java
index 1bf786f..116310a 100644
--- a/core/java/android/bluetooth/ScoSocket.java
+++ b/core/java/android/bluetooth/ScoSocket.java
@@ -87,7 +87,7 @@
      *  Does not block.
      */
     public synchronized boolean connect(String address) {
-        if (VDBG) log("connect() " + this);
+        if (DBG) log("connect() " + this);
         if (mState != STATE_READY) {
             if (DBG) log("connect(): Bad state");
             return false;
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index 238792b..60b406d 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -221,26 +221,30 @@
         } else if (mType == TYPE_UPDATE) {
             numRows = provider.update(mUri, values, mSelection, selectionArgs);
         } else if (mType == TYPE_ASSERT) {
-            // Build projection map from expected values
-            final ArrayList<String> projectionList = new ArrayList<String>();
-            for (Map.Entry<String, Object> entry : values.valueSet()) {
-                projectionList.add(entry.getKey());
-            }
-
             // Assert that all rows match expected values
-            final String[] projection = projectionList.toArray(new String[projectionList.size()]);
+            String[] projection =  null;
+            if (values != null) {
+                // Build projection map from expected values
+                final ArrayList<String> projectionList = new ArrayList<String>();
+                for (Map.Entry<String, Object> entry : values.valueSet()) {
+                    projectionList.add(entry.getKey());
+                }
+                projection = projectionList.toArray(new String[projectionList.size()]);
+            }
             final Cursor cursor = provider.query(mUri, projection, mSelection, selectionArgs, null);
-            numRows = cursor.getCount();
             try {
-                while (cursor.moveToNext()) {
-                    for (int i = 0; i < projection.length; i++) {
-                        final String cursorValue = cursor.getString(i);
-                        final String expectedValue = values.getAsString(projection[i]);
-                        if (!TextUtils.equals(cursorValue, expectedValue)) {
-                            // Throw exception when expected values don't match
-                            throw new OperationApplicationException("Found value " + cursorValue
-                                    + " when expected " + expectedValue + " for column "
-                                    + projection[i]);
+                numRows = cursor.getCount();
+                if (projection != null) {
+                    while (cursor.moveToNext()) {
+                        for (int i = 0; i < projection.length; i++) {
+                            final String cursorValue = cursor.getString(i);
+                            final String expectedValue = values.getAsString(projection[i]);
+                            if (!TextUtils.equals(cursorValue, expectedValue)) {
+                                // Throw exception when expected values don't match
+                                throw new OperationApplicationException("Found value " + cursorValue
+                                        + " when expected " + expectedValue + " for column "
+                                        + projection[i]);
+                            }
                         }
                     }
                 }
@@ -395,12 +399,19 @@
 
         /** Create a ContentProviderOperation from this {@link Builder}. */
         public ContentProviderOperation build() {
-            if (mType == TYPE_UPDATE || mType == TYPE_ASSERT) {
+            if (mType == TYPE_UPDATE) {
                 if ((mValues == null || mValues.size() == 0)
                         && (mValuesBackReferences == null || mValuesBackReferences.size() == 0)) {
                     throw new IllegalArgumentException("Empty values");
                 }
             }
+            if (mType == TYPE_ASSERT) {
+                if ((mValues == null || mValues.size() == 0)
+                        && (mValuesBackReferences == null || mValuesBackReferences.size() == 0)
+                        && (mExpectedCount == null)) {
+                    throw new IllegalArgumentException("Empty values");
+                }
+            }
             return new ContentProviderOperation(this);
         }
 
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 60551b8..fe4665e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -559,6 +559,27 @@
     public abstract void startActivity(Intent intent);
 
     /**
+     * Like {@link #startActivity(Intent)}, but taking a IntentSender
+     * to start.  If the IntentSender is for an activity, that activity will be started
+     * as if you had called the regular {@link #startActivity(Intent)}
+     * here; otherwise, its associated action will be executed (such as
+     * sending a broadcast) as if you had called
+     * {@link IntentSender#sendIntent IntentSender.sendIntent} on it.
+     * 
+     * @param intent The IntentSender to launch.
+     * @param fillInIntent If non-null, this will be provided as the
+     * intent parameter to {@link IntentSender#sendIntent}.
+     * @param flagsMask Intent flags in the original IntentSender that you
+     * would like to change.
+     * @param flagsValues Desired values for any bits set in
+     * <var>flagsMask</var>
+     * @param extraFlags Always set to 0.
+     */
+    public abstract void startIntentSender(IntentSender intent,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            throws IntentSender.SendIntentException;
+
+    /**
      * Broadcast the given intent to all interested BroadcastReceivers.  This
      * call is asynchronous; it returns immediately, and you will continue
      * executing while the receivers are run.  No results are propagated from
@@ -636,8 +657,7 @@
      * supplying your own BroadcastReceiver when calling, which will be
      * treated as a final receiver at the end of the broadcast -- its
      * {@link BroadcastReceiver#onReceive} method will be called with
-     * the result values collected from the other receivers.  If you use
-     * an <var>resultReceiver</var> with this method, then the broadcast will
+     * the result values collected from the other receivers.  The broadcast will
      * be serialized in the same way as calling
      * {@link #sendOrderedBroadcast(Intent, String)}.
      *
@@ -668,6 +688,7 @@
      * @see #sendBroadcast(Intent, String)
      * @see #sendOrderedBroadcast(Intent, String)
      * @see #sendStickyBroadcast(Intent)
+     * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
      * @see android.content.BroadcastReceiver
      * @see #registerReceiver
      * @see android.app.Activity#RESULT_OK
@@ -694,8 +715,55 @@
      * be re-broadcast to future receivers.
      *
      * @see #sendBroadcast(Intent)
+     * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
      */
     public abstract void sendStickyBroadcast(Intent intent);
+    
+    /**
+     * Version of {@link #sendStickyBroadcast} that allows you to
+     * receive data back from the broadcast.  This is accomplished by
+     * supplying your own BroadcastReceiver when calling, which will be
+     * treated as a final receiver at the end of the broadcast -- its
+     * {@link BroadcastReceiver#onReceive} method will be called with
+     * the result values collected from the other receivers.  The broadcast will
+     * be serialized in the same way as calling
+     * {@link #sendOrderedBroadcast(Intent, String)}.
+     *
+     * <p>Like {@link #sendBroadcast(Intent)}, this method is
+     * asynchronous; it will return before
+     * resultReceiver.onReceive() is called.  Note that the sticky data
+     * stored is only the data you initially supply to the broadcast, not
+     * the result of any changes made by the receivers.
+     *
+     * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
+     *
+     * @param intent The Intent to broadcast; all receivers matching this
+     *               Intent will receive the broadcast.
+     * @param resultReceiver Your own BroadcastReceiver to treat as the final
+     *                       receiver of the broadcast.
+     * @param scheduler A custom Handler with which to schedule the
+     *                  resultReceiver callback; if null it will be
+     *                  scheduled in the Context's main thread.
+     * @param initialCode An initial value for the result code.  Often
+     *                    Activity.RESULT_OK.
+     * @param initialData An initial value for the result data.  Often
+     *                    null.
+     * @param initialExtras An initial value for the result extras.  Often
+     *                      null.
+     *
+     * @see #sendBroadcast(Intent)
+     * @see #sendBroadcast(Intent, String)
+     * @see #sendOrderedBroadcast(Intent, String)
+     * @see #sendStickyBroadcast(Intent)
+     * @see android.content.BroadcastReceiver
+     * @see #registerReceiver
+     * @see android.app.Activity#RESULT_OK
+     */
+    public abstract void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData,
+            Bundle initialExtras);
+
 
     /**
      * Remove the data previously sent with {@link #sendStickyBroadcast},
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 15612ce..1b34320c 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -249,6 +249,14 @@
     }
 
     @Override
+    public void startIntentSender(IntentSender intent,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            throws IntentSender.SendIntentException {
+        mBase.startIntentSender(intent, fillInIntent, flagsMask,
+                flagsValues, extraFlags);
+    }
+    
+    @Override
     public void sendBroadcast(Intent intent) {
         mBase.sendBroadcast(intent);
     }
@@ -280,6 +288,16 @@
     }
 
     @Override
+    public void sendStickyOrderedBroadcast(
+        Intent intent, BroadcastReceiver resultReceiver,
+        Handler scheduler, int initialCode, String initialData,
+        Bundle initialExtras) {
+        mBase.sendStickyOrderedBroadcast(intent,
+                resultReceiver, scheduler, initialCode,
+                initialData, initialExtras);
+    }
+
+    @Override
     public void removeStickyBroadcast(Intent intent) {
         mBase.removeStickyBroadcast(intent);
     }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index fc977c8..7366b8b 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1352,14 +1352,20 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED";
     /**
-     * Broadcast Action:  The charging state, or charge level of the battery has
-     * changed.
+     * Broadcast Action:  This is a <em>sticky broadcast</em> containing the
+     * charging state, level, and other information about the battery.
+     * See {@link android.os.BatteryManager} for documentation on the
+     * contents of the Intent.
      *
      * <p class="note">
      * You can <em>not</em> receive this through components declared
      * in manifests, only by explicitly registering for it with
      * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
-     * Context.registerReceiver()}.
+     * Context.registerReceiver()}.  See {@link #ACTION_BATTERY_LOW},
+     * {@link #ACTION_BATTERY_OKAY}, {@link #ACTION_POWER_CONNECTED},
+     * and {@link #ACTION_POWER_DISCONNECTED} for distinct battery-related
+     * broadcasts that are sent and can be received through manifest
+     * receivers.
      * 
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
@@ -1434,7 +1440,8 @@
      */
     public static final String ACTION_REQUEST_SHUTDOWN = "android.intent.action.ACTION_REQUEST_SHUTDOWN";
     /**
-     * Broadcast Action:  Indicates low memory condition on the device
+     * Broadcast Action:  A sticky broadcast that indicates low memory
+     * condition on the device
      * 
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
@@ -1711,6 +1718,18 @@
             "android.intent.action.REBOOT";
 
     /**
+     * Broadcast Action:  A sticky broadcast indicating the phone was docked
+     * or undocked.  Includes the extra
+     * field {@link #EXTRA_DOCK_STATE}, containing the current dock state.
+     * This is intended for monitoring the current dock state.
+     * To launch an activity from a dock state change, use {@link #CATEGORY_CAR_DOCK}
+     * or {@link #CATEGORY_DESK_DOCK} instead.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DOCK_EVENT =
+            "android.intent.action.DOCK_EVENT";
+
+    /**
      * Broadcast Action: a remote intent is to be broadcasted.
      *
      * A remote intent is used for remote RPC between devices. The remote intent
@@ -1720,6 +1739,7 @@
      * does not trust intent broadcasts from arbitrary intent senders, it should require
      * the sender to hold certain permissions so only trusted sender's broadcast will be
      * let through.
+     * @hide
      */
     public static final String ACTION_REMOTE_INTENT =
             "android.intent.action.REMOTE_INTENT";
@@ -1878,16 +1898,6 @@
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
     public static final String CATEGORY_DESK_DOCK = "android.intent.category.DESK_DOCK";
 
-    /**
-     * Broadcast Action:  The phone was docked or undocked.  Includes the extra
-     * field {@link #EXTRA_DOCK_STATE}, containing the current dock state.
-     * This is intended for monitoring the current dock state.
-     * To launch an activity from a dock state change, use {@link #CATEGORY_CAR_DOCK}
-     * or {@link #CATEGORY_DESK_DOCK} instead.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_DOCK_EVENT = "android.intent.action.DOCK_EVENT";
-
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard extra data keys.
@@ -2334,6 +2344,13 @@
      */
     public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x10000000;
 
+    /**
+     * @hide Flags that can't be changed with PendingIntent.
+     */
+    public static final int IMMUTABLE_FLAGS =
+            FLAG_GRANT_READ_URI_PERMISSION
+            | FLAG_GRANT_WRITE_URI_PERMISSION;
+    
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // toUri() and parseUri() options.
@@ -2514,6 +2531,7 @@
      *
      * @param uri The URI to turn into an Intent.
      * @param flags Additional processing flags.  Either 0 or
+     * {@link #URI_INTENT_SCHEME}.
      *
      * @return Intent The newly created Intent object.
      *
@@ -2647,24 +2665,24 @@
 
         int i = uri.lastIndexOf('#');
         if (i >= 0) {
-            Uri data = null;
             String action = null;
-            if (i > 0) {
-                data = Uri.parse(uri.substring(0, i));
-            }
+            final int intentFragmentStart = i;
+            boolean isIntentFragment = false;
 
             i++;
 
             if (uri.regionMatches(i, "action(", 0, 7)) {
+                isIntentFragment = true;
                 i += 7;
                 int j = uri.indexOf(')', i);
                 action = uri.substring(i, j);
                 i = j + 1;
             }
 
-            intent = new Intent(action, data);
+            intent = new Intent(action);
 
             if (uri.regionMatches(i, "categories(", 0, 11)) {
+                isIntentFragment = true;
                 i += 11;
                 int j = uri.indexOf(')', i);
                 while (i < j) {
@@ -2679,6 +2697,7 @@
             }
 
             if (uri.regionMatches(i, "type(", 0, 5)) {
+                isIntentFragment = true;
                 i += 5;
                 int j = uri.indexOf(')', i);
                 intent.mType = uri.substring(i, j);
@@ -2686,6 +2705,7 @@
             }
 
             if (uri.regionMatches(i, "launchFlags(", 0, 12)) {
+                isIntentFragment = true;
                 i += 12;
                 int j = uri.indexOf(')', i);
                 intent.mFlags = Integer.decode(uri.substring(i, j)).intValue();
@@ -2693,6 +2713,7 @@
             }
 
             if (uri.regionMatches(i, "component(", 0, 10)) {
+                isIntentFragment = true;
                 i += 10;
                 int j = uri.indexOf(')', i);
                 int sep = uri.indexOf('!', i);
@@ -2705,6 +2726,7 @@
             }
 
             if (uri.regionMatches(i, "extras(", 0, 7)) {
+                isIntentFragment = true;
                 i += 7;
 
                 final int closeParen = uri.indexOf(')', i);
@@ -2776,6 +2798,12 @@
                 }
             }
 
+            if (isIntentFragment) {
+                intent.mData = Uri.parse(uri.substring(0, intentFragmentStart));
+            } else {
+                intent.mData = Uri.parse(uri);
+            }
+            
             if (intent.mAction == null) {
                 // By default, if no action is specified, then use VIEW.
                 intent.mAction = ACTION_VIEW;
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 0e4d984..c8f7aa9 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -249,6 +249,11 @@
     }
 
     /** @hide */
+    public IIntentSender getTarget() {
+        return mTarget;
+    }
+
+    /** @hide */
     public IntentSender(IIntentSender target) {
         mTarget = target;
     }
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 7859d5a..80613d8 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -514,7 +514,7 @@
     public SyncStorageEngine getSyncStorageEngine() {
         return mSyncStorageEngine;
     }
-    
+
     private void ensureAlarmService() {
         if (mAlarmService == null) {
             mAlarmService = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
@@ -1125,7 +1125,7 @@
         tobj.set(time);
         return tobj.format("%Y-%m-%d %H:%M:%S");
     }
-    
+
     protected void dumpSyncState(PrintWriter pw, StringBuilder sb) {
         pw.print("sync enabled: "); pw.println(isSyncEnabled());
         pw.print("data connected: "); pw.println(mDataConnectionIsConnected);
@@ -1219,13 +1219,13 @@
                         = mSyncStorageEngine.getAuthority(status.authorityId);
                 if (authority != null) {
                     Account curAccount = authority.account;
-                    
+
                     if (processedAccounts.contains(curAccount)) {
                         continue;
                     }
-                    
+
                     processedAccounts.add(curAccount);
-                    
+
                     pw.print("  Account "); pw.print(authority.account.name);
                             pw.print(" "); pw.print(authority.account.type);
                             pw.println(":");
@@ -1271,7 +1271,7 @@
         pw.print(time/1000); pw.print('.'); pw.print((time/100)%10);
         pw.print('s');
     }
-    
+
     private void dumpDayStatistic(PrintWriter pw, SyncStorageEngine.DayStats ds) {
         pw.print("Success ("); pw.print(ds.successCount);
         if (ds.successCount > 0) {
@@ -1285,7 +1285,7 @@
         }
         pw.println(")");
     }
-    
+
     protected void dumpSyncHistory(PrintWriter pw, StringBuilder sb) {
         SyncStorageEngine.DayStats dses[] = mSyncStorageEngine.getDayStatistics();
         if (dses != null && dses[0] != null) {
@@ -1295,18 +1295,18 @@
             int today = dses[0].day;
             int i;
             SyncStorageEngine.DayStats ds;
-            
+
             // Print each day in the current week.
             for (i=1; i<=6 && i < dses.length; i++) {
                 ds = dses[i];
                 if (ds == null) break;
                 int delta = today-ds.day;
                 if (delta > 6) break;
-                
+
                 pw.print("  Day-"); pw.print(delta); pw.print(":  ");
                 dumpDayStatistic(pw, ds);
             }
-            
+
             // Aggregate all following days into weeks and print totals.
             int weekDay = today;
             while (i < dses.length) {
@@ -1321,7 +1321,7 @@
                     int delta = weekDay-ds.day;
                     if (delta > 6) break;
                     i++;
-                    
+
                     if (aggr == null) {
                         aggr = new SyncStorageEngine.DayStats(weekDay);
                     }
@@ -1336,7 +1336,7 @@
                 }
             }
         }
-        
+
         ArrayList<SyncStorageEngine.SyncHistoryItem> items
                 = mSyncStorageEngine.getSyncHistory();
         if (items != null && items.size() > 0) {
@@ -2132,7 +2132,8 @@
             final long now = System.currentTimeMillis();
 
             EventLog.writeEvent(2720, syncOperation.authority,
-                    SyncStorageEngine.EVENT_START, source);
+                                SyncStorageEngine.EVENT_START, source,
+                                syncOperation.account.name.hashCode());
 
             return mSyncStorageEngine.insertStartSyncEvent(
                     syncOperation.account, syncOperation.authority, now, source);
@@ -2141,7 +2142,8 @@
         public void stopSyncEvent(long rowId, SyncOperation syncOperation, String resultMessage,
                 int upstreamActivity, int downstreamActivity, long elapsedTime) {
             EventLog.writeEvent(2720, syncOperation.authority,
-                    SyncStorageEngine.EVENT_STOP, syncOperation.syncSource);
+                                SyncStorageEngine.EVENT_STOP, syncOperation.syncSource,
+                                syncOperation.account.name.hashCode());
 
             mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime, resultMessage,
                     downstreamActivity, upstreamActivity);
@@ -2173,7 +2175,7 @@
                 syncOperation.pendingOperation = op;
                 add(syncOperation, op);
             }
-            
+
             if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
         }
 
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index f251984..6e312d2 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -346,16 +346,6 @@
                 }
             }
         }
-        // Inform the backup manager about a data change
-        IBackupManager ibm = IBackupManager.Stub.asInterface(
-                ServiceManager.getService(Context.BACKUP_SERVICE));
-        if (ibm != null) {
-            try {
-                ibm.dataChanged("com.android.providers.settings");
-            } catch (RemoteException e) {
-                // Try again later
-            }
-        }
     }
 
     public boolean getSyncAutomatically(Account account, String providerName) {
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index f5f8f30..538373f 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -53,6 +53,16 @@
     private final String mMetaDataName;
     private final String mAttributesName;
 
+    public RegisteredServicesCacheListener getListener() {
+        return mListener;
+    }
+
+    public void setListener(RegisteredServicesCacheListener listener) {
+        mListener = listener;
+    }
+
+    private volatile RegisteredServicesCacheListener mListener;
+
     // no need to be synchronized since the map is never changed once mService is written
     volatile Map<V, ServiceInfo<V>> mServices;
 
@@ -84,6 +94,10 @@
                         @Override
                         public void onReceive(Context context, Intent intent) {
                             mServices = generateServicesMap();
+                            RegisteredServicesCacheListener listener = mListener;
+                            if (listener != null) {
+                                listener.onRegisteredServicesCacheChanged();
+                            }
                         }
                     };
                 }
diff --git a/core/java/android/content/pm/RegisteredServicesCacheListener.java b/core/java/android/content/pm/RegisteredServicesCacheListener.java
new file mode 100644
index 0000000..8cf15e4
--- /dev/null
+++ b/core/java/android/content/pm/RegisteredServicesCacheListener.java
@@ -0,0 +1,11 @@
+package android.content.pm;
+
+/**
+ * Listener for changes to the set of registered services managed by a RegisteredServicesCache.
+ */
+public interface RegisteredServicesCacheListener {
+    /**
+     * Invoked when the registered services cache changes.
+     */
+    void onRegisteredServicesCacheChanged();
+}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 13effe0..cc44400 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -137,7 +137,6 @@
      *
      * @throws IOException if the method fails.
      *
-     * FIXME: Unhide after approval
      * @hide
      */
     public native final void reconnect() throws IOException;
@@ -150,25 +149,20 @@
      * Camera object is locked. Locking it again from the same process will
      * have no effect. Attempting to lock it from another process if it has
      * not been unlocked will fail.
-     * Returns 0 if lock was successful.
      *
-     * FIXME: Unhide after approval
-     * @hide
+     * @throws RuntimeException if the method fails.
      */
-    public native final int lock();
+    public native final void lock();
 
     /**
      * Unlock the camera to allow another process to access it. To save
      * setup/teardown time, a client of Camera can pass an initialized Camera
      * object to another process. This method is used to unlock the Camera
      * object before handing off the Camera object to the other process.
-
-     * Returns 0 if unlock was successful.
      *
-     * FIXME: Unhide after approval
-     * @hide
+     * @throws RuntimeException if the method fails.
      */
-    public native final int unlock();
+    public native final void unlock();
 
     /**
      * Sets the SurfaceHolder to be used for a picture preview. If the surface
@@ -673,6 +667,7 @@
         // Formats for setPreviewFormat and setPictureFormat.
         private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
         private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
+        private static final String PIXEL_FORMAT_YUV422I = "yuv422i-yuyv";
         private static final String PIXEL_FORMAT_RGB565 = "rgb565";
         private static final String PIXEL_FORMAT_JPEG = "jpeg";
 
@@ -957,7 +952,13 @@
          */
         public List<Integer> getSupportedPreviewFormats() {
             String str = get(KEY_PREVIEW_FORMAT + SUPPORTED_VALUES_SUFFIX);
-            return splitInt(str);
+            ArrayList<Integer> formats = new ArrayList<Integer>();
+            for (String s : split(str)) {
+                int f = pixelFormatForCameraFormat(s);
+                if (f == PixelFormat.UNKNOWN) continue;
+                formats.add(f);
+            }
+            return formats;
         }
 
         /**
@@ -1036,6 +1037,7 @@
             switch(pixel_format) {
             case PixelFormat.YCbCr_422_SP: return PIXEL_FORMAT_YUV422SP;
             case PixelFormat.YCbCr_420_SP: return PIXEL_FORMAT_YUV420SP;
+            case PixelFormat.YCbCr_422_I:  return PIXEL_FORMAT_YUV422I;
             case PixelFormat.RGB_565:      return PIXEL_FORMAT_RGB565;
             case PixelFormat.JPEG:         return PIXEL_FORMAT_JPEG;
             default:                       return null;
@@ -1052,6 +1054,9 @@
             if (format.equals(PIXEL_FORMAT_YUV420SP))
                 return PixelFormat.YCbCr_420_SP;
 
+            if (format.equals(PIXEL_FORMAT_YUV422I))
+                return PixelFormat.YCbCr_422_I;
+
             if (format.equals(PIXEL_FORMAT_RGB565))
                 return PixelFormat.RGB_565;
 
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index a141a2a..e59a987 100755
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -408,6 +408,8 @@
         if (mKeyboard != null) {
             showPreview(NOT_A_KEY);
         }
+        // Remove any pending messages
+        removeMessages();
         mKeyboard = keyboard;
         List<Key> keys = mKeyboard.getKeys();
         mKeys = keys.toArray(new Key[keys.size()]);
@@ -828,6 +830,7 @@
     private void showKey(final int keyIndex) {
         final PopupWindow previewPopup = mPreviewPopup;
         final Key[] keys = mKeys;
+        if (keyIndex < 0 || keyIndex >= mKeys.length) return;
         Key key = keys[keyIndex];
         if (key.icon != null) {
             mPreviewText.setCompoundDrawables(null, null, null, 
@@ -1145,9 +1148,7 @@
                 break;
 
             case MotionEvent.ACTION_UP:
-                mHandler.removeMessages(MSG_SHOW_PREVIEW);
-                mHandler.removeMessages(MSG_REPEAT);
-                mHandler.removeMessages(MSG_LONGPRESS);
+                removeMessages();
                 if (keyIndex == mCurrentKey) {
                     mCurrentKeyTime += eventTime - mLastMoveTime;
                 } else {
@@ -1203,16 +1204,20 @@
         if (mPreviewPopup.isShowing()) {
             mPreviewPopup.dismiss();
         }
-        mHandler.removeMessages(MSG_REPEAT);
-        mHandler.removeMessages(MSG_LONGPRESS);
-        mHandler.removeMessages(MSG_SHOW_PREVIEW);
+        removeMessages();
         
         dismissPopupKeyboard();
         mBuffer = null;
         mCanvas = null;
         mMiniKeyboardCache.clear();
     }
-    
+
+    private void removeMessages() {
+        mHandler.removeMessages(MSG_REPEAT);
+        mHandler.removeMessages(MSG_LONGPRESS);
+        mHandler.removeMessages(MSG_SHOW_PREVIEW);
+    }
+
     @Override
     public void onDetachedFromWindow() {
         super.onDetachedFromWindow();
diff --git a/core/java/android/net/http/Connection.java b/core/java/android/net/http/Connection.java
index 563634f..2d39e39 100644
--- a/core/java/android/net/http/Connection.java
+++ b/core/java/android/net/http/Connection.java
@@ -251,9 +251,7 @@
                             pipe.addLast(req);
                         }
                         exception = null;
-                        state = (clearPipe(pipe) ||
-                                 !mConnectionManager.isNetworkConnected()) ?
-                                DONE : SEND;
+                        state = clearPipe(pipe) ? DONE : SEND;
                         minPipe = maxPipe = 1;
                         break;
                     }
@@ -314,9 +312,7 @@
                         mHttpContext.removeAttribute(HTTP_CONNECTION);
                         clearPipe(pipe);
                         minPipe = maxPipe = 1;
-                        /* If network active continue to service this queue */
-                        state = mConnectionManager.isNetworkConnected() ?
-                                SEND : DONE;
+                        state = SEND;
                     }
                     break;
                 }
@@ -408,8 +404,7 @@
         if (error == EventHandler.OK) {
             return true;
         } else {
-            if (mConnectionManager.isNetworkConnected() == false ||
-                req.mFailCount < RETRY_REQUEST_LIMIT) {
+            if (req.mFailCount < RETRY_REQUEST_LIMIT) {
                 // requeue
                 mRequestFeeder.requeueRequest(req);
                 req.mFailCount++;
@@ -432,14 +427,13 @@
      */
     private boolean httpFailure(Request req, int errorId, Exception e) {
         boolean ret = true;
-        boolean networkConnected = mConnectionManager.isNetworkConnected();
 
         // e.printStackTrace();
         if (HttpLog.LOGV) HttpLog.v(
                 "httpFailure() ******* " + e + " count " + req.mFailCount +
-                " networkConnected " + networkConnected + " " + mHost + " " + req.getUri());
+                " " + mHost + " " + req.getUri());
 
-        if (networkConnected && ++req.mFailCount >= RETRY_REQUEST_LIMIT) {
+        if (++req.mFailCount >= RETRY_REQUEST_LIMIT) {
             ret = false;
             String error;
             if (errorId < 0) {
diff --git a/core/java/android/net/http/RequestQueue.java b/core/java/android/net/http/RequestQueue.java
index e14af66..875caa0 100644
--- a/core/java/android/net/http/RequestQueue.java
+++ b/core/java/android/net/http/RequestQueue.java
@@ -26,7 +26,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
-import android.net.NetworkConnectivityListener;
 import android.net.NetworkInfo;
 import android.net.Proxy;
 import android.net.WebAddress;
@@ -50,151 +49,22 @@
  */
 public class RequestQueue implements RequestFeeder {
 
-    private Context mContext;
 
     /**
      * Requests, indexed by HttpHost (scheme, host, port)
      */
-    private LinkedHashMap<HttpHost, LinkedList<Request>> mPending;
-
-    /** true if connected */
-    boolean mNetworkConnected = true;
+    private final LinkedHashMap<HttpHost, LinkedList<Request>> mPending;
+    private final Context mContext;
+    private final ActivePool mActivePool;
+    private final ConnectivityManager mConnectivityManager;
 
     private HttpHost mProxyHost = null;
     private BroadcastReceiver mProxyChangeReceiver;
 
-    private ActivePool mActivePool;
-
     /* default simultaneous connection count */
     private static final int CONNECTION_COUNT = 4;
 
     /**
-     * This intent broadcast when http is paused or unpaused due to
-     * net availability toggling
-     */
-    public final static String HTTP_NETWORK_STATE_CHANGED_INTENT =
-            "android.net.http.NETWORK_STATE";
-    public final static String HTTP_NETWORK_STATE_UP = "up";
-
-    /**
-     * Listen to platform network state.  On a change,
-     * (1) kick stack on or off as appropriate
-     * (2) send an intent to my host app telling
-     *     it what I've done
-     */
-    private NetworkStateTracker mNetworkStateTracker;
-    class NetworkStateTracker {
-
-        final static int EVENT_DATA_STATE_CHANGED = 100;
-
-        Context mContext;
-        NetworkConnectivityListener mConnectivityListener;
-        NetworkInfo.State mLastNetworkState = NetworkInfo.State.CONNECTED;
-        int mCurrentNetworkType;
-
-        NetworkStateTracker(Context context) {
-            mContext = context;
-        }
-
-        /**
-         * register for updates
-         */
-        protected void enable() {
-            if (mConnectivityListener == null) {
-                /*
-                 * Initializing the network type is really unnecessary,
-                 * since as soon as we register with the NCL, we'll
-                 * get a CONNECTED event for the active network, and
-                 * we'll configure the HTTP proxy accordingly. However,
-                 * as a fallback in case that doesn't happen for some
-                 * reason, initializing to type WIFI would mean that
-                 * we'd start out without a proxy. This seems better
-                 * than thinking we have a proxy (which is probably
-                 * private to the carrier network and therefore
-                 * unreachable outside of that network) when we really
-                 * shouldn't.
-                 */
-                mCurrentNetworkType = ConnectivityManager.TYPE_WIFI;
-                mConnectivityListener = new NetworkConnectivityListener();
-                mConnectivityListener.registerHandler(mHandler, EVENT_DATA_STATE_CHANGED);
-                mConnectivityListener.startListening(mContext);
-            }
-        }
-
-        protected void disable() {
-            if (mConnectivityListener != null) {
-                mConnectivityListener.unregisterHandler(mHandler);
-                mConnectivityListener.stopListening();
-                mConnectivityListener = null;
-            }
-        }
-
-        private Handler mHandler = new Handler() {
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                    case EVENT_DATA_STATE_CHANGED:
-                        networkStateChanged();
-                        break;
-                }
-            }
-        };
-
-        int getCurrentNetworkType() {
-            return mCurrentNetworkType;
-        }
-
-        void networkStateChanged() {
-            if (mConnectivityListener == null)
-                return;
-
-            
-            NetworkConnectivityListener.State connectivityState = mConnectivityListener.getState();
-            NetworkInfo info = mConnectivityListener.getNetworkInfo();
-            if (info == null) {
-                /**
-                 * We've been seeing occasional NPEs here. I believe recent changes
-                 * have made this impossible, but in the interest of being totally
-                 * paranoid, check and log this here.
-                 */
-                HttpLog.v("NetworkStateTracker: connectivity broadcast"
-                    + " has null network info - ignoring");
-                return;
-            }
-            NetworkInfo.State state = info.getState();
-
-            if (HttpLog.LOGV) {
-                HttpLog.v("NetworkStateTracker " + info.getTypeName() +
-                " state= " + state + " last= " + mLastNetworkState +
-                " connectivityState= " + connectivityState.toString());
-            }
-
-            boolean newConnection =
-                state != mLastNetworkState && state == NetworkInfo.State.CONNECTED;
-
-            if (state == NetworkInfo.State.CONNECTED) {
-                mCurrentNetworkType = info.getType();
-                setProxyConfig();
-            }
-
-            mLastNetworkState = state;
-            if (connectivityState == NetworkConnectivityListener.State.NOT_CONNECTED) {
-                setNetworkState(false);
-                broadcastState(false);
-            } else if (newConnection) {
-                setNetworkState(true);
-                broadcastState(true);
-            }
-
-        }
-
-        void broadcastState(boolean connected) {
-            Intent intent = new Intent(HTTP_NETWORK_STATE_CHANGED_INTENT);
-            intent.putExtra(HTTP_NETWORK_STATE_UP, connected);
-            mContext.sendBroadcast(intent);
-        }
-    }
-
-    /**
      * This class maintains active connection threads
      */
     class ActivePool implements ConnectionManager {
@@ -230,10 +100,6 @@
             }
         }
 
-        public boolean isNetworkConnected() {
-            return mNetworkConnected;
-        }
-
         void startConnectionThread() {
             synchronized (RequestQueue.this) {
                 RequestQueue.this.notify();
@@ -349,6 +215,9 @@
 
         mActivePool = new ActivePool(connectionCount);
         mActivePool.startup();
+
+        mConnectivityManager = (ConnectivityManager)
+                context.getSystemService(Context.CONNECTIVITY_SERVICE);
     }
 
     /**
@@ -368,18 +237,6 @@
             mContext.registerReceiver(mProxyChangeReceiver,
                                       new IntentFilter(Proxy.PROXY_CHANGE_ACTION));
         }
-
-        /* Network state notification is broken on the simulator
-           don't register for notifications on SIM */
-        String device = SystemProperties.get("ro.product.device");
-        boolean simulation = TextUtils.isEmpty(device);
-
-        if (!simulation) {
-            if (mNetworkStateTracker == null) {
-                mNetworkStateTracker = new NetworkStateTracker(mContext);
-            }
-            mNetworkStateTracker.enable();
-        }
     }
 
     /**
@@ -389,10 +246,6 @@
     public synchronized void disablePlatformNotifications() {
         if (HttpLog.LOGV) HttpLog.v("RequestQueue.disablePlatformNotifications() network");
 
-        if (mNetworkStateTracker != null) {
-            mNetworkStateTracker.disable();
-        }
-
         if (mProxyChangeReceiver != null) {
             mContext.unregisterReceiver(mProxyChangeReceiver);
             mProxyChangeReceiver = null;
@@ -404,7 +257,8 @@
      * synchronize setting the proxy
      */
     private synchronized void setProxyConfig() {
-        if (mNetworkStateTracker.getCurrentNetworkType() == ConnectivityManager.TYPE_WIFI) {
+        NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
+        if (info != null && info.getType() == ConnectivityManager.TYPE_WIFI) {
             mProxyHost = null;
         } else {
             String host = Proxy.getHost(mContext);
@@ -489,19 +343,6 @@
     }
 
     /**
-     * Called by the NetworkStateTracker -- updates when network connectivity
-     * is lost/restored.
-     *
-     * If isNetworkConnected is true, start processing requests
-     */
-    public void setNetworkState(boolean isNetworkConnected) {
-        if (HttpLog.LOGV) HttpLog.v("RequestQueue.setNetworkState() " + isNetworkConnected);
-        mNetworkConnected = isNetworkConnected;
-        if (isNetworkConnected)
-            mActivePool.startConnectionThread();
-    }
-
-    /**
      * @return true iff there are any non-active requests pending
      */
     synchronized boolean requestsPending() {
@@ -546,7 +387,7 @@
     public synchronized Request getRequest() {
         Request ret = null;
 
-        if (mNetworkConnected && !mPending.isEmpty()) {
+        if (!mPending.isEmpty()) {
             ret = removeFirst(mPending);
         }
         if (HttpLog.LOGV) HttpLog.v("RequestQueue.getRequest() => " + ret);
@@ -559,7 +400,7 @@
     public synchronized Request getRequest(HttpHost host) {
         Request ret = null;
 
-        if (mNetworkConnected && mPending.containsKey(host)) {
+        if (mPending.containsKey(host)) {
             LinkedList<Request> reqList = mPending.get(host);
             ret = reqList.removeFirst();
             if (reqList.isEmpty()) {
@@ -635,7 +476,6 @@
      * This interface is exposed to each connection
      */
     interface ConnectionManager {
-        boolean isNetworkConnected();
         HttpHost getProxyHost();
         Connection getConnection(Context context, HttpHost host);
         boolean recycleConnection(HttpHost host, Connection connection);
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 8f1a756..44b73c5 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -18,10 +18,73 @@
 
 /**
  * The BatteryManager class contains strings and constants used for values
- * in the ACTION_BATTERY_CHANGED Intent.
+ * in the {@link android.content.Intent#ACTION_BATTERY_CHANGED} Intent.
  */
 public class BatteryManager {
-
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the current status constant.
+     */
+    public static final String EXTRA_STATUS = "status";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the current health constant.
+     */
+    public static final String EXTRA_HEALTH = "health";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * boolean indicating whether a battery is present.
+     */
+    public static final String EXTRA_PRESENT = "present";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer field containing the current battery level, from 0 to
+     * {@link #EXTRA_SCALE}.
+     */
+    public static final String EXTRA_LEVEL = "level";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the maximum battery level.
+     */
+    public static final String EXTRA_SCALE = "scale";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the resource ID of a small status bar icon
+     * indicating the current battery state.
+     */
+    public static final String EXTRA_ICON_SMALL = "icon-small";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer indicating whether the device is plugged in to a power
+     * source; 0 means it is on battery, other constants are different
+     * types of power sources.
+     */
+    public static final String EXTRA_PLUGGED = "plugged";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the current battery voltage level.
+     */
+    public static final String EXTRA_VOLTAGE = "voltage";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * integer containing the current battery temperature.
+     */
+    public static final String EXTRA_TEMPERATURE = "temperature";
+    
+    /**
+     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+     * String describing the technology of the current battery.
+     */
+    public static final String EXTRA_TECHNOLOGY = "technology";
+    
     // values for "status" field in the ACTION_BATTERY_CHANGED Intent
     public static final int BATTERY_STATUS_UNKNOWN = 1;
     public static final int BATTERY_STATUS_CHARGING = 2;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e203fd5..a49a27a0 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -314,6 +314,15 @@
              * @return foreground cpu time in microseconds
              */
             public abstract long getForegroundTime(int which);
+
+            /**
+             * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
+             * @param speedStep the index of the CPU speed. This is not the actual speed of the
+             * CPU.
+             * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
+             * @see BatteryStats#getCpuSpeedSteps()
+             */
+            public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
         }
 
         /**
@@ -573,6 +582,9 @@
     
     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
 
+    /** Returns the number of different speeds that the CPU can run at */
+    public abstract int getCpuSpeedSteps();
+
     private final static void formatTimeRaw(StringBuilder out, long seconds) {
         long days = seconds / (60 * 60 * 24);
         if (days != 0) {
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 5352cf6..b4f64b6 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -129,6 +129,27 @@
         public MemoryInfo() {
         }
 
+        /**
+         * Return total PSS memory usage in kB.
+         */
+        public int getTotalPss() {
+            return dalvikPss + nativePss + otherPss;
+        }
+        
+        /**
+         * Return total private dirty memory usage in kB.
+         */
+        public int getTotalPrivateDirty() {
+            return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty;
+        }
+        
+        /**
+         * Return total shared dirty memory usage in kB.
+         */
+        public int getTotalSharedDirty() {
+            return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
+        }
+        
         public int describeContents() {
             return 0;
         }
diff --git a/core/java/android/pim/vcard/ContactStruct.java b/core/java/android/pim/vcard/ContactStruct.java
index 06b0636..b212f5a 100644
--- a/core/java/android/pim/vcard/ContactStruct.java
+++ b/core/java/android/pim/vcard/ContactStruct.java
@@ -20,11 +20,14 @@
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.OperationApplicationException;
+import android.database.Cursor;
 import android.os.RemoteException;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.CommonDataKinds.Miscellaneous;
 import android.provider.ContactsContract.CommonDataKinds.Nickname;
@@ -1023,14 +1026,37 @@
         }
     }
     
+    // From HardCodedSources.java in Contacts app.
+    // TODO: fix this.
+    private static final String ACCOUNT_TYPE_GOOGLE = "com.google.GAIA";
+    private static final String GOOGLE_MY_CONTACTS_GROUP = "System Group: My Contacts";
+
     public void pushIntoContentResolver(ContentResolver resolver) {
         ArrayList<ContentProviderOperation> operationList =
             new ArrayList<ContentProviderOperation>();  
         ContentProviderOperation.Builder builder =
             ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
+        String myGroupsId = null;
         if (mAccount != null) {
             builder.withValue(RawContacts.ACCOUNT_NAME, mAccount.name);
             builder.withValue(RawContacts.ACCOUNT_TYPE, mAccount.type);
+
+            // TODO: temporal fix for "My Groups" issue. Need to be refactored.
+            if (ACCOUNT_TYPE_GOOGLE.equals(mAccount.type)) {
+                final Cursor cursor = resolver.query(Groups.CONTENT_URI, new String[] {
+                        Groups.SOURCE_ID },
+                        Groups.TITLE + "=?", new String[] {
+                        GOOGLE_MY_CONTACTS_GROUP }, null);
+                try {
+                    if (cursor != null && cursor.moveToFirst()) {
+                        myGroupsId = cursor.getString(0);
+                    }
+                } finally {
+                    if (cursor != null) {
+                        cursor.close();
+                    }
+                }
+            }
         } else {
             builder.withValues(new ContentValues());
         }
@@ -1196,6 +1222,14 @@
             operationList.add(builder.build());
         }
 
+        if (myGroupsId != null) {
+            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+            builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0);
+            builder.withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
+            builder.withValue(GroupMembership.GROUP_SOURCE_ID, myGroupsId);
+            operationList.add(builder.build());
+        }
+
         try {
             resolver.applyBatch(ContactsContract.AUTHORITY, operationList);
         } catch (RemoteException e) {
diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java
index b337d28..a264594 100644
--- a/core/java/android/preference/VolumePreference.java
+++ b/core/java/android/preference/VolumePreference.java
@@ -121,6 +121,9 @@
        if (mSeekBarVolumizer != null) {
            Dialog dialog = getDialog();
            if (dialog != null && dialog.isShowing()) {
+               View view = dialog.getWindow().getDecorView()
+                       .findViewById(com.android.internal.R.id.seekbar);
+               if (view != null) view.setOnKeyListener(null);
                // Stopped while dialog was showing, revert changes
                mSeekBarVolumizer.revertVolume();
            }
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index d57155c..f046cef 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -110,6 +110,7 @@
         public static final int EDITOR_ACCESS = 600;
         /** Full access to the calendar */
         public static final int OWNER_ACCESS = 700;
+        /** Domain admin */
         public static final int ROOT_ACCESS = 800;
 
         /**
@@ -506,6 +507,13 @@
          * <P>Type: INTEGER (boolean, readonly)</P>
          */
         public static final String CAN_INVITE_OTHERS = "canInviteOthers";
+
+        /**
+         * The owner account for this calendar, based on the calendar (foreign
+         * key into the calendars table).
+         * <P>Type: String</P>
+         */
+        public static final String OWNER_ACCOUNT = "ownerAccount";
     }
 
     /**
diff --git a/core/java/android/provider/Contacts.java b/core/java/android/provider/Contacts.java
index 667ec5a..d87018d 100644
--- a/core/java/android/provider/Contacts.java
+++ b/core/java/android/provider/Contacts.java
@@ -533,7 +533,7 @@
             Uri photoUri = Uri.withAppendedPath(person, Contacts.Photos.CONTENT_DIRECTORY);
             Cursor cursor = cr.query(photoUri, new String[]{Photos.DATA}, null, null, null);
             try {
-                if (!cursor.moveToNext()) {
+                if (cursor == null || !cursor.moveToNext()) {
                     return null;
                 }
                 byte[] data = cursor.getBlob(0);
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index afa0a7c..90c6328 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -26,10 +26,12 @@
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.BitmapFactory;
+import android.graphics.Rect;
 import android.net.Uri;
 import android.os.RemoteException;
 import android.text.TextUtils;
 import android.util.Pair;
+import android.view.View;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
@@ -38,7 +40,7 @@
  * The contract between the contacts provider and applications. Contains definitions
  * for the supported URIs and columns.
  *
- * @hide
+ * @hide pending API council approval
  */
 public final class ContactsContract {
     /** The authority for the contacts provider */
@@ -278,27 +280,25 @@
                 "lookup");
 
         /**
-         * Computes a complete lookup URI (see {@link #CONTENT_LOOKUP_URI}).
-         * Pass either a basic content URI with a contact ID to obtain an
-         * equivalent lookup URI. Pass a possibly stale lookup URI to get a fresh
-         * lookup URI for the same contact.
-         * <p>
-         * Returns null if the contact cannot be found.
+         * Builds a {@link #CONTENT_LOOKUP_URI} style {@link Uri} describing the
+         * requested {@link Contacts} entry.
+         *
+         * @param contactUri A {@link #CONTENT_URI} row, or an existing
+         *            {@link #CONTENT_LOOKUP_URI} to attempt refreshing.
          */
-        public static Uri getLookupUri(ContentResolver resolver, Uri contentUri) {
-            Cursor c = resolver.query(contentUri,
-                    new String[]{Contacts.LOOKUP_KEY, Contacts._ID}, null, null, null);
+        public static Uri getLookupUri(ContentResolver resolver, Uri contactUri) {
+            final Cursor c = resolver.query(contactUri, new String[] {
+                    Contacts.LOOKUP_KEY, Contacts._ID
+            }, null, null, null);
             if (c == null) {
                 return null;
             }
 
             try {
                 if (c.moveToFirst()) {
-                    String lookupKey = c.getString(0);
-                    long contactId = c.getLong(1);
-                    return ContentUris.withAppendedId(
-                            Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
-                            contactId);
+                    final String lookupKey = c.getString(0);
+                    final long contactId = c.getLong(1);
+                    return getLookupUri(contactId, lookupKey);
                 }
             } finally {
                 c.close();
@@ -553,6 +553,30 @@
         public static final int AGGREGATION_MODE_DISABLED = 3;
 
         /**
+         * Build a {@link Contacts#CONTENT_LOOKUP_URI} style {@link Uri} for the
+         * parent {@link Contacts} entry of the given {@link RawContacts} entry.
+         */
+        public static Uri getContactLookupUri(ContentResolver resolver, Uri rawContactUri) {
+            // TODO: use a lighter query by joining rawcontacts with contacts in provider
+            final Uri dataUri = Uri.withAppendedPath(rawContactUri, Data.CONTENT_DIRECTORY);
+            final Cursor cursor = resolver.query(dataUri, new String[] {
+                    RawContacts.CONTACT_ID, Contacts.LOOKUP_KEY
+            }, null, null, null);
+
+            Uri lookupUri = null;
+            try {
+                if (cursor != null && cursor.moveToFirst()) {
+                    final long contactId = cursor.getLong(0);
+                    final String lookupKey = cursor.getString(1);
+                    return Contacts.getLookupUri(contactId, lookupKey);
+                }
+            } finally {
+                if (cursor != null) cursor.close();
+            }
+            return lookupUri;
+        }
+
+        /**
          * A sub-directory of a single raw contact that contains all of their {@link Data} rows.
          * To access this directory append {@link Data#CONTENT_DIRECTORY} to the contact URI.
          */
@@ -653,12 +677,20 @@
     }
 
     /**
+     * Combines all columns returned by {@link Data} table queries.
+     */
+    private interface DataColumnsWithJoins extends BaseColumns, DataColumns, RawContactsColumns,
+            ContactsColumns, ContactOptionsColumns {
+
+    }
+
+    /**
      * Constants for the data table, which contains data points tied to a raw contact.
      * For example, a phone number or email address. Each row in this table contains a type
      * definition and some generic columns. Each data type can define the meaning for each of
      * the generic columns.
      */
-    public static final class Data implements BaseColumns, DataColumns {
+    public final static class Data implements DataColumnsWithJoins {
         /**
          * This utility class cannot be instantiated
          */
@@ -682,6 +714,28 @@
          * The MIME type of {@link #CONTENT_URI} providing a directory of data.
          */
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/data";
+
+        /**
+         * Build a {@link Contacts#CONTENT_LOOKUP_URI} style {@link Uri} for the
+         * parent {@link Contacts} entry of the given {@link Data} entry.
+         */
+        public static Uri getContactLookupUri(ContentResolver resolver, Uri dataUri) {
+            final Cursor cursor = resolver.query(dataUri, new String[] {
+                    RawContacts.CONTACT_ID, Contacts.LOOKUP_KEY
+            }, null, null, null);
+
+            Uri lookupUri = null;
+            try {
+                if (cursor != null && cursor.moveToFirst()) {
+                    final long contactId = cursor.getLong(0);
+                    final String lookupKey = cursor.getString(1);
+                    return Contacts.getLookupUri(contactId, lookupKey);
+                }
+            } finally {
+                if (cursor != null) cursor.close();
+            }
+            return lookupUri;
+        }
     }
 
     private interface PhoneLookupColumns {
@@ -883,94 +937,94 @@
          */
         private interface CommonColumns extends BaseTypes{
             /**
-             * The type of data, for example Home or Work.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String TYPE = "data1";
-
-            /**
              * The data for the contact method.
              * <P>Type: TEXT</P>
              */
-            public static final String DATA = "data2";
+            public static final String DATA = DataColumns.DATA1;
+
+            /**
+             * The type of data, for example Home or Work.
+             * <P>Type: INTEGER</P>
+             */
+            public static final String TYPE = DataColumns.DATA2;
 
             /**
              * The user defined label for the the contact method.
              * <P>Type: TEXT</P>
              */
-            public static final String LABEL = "data3";
+            public static final String LABEL = DataColumns.DATA3;
         }
 
         /**
          * Parts of the name.
          */
-        public static final class StructuredName implements BaseCommonColumns {
+        public static final class StructuredName implements DataColumnsWithJoins {
             private StructuredName() {}
 
             /** MIME type used when storing this in data table. */
             public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/name";
 
             /**
-             * The given name for the contact.
-             * <P>Type: TEXT</P>
-             */
-            public static final String GIVEN_NAME = "data1";
-
-            /**
-             * The family name for the contact.
-             * <P>Type: TEXT</P>
-             */
-            public static final String FAMILY_NAME = "data2";
-
-            /**
-             * The contact's honorific prefix, e.g. "Sir"
-             * <P>Type: TEXT</P>
-             */
-            public static final String PREFIX = "data3";
-
-            /**
-             * The contact's middle name
-             * <P>Type: TEXT</P>
-             */
-            public static final String MIDDLE_NAME = "data4";
-
-            /**
-             * The contact's honorific suffix, e.g. "Jr"
-             */
-            public static final String SUFFIX = "data5";
-
-            /**
-             * The phonetic version of the given name for the contact.
-             * <P>Type: TEXT</P>
-             */
-            public static final String PHONETIC_GIVEN_NAME = "data6";
-
-            /**
-             * The phonetic version of the additional name for the contact.
-             * <P>Type: TEXT</P>
-             */
-            public static final String PHONETIC_MIDDLE_NAME = "data7";
-
-            /**
-             * The phonetic version of the family name for the contact.
-             * <P>Type: TEXT</P>
-             */
-            public static final String PHONETIC_FAMILY_NAME = "data8";
-
-            /**
              * The name that should be used to display the contact.
              * <i>Unstructured component of the name should be consistent with
              * its structured representation.</i>
              * <p>
              * Type: TEXT
              */
-            public static final String DISPLAY_NAME = "data9";
+            public static final String DISPLAY_NAME = DATA1;
+
+            /**
+             * The given name for the contact.
+             * <P>Type: TEXT</P>
+             */
+            public static final String GIVEN_NAME = DATA2;
+
+            /**
+             * The family name for the contact.
+             * <P>Type: TEXT</P>
+             */
+            public static final String FAMILY_NAME = DATA3;
+
+            /**
+             * The contact's honorific prefix, e.g. "Sir"
+             * <P>Type: TEXT</P>
+             */
+            public static final String PREFIX = DATA4;
+
+            /**
+             * The contact's middle name
+             * <P>Type: TEXT</P>
+             */
+            public static final String MIDDLE_NAME = DATA5;
+
+            /**
+             * The contact's honorific suffix, e.g. "Jr"
+             */
+            public static final String SUFFIX = DATA6;
+
+            /**
+             * The phonetic version of the given name for the contact.
+             * <P>Type: TEXT</P>
+             */
+            public static final String PHONETIC_GIVEN_NAME = DATA7;
+
+            /**
+             * The phonetic version of the additional name for the contact.
+             * <P>Type: TEXT</P>
+             */
+            public static final String PHONETIC_MIDDLE_NAME = DATA8;
+
+            /**
+             * The phonetic version of the family name for the contact.
+             * <P>Type: TEXT</P>
+             */
+            public static final String PHONETIC_FAMILY_NAME = DATA9;
         }
 
         /**
          * A nickname.
          */
-        public static final class Nickname implements CommonColumns, BaseCommonColumns {
+        public static final class Nickname implements DataColumnsWithJoins, CommonColumns {
             private Nickname() {}
 
             /** MIME type used when storing this in data table. */
@@ -991,7 +1045,7 @@
         /**
          * Common data definition for telephone numbers.
          */
-        public static final class Phone implements BaseCommonColumns, CommonColumns {
+        public static final class Phone implements DataColumnsWithJoins, CommonColumns {
             private Phone() {}
 
             /** MIME type used when storing this in data table. */
@@ -1039,6 +1093,7 @@
             public static final int TYPE_WORK_MOBILE = 17;
             public static final int TYPE_WORK_PAGER = 18;
             public static final int TYPE_ASSISTANT = 19;
+            public static final int TYPE_MMS = 20;
 
             /**
              * The phone number as the user entered it.
@@ -1076,13 +1131,18 @@
         /**
          * Common data definition for email addresses.
          */
-        public static final class Email implements BaseCommonColumns, CommonColumns {
+        public static final class Email implements DataColumnsWithJoins, CommonColumns {
             private Email() {}
 
             /** MIME type used when storing this in data table. */
             public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email_v2";
 
             /**
+             * The MIME type of {@link #CONTENT_URI} providing a directory of email addresses.
+             */
+            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/email_v2";
+
+            /**
              * The content:// style URI for all data records of the
              * {@link Email#CONTENT_ITEM_TYPE} MIME type, combined with the
              * associated raw contact and aggregate contact data.
@@ -1098,9 +1158,6 @@
             public static final Uri CONTENT_LOOKUP_URI = Uri.withAppendedPath(CONTENT_URI,
                     "lookup");
 
-            @Deprecated
-            public static final Uri CONTENT_FILTER_EMAIL_URI = CONTENT_LOOKUP_URI;
-
             /**
              * The content:// style URL for email lookup using a filter. The filter returns
              * records of MIME type {@link Email#CONTENT_ITEM_TYPE}. The filter is applied
@@ -1119,13 +1176,13 @@
              * The display name for the email address
              * <P>Type: TEXT</P>
              */
-            public static final String DISPLAY_NAME = "data4";
+            public static final String DISPLAY_NAME = DATA4;
         }
 
         /**
          * Common data definition for postal addresses.
          */
-        public static final class StructuredPostal implements BaseCommonColumns, CommonColumns {
+        public static final class StructuredPostal implements DataColumnsWithJoins, CommonColumns {
             private StructuredPostal() {
             }
 
@@ -1164,7 +1221,7 @@
              * <p>
              * Type: TEXT
              */
-            public static final String STREET = "data6";
+            public static final String STREET = DATA4;
 
             /**
              * Covers actual P.O. boxes, drawers, locked bags, etc. This is
@@ -1172,7 +1229,7 @@
              * <p>
              * Type: TEXT
              */
-            public static final String POBOX = "data7";
+            public static final String POBOX = DATA5;
 
             /**
              * This is used to disambiguate a street address when a city
@@ -1182,7 +1239,7 @@
              * <p>
              * Type: TEXT
              */
-            public static final String NEIGHBORHOOD = "data8";
+            public static final String NEIGHBORHOOD = DATA6;
 
             /**
              * Can be city, village, town, borough, etc. This is the postal town
@@ -1190,7 +1247,7 @@
              * <p>
              * Type: TEXT
              */
-            public static final String CITY = "data9";
+            public static final String CITY = DATA7;
 
             /**
              * A state, province, county (in Ireland), Land (in Germany),
@@ -1198,7 +1255,7 @@
              * <p>
              * Type: TEXT
              */
-            public static final String REGION = "data11";
+            public static final String REGION = DATA8;
 
             /**
              * Postal code. Usually country-wide, but sometimes specific to the
@@ -1206,20 +1263,20 @@
              * <p>
              * Type: TEXT
              */
-            public static final String POSTCODE = "data12";
+            public static final String POSTCODE = DATA9;
 
             /**
              * The name or code of the country.
              * <p>
              * Type: TEXT
              */
-            public static final String COUNTRY = "data13";
+            public static final String COUNTRY = DATA10;
         }
 
         /**
          * Common data definition for IM addresses.
          */
-        public static final class Im implements BaseCommonColumns, CommonColumns {
+        public static final class Im implements DataColumnsWithJoins, CommonColumns {
             private Im() {}
 
             /** MIME type used when storing this in data table. */
@@ -1235,9 +1292,9 @@
              * column is {@link #PROTOCOL_CUSTOM}, the {@link #CUSTOM_PROTOCOL}
              * should contain the name of the custom protocol.
              */
-            public static final String PROTOCOL = "data5";
+            public static final String PROTOCOL = DATA5;
 
-            public static final String CUSTOM_PROTOCOL = "data6";
+            public static final String CUSTOM_PROTOCOL = DATA6;
 
             /*
              * The predefined IM protocol types.
@@ -1257,7 +1314,7 @@
         /**
          * Common data definition for organizations.
          */
-        public static final class Organization implements BaseCommonColumns, CommonColumns {
+        public static final class Organization implements DataColumnsWithJoins, CommonColumns {
             private Organization() {}
 
             /** MIME type used when storing this in data table. */
@@ -1276,37 +1333,37 @@
              * The position title at this company as the user entered it.
              * <P>Type: TEXT</P>
              */
-            public static final String TITLE = "data4";
+            public static final String TITLE = DATA4;
 
             /**
              * The department at this company as the user entered it.
              * <P>Type: TEXT</P>
              */
-            public static final String DEPARTMENT = "data5";
+            public static final String DEPARTMENT = DATA5;
 
             /**
              * The job description at this company as the user entered it.
              * <P>Type: TEXT</P>
              */
-            public static final String JOB_DESCRIPTION = "data6";
+            public static final String JOB_DESCRIPTION = DATA6;
 
             /**
              * The symbol of this company as the user entered it.
              * <P>Type: TEXT</P>
              */
-            public static final String SYMBOL = "data7";
+            public static final String SYMBOL = DATA7;
 
             /**
              * The phonetic name of this company as the user entered it.
              * <P>Type: TEXT</P>
              */
-            public static final String PHONETIC_NAME = "data8";
+            public static final String PHONETIC_NAME = DATA8;
         }
 
         /**
          * Common data definition for miscellaneous information.
          */
-        public static final class Miscellaneous implements BaseCommonColumns {
+        public static final class Miscellaneous implements DataColumnsWithJoins {
             private Miscellaneous() {}
 
             /** MIME type used when storing this in data table. */
@@ -1316,19 +1373,19 @@
              * The birthday as the user entered it.
              * <P>Type: TEXT</P>
              */
-            public static final String BIRTHDAY = "data1";
+            public static final String BIRTHDAY = DATA1;
 
             /**
              * The nickname as the user entered it.
              * <P>Type: TEXT</P>
              */
-            public static final String NICKNAME = "data2";
+            public static final String NICKNAME = DATA2;
         }
 
         /**
          * Common data definition for relations.
          */
-        public static final class Relation implements BaseCommonColumns, CommonColumns {
+        public static final class Relation implements DataColumnsWithJoins, CommonColumns {
             private Relation() {}
 
             /** MIME type used when storing this in data table. */
@@ -1359,7 +1416,7 @@
         /**
          * Common data definition for events.
          */
-        public static final class Event implements BaseCommonColumns, CommonColumns {
+        public static final class Event implements DataColumnsWithJoins, CommonColumns {
             private Event() {}
 
             /** MIME type used when storing this in data table. */
@@ -1378,7 +1435,7 @@
         /**
          * Photo of the contact.
          */
-        public static final class Photo implements BaseCommonColumns {
+        public static final class Photo implements DataColumnsWithJoins {
             private Photo() {}
 
             /** MIME type used when storing this in data table. */
@@ -1390,13 +1447,13 @@
              * <p>
              * Type: BLOB
              */
-            public static final String PHOTO = "data1";
+            public static final String PHOTO = DATA15;
         }
 
         /**
          * Notes about the contact.
          */
-        public static final class Note implements BaseCommonColumns {
+        public static final class Note implements DataColumnsWithJoins {
             private Note() {}
 
             /** MIME type used when storing this in data table. */
@@ -1406,13 +1463,13 @@
              * The note text.
              * <P>Type: TEXT</P>
              */
-            public static final String NOTE = "data1";
+            public static final String NOTE = DATA1;
         }
 
         /**
          * Group Membership.
          */
-        public static final class GroupMembership implements BaseCommonColumns {
+        public static final class GroupMembership implements DataColumnsWithJoins {
             private GroupMembership() {}
 
             /** MIME type used when storing this in data table. */
@@ -1424,7 +1481,7 @@
              * this or {@link #GROUP_SOURCE_ID} must be set when inserting a row.
              * <P>Type: INTEGER</P>
              */
-            public static final String GROUP_ROW_ID = "data1";
+            public static final String GROUP_ROW_ID = DATA1;
 
             /**
              * The sourceid of the group that this group membership refers to.  Exactly one of
@@ -1437,7 +1494,7 @@
         /**
          * Website related to the contact.
          */
-        public static final class Website implements BaseCommonColumns, CommonColumns {
+        public static final class Website implements DataColumnsWithJoins, CommonColumns {
             private Website() {}
 
             /** MIME type used when storing this in data table. */
@@ -1455,7 +1512,7 @@
              * The website URL string.
              * <P>Type: TEXT</P>
              */
-            public static final String URL = "data1";
+            public static final String URL = DATA;
         }
     }
 
@@ -1625,24 +1682,12 @@
          */
         public static final int TYPE_KEEP_TOGETHER = 1;
 
-        @Deprecated
-        public static final int TYPE_KEEP_IN = 1;
-
         /**
          * Makes sure that the specified raw contacts are NOT included in the same
          * aggregate contact.
          */
         public static final int TYPE_KEEP_SEPARATE = 2;
 
-        @Deprecated
-        public static final int TYPE_KEEP_OUT = 2;
-
-        @Deprecated
-        public static final String CONTACT_ID = "contact_id";
-
-        @Deprecated
-        public static final String RAW_CONTACT_ID = "raw_contact_id";
-
         /**
          * A reference to the {@link RawContacts#_ID} of the raw contact that the rule applies to.
          */
@@ -1738,6 +1783,130 @@
     }
 
     /**
+     * Helper methods to display FastTrack dialogs that allow users to pivot on
+     * a specific {@link Contacts} entry.
+     */
+    public static final class FastTrack {
+        /**
+         * Action used to trigger person pivot dialog.
+         * @hide
+         */
+        public static final String ACTION_FAST_TRACK =
+                "com.android.contacts.action.FAST_TRACK";
+
+        /**
+         * Extra used to specify pivot dialog location in screen coordinates.
+         * @hide
+         */
+        public static final String EXTRA_TARGET_RECT = "target_rect";
+
+        /**
+         * Extra used to specify size of pivot dialog.
+         * @hide
+         */
+        public static final String EXTRA_MODE = "mode";
+
+        /**
+         * Extra used to indicate a list of specific MIME-types to exclude and
+         * not display. Stored as a {@link String} array.
+         * @hide
+         */
+        public static final String EXTRA_EXCLUDE_MIMES = "exclude_mimes";
+
+        /**
+         * Small FastTrack mode, usually presented with minimal actions.
+         */
+        public static final int MODE_SMALL = 1;
+
+        /**
+         * Medium FastTrack mode, includes actions and light summary describing
+         * the {@link Contacts} entry being shown. This may include social
+         * status and presence details.
+         */
+        public static final int MODE_MEDIUM = 2;
+
+        /**
+         * Large FastTrack mode, includes actions and larger, card-like summary
+         * of the {@link Contacts} entry being shown. This may include detailed
+         * information, such as a photo.
+         */
+        public static final int MODE_LARGE = 3;
+
+        /**
+         * Trigger a dialog that lists the various methods of interacting with
+         * the requested {@link Contacts} entry. This may be based on available
+         * {@link Data} rows under that contact, and may also include social
+         * status and presence details.
+         *
+         * @param context The parent {@link Context} that may be used as the
+         *            parent for this dialog.
+         * @param target Specific {@link View} from your layout that this dialog
+         *            should be centered around. In particular, if the dialog
+         *            has a "callout" arrow, it will be pointed and centered
+         *            around this {@link View}.
+         * @param lookupUri A {@link Contacts#CONTENT_LOOKUP_URI} style
+         *            {@link Uri} that describes a specific contact to feature
+         *            in this dialog.
+         * @param mode Any of {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or
+         *            {@link #MODE_LARGE}, indicating the desired dialog size,
+         *            when supported.
+         * @param excludeMimes Optional list of {@link Data#MIMETYPE} MIME-types
+         *            to exclude when showing this dialog. For example, when
+         *            already viewing the contact details card, this can be used
+         *            to omit the details entry from the dialog.
+         */
+        public static void showFastTrack(Context context, View target, Uri lookupUri, int mode,
+                String[] excludeMimes) {
+            // Find location and bounds of target view
+            final int[] location = new int[2];
+            target.getLocationOnScreen(location);
+
+            final Rect rect = new Rect();
+            rect.left = location[0];
+            rect.top = location[1];
+            rect.right = rect.left + target.getWidth();
+            rect.bottom = rect.top + target.getHeight();
+
+            // Trigger with obtained rectangle
+            showFastTrack(context, rect, lookupUri, mode, excludeMimes);
+        }
+
+        /**
+         * Trigger a dialog that lists the various methods of interacting with
+         * the requested {@link Contacts} entry. This may be based on available
+         * {@link Data} rows under that contact, and may also include social
+         * status and presence details.
+         *
+         * @param context The parent {@link Context} that may be used as the
+         *            parent for this dialog.
+         * @param target Specific {@link Rect} that this dialog should be
+         *            centered around, in screen coordinates. In particular, if
+         *            the dialog has a "callout" arrow, it will be pointed and
+         *            centered around this {@link Rect}.
+         * @param lookupUri A {@link Contacts#CONTENT_LOOKUP_URI} style
+         *            {@link Uri} that describes a specific contact to feature
+         *            in this dialog.
+         * @param mode Any of {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or
+         *            {@link #MODE_LARGE}, indicating the desired dialog size,
+         *            when supported.
+         * @param excludeMimes Optional list of {@link Data#MIMETYPE} MIME-types
+         *            to exclude when showing this dialog. For example, when
+         *            already viewing the contact details card, this can be used
+         *            to omit the details entry from the dialog.
+         */
+        public static void showFastTrack(Context context, Rect target, Uri lookupUri, int mode,
+                String[] excludeMimes) {
+            // Launch pivot dialog through intent for now
+            final Intent intent = new Intent(ACTION_FAST_TRACK);
+            intent.setData(lookupUri);
+            intent.putExtra(EXTRA_TARGET_RECT, target);
+            intent.putExtra(EXTRA_MODE, mode);
+            intent.putExtra(EXTRA_EXCLUDE_MIMES, excludeMimes);
+            context.startActivity(intent);
+        }
+    }
+
+    /**
      * Contains helper classes used to create or manage {@link android.content.Intent Intents}
      * that involve contacts.
      */
@@ -1820,6 +1989,7 @@
          * dialog location using screen coordinates. When not specified, the
          * dialog will be centered.
          */
+        @Deprecated
         public static final String EXTRA_TARGET_RECT = "target_rect";
 
         /**
@@ -1827,21 +1997,25 @@
          * desired dialog style, usually a variation on size. One of
          * {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or {@link #MODE_LARGE}.
          */
+        @Deprecated
         public static final String EXTRA_MODE = "mode";
 
         /**
          * Value for {@link #EXTRA_MODE} to show a small-sized dialog.
          */
+        @Deprecated
         public static final int MODE_SMALL = 1;
 
         /**
          * Value for {@link #EXTRA_MODE} to show a medium-sized dialog.
          */
+        @Deprecated
         public static final int MODE_MEDIUM = 2;
 
         /**
          * Value for {@link #EXTRA_MODE} to show a large-sized dialog.
          */
+        @Deprecated
         public static final int MODE_LARGE = 3;
 
         /**
@@ -1849,6 +2023,7 @@
          * a list of specific MIME-types to exclude and not display. Stored as a
          * {@link String} array.
          */
+        @Deprecated
         public static final String EXTRA_EXCLUDE_MIMES = "exclude_mimes";
 
         /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6d03095..6cf8db6 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2406,7 +2406,6 @@
             WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
             WIFI_NUM_ALLOWED_CHANNELS,
             WIFI_NUM_OPEN_NETWORKS_KEPT,
-            BACKGROUND_DATA,
         };
 
         /**
@@ -3204,6 +3203,24 @@
                 "vending_carrier_ref_freq_ms";
 
         /**
+         * Interval in milliseconds after which a failed provisioning request should be retried.
+         */
+        public static final String VENDING_CARRIER_PROVISIONING_RETRY_MS =
+            "vending_carrier_prov_retry_ms";
+
+        /**
+         * Buffer in milliseconds for carrier credentials to be considered valid.
+         */
+        public static final String VENDING_CARRIER_CREDENTIALS_BUFFER_MS =
+            "vending_carrier_cred_buf_ms";
+
+        /**
+         * Setting which states if German Direct Debit support should be enabled.
+         */
+        public static final String VENDING_GDD_ENABLE =
+            "vending_gdd_enable";
+
+        /**
          * URL that points to the legal terms of service to display in Settings.
          * <p>
          * This should be a https URL. For a pretty user-friendly URL, use
@@ -3581,6 +3598,14 @@
                 "search_per_source_concurrent_query_limit";
 
         /**
+         * Flag for allowing ActivityManagerService to send ACTION_APP_ERROR intents
+         * on application crashes and ANRs. If this is disabled, the crash/ANR dialog
+         * will never display the "Report" button.
+         * Type: int ( 0 = disallow, 1 = allow )
+         */
+        public static final String SEND_ACTION_APP_ERROR = "send_action_app_error";
+
+        /**
          * @deprecated
          * @hide
          */
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index ba53307..34921f4 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -266,8 +266,8 @@
         }
         String name = propValues[0];
         if (name.equals("Name")) {
-            Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED);
-            intent.putExtra(BluetoothDevice.EXTRA_NAME, propValues[1]);
+            Intent intent = new Intent(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+            intent.putExtra(BluetoothAdapter.EXTRA_LOCAL_NAME, propValues[1]);
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
             mBluetoothService.setProperty(name, propValues[1]);
         } else if (name.equals("Pairable") || name.equals("Discoverable")) {
@@ -330,6 +330,9 @@
             Log.e(TAG, "onDevicePropertyChanged: Address of the remote device in null");
             return;
         }
+        if (DBG) {
+            log("Device property changed:" + address + "property:" + name);
+        }
         BluetoothDevice device = mAdapter.getRemoteDevice(address);
         if (name.equals("Name")) {
             Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED);
@@ -366,6 +369,7 @@
                 uuid = str.toString();
             }
             mBluetoothService.setRemoteDeviceProperty(address, name, uuid);
+            mBluetoothService.sendUuidIntent(address);
         } else if (name.equals("Paired")) {
             if (propValues[1].equals("true")) {
                 mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
@@ -453,8 +457,9 @@
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
 
-        if (mBluetoothService.getBondState().getBondState(address) ==
-                BluetoothDevice.BOND_BONDING) {
+        String pendingOutgoingAddress =
+                mBluetoothService.getBondState().getPendingOutgoingBonding();
+        if (address.equals(pendingOutgoingAddress)) {
             // we initiated the bonding
             BluetoothClass btClass = new BluetoothClass(mBluetoothService.getRemoteClass(address));
 
@@ -528,6 +533,25 @@
         return;
     }
 
+    private void onDiscoverServicesResult(String deviceObjectPath, boolean result) {
+        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
+        // We don't parse the xml here, instead just query Bluez for the properties.
+        if (result) {
+            String[] properties = mBluetoothService.getRemoteDeviceProperties(address);
+            mBluetoothService.addRemoteDeviceProperties(address, properties);
+        }
+        mBluetoothService.sendUuidIntent(address);
+    }
+
+    private void onCreateDeviceResult(String address, boolean result) {
+        if (DBG) {
+            log("Result of onCreateDeviceResult:" + result);
+        }
+        if (!result) {
+            mBluetoothService.sendUuidIntent(address);
+        }
+    }
+
     private void onRestartRequired() {
         if (mBluetoothService.isEnabled()) {
             Log.e(TAG, "*** A serious error occured (did bluetoothd crash?) - " +
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index c0e4f34..26007c5 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -76,10 +76,17 @@
 
     private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
     private static final int MESSAGE_FINISH_DISABLE = 2;
+    private static final int MESSAGE_UUID_INTENT = 3;
+
+    // The timeout used to sent the UUIDs Intent
+    // This timeout should be greater than the page timeout
+    private static final int UUID_INTENT_DELAY = 6000;
 
     private final Map<String, String> mAdapterProperties;
     private final HashMap <String, Map<String, String>> mDeviceProperties;
 
+    private final ArrayList <String> mUuidIntentTracker;
+
     static {
         classInitNative();
     }
@@ -104,6 +111,7 @@
         mIsDiscovering = false;
         mAdapterProperties = new HashMap<String, String>();
         mDeviceProperties = new HashMap<String, Map<String,String>>();
+        mUuidIntentTracker = new ArrayList<String>();
         registerForAirplaneMode();
     }
 
@@ -291,6 +299,11 @@
             case MESSAGE_FINISH_DISABLE:
                 finishDisable(msg.arg1 != 0);
                 break;
+            case MESSAGE_UUID_INTENT:
+                String address = (String)msg.obj;
+                if (address != null)
+                    sendUuidIntent(address);
+                break;
             }
         }
     };
@@ -414,6 +427,18 @@
                 new ArrayList<String>(Arrays.asList(
                         "Motorola IHF1000", "i.TechBlueBAND", "X5 Stereo v1.3"));
 
+        // 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;
@@ -444,6 +469,15 @@
             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 (DBG) log(address + " bond state " + oldState + " -> " + state + " (" +
                          reason + ")");
             Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
@@ -766,8 +800,7 @@
         }
         address = address.toUpperCase();
 
-        String[] bonding = mBondState.listInState(BluetoothDevice.BOND_BONDING);
-        if (bonding.length > 0 && !bonding[0].equals(address)) {
+        if (mBondState.getPendingOutgoingBonding() != null) {
             log("Ignoring createBond(): another device is bonding");
             // a different device is currently bonding, fail
             return false;
@@ -785,7 +818,9 @@
             return false;
         }
 
+        mBondState.setPendingOutgoingBonding(address);
         mBondState.setBondState(address, BluetoothDevice.BOND_BONDING);
+
         return true;
     }
 
@@ -976,6 +1011,10 @@
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return null;
         }
+        return getUuidFromCache(address);
+    }
+
+    private ParcelUuid[] getUuidFromCache(String address) {
         String value = getRemoteDeviceProperty(address, "UUIDs");
         if (value == null) return null;
 
@@ -990,6 +1029,36 @@
         return uuids;
     }
 
+    public synchronized boolean fetchRemoteUuidsWithSdp(String address) {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+            return false;
+        }
+
+        if (mUuidIntentTracker.contains(address)) {
+            // An SDP query for this address is already in progress
+            return true;
+        }
+
+        boolean ret;
+        if (getBondState(address) == BluetoothDevice.BOND_BONDED) {
+            String path = getObjectPathFromAddress(address);
+            if (path == null) return false;
+
+            // Use an empty string for the UUID pattern
+            ret = discoverServicesNative(path, "");
+        } else {
+            ret = createDeviceNative(address);
+        }
+
+        mUuidIntentTracker.add(address);
+
+        Message message = mHandler.obtainMessage(MESSAGE_UUID_INTENT);
+        message.obj = address;
+        mHandler.sendMessageDelayed(message, UUID_INTENT_DELAY);
+        return ret;
+    }
+
     /**
      * Gets the rfcomm channel associated with the UUID.
      *
@@ -1121,6 +1190,17 @@
                 Settings.System.AIRPLANE_MODE_ON, 0) == 1;
     }
 
+    /* Broadcast the Uuid intent */
+    /*package*/ synchronized void sendUuidIntent(String address) {
+        ParcelUuid[] uuid = getUuidFromCache(address);
+        Intent intent = new Intent(BluetoothDevice.ACTION_UUID);
+        intent.putExtra(BluetoothDevice.EXTRA_UUID, uuid);
+        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+
+        if (mUuidIntentTracker.contains(address))
+            mUuidIntentTracker.remove(address);
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("\nmIsAirplaneSensitive = " + mIsAirplaneSensitive + "\n");
@@ -1284,4 +1364,6 @@
     private native boolean setPairingConfirmationNative(String address, boolean confirm,
             int nativeData);
     private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value);
+    private native boolean createDeviceNative(String address);
+    private native boolean discoverServicesNative(String objectPath, String pattern);
 }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index cd5cf10..da8d62c0 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -321,7 +321,7 @@
          * Called as the user performs touch-screen interaction with the
          * window that is currently showing this wallpaper.  Note that the
          * events you receive here are driven by the actual application the
-         * user is interacting with, so if it is slow you will get viewer
+         * user is interacting with, so if it is slow you will get fewer
          * move events.
          */
         public void onTouchEvent(MotionEvent event) {
diff --git a/core/java/android/speech/IRecognitionListener.aidl b/core/java/android/speech/IRecognitionListener.aidl
new file mode 100644
index 0000000..2da2258
--- /dev/null
+++ b/core/java/android/speech/IRecognitionListener.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 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.speech;
+
+import android.os.Bundle;
+import android.speech.RecognitionResult;
+
+/**
+ * Listener for speech recognition events, used with RecognitionService.
+ *  This gives you both the final recognition results, as well as various
+ *  intermediate events that can be used to show visual feedback to the user.
+ *  {@hide}
+ */
+interface IRecognitionListener {
+    /** Called when the endpointer is ready for the user to start speaking. */
+    void onReadyForSpeech(in Bundle noiseParams);
+
+    /** The user has started to speak. */
+    void onBeginningOfSpeech();
+
+    /** The sound level in the audio stream has changed. */
+    void onRmsChanged(in float rmsdB);
+
+    /**
+     * More sound has been received. Buffer is a byte buffer containing
+     * a sequence of 16-bit shorts. 
+     */
+    void onBufferReceived(in byte[] buffer);
+
+    /** Called after the user stops speaking. */
+    void onEndOfSpeech();
+
+    /**
+     * A network or recognition error occurred. The code is defined in
+     * {@link android.speech.RecognitionResult}
+     */
+    void onError(in int error);
+
+    /** 
+     * Called when recognition results are ready.
+     * @param results: an ordered list of the most likely results (N-best list).
+     * @param key: a key associated with the results. The same results can
+     * be retrieved asynchronously later using the key, if available. 
+     */
+    void onResults(in List<RecognitionResult> results, long key);
+}
diff --git a/core/java/android/speech/IRecognitionService.aidl b/core/java/android/speech/IRecognitionService.aidl
new file mode 100644
index 0000000..a18c380
--- /dev/null
+++ b/core/java/android/speech/IRecognitionService.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 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.speech;
+
+import android.content.Intent;
+import android.speech.IRecognitionListener;
+import android.speech.RecognitionResult;
+
+// A Service interface to speech recognition. Call startListening when
+// you want to begin capturing audio; RecognitionService will automatically
+// determine when the user has finished speaking, stream the audio to the
+// recognition servers, and notify you when results are ready.
+/** {@hide} */
+interface IRecognitionService {
+    // Start listening for speech. Can only call this from one thread at once.
+    // see RecognizerIntent.java for constants used to specify the intent.
+    void startListening(in Intent recognizerIntent,
+        in IRecognitionListener listener);
+        
+    List<RecognitionResult> getRecognitionResults(in long key);
+
+    void cancel();
+}
diff --git a/core/java/android/speech/RecognitionResult.aidl b/core/java/android/speech/RecognitionResult.aidl
new file mode 100644
index 0000000..59e53ab
--- /dev/null
+++ b/core/java/android/speech/RecognitionResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2009 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.speech;
+
+parcelable RecognitionResult;
diff --git a/core/java/android/speech/RecognitionResult.java b/core/java/android/speech/RecognitionResult.java
new file mode 100644
index 0000000..95715ee
--- /dev/null
+++ b/core/java/android/speech/RecognitionResult.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2009 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.speech;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * RecognitionResult is a passive object that stores a single recognized query
+ * and its search result.
+ * 
+ * TODO: Revisit and improve this class, reconciling the different types of actions and
+ * the different ways they are represented. Maybe we should have a separate result object
+ * for each type, and put them (type/value) in bundle?
+ * {@hide}
+ */
+public class RecognitionResult implements Parcelable {
+    /**
+     * Status of the recognize request.
+     */
+    public static final int NETWORK_TIMEOUT = 1; // Network operation timed out.
+
+    public static final int NETWORK_ERROR = 2; // Other network related errors.
+
+    public static final int AUDIO_ERROR = 3; // Audio recording error.
+
+    public static final int SERVER_ERROR = 4; // Server sends error status.
+
+    public static final int CLIENT_ERROR = 5; // Other client side errors.
+
+    public static final int SPEECH_TIMEOUT = 6; // No speech input
+
+    public static final int NO_MATCH = 7; // No recognition result matched.
+
+    public static final int SERVICE_BUSY = 8; // RecognitionService busy.
+
+    /**
+     * Type of the recognition results.
+     */
+    public static final int RAW_RECOGNITION_RESULT = 0;
+
+    public static final int WEB_SEARCH_RESULT = 1;
+
+    public static final int CONTACT_RESULT = 2;
+    
+    public static final int ACTION_RESULT = 3;
+
+    /**
+     * A factory method to create a raw RecognitionResult
+     * 
+     * @param sentence the recognized text.
+     */
+    public static RecognitionResult newRawRecognitionResult(String sentence) {
+        return new RecognitionResult(RAW_RECOGNITION_RESULT, sentence, null, null);
+    }
+
+    /**
+     * A factory method to create a RecognitionResult for contacts.
+     * 
+     * @param contact the contact name.
+     * @param phoneType the phone type.
+     * @param callAction whether this result included a command to "call", or
+     *            just the contact name.
+     */
+    public static RecognitionResult newContactResult(String contact, int phoneType,
+            boolean callAction) {
+        return new RecognitionResult(CONTACT_RESULT, contact, phoneType, callAction);
+    }
+
+    /**
+     * A factory method to create a RecognitionResult for a web search query.
+     * 
+     * @param query the query string.
+     * @param html the html page of the search result.
+     * @param url the url that performs the search with the query.
+     */
+    public static RecognitionResult newWebResult(String query, String html, String url) {
+        return new RecognitionResult(WEB_SEARCH_RESULT, query, html, url);
+    }
+    
+    /**
+     * A factory method to create a RecognitionResult for an action.
+     * 
+     * @param action the action type
+     * @param query the query string associated with that action.
+     */
+    public static RecognitionResult newActionResult(int action, String query) {
+        return new RecognitionResult(ACTION_RESULT, action, query);
+    }
+
+    public static final Parcelable.Creator<RecognitionResult> CREATOR =
+            new Parcelable.Creator<RecognitionResult>() {
+
+                public RecognitionResult createFromParcel(Parcel in) {
+                    return new RecognitionResult(in);
+                }
+        
+                public RecognitionResult[] newArray(int size) {
+                    return new RecognitionResult[size];
+                }
+            };
+
+    /**
+     * Result type.
+     */
+    public final int mResultType;
+
+    /**
+     * The recognized string when mResultType is WEB_SEARCH_RESULT. The name of
+     * the contact when mResultType is CONTACT_RESULT. The relevant query when
+     * mResultType is ACTION_RESULT.
+     */
+    public final String mText;
+
+    /**
+     * The HTML result page for the query. If this is null, then the application
+     * must use the url field to get the HTML result page.
+     */
+    public final String mHtml;
+
+    /**
+     * The url to get the result page for the query string. The application must
+     * use this url instead of performing the search with the query.
+     */
+    public final String mUrl;
+
+    /**
+     * Phone number type. This is valid only when mResultType == CONTACT_RESULT.
+     */
+    public final int mPhoneType;
+    
+    /**
+     * Action type.  This is valid only when mResultType == ACTION_RESULT.
+     */
+    public final int mAction;
+
+    /**
+     * Whether a contact recognition result included a command to "call". This
+     * is valid only when mResultType == CONTACT_RESULT.
+     */
+    public final boolean mCallAction;
+
+    private RecognitionResult(int type, int action, String query) {
+        mResultType = type;
+        mAction = action;
+        mText = query;
+        mHtml = null;
+        mUrl = null;
+        mPhoneType = -1;
+        mCallAction = false;
+    }
+    
+    private RecognitionResult(int type, String query, String html, String url) {
+        mResultType = type;
+        mText = query;
+        mHtml = html;
+        mUrl = url;
+        mPhoneType = -1;
+        mAction = -1;
+        mCallAction = false;
+    }
+
+    private RecognitionResult(int type, String query, int phoneType, boolean callAction) {
+        mResultType = type;
+        mText = query;
+        mPhoneType = phoneType;
+        mHtml = null;
+        mUrl = null;
+        mAction = -1;
+        mCallAction = callAction;
+    }
+
+    private RecognitionResult(Parcel in) {
+        mResultType = in.readInt();
+        mText = in.readString();
+        mHtml = in.readString();
+        mUrl = in.readString();
+        mPhoneType = in.readInt();
+        mAction = in.readInt();
+        mCallAction = (in.readInt() == 1);
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mResultType);
+        out.writeString(mText);
+        out.writeString(mHtml);
+        out.writeString(mUrl);
+        out.writeInt(mPhoneType);
+        out.writeInt(mAction);
+        out.writeInt(mCallAction ? 1 : 0);
+    }
+
+    @Override
+    public String toString() {
+        String resultType[] = {
+                "RAW", "WEB", "CONTACT", "ACTION"
+        };
+        return "[type=" + resultType[mResultType] + ", text=" + mText + ", mUrl=" + mUrl
+                + ", html=" + mHtml + ", mAction=" + mAction + ", mCallAction=" + mCallAction + "]";
+    }
+
+    public int describeContents() {
+        // no special description
+        return 0;
+    }
+}
diff --git a/core/java/android/speech/RecognitionServiceUtil.java b/core/java/android/speech/RecognitionServiceUtil.java
new file mode 100644
index 0000000..4207543
--- /dev/null
+++ b/core/java/android/speech/RecognitionServiceUtil.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2009 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.speech;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.speech.RecognitionResult;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Utils for Google's network-based speech recognizer, which lets you perform
+ * speech-to-text translation through RecognitionService. IRecognitionService
+ * and IRecognitionListener are the core interfaces; you begin recognition
+ * through IRecognitionService and subscribe to callbacks about when the user
+ * stopped speaking, results come in, errors, etc. through IRecognitionListener.
+ * RecognitionServiceUtil includes default IRecognitionListener and
+ * ServiceConnection implementations to reduce the amount of boilerplate.
+ *
+ * The Service provides no user interface. See RecognitionActivity if you
+ * want the standard voice search UI.
+ *
+ * Below is a small skeleton of how to use the recognizer:
+ *
+ * ServiceConnection conn = new RecognitionServiceUtil.Connection();
+ * mContext.bindService(RecognitionServiceUtil.sDefaultIntent,
+ *     conn, Context.BIND_AUTO_CREATE);
+ * IRecognitionListener listener = new RecognitionServiceWrapper.NullListener() {
+ *         public void onResults(List<String> results) {
+ *             // Do something with recognition transcripts
+ *         }
+ *     }
+ *
+ * // Must wait for conn.mService to be populated, then call below
+ * conn.mService.startListening(null, listener);
+ *
+ * {@hide}
+ */
+public class RecognitionServiceUtil {
+    public static final Intent sDefaultIntent = new Intent(
+            RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+
+    // Recognize request parameters
+    public static final String USE_LOCATION = "useLocation";
+    public static final String CONTACT_AUTH_TOKEN = "contactAuthToken";
+    
+    // Bundles
+    public static final String NOISE_LEVEL = "NoiseLevel";
+    public static final String SIGNAL_NOISE_RATIO = "SignalNoiseRatio";
+
+    private RecognitionServiceUtil() {}
+
+    /**
+     * IRecognitionListener which does nothing in response to recognition
+     * callbacks. You can subclass from this and override only the methods
+     * whose events you want to respond to.
+     */
+    public static class NullListener extends IRecognitionListener.Stub {
+        public void onReadyForSpeech(Bundle bundle) {}
+        public void onBeginningOfSpeech() {}
+        public void onRmsChanged(float rmsdB) {}
+        public void onBufferReceived(byte[] buf) {}
+        public void onEndOfSpeech() {}
+        public void onError(int error) {}
+        public void onResults(List<RecognitionResult> results, long key) {}
+    }
+
+    /**
+     * Basic ServiceConnection which just records mService variable.
+     */
+    public static class Connection implements ServiceConnection {
+        public IRecognitionService mService;
+
+        public synchronized void onServiceConnected(ComponentName name, IBinder service) {
+            mService = IRecognitionService.Stub.asInterface(service);
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+            mService = null;
+        }
+    }
+}
diff --git a/core/java/android/text/InputType.java b/core/java/android/text/InputType.java
index d50684a..14b8308 100644
--- a/core/java/android/text/InputType.java
+++ b/core/java/android/text/InputType.java
@@ -128,6 +128,15 @@
      */
     public static final int TYPE_TEXT_FLAG_IME_MULTI_LINE = 0x00040000;
     
+    /**
+     * Flag for {@link #TYPE_CLASS_TEXT}: the input method does not need to
+     * display any dictionary-based candidates. This is useful for text views that
+     * do not contain words from the language and do not benefit from any
+     * dictionary-based completions or corrections. It overrides the
+     * {@link #TYPE_TEXT_FLAG_AUTO_CORRECT} value when set.
+     */
+    public static final int TYPE_TEXT_FLAG_NO_SUGGESTIONS = 0x00080000;
+
     // ----------------------------------------------------------------------
     
     /**
diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java
index 38881d3..f736f85 100644
--- a/core/java/android/text/method/QwertyKeyListener.java
+++ b/core/java/android/text/method/QwertyKeyListener.java
@@ -431,6 +431,7 @@
         PICKER_SETS.put('z', "\u017A\u017C\u017E");
         PICKER_SETS.put(KeyCharacterMap.PICKER_DIALOG_INPUT,
                              "\u2026\u00A5\u2022\u00AE\u00A9\u00B1[]{}\\");
+        PICKER_SETS.put('/', "\\");
 
         // From packages/inputmethods/LatinIME/res/xml/kbd_symbols.xml
 
diff --git a/core/java/android/text/util/Rfc822InputFilter.java b/core/java/android/text/util/Rfc822InputFilter.java
new file mode 100644
index 0000000..8c8b7fc
--- /dev/null
+++ b/core/java/android/text/util/Rfc822InputFilter.java
@@ -0,0 +1,58 @@
+package android.text.util;
+
+import android.text.InputFilter;
+import android.text.Spanned;
+import android.text.SpannableStringBuilder;
+
+/**
+ * Implements special address cleanup rules:
+ * The first space key entry following an "@" symbol that is followed by any combination
+ * of letters and symbols, including one+ dots and zero commas, should insert an extra
+ * comma (followed by the space).
+ *
+ * @hide
+ */
+public class Rfc822InputFilter implements InputFilter {
+
+    public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
+        int dstart, int dend) {
+
+        // quick check - did they enter a single space?
+        if (end-start != 1 || source.charAt(start) != ' ') {
+            return null;
+        }
+
+        // determine if the characters before the new space fit the pattern
+        // follow backwards and see if we find a comma, dot, or @
+        int scanBack = dstart;
+        boolean dotFound = false;
+        while (scanBack > 0) {
+            char c = dest.charAt(--scanBack);
+            switch (c) {
+                case '.':
+                    dotFound = true;    // one or more dots are req'd
+                    break;
+                case ',':
+                    return null;
+                case '@':
+                    if (!dotFound) {
+                        return null;
+                    }
+                    // we have found a comma-insert case.  now just do it
+                    // in the least expensive way we can.
+                    if (source instanceof Spanned) {
+                        SpannableStringBuilder sb = new SpannableStringBuilder(",");
+                        sb.append(source);
+                        return sb;
+                    } else {
+                        return ", ";
+                    }
+                default:
+                    // just keep going
+            }
+        }
+
+        // no termination cases were found, so don't edit the input
+        return null;
+    }
+}
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 94acd3f..e5985c1 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -458,11 +458,12 @@
     public final View createView(String name, String prefix, AttributeSet attrs)
             throws ClassNotFoundException, InflateException {
         Constructor constructor = sConstructorMap.get(name);
+        Class clazz = null;
 
         try {
             if (constructor == null) {
                 // Class not found in the cache, see if it's real, and try to add it
-                Class clazz = mContext.getClassLoader().loadClass(
+                clazz = mContext.getClassLoader().loadClass(
                         prefix != null ? (prefix + name) : name);
                 
                 if (mFilter != null && clazz != null) {
@@ -480,7 +481,7 @@
                     Boolean allowedState = mFilterMap.get(name);
                     if (allowedState == null) {
                         // New class -- remember whether it is allowed
-                        Class clazz = mContext.getClassLoader().loadClass(
+                        clazz = mContext.getClassLoader().loadClass(
                                 prefix != null ? (prefix + name) : name);
                         
                         boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
@@ -511,7 +512,7 @@
         } catch (Exception e) {
             InflateException ie = new InflateException(attrs.getPositionDescription()
                     + ": Error inflating class "
-                    + (constructor == null ? "<unknown>" : constructor.getClass().getName()));
+                    + (clazz == null ? "<unknown>" : clazz.getName()));
             ie.initCause(e);
             throw ie;
         }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index c40107b..45ff27e 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -361,8 +361,6 @@
     public final int OFF_BECAUSE_OF_USER = 1;
     /** Screen turned off because of timeout */
     public final int OFF_BECAUSE_OF_TIMEOUT = 2;
-    /** Screen turned off because of proximity sensor */
-    public final int OFF_BECAUSE_OF_PROXIMITY_SENSOR = 3;
 
     /**
      * Magic constant to {@link IWindowManager#setRotation} to not actually
@@ -438,6 +436,12 @@
     public int subWindowTypeToLayerLw(int type);
 
     /**
+     * Get the highest layer (actually one more than) that the wallpaper is
+     * allowed to be in.
+     */
+    public int getMaxWallpaperLayer();
+    
+    /**
      * Called when the system would like to show a UI to indicate that an
      * application is starting.  You can use this to add a
      * APPLICATION_STARTING_TYPE window with the given appToken to the window
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 465eef8..dbddb2e 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -103,7 +103,7 @@
         // Create a global JWebCoreJavaBridge to handle timers and
         // cookies in the WebCore thread.
         if (sJavaBridge == null) {
-            sJavaBridge = new JWebCoreJavaBridge();
+            sJavaBridge = new JWebCoreJavaBridge(context);
             // set WebCore native cache size
             sJavaBridge.setCacheSize(4 * 1024 * 1024);
             // initialize CacheManager
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index e504591..b051675 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -65,7 +65,8 @@
     // Keep track of multiple progress updates.
     private boolean mProgressUpdatePending;
     // Keep track of the last progress amount.
-    private volatile int mLatestProgress;
+    // Start with 100 to indicate it is not in load for the empty page.
+    private volatile int mLatestProgress = 100;
     // Back/Forward list
     private final WebBackForwardList mBackForwardList;
     // Used to call startActivity during url override.
diff --git a/core/java/android/webkit/CertTool.java b/core/java/android/webkit/CertTool.java
new file mode 100644
index 0000000..99757d2
--- /dev/null
+++ b/core/java/android/webkit/CertTool.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2009 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.webkit;
+
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.jce.netscape.NetscapeCertRequest;
+import org.bouncycastle.util.encoders.Base64;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.security.Credentials;
+import android.util.Log;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+
+class CertTool {
+    private static final String LOGTAG = "CertTool";
+
+    private static final AlgorithmIdentifier MD5_WITH_RSA =
+            new AlgorithmIdentifier(PKCSObjectIdentifiers.md5WithRSAEncryption);
+
+    static final String CERT = Credentials.CERTIFICATE;
+    static final String PKCS12 = Credentials.PKCS12;
+
+    static String[] getKeyStrengthList() {
+        return new String[] {"High Grade", "Medium Grade"};
+    }
+
+    static String getSignedPublicKey(Context context, int index, String challenge) {
+        try {
+            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
+            generator.initialize((index == 0) ? 2048 : 1024);
+            KeyPair pair = generator.genKeyPair();
+
+            NetscapeCertRequest request = new NetscapeCertRequest(challenge,
+                    MD5_WITH_RSA, pair.getPublic());
+            request.sign(pair.getPrivate());
+            byte[] signed = request.toASN1Object().getDEREncoded();
+
+            Credentials.getInstance().install(context, pair);
+            return new String(Base64.encode(signed));
+        } catch (Exception e) {
+            Log.w(LOGTAG, e);
+        }
+        return null;
+    }
+
+    static void addCertificate(Context context, String type, byte[] value) {
+        Credentials.getInstance().install(context, type, value);
+    }
+
+    private CertTool() {}
+}
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 5a164f8..8b783e8 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -17,8 +17,18 @@
 package android.webkit;
 
 import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.media.MediaPlayer;
 import android.media.MediaPlayer.OnPreparedListener;
+import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaPlayer.OnErrorListener;
+import android.net.http.EventHandler;
+import android.net.http.Headers;
+import android.net.http.RequestHandle;
+import android.net.http.RequestQueue;
+import android.net.http.SslCertificate;
+import android.net.http.SslError;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -26,186 +36,435 @@
 import android.os.Message;
 import android.util.Log;
 import android.view.MotionEvent;
+import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.webkit.ViewManager.ChildView;
 import android.widget.AbsoluteLayout;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
 import android.widget.MediaController;
 import android.widget.VideoView;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.util.HashMap;
+import java.util.Map;
 
 /**
  * <p>Proxy for HTML5 video views.
  */
-class HTML5VideoViewProxy extends Handler {
+class HTML5VideoViewProxy extends Handler
+                          implements MediaPlayer.OnPreparedListener,
+                          MediaPlayer.OnCompletionListener {
     // Logging tag.
     private static final String LOGTAG = "HTML5VideoViewProxy";
 
     // Message Ids for WebCore thread -> UI thread communication.
     private static final int INIT              = 100;
     private static final int PLAY              = 101;
+    private static final int SET_POSTER        = 102;
+    private static final int SEEK              = 103;
+    private static final int PAUSE             = 104;
 
+    // Message Ids to be handled on the WebCore thread
+    private static final int PREPARED          = 200;
+    private static final int ENDED             = 201;
+
+    // The C++ MediaPlayerPrivateAndroid object.
+    int mNativePointer;
+    // The handler for WebCore thread messages;
+    private Handler mWebCoreHandler;
     // The WebView instance that created this view.
     private WebView mWebView;
     // The ChildView instance used by the ViewManager.
     private ChildView mChildView;
-    // The VideoView instance. Note that we could
-    // also access this via mChildView.mView but it would
-    // always require cast, so it is more convenient to store
-    // it here as well.
-    private HTML5VideoView mVideoView;
+    // The poster image to be shown when the video is not playing.
+    private ImageView mPosterView;
+    // The poster downloader.
+    private PosterDownloader mPosterDownloader;
+    // The seek position.
+    private int mSeekPosition;
+    // A helper class to control the playback. This executes on the UI thread!
+    private static final class VideoPlayer {
+        // The proxy that is currently playing (if any).
+        private static HTML5VideoViewProxy mCurrentProxy;
+        // The VideoView instance. This is a singleton for now, at least until
+        // http://b/issue?id=1973663 is fixed.
+        private static VideoView mVideoView;
+        // The progress view.
+        private static View mProgressView;
+        // The container for the progress view and video view
+        private static FrameLayout mLayout;
 
-    // A VideoView subclass that responds to double-tap
-    // events by going fullscreen.
-    class HTML5VideoView extends VideoView {
-        // Used to save the layout parameters if the view
-        // is changed to fullscreen.
-        private AbsoluteLayout.LayoutParams mEmbeddedLayoutParams;
-        // Flag that denotes whether the view is fullscreen or not.
-        private boolean mIsFullscreen;
-        // Used to save the current playback position when
-        // transitioning to/from fullscreen.
-        private int mPlaybackPosition;
-        // The callback object passed to the host application. This callback
-        // is invoked when the host application dismisses our VideoView
-        // (e.g. the user presses the back key).
-        private WebChromeClient.CustomViewCallback mCallback =
-                new WebChromeClient.CustomViewCallback() {
-            public void onCustomViewHidden() {
-                playEmbedded();
-            }
-        };
+        private static final WebChromeClient.CustomViewCallback mCallback =
+            new WebChromeClient.CustomViewCallback() {
+                public void onCustomViewHidden() {
+                    // At this point the videoview is pretty much destroyed.
+                    // It listens to SurfaceHolder.Callback.SurfaceDestroyed event
+                    // which happens when the video view is detached from its parent
+                    // view. This happens in the WebChromeClient before this method
+                    // is invoked.
+                    mCurrentProxy.playbackEnded();
+                    mCurrentProxy = null;
+                    mLayout.removeView(mVideoView);
+                    mVideoView = null;
+                    if (mProgressView != null) {
+                        mLayout.removeView(mProgressView);
+                        mProgressView = null;
+                    }
+                    mLayout = null;
+                }
+            };
 
-        // The OnPreparedListener, used to automatically resume
-        // playback when transitioning to/from fullscreen.
-        private MediaPlayer.OnPreparedListener mPreparedListener =
-                new MediaPlayer.OnPreparedListener() {
-            public void onPrepared(MediaPlayer mp) {
-                resumePlayback();
-            }
-        };
-
-        HTML5VideoView(Context context) {
-            super(context);
-        }
-
-        void savePlaybackPosition() {
-            if (isPlaying()) {
-                mPlaybackPosition = getCurrentPosition();
-            }
-        }
-
-        void resumePlayback() {
-            seekTo(mPlaybackPosition);
-            start();
-            setOnPreparedListener(null);
-        }
-
-        void playEmbedded() {
-            // Attach to the WebView.
-            mChildView.attachViewOnUIThread(mEmbeddedLayoutParams);
-            // Make sure we're visible
-            setVisibility(View.VISIBLE);
-            // Set the onPrepared listener so we start
-            // playing when the video view is reattached
-            // and its surface is recreated.
-            setOnPreparedListener(mPreparedListener);
-            mIsFullscreen = false;
-        }
-
-        void playFullScreen() {
-            WebChromeClient client = mWebView.getWebChromeClient();
-            if (client == null) {
+        public static void play(String url, int time, HTML5VideoViewProxy proxy,
+                WebChromeClient client) {
+            if (mCurrentProxy != null) {
+                // Some other video is already playing. Notify the caller that its playback ended.
+                proxy.playbackEnded();
                 return;
             }
-            // Save the current layout params.
-            mEmbeddedLayoutParams =
-                    (AbsoluteLayout.LayoutParams) getLayoutParams();
-            // Detach from the WebView.
-            mChildView.removeViewOnUIThread();
-            // Attach to the browser UI.
-            client.onShowCustomView(this, mCallback);
-            // Set the onPrepared listener so we start
-            // playing when after the video view is reattached
-            // and its surface is recreated.
-            setOnPreparedListener(mPreparedListener);
-            mIsFullscreen = true;
-        }
-
-        @Override
-        public boolean onTouchEvent(MotionEvent ev) {
-            // TODO: implement properly (i.e. detect double tap)
-            if (mIsFullscreen || !isPlaying()) {
-                return super.onTouchEvent(ev);
+            mCurrentProxy = proxy;
+            // Create a FrameLayout that will contain the VideoView and the
+            // progress view (if any).
+            mLayout = new FrameLayout(proxy.getContext());
+            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
+                    ViewGroup.LayoutParams.WRAP_CONTENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT,
+                    Gravity.CENTER);
+            mVideoView = new VideoView(proxy.getContext());
+            mVideoView.setWillNotDraw(false);
+            mVideoView.setMediaController(new MediaController(proxy.getContext()));
+            mVideoView.setVideoURI(Uri.parse(url));
+            mVideoView.setOnCompletionListener(proxy);
+            mVideoView.setOnPreparedListener(proxy);
+            mVideoView.seekTo(time);
+            mLayout.addView(mVideoView, layoutParams);
+            mProgressView = client.getVideoLoadingProgressView();
+            if (mProgressView != null) {
+                mLayout.addView(mProgressView, layoutParams);
+                mProgressView.setVisibility(View.VISIBLE);
             }
-            playFullScreen();
-            return true;
+            mLayout.setVisibility(View.VISIBLE);
+            mVideoView.start();
+            client.onShowCustomView(mLayout, mCallback);
         }
 
-        @Override
-        public void onDetachedFromWindow() {
-            super.onDetachedFromWindow();
-            savePlaybackPosition();
+        public static void seek(int time, HTML5VideoViewProxy proxy) {
+            if (mCurrentProxy == proxy && time >= 0 && mVideoView != null) {
+                mVideoView.seekTo(time);
+            }
+        }
+
+        public static void pause(HTML5VideoViewProxy proxy) {
+            if (mCurrentProxy == proxy && mVideoView != null) {
+                mVideoView.pause();
+            }
+        }
+
+        public static void onPrepared() {
+            if (mProgressView != null) {
+                mProgressView.setVisibility(View.GONE);
+                mLayout.removeView(mProgressView);
+                mProgressView = null;
+            }
+        }
+    }
+
+    // A bunch event listeners for our VideoView
+    // MediaPlayer.OnPreparedListener
+    public void onPrepared(MediaPlayer mp) {
+        VideoPlayer.onPrepared();
+        Message msg = Message.obtain(mWebCoreHandler, PREPARED);
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("dur", new Integer(mp.getDuration()));
+        map.put("width", new Integer(mp.getVideoWidth()));
+        map.put("height", new Integer(mp.getVideoHeight()));
+        msg.obj = map;
+        mWebCoreHandler.sendMessage(msg);
+    }
+
+    // MediaPlayer.OnCompletionListener;
+    public void onCompletion(MediaPlayer mp) {
+        playbackEnded();
+    }
+
+    public void playbackEnded() {
+        Message msg = Message.obtain(mWebCoreHandler, ENDED);
+        mWebCoreHandler.sendMessage(msg);
+    }
+
+    // Handler for the messages from WebCore thread to the UI thread.
+    @Override
+    public void handleMessage(Message msg) {
+        // This executes on the UI thread.
+        switch (msg.what) {
+            case INIT: {
+                mPosterView = new ImageView(mWebView.getContext());
+                WebChromeClient client = mWebView.getWebChromeClient();
+                if (client != null) {
+                    Bitmap poster = client.getDefaultVideoPoster();
+                    if (poster != null) {
+                        mPosterView.setImageBitmap(poster);
+                    }
+                }
+                mChildView.mView = mPosterView;
+                break;
+            }
+            case PLAY: {
+                String url = (String) msg.obj;
+                WebChromeClient client = mWebView.getWebChromeClient();
+                if (client != null) {
+                    VideoPlayer.play(url, mSeekPosition, this, client);
+                }
+                break;
+            }
+            case SET_POSTER: {
+                Bitmap poster = (Bitmap) msg.obj;
+                mPosterView.setImageBitmap(poster);
+                break;
+            }
+            case SEEK: {
+                Integer time = (Integer) msg.obj;
+                mSeekPosition = time;
+                VideoPlayer.seek(mSeekPosition, this);
+                break;
+            }
+            case PAUSE: {
+                VideoPlayer.pause(this);
+                break;
+            }
+        }
+    }
+
+    // Everything below this comment executes on the WebCore thread, except for
+    // the EventHandler methods, which are called on the network thread.
+
+    // A helper class that knows how to download posters
+    private static final class PosterDownloader implements EventHandler {
+        // The request queue. This is static as we have one queue for all posters.
+        private static RequestQueue mRequestQueue;
+        private static int mQueueRefCount = 0;
+        // The poster URL
+        private String mUrl;
+        // The proxy we're doing this for.
+        private final HTML5VideoViewProxy mProxy;
+        // The poster bytes. We only touch this on the network thread.
+        private ByteArrayOutputStream mPosterBytes;
+        // The request handle. We only touch this on the WebCore thread.
+        private RequestHandle mRequestHandle;
+        // The response status code.
+        private int mStatusCode;
+        // The response headers.
+        private Headers mHeaders;
+        // The handler to handle messages on the WebCore thread.
+        private Handler mHandler;
+
+        public PosterDownloader(String url, HTML5VideoViewProxy proxy) {
+            mUrl = url;
+            mProxy = proxy;
+            mHandler = new Handler();
+        }
+        // Start the download. Called on WebCore thread.
+        public void start() {
+            retainQueue();
+            mRequestHandle = mRequestQueue.queueRequest(mUrl, "GET", null, this, null, 0);
+        }
+        // Cancel the download if active and release the queue. Called on WebCore thread.
+        public void cancelAndReleaseQueue() {
+            if (mRequestHandle != null) {
+                mRequestHandle.cancel();
+                mRequestHandle = null;
+            }
+            releaseQueue();
+        }
+        // EventHandler methods. Executed on the network thread.
+        public void status(int major_version,
+                int minor_version,
+                int code,
+                String reason_phrase) {
+            mStatusCode = code;
+        }
+
+        public void headers(Headers headers) {
+            mHeaders = headers;
+        }
+
+        public void data(byte[] data, int len) {
+            if (mPosterBytes == null) {
+                mPosterBytes = new ByteArrayOutputStream();
+            }
+            mPosterBytes.write(data, 0, len);
+        }
+
+        public void endData() {
+            if (mStatusCode == 200) {
+                if (mPosterBytes.size() > 0) {
+                    Bitmap poster = BitmapFactory.decodeByteArray(
+                            mPosterBytes.toByteArray(), 0, mPosterBytes.size());
+                    if (poster != null) {
+                        mProxy.doSetPoster(poster);
+                    }
+                }
+                cleanup();
+            } else if (mStatusCode >= 300 && mStatusCode < 400) {
+                // We have a redirect.
+                mUrl = mHeaders.getLocation();
+                if (mUrl != null) {
+                    mHandler.post(new Runnable() {
+                       public void run() {
+                           if (mRequestHandle != null) {
+                               mRequestHandle.setupRedirect(mUrl, mStatusCode,
+                                       new HashMap<String, String>());
+                           }
+                       }
+                    });
+                }
+            }
+        }
+
+        public void certificate(SslCertificate certificate) {
+            // Don't care.
+        }
+
+        public void error(int id, String description) {
+            cleanup();
+        }
+
+        public boolean handleSslErrorRequest(SslError error) {
+            // Don't care. If this happens, data() will never be called so
+            // mPosterBytes will never be created, so no need to call cleanup.
+            return false;
+        }
+        // Tears down the poster bytes stream. Called on network thread.
+        private void cleanup() {
+            if (mPosterBytes != null) {
+                try {
+                    mPosterBytes.close();
+                } catch (IOException ignored) {
+                    // Ignored.
+                } finally {
+                    mPosterBytes = null;
+                }
+            }
+        }
+
+        // Queue management methods. Called on WebCore thread.
+        private void retainQueue() {
+            if (mRequestQueue == null) {
+                mRequestQueue = new RequestQueue(mProxy.getContext());
+            }
+            mQueueRefCount++;
+        }
+
+        private void releaseQueue() {
+            if (mQueueRefCount == 0) {
+                return;
+            }
+            if (--mQueueRefCount == 0) {
+                mRequestQueue.shutdown();
+                mRequestQueue = null;
+            }
         }
     }
 
     /**
      * Private constructor.
-     * @param context is the application context.
+     * @param webView is the WebView that hosts the video.
+     * @param nativePtr is the C++ pointer to the MediaPlayerPrivate object.
      */
-    private HTML5VideoViewProxy(WebView webView) {
+    private HTML5VideoViewProxy(WebView webView, int nativePtr) {
         // This handler is for the main (UI) thread.
         super(Looper.getMainLooper());
         // Save the WebView object.
         mWebView = webView;
+        // Save the native ptr
+        mNativePointer = nativePtr;
+        // create the message handler for this thread
+        createWebCoreHandler();
     }
 
-    @Override
-    public void handleMessage(Message msg) {
-        // This executes on the UI thread.
-        switch (msg.what) {
-            case INIT:
-                // Create the video view and set a default controller.
-                mVideoView = new HTML5VideoView(mWebView.getContext());
-                // This is needed because otherwise there will be a black square
-                // stuck on the screen.
-                mVideoView.setWillNotDraw(false);
-                mVideoView.setMediaController(new MediaController(mWebView.getContext()));
-                mChildView.mView = mVideoView;
-                break;
-            case PLAY:
-                if (mVideoView == null) {
-                    return;
+    private void createWebCoreHandler() {
+        mWebCoreHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case PREPARED: {
+                        Map<String, Object> map = (Map<String, Object>) msg.obj;
+                        Integer duration = (Integer) map.get("dur");
+                        Integer width = (Integer) map.get("width");
+                        Integer height = (Integer) map.get("height");
+                        nativeOnPrepared(duration.intValue(), width.intValue(),
+                                height.intValue(), mNativePointer);
+                        break;
+                    }
+                    case ENDED:
+                        nativeOnEnded(mNativePointer);
+                        break;
                 }
-                HashMap<String, Object> map =
-                        (HashMap<String, Object>) msg.obj;
-                String url = (String) map.get("url");
-                mVideoView.setVideoURI(Uri.parse(url));
-                mVideoView.start();
-                break;
-        }
+            }
+        };
     }
 
-    /**
-     * Play a video stream.
-     * @param url is the URL of the video stream.
-     * @param webview is the WebViewCore that is requesting the playback.
-     */
-    public void play(String url) {
-         // We need to know the webview that is requesting the playback.
-        Message message = obtainMessage(PLAY);
-        HashMap<String, Object> map = new HashMap();
-        map.put("url", url);
-        message.obj = map;
+    private void doSetPoster(Bitmap poster) {
+        if (poster == null) {
+            return;
+        }
+        // Send the bitmap over to the UI thread.
+        Message message = obtainMessage(SET_POSTER);
+        message.obj = poster;
         sendMessage(message);
     }
 
+    public Context getContext() {
+        return mWebView.getContext();
+    }
+
+    // The public methods below are all called from WebKit only.
+    /**
+     * Play a video stream.
+     * @param url is the URL of the video stream.
+     */
+    public void play(String url) {
+        if (url == null) {
+            return;
+        }
+        Message message = obtainMessage(PLAY);
+        message.obj = url;
+        sendMessage(message);
+    }
+
+    /**
+     * Seek into the video stream.
+     * @param  time is the position in the video stream.
+     */
+    public void seek(int time) {
+        Message message = obtainMessage(SEEK);
+        message.obj = new Integer(time);
+        sendMessage(message);
+    }
+
+    /**
+     * Pause the playback.
+     */
+    public void pause() {
+        Message message = obtainMessage(PAUSE);
+        sendMessage(message);
+    }
+
+    /**
+     * Create the child view that will cary the poster.
+     */
     public void createView() {
         mChildView = mWebView.mViewManager.createView();
         sendMessage(obtainMessage(INIT));
     }
 
+    /**
+     * Attach the poster view.
+     * @param x, y are the screen coordinates where the poster should be hung.
+     * @param width, height denote the size of the poster.
+     */
     public void attachView(int x, int y, int width, int height) {
         if (mChildView == null) {
             return;
@@ -213,11 +472,36 @@
         mChildView.attachView(x, y, width, height);
     }
 
+    /**
+     * Remove the child view and, thus, the poster.
+     */
     public void removeView() {
         if (mChildView == null) {
             return;
         }
         mChildView.removeView();
+        // This is called by the C++ MediaPlayerPrivate dtor.
+        // Cancel any active poster download.
+        if (mPosterDownloader != null) {
+            mPosterDownloader.cancelAndReleaseQueue();
+        }
+    }
+
+    /**
+     * Load the poster image.
+     * @param url is the URL of the poster image.
+     */
+    public void loadPoster(String url) {
+        if (url == null) {
+            return;
+        }
+        // Cancel any active poster download.
+        if (mPosterDownloader != null) {
+            mPosterDownloader.cancelAndReleaseQueue();
+        }
+        // Load the poster asynchronously
+        mPosterDownloader = new PosterDownloader(url, this);
+        mPosterDownloader.start();
     }
 
     /**
@@ -226,7 +510,10 @@
      *
      * @return a new HTML5VideoViewProxy object.
      */
-    public static HTML5VideoViewProxy getInstance(WebViewCore webViewCore) {
-        return new HTML5VideoViewProxy(webViewCore.getWebView());
+    public static HTML5VideoViewProxy getInstance(WebViewCore webViewCore, int nativePtr) {
+        return new HTML5VideoViewProxy(webViewCore.getWebView(), nativePtr);
     }
+
+    private native void nativeOnPrepared(int duration, int width, int height, int nativePointer);
+    private native void nativeOnEnded(int nativePointer);
 }
diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java
index ddc2da1..f350d13 100644
--- a/core/java/android/webkit/JWebCoreJavaBridge.java
+++ b/core/java/android/webkit/JWebCoreJavaBridge.java
@@ -16,9 +16,9 @@
 
 package android.webkit;
 
+import android.content.Context;
 import android.os.Handler;
 import android.os.Message;
-import android.security.CertTool;
 import android.util.Log;
 
 final class JWebCoreJavaBridge extends Handler {
@@ -41,6 +41,8 @@
     private boolean mTimerPaused;
     private boolean mHasDeferredTimers;
 
+    private Context mContext;
+
     /* package */
     static final int REFRESH_PLUGINS = 100;
 
@@ -48,7 +50,8 @@
      * Construct a new JWebCoreJavaBridge to interface with
      * WebCore timers and cookies.
      */
-    public JWebCoreJavaBridge() {
+    public JWebCoreJavaBridge(Context context) {
+        mContext = context;
         nativeConstructor();
     }
 
@@ -230,12 +233,12 @@
     }
 
     private String[] getKeyStrengthList() {
-        return CertTool.getInstance().getSupportedKeyStrenghs();
+        return CertTool.getKeyStrengthList();
     }
 
     private String getSignedPublicKey(int index, String challenge, String url) {
         // generateKeyPair expects organizations which we don't have. Ignore url.
-        return CertTool.getInstance().generateKeyPair(index, challenge, null);
+        return CertTool.getSignedPublicKey(mContext, index, challenge);
     }
 
     private native void nativeConstructor();
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index aee8a6d..5995121 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -28,7 +28,6 @@
 
 import android.os.Handler;
 import android.os.Message;
-import android.security.CertTool;
 import android.util.Log;
 import android.webkit.CacheManager.CacheResult;
 
@@ -37,7 +36,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Vector;
 import java.util.regex.Pattern;
@@ -70,12 +68,12 @@
     private static final int HTTP_NOT_FOUND = 404;
     private static final int HTTP_PROXY_AUTH = 407;
 
-    private static HashSet<String> sCertificateMimeTypeMap;
+    private static HashMap<String, String> sCertificateTypeMap;
     static {
-        sCertificateMimeTypeMap = new HashSet<String>();
-        sCertificateMimeTypeMap.add("application/x-x509-ca-cert");
-        sCertificateMimeTypeMap.add("application/x-x509-user-cert");
-        sCertificateMimeTypeMap.add("application/x-pkcs12");
+        sCertificateTypeMap = new HashMap<String, String>();
+        sCertificateTypeMap.put("application/x-x509-ca-cert", CertTool.CERT);
+        sCertificateTypeMap.put("application/x-x509-user-cert", CertTool.CERT);
+        sCertificateTypeMap.put("application/x-pkcs12", CertTool.PKCS12);
     }
 
     private static int sNativeLoaderCount;
@@ -964,9 +962,9 @@
 
     // This commits the headers without checking the response status code.
     private void commitHeaders() {
-        if (mIsMainPageLoader && sCertificateMimeTypeMap.contains(mMimeType)) {
+        if (mIsMainPageLoader && sCertificateTypeMap.containsKey(mMimeType)) {
             // In the case of downloading certificate, we will save it to the
-            // Keystore in commitLoad. Do not call webcore.
+            // KeyStore in commitLoad. Do not call webcore.
             return;
         }
 
@@ -1009,26 +1007,28 @@
     private void commitLoad() {
         if (mCancelled) return;
 
-        if (mIsMainPageLoader && sCertificateMimeTypeMap.contains(mMimeType)) {
-            // In the case of downloading certificate, we will save it to the
-            // Keystore and stop the current loading so that it will not
-            // generate a new history page
-            byte[] cert = new byte[mDataBuilder.getByteSize()];
-            int position = 0;
-            ByteArrayBuilder.Chunk c;
-            while (true) {
-                c = mDataBuilder.getFirstChunk();
-                if (c == null) break;
+        if (mIsMainPageLoader) {
+            String type = sCertificateTypeMap.get(mMimeType);
+            if (type != null) {
+                // In the case of downloading certificate, we will save it to
+                // the KeyStore and stop the current loading so that it will not
+                // generate a new history page
+                byte[] cert = new byte[mDataBuilder.getByteSize()];
+                int offset = 0;
+                while (true) {
+                    ByteArrayBuilder.Chunk c = mDataBuilder.getFirstChunk();
+                    if (c == null) break;
 
-                if (c.mLength != 0) {
-                    System.arraycopy(c.mArray, 0, cert, position, c.mLength);
-                    position += c.mLength;
+                    if (c.mLength != 0) {
+                        System.arraycopy(c.mArray, 0, cert, offset, c.mLength);
+                        offset += c.mLength;
+                    }
+                    mDataBuilder.releaseChunk(c);
                 }
-                mDataBuilder.releaseChunk(c);
+                CertTool.addCertificate(mContext, type, cert);
+                mBrowserFrame.stopLoading();
+                return;
             }
-            CertTool.getInstance().addCertificate(cert, mContext);
-            mBrowserFrame.stopLoading();
-            return;
         }
 
         // Give the data to WebKit now
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 6421fe7..0e08514 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -273,4 +273,26 @@
      * @hide pending API council.
      */
     public void addMessageToConsole(String message, int lineNumber, String sourceID) {}
+
+    /**
+     * Ask the host application for an icon to represent a <video> element.
+     * This icon will be used if the Web page did not specify a poster attribute.
+     *
+     * @return Bitmap The icon or null if no such icon is available.
+     * @hide pending API Council approval
+     */
+    public Bitmap getDefaultVideoPoster() {
+        return null;
+    }
+
+    /**
+     * Ask the host application for a custom progress view to show while
+     * a <video> is loading.
+     *
+     * @return View The progress view.
+     * @hide pending API Council approval
+     */
+    public View getVideoLoadingProgressView() {
+        return null;
+    }
 }
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 196bbd7..3c43fd15 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -17,6 +17,7 @@
 package android.webkit;
 
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.Handler;
@@ -193,12 +194,20 @@
     // with Google' and the browser.
     static GoogleLocationSettingManager sGoogleLocationSettingManager;
 
+    // private WebSettings, not accessible by the host activity
+    private int             mDoubleTapToastCount = 3;
+
+    private static final String PREF_FILE = "WebViewSettings";
+    private static final String DOUBLE_TAP_TOAST_COUNT = "double_tap_toast_count";
+
     // Class to handle messages before WebCore is ready.
     private class EventHandler {
         // Message id for syncing
         static final int SYNC = 0;
         // Message id for setting priority
         static final int PRIORITY = 1;
+        // Message id for writing double-tap toast count
+        static final int SET_DOUBLE_TAP_TOAST_COUNT = 2;
         // Actual WebCore thread handler
         private Handler mHandler;
 
@@ -224,6 +233,16 @@
                             setRenderPriority();
                             break;
                         }
+
+                        case SET_DOUBLE_TAP_TOAST_COUNT: {
+                            SharedPreferences.Editor editor = mContext
+                                    .getSharedPreferences(PREF_FILE,
+                                            Context.MODE_PRIVATE).edit();
+                            editor.putInt(DOUBLE_TAP_TOAST_COUNT,
+                                    mDoubleTapToastCount);
+                            editor.commit();
+                            break;
+                        }
                     }
                 }
             };
@@ -1311,6 +1330,19 @@
         }
      }
 
+    int getDoubleTapToastCount() {
+        return mDoubleTapToastCount;
+    }
+
+    void setDoubleTapToastCount(int count) {
+        if (mDoubleTapToastCount != count) {
+            mDoubleTapToastCount = count;
+            // write the settings in the non-UI thread
+            mEventHandler.sendMessage(Message.obtain(null,
+                    EventHandler.SET_DOUBLE_TAP_TOAST_COUNT));
+        }
+    }
+
     /**
      * Transfer messages from the queue to the new WebCoreThread. Called from
      * WebCore thread.
@@ -1323,6 +1355,10 @@
         }
         sGoogleLocationSettingManager = new GoogleLocationSettingManager(mContext);
         sGoogleLocationSettingManager.start();
+        SharedPreferences sp = mContext.getSharedPreferences(PREF_FILE,
+                Context.MODE_PRIVATE);
+        mDoubleTapToastCount = sp.getInt(DOUBLE_TAP_TOAST_COUNT,
+                mDoubleTapToastCount);
         nativeSync(frame.mNativeFrame);
         mSyncPending = false;
         mEventHandler.createHandler();
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 95b3a12..39a2470 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -16,6 +16,8 @@
 
 package android.webkit;
 
+import com.android.internal.widget.EditableInputConnection;
+
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -38,6 +40,7 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
@@ -346,6 +349,16 @@
 
     @Override
     protected void onSelectionChanged(int selStart, int selEnd) {
+        // This code is copied from TextView.onDraw().  That code does not get
+        // executed, however, because the WebTextView does not draw, allowing
+        // webkit's drawing to show through.
+        InputMethodManager imm = InputMethodManager.peekInstance();
+        if (imm != null && imm.isActive(this)) {
+            Spannable sp = (Spannable) getText();
+            int candStart = EditableInputConnection.getComposingSpanStart(sp);
+            int candEnd = EditableInputConnection.getComposingSpanEnd(sp);
+            imm.updateSelection(this, selStart, selEnd, candStart, candEnd);
+        }
         if (!mFromWebKit && mWebView != null) {
             if (DebugFlags.WEB_TEXT_VIEW) {
                 Log.v(LOGTAG, "onSelectionChanged selStart=" + selStart
@@ -430,18 +443,26 @@
             mGotTouchDown = true;
             break;
         case MotionEvent.ACTION_MOVE:
+            int slop = ViewConfiguration.get(mContext).getScaledTouchSlop();
             Spannable buffer = getText();
             int initialScrollX = Touch.getInitialScrollX(this, buffer);
             int initialScrollY = Touch.getInitialScrollY(this, buffer);
             super.onTouchEvent(event);
-            if (mScrollX != initialScrollX
-                    || mScrollY != initialScrollY) {
+            if (Math.abs(mScrollX - initialScrollX) > slop
+                    || Math.abs(mScrollY - initialScrollY) > slop) {
                 if (mWebView != null) {
                     mWebView.scrollFocusedTextInput(mScrollX, mScrollY);
                 }
                 mScrolled = true;
                 return true;
             }
+            if (Math.abs((int) event.getX() - mDragStartX) < slop
+                    && Math.abs((int) event.getY() - mDragStartY) < slop) {
+                // If the user has not scrolled further than slop, we should not
+                // send the drag.  Instead, do nothing, and when the user lifts
+                // their finger, we will change the selection.
+                return true;
+            }
             if (mWebView != null) {
                 // Only want to set the initial state once.
                 if (!mDragSent) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 4ca17ac..95e2e43 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -420,6 +420,7 @@
     private static final int STD_SPEED = 480;  // pixels per second
     // time for the longest scroll animation
     private static final int MAX_DURATION = 750;   // milliseconds
+    private static final int SLIDE_TITLE_DURATION = 500;   // milliseconds
     private Scroller mScroller;
 
     private boolean mWrapContent;
@@ -905,8 +906,9 @@
     /*
      * Return the width of the view where the content of WebView should render
      * to.
+     * Note: this can be called from WebCoreThread.
      */
-    private int getViewWidth() {
+    /* package */ int getViewWidth() {
         if (!isVerticalScrollBarEnabled() || mOverlayVerticalScrollbar) {
             return getWidth();
         } else {
@@ -932,8 +934,9 @@
     /*
      * Return the height of the view where the content of WebView should render
      * to.  Note that this excludes mTitleBar, if there is one.
+     * Note: this can be called from WebCoreThread.
      */
-    private int getViewHeight() {
+    /* package */ int getViewHeight() {
         int height = getHeight();
         if (isHorizontalScrollBarEnabled() && !mOverlayHorizontalScrollbar) {
             height -= getHorizontalScrollbarHeight();
@@ -1747,6 +1750,14 @@
     private View mTitleBar;
 
     /**
+     * Since we draw the title bar ourselves, we removed the shadow from the
+     * browser's activity.  We do want a shadow at the bottom of the title bar,
+     * or at the top of the screen if the title bar is not visible.  This
+     * drawable serves that purpose.
+     */
+    private Drawable mTitleShadow;
+
+    /**
      * Add or remove a title bar to be embedded into the WebView, and scroll
      * along with it vertically, while remaining in view horizontally. Pass
      * null to remove the title bar from the WebView, and return to drawing
@@ -1762,6 +1773,10 @@
             addView(v, new AbsoluteLayout.LayoutParams(
                     ViewGroup.LayoutParams.FILL_PARENT,
                     ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0));
+            if (mTitleShadow == null) {
+                mTitleShadow = (Drawable) mContext.getResources().getDrawable(
+                        com.android.internal.R.drawable.title_bar_shadow);
+            }
         }
         mTitleBar = v;
     }
@@ -1922,7 +1937,8 @@
                 int oldY = mScrollY;
                 float ratio = scale * mInvActualScale;   // old inverse
                 float sx = ratio * oldX + (ratio - 1) * mZoomCenterX;
-                float sy = ratio * oldY + (ratio - 1) * mZoomCenterY;
+                float sy = ratio * oldY + (ratio - 1)
+                        * (mZoomCenterY - getTitleHeight());
 
                 // now update our new scale and inverse
                 if (scale != mActualScale && !mPreviewZoomOnly) {
@@ -1985,7 +2001,7 @@
         getGlobalVisibleRect(r, p);
         r.offset(-p.x, -p.y);
         if (mFindIsUp) {
-            r.bottom -= FIND_HEIGHT;
+            r.bottom -= mFindHeight;
         }
     }
 
@@ -2057,9 +2073,6 @@
         }
     }
 
-    // Make sure this stays in sync with the actual height of the FindDialog.
-    private static final int FIND_HEIGHT = 79;
-
     @Override
     protected int computeVerticalScrollRange() {
         if (mDrawHistory) {
@@ -2290,7 +2303,11 @@
      *              that were found.
      */
     public int findAll(String find) {
-        mFindIsUp = true;
+        if (mFindIsUp == false) {
+            recordNewContentSize(mContentWidth, mContentHeight + mFindHeight,
+                    false);
+            mFindIsUp = true;
+        }
         int result = nativeFindAll(find.toLowerCase(), find.toUpperCase());
         invalidate();
         return result;
@@ -2299,6 +2316,7 @@
     // Used to know whether the find dialog is open.  Affects whether
     // or not we draw the highlights for matches.
     private boolean mFindIsUp;
+    private int mFindHeight;
 
     /**
      * Return the first substring consisting of the address of a physical
@@ -2354,7 +2372,11 @@
      * Clear the highlighting surrounding text matches created by findAll.
      */
     public void clearMatches() {
-        mFindIsUp = false;
+        if (mFindIsUp) {
+            recordNewContentSize(mContentWidth, mContentHeight - mFindHeight,
+                    false);
+            mFindIsUp = false;
+        }
         nativeSetFindIsDown();
         // Now that the dialog has been removed, ensure that we scroll to a
         // location that is not beyond the end of the page.
@@ -2363,6 +2385,16 @@
     }
 
     /**
+     * @hide
+     */
+    public void setFindDialogHeight(int height) {
+        if (DebugFlags.WEB_VIEW) {
+            Log.v(LOGTAG, "setFindDialogHeight height=" + height);
+        }
+        mFindHeight = height;
+    }
+
+    /**
      * Query the document to see if it contains any image references. The
      * message object will be dispatched with arg1 being set to 1 if images
      * were found and 0 if the document does not reference any images.
@@ -2404,7 +2436,6 @@
     private boolean pinScrollBy(int dx, int dy, boolean animate, int animationDuration) {
         return pinScrollTo(mScrollX + dx, mScrollY + dy, animate, animationDuration);
     }
-
     // helper to pin the scrollTo parameters (already in view coordinates)
     // returns true if the scroll was changed
     private boolean pinScrollTo(int x, int y, boolean animate, int animationDuration) {
@@ -2416,10 +2447,8 @@
         if ((dx | dy) == 0) {
             return false;
         }
-
-        if (true && animate) {
+        if (animate) {
             //        Log.d(LOGTAG, "startScroll: " + dx + " " + dy);
-
             mScroller.startScroll(mScrollX, mScrollY, dx, dy,
                     animationDuration > 0 ? animationDuration : computeDuration(dx, dy));
             invalidate();
@@ -2462,8 +2491,11 @@
     }
 
     // scale from content to view coordinates, and pin
-    // return true if pin caused the final x/y different than the request cx/cy;
-    // return false if the view scroll to the exact position as it is requested.
+    // return true if pin caused the final x/y different than the request cx/cy,
+    // and a future scroll may reach the request cx/cy after our size has
+    // changed
+    // return false if the view scroll to the exact position as it is requested,
+    // where negative numbers are taken to mean 0
     private boolean setContentScrollTo(int cx, int cy) {
         if (mDrawHistory) {
             // disallow WebView to change the scroll position as History Picture
@@ -2473,12 +2505,35 @@
             // saved scroll position, it is ok to skip this.
             return false;
         }
-        int vx = contentToViewX(cx);
-        int vy = contentToViewY(cy);
+        int vx;
+        int vy;
+        if ((cx | cy) == 0) {
+            // If the page is being scrolled to (0,0), do not add in the title
+            // bar's height, and simply scroll to (0,0). (The only other work
+            // in contentToView_ is to multiply, so this would not change 0.)
+            vx = 0;
+            vy = 0;
+        } else {
+            vx = contentToViewX(cx);
+            vy = contentToViewY(cy);
+        }
 //        Log.d(LOGTAG, "content scrollTo [" + cx + " " + cy + "] view=[" +
 //                      vx + " " + vy + "]");
+        // Some mobile sites attempt to scroll the title bar off the page by
+        // scrolling to (0,1).  If we are at the top left corner of the
+        // page, assume this is an attempt to scroll off the title bar, and
+        // animate the title bar off screen slowly enough that the user can see
+        // it.
+        if (cx == 0 && cy == 1 && mScrollX == 0 && mScrollY == 0) {
+            pinScrollTo(vx, vy, true, SLIDE_TITLE_DURATION);
+            // Since we are animating, we have not yet reached the desired
+            // scroll position.  Do not return true to request another attempt
+            return false;
+        }
         pinScrollTo(vx, vy, false, 0);
-        if (mScrollX != vx || mScrollY != vy) {
+        // If the request was to scroll to a negative coordinate, treat it as if
+        // it was a request to scroll to 0
+        if ((mScrollX != vx && cx >= 0) || (mScrollY != vy && cy >= 0)) {
             return true;
         } else {
             return false;
@@ -2668,16 +2723,14 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        int saveCount = canvas.getSaveCount();
-        if (mTitleBar != null) {
-            canvas.save();
-            canvas.translate(0, (int) mTitleBar.getHeight());
-        }
         // if mNativeClass is 0, the WebView has been destroyed. Do nothing.
         if (mNativeClass == 0) {
             return;
         }
-        canvas.save();
+        int saveCount = canvas.save();
+        if (mTitleBar != null) {
+            canvas.translate(0, (int) mTitleBar.getHeight());
+        }
         // Update the buttons in the picture, so when we draw the picture
         // to the screen, they are in the correct state.
         // Tell the native side if user is a) touching the screen,
@@ -2692,6 +2745,15 @@
         drawCoreAndCursorRing(canvas, mBackgroundColor, mDrawCursorRing);
         canvas.restoreToCount(saveCount);
 
+        // Now draw the shadow.
+        if (mTitleBar != null) {
+            int y = mScrollY + getVisibleTitleHeight();
+            int height = (int) (5f * getContext().getResources()
+                    .getDisplayMetrics().density);
+            mTitleShadow.setBounds(mScrollX, y, mScrollX + getWidth(),
+                    y + height);
+            mTitleShadow.draw(canvas);
+        }
         if (AUTO_REDRAW_HACK && mAutoRedraw) {
             invalidate();
         }
@@ -2754,7 +2816,8 @@
                 zoomScale = mZoomScale;
                 // set mZoomScale to be 0 as we have done animation
                 mZoomScale = 0;
-                animateZoom = false;    // inform drawContentPicture we're done
+                // call invalidate() again to draw with the final filters
+                invalidate();
                 if (mNeedToAdjustWebTextView) {
                     mNeedToAdjustWebTextView = false;
                     mWebTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
@@ -2771,15 +2834,20 @@
                     }
                 }
             }
+            // calculate the intermediate scroll position. As we need to use
+            // zoomScale, we can't use pinLocX/Y directly. Copy the logic here.
             float scale = zoomScale * mInvInitialZoomScale;
             int tx = Math.round(scale * (mInitialScrollX + mZoomCenterX)
                     - mZoomCenterX);
             tx = -pinLoc(tx, getViewWidth(), Math.round(mContentWidth
                     * zoomScale)) + mScrollX;
-            int ty = Math.round(scale * (mInitialScrollY + mZoomCenterY)
-                    - mZoomCenterY);
-            ty = -pinLoc(ty, getViewHeight(), Math.round(mContentHeight
-                    * zoomScale)) + mScrollY;
+            int titleHeight = getTitleHeight();
+            int ty = Math.round(scale
+                    * (mInitialScrollY + mZoomCenterY - titleHeight)
+                    - (mZoomCenterY - titleHeight));
+            ty = -(ty <= titleHeight ? Math.max(ty, 0) : pinLoc(ty
+                    - titleHeight, getViewHeight(), Math.round(mContentHeight
+                    * zoomScale)) + titleHeight) + mScrollY;
             canvas.translate(tx, ty);
             canvas.scale(zoomScale, zoomScale);
             if (inEditingMode() && !mNeedToAdjustWebTextView
@@ -2899,6 +2967,8 @@
                 getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
 
         if (isTextView) {
+            if (mWebTextView == null) return;
+
             imm.showSoftInput(mWebTextView, 0);
             // Now we need to fake a touch event to place the cursor where the
             // user touched.
@@ -3690,6 +3760,13 @@
                             && !mZoomButtonsController.isVisible()
                             && mMinZoomScale < mMaxZoomScale) {
                         mZoomButtonsController.setVisible(true);
+                        int count = settings.getDoubleTapToastCount();
+                        if (mInZoomOverview && count > 0) {
+                            settings.setDoubleTapToastCount(count--);
+                            Toast.makeText(mContext,
+                                    com.android.internal.R.string.double_tap_toast,
+                                    Toast.LENGTH_SHORT).show();
+                        }
                     }
                 }
 
@@ -4462,7 +4539,8 @@
         mZoomCenterY = mLastTouchY;
         mInZoomOverview = !mInZoomOverview;
         // remove the zoom control after double tap
-        if (getSettings().getBuiltInZoomControls()) {
+        WebSettings settings = getSettings();
+        if (settings.getBuiltInZoomControls()) {
             if (mZoomButtonsController.isVisible()) {
                 mZoomButtonsController.setVisible(false);
             }
@@ -4474,7 +4552,10 @@
                 mZoomControls.hide();
             }
         }
+        settings.setDoubleTapToastCount(0);
         if (mInZoomOverview) {
+            // Force the titlebar fully reveal in overview mode
+            if (mScrollY < getTitleHeight()) mScrollY = 0;
             zoomWithPreview((float) getViewWidth() / mZoomOverviewWidth);
         } else {
             // mLastTouchX and mLastTouchY are the point in the current viewport
@@ -4791,11 +4872,8 @@
                             mMaxZoomScale = restoreState.mMaxScale;
                         }
                         setNewZoomScale(mLastScale, false);
-                        if (getVisibleTitleHeight() == 0
-                                || restoreState.mScrollY != 0) {
-                            setContentScrollTo(restoreState.mScrollX,
-                                    restoreState.mScrollY);
-                        }
+                        setContentScrollTo(restoreState.mScrollX,
+                                restoreState.mScrollY);
                         if (useWideViewport
                                 && settings.getLoadWithOverviewMode()) {
                             if (restoreState.mViewScale == 0
@@ -4817,7 +4895,8 @@
                     final boolean updateLayout = viewSize.x == mLastWidthSent
                             && viewSize.y == mLastHeightSent;
                     recordNewContentSize(draw.mWidthHeight.x,
-                            draw.mWidthHeight.y, updateLayout);
+                            draw.mWidthHeight.y
+                            + (mFindIsUp ? mFindHeight : 0), updateLayout);
                     if (DebugFlags.WEB_VIEW) {
                         Rect b = draw.mInvalRegion.getBounds();
                         Log.v(LOGTAG, "NEW_PICTURE_MSG_ID {" +
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index ac3334c..d4142bb 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1890,7 +1890,22 @@
         if (mViewportWidth != 0 && !updateRestoreState) return;
 
         // now notify webview
-        int webViewWidth = Math.round(mCurrentViewWidth * mCurrentViewScale);
+        // webViewWidth refers to the width in the view system
+        int webViewWidth;
+        // viewportWidth refers to the width in the document system
+        int viewportWidth = mCurrentViewWidth;
+        if (viewportWidth == 0) {
+            // this may happen when WebView just starts. This is not perfect as
+            // we call WebView method from WebCore thread. But not perfect
+            // reference is better than no reference.
+            webViewWidth = mWebView.getViewWidth();
+            viewportWidth = webViewWidth * 100 / WebView.DEFAULT_SCALE_PERCENT;
+            if (viewportWidth == 0) {
+                Log.w(LOGTAG, "Can't get the viewWidth after the first layout");
+            }
+        } else {
+            webViewWidth = Math.round(viewportWidth * mCurrentViewScale);
+        }
         mRestoreState = new RestoreState();
         mRestoreState.mMinScale = mViewportMinimumScale / 100.0f;
         mRestoreState.mMaxScale = mViewportMaximumScale / 100.0f;
@@ -1942,7 +1957,7 @@
             mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
                     EventHub.VIEW_SIZE_CHANGED, data));
         } else if (mSettings.getUseWideViewPort()) {
-            if (mCurrentViewWidth == 0) {
+            if (viewportWidth == 0) {
                 // Trick to ensure VIEW_SIZE_CHANGED will be sent from WebView
                 // to WebViewCore
                 mWebView.mLastWidthSent = 0;
@@ -1956,8 +1971,7 @@
                                 : mRestoreState.mTextWrapScale)
                         : mRestoreState.mViewScale;
                 data.mWidth = Math.round(webViewWidth / data.mScale);
-                data.mHeight = mCurrentViewHeight * data.mWidth
-                        / mCurrentViewWidth;
+                data.mHeight = mCurrentViewHeight * data.mWidth / viewportWidth;
                 data.mTextWrapWidth = Math.round(webViewWidth
                         / mRestoreState.mTextWrapScale);
                 data.mIgnoreHeight = false;
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 4566c4c..953dd92 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -1325,7 +1325,7 @@
         final int maxHeight = mPopup.getMaxAvailableHeight(
                 getDropDownAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations);
 
-        if (mDropDownAlwaysVisible) {
+        if (mDropDownAlwaysVisible || mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) {
             // getMaxAvailableHeight() subtracts the padding, so we put it back,
             // to get the available height for the whole window
             int padding = 0;
diff --git a/core/java/android/widget/FasttrackBadgeWidget.java b/core/java/android/widget/FasttrackBadgeWidget.java
index 22ca5fd..9d2307f 100644
--- a/core/java/android/widget/FasttrackBadgeWidget.java
+++ b/core/java/android/widget/FasttrackBadgeWidget.java
@@ -22,9 +22,9 @@
 import android.content.Intent;
 import android.content.res.TypedArray;
 import android.database.Cursor;
-import android.graphics.Rect;
 import android.net.Uri;
 import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.FastTrack;
 import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.PhoneLookup;
 import android.provider.ContactsContract.RawContacts;
@@ -32,7 +32,6 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.View.OnClickListener;
-import android.widget.ImageView;
 
 /**
  * Widget used to show an image with the standard fasttrack badge
@@ -87,7 +86,7 @@
                     com.android.internal.R.styleable.FasttrackBadgeWidget, defStyle, 0);
 
         mMode = a.getInt(com.android.internal.R.styleable.FasttrackBadgeWidget_fasttrackWindowSize,
-                Intents.MODE_MEDIUM);
+                FastTrack.MODE_MEDIUM);
 
         a.recycle();
 
@@ -100,12 +99,12 @@
     }
 
     /**
-     * Assign the contact uri that this fasttrack badge should be associated with.
-     * Note that this is only used for displaying the fasttrack window and won't
-     * bind the contact's photo for you.
+     * Assign the contact uri that this fasttrack badge should be associated
+     * with. Note that this is only used for displaying the fasttrack window and
+     * won't bind the contact's photo for you.
      *
-     * @param conatctUri Either a {Contacts.CONTENT_URI} or {Contacts.CONTENT_LOOKUP_URI}
-     * style URI.
+     * @param contactUri Either a {@link Contacts#CONTENT_URI} or
+     *            {@link Contacts#CONTENT_LOOKUP_URI} style URI.
      */
     public void assignContactUri(Uri contactUri) {
         mContactUri = contactUri;
@@ -126,6 +125,8 @@
             mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP, null,
                     Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
                     EMAIL_LOOKUP_PROJECTION, null, null, null);
+        } else {
+            mContactUri = null;
         }
     }
 
@@ -144,12 +145,14 @@
             mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP, null,
                     Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
                     PHONE_LOOKUP_PROJECTION, null, null, null);
+        } else {
+            mContactUri = null;
         }
     }
 
     /**
-     * Set the fasttrack window mode. Options are {@link Intents.MODE_SMALL},
-     * {@link Intents.MODE_MEDIUM}, {@link Intents.MODE_LARGE}.
+     * Set the fasttrack window mode. Options are {@link FastTrack#MODE_SMALL},
+     * {@link FastTrack#MODE_MEDIUM}, {@link FastTrack#MODE_LARGE}.
      * @param size
      */
     public void setMode(int size) {
@@ -157,16 +160,16 @@
     }
 
     public void onClick(View v) {
-        final Rect target = getTargetRect(v);
-
         if (mContactUri != null) {
-            trigger(mContactUri, target);
+            final ContentResolver resolver = getContext().getContentResolver();
+            final Uri lookupUri = Contacts.getLookupUri(resolver, mContactUri);
+            trigger(lookupUri);
         } else if (mContactEmail != null) {
-            mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, target,
+            mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, mContactEmail,
                     Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
                     EMAIL_LOOKUP_PROJECTION, null, null, null);
         } else if (mContactPhone != null) {
-            mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP_AND_TRIGGER, target,
+            mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP_AND_TRIGGER, mContactPhone,
                     Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
                     PHONE_LOOKUP_PROJECTION, null, null, null);
         } else {
@@ -184,23 +187,8 @@
         mExcludeMimes = excludeMimes;
     }
 
-    private void trigger(Uri contactUri, Rect target) {
-        Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, contactUri);
-        intent.putExtra(Intents.EXTRA_TARGET_RECT, target);
-        intent.putExtra(Intents.EXTRA_MODE, mMode);
-        mContext.startActivity(intent);
-    }
-
-    private Rect getTargetRect(View anchor) {
-        final int[] location = new int[2];
-        anchor.getLocationOnScreen(location);
-
-        final Rect rect = new Rect();
-        rect.left = location[0];
-        rect.top = location[1];
-        rect.right = rect.left + anchor.getWidth();
-        rect.bottom = rect.top + anchor.getHeight();
-        return rect;
+    private void trigger(Uri lookupUri) {
+        FastTrack.showFastTrack(getContext(), this, lookupUri, mMode, mExcludeMimes);
     }
 
     private class QueryHandler extends AsyncQueryHandler {
@@ -211,28 +199,34 @@
 
         @Override
         protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
-            Uri contactUri = null;
+            Uri lookupUri = null;
+            Uri createUri = null;
             boolean trigger = false;
 
-            try{
+            try {
                 switch(token) {
                     case TOKEN_PHONE_LOOKUP_AND_TRIGGER:
                         trigger = true;
+                        createUri = Uri.fromParts("tel", (String)cookie, null);
+
                     case TOKEN_PHONE_LOOKUP: {
                         if (cursor != null && cursor.moveToFirst()) {
                             long contactId = cursor.getLong(PHONE_ID_COLUMN_INDEX);
                             String lookupKey = cursor.getString(PHONE_LOOKUP_STRING_COLUMN_INDEX);
-                            contactUri = Contacts.getLookupUri(contactId, lookupKey);
+                            lookupUri = Contacts.getLookupUri(contactId, lookupKey);
                         }
+
                         break;
                     }
                     case TOKEN_EMAIL_LOOKUP_AND_TRIGGER:
                         trigger = true;
+                        createUri = Uri.fromParts("mailto", (String)cookie, null);
+
                     case TOKEN_EMAIL_LOOKUP: {
                         if (cursor != null && cursor.moveToFirst()) {
                             long contactId = cursor.getLong(EMAIL_ID_COLUMN_INDEX);
                             String lookupKey = cursor.getString(EMAIL_LOOKUP_STRING_COLUMN_INDEX);
-                            contactUri = Contacts.getLookupUri(contactId, lookupKey);
+                            lookupUri = Contacts.getLookupUri(contactId, lookupKey);
                         }
                     }
                 }
@@ -242,11 +236,15 @@
                 }
             }
 
-            if (contactUri != null) {
-                mContactUri = contactUri;
-                if (trigger && cookie != null) {
-                    trigger(contactUri, (Rect) cookie);
-                }
+            mContactUri = lookupUri;
+
+            if (trigger && lookupUri != null) {
+                // Found contact, so trigger track
+                trigger(lookupUri);
+            } else if (createUri != null) {
+                // Prompt user to add this person to contacts
+                final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, createUri);
+                getContext().startActivity(intent);
             }
         }
     }
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 2dac652..8ef65db 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -17,8 +17,9 @@
 package android.widget;
 
 import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.graphics.Bitmap;
 import android.graphics.PorterDuff;
@@ -137,8 +138,11 @@
                     public void onClick(View v) {
                         try {
                             // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
-                            pendingIntent.send();
-                        } catch (CanceledException e) {
+                            v.getContext().startIntentSender(
+                                    pendingIntent.getIntentSender(), null,
+                                    Intent.FLAG_ACTIVITY_NEW_TASK,
+                                    Intent.FLAG_ACTIVITY_NEW_TASK, 0);
+                        } catch (IntentSender.SendIntentException e) {
                             throw new ActionException(e.toString());
                         }
                     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index e98fd13..2e3364b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3408,7 +3408,8 @@
         if (mPopup != null) {
             TextView tv = (TextView) mPopup.getContentView();
             chooseSize(mPopup, mError, tv);
-            mPopup.update(this, getErrorX(), getErrorY(), -1, -1);
+            mPopup.update(this, getErrorX(), getErrorY(),
+                          mPopup.getWidth(), mPopup.getHeight());
         }
 
         restartMarqueeIfNeeded();
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index af06965..250bc91 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -77,10 +77,15 @@
      * @param data The data stream that resulted from invoking the application's
      *   BackupService.doBackup() method.  This may be a pipe rather than a file on
      *   persistent media, so it may not be seekable.
+     * @param wipeAllFirst When true, <i>all</i> backed-up data for the current device/account
+     *   will be erased prior to the storage of the data provided here.  The purpose of this
+     *   is to provide a guarantee that no stale data exists in the restore set when the
+     *   device begins providing backups.
      * @return false if errors occurred (the backup should be aborted and rescheduled),
      *   true if everything is OK so far (but {@link #finishBackup} must be called).
      */
-    boolean performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd);
+    boolean performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd,
+            boolean wipeAllFirst);
 
     /**
      * Erase the give application's data from the backup destination.  This clears
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 2facce2..981ea82 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -56,12 +56,16 @@
         return 0;
     }
 
-    public boolean performBackup(PackageInfo packageInfo, ParcelFileDescriptor data)
-            throws RemoteException {
+    public boolean performBackup(PackageInfo packageInfo, ParcelFileDescriptor data,
+            boolean wipeAllFirst) throws RemoteException {
         if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName);
 
         File packageDir = new File(mDataDir, packageInfo.packageName);
         packageDir.mkdirs();
+        if (wipeAllFirst) {
+            if (DEBUG) Log.v(TAG, "wiping all data first");
+            deleteContents(mDataDir);
+        }
 
         // Each 'record' in the restore set is kept in its own file, named by
         // the record key.  Wind through the data file, extracting individual
@@ -111,6 +115,21 @@
         }
     }
 
+    // Deletes the contents but not the given directory
+    private void deleteContents(File dirname) {
+        File[] contents = dirname.listFiles();
+        if (contents != null) {
+            for (File f : contents) {
+                if (f.isDirectory()) {
+                    // delete the directory's contents then fall through
+                    // and delete the directory itself.
+                    deleteContents(f);
+                }
+                f.delete();
+            }
+        }
+    }
+
     public boolean clearBackupData(PackageInfo packageInfo) {
         if (DEBUG) Log.v(TAG, "clearBackupData() pkg=" + packageInfo.packageName);
 
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 2da72df..35c66ba 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -56,7 +56,9 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS' 
 
     // Current on-disk Parcel version
-    private static final int VERSION = 39;
+    private static final int VERSION = 40;
+
+    private static int sNumSpeedSteps;
 
     private final File mFile;
     private final File mBackupFile;
@@ -213,7 +215,7 @@
     /**
      * State for keeping track of counting information.
      */
-    public static final class Counter extends BatteryStats.Counter implements Unpluggable {
+    public static class Counter extends BatteryStats.Counter implements Unpluggable {
         int mCount;
         int mLoadedCount;
         int mLastCount;
@@ -302,7 +304,22 @@
             mUnpluggedCount = mPluggedCount = mCount;
         }
     }
-    
+
+    public static class SamplingCounter extends Counter {
+
+        SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
+            super(unpluggables, in);
+        }
+
+        SamplingCounter(ArrayList<Unpluggable> unpluggables) {
+            super(unpluggables);
+        }
+
+        public void addCountLocked(long count) {
+            mCount += count;
+        }
+    }
+
     /**
      * State for keeping track of timing information.
      */
@@ -1940,10 +1957,16 @@
              */
             long mUnpluggedForegroundTime;
 
+            SamplingCounter[] mSpeedBins;
+
             Proc() {
                 mUnpluggables.add(this);
+                mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
+                for (int i = 0; i < mSpeedBins.length; i++) {
+                    mSpeedBins[i] = new SamplingCounter(mUnpluggables);
+                }
             }
-            
+
             public void unplug(long batteryUptime, long batteryRealtime) {
                 mUnpluggedUserTime = mUserTime;
                 mUnpluggedSystemTime = mSystemTime;
@@ -1974,6 +1997,11 @@
                 out.writeLong(mUnpluggedSystemTime);
                 out.writeLong(mUnpluggedForegroundTime);
                 out.writeInt(mUnpluggedStarts);
+
+                out.writeInt(mSpeedBins.length);
+                for (int i = 0; i < mSpeedBins.length; i++) {
+                    mSpeedBins[i].writeToParcel(out);
+                }
             }
 
             void readFromParcelLocked(Parcel in) {
@@ -1993,6 +2021,12 @@
                 mUnpluggedSystemTime = in.readLong();
                 mUnpluggedForegroundTime = in.readLong();
                 mUnpluggedStarts = in.readInt();
+
+                int bins = in.readInt();
+                mSpeedBins = new SamplingCounter[bins];
+                for (int i = 0; i < bins; i++) {
+                    mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
+                }
             }
 
             public BatteryStatsImpl getBatteryStats() {
@@ -2075,6 +2109,22 @@
                 }
                 return val;
             }
+
+            /* Called by ActivityManagerService when CPU times are updated. */
+            public void addSpeedStepTimes(long[] values) {
+                for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
+                    mSpeedBins[i].addCountLocked(values[i]);
+                }
+            }
+
+            @Override
+            public long getTimeAtCpuSpeedStep(int speedStep, int which) {
+                if (speedStep < mSpeedBins.length) {
+                    return mSpeedBins[speedStep].getCountLocked(which);
+                } else {
+                    return 0;
+                }
+            }
         }
 
         /**
@@ -2625,6 +2675,10 @@
         readFromParcel(p);
     }
 
+    public void setNumSpeedSteps(int steps) {
+        if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
+    }
+
     @Override
     public int getStartCount() {
         return mStartCount;
@@ -2853,6 +2907,11 @@
             return mDischargeCurrentLevel;
     }
 
+    @Override
+    public int getCpuSpeedSteps() {
+        return sNumSpeedSteps;
+    }
+
     /**
      * Retrieve the statistics object for a particular uid, creating if needed.
      */
@@ -3063,7 +3122,9 @@
                 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
             }
         }
-        
+
+        sNumSpeedSteps = in.readInt();
+
         final int NU = in.readInt();
         for (int iu = 0; iu < NU; iu++) {
             int uid = in.readInt();
@@ -3206,6 +3267,7 @@
             }
         }
         
+        out.writeInt(sNumSpeedSteps);
         final int NU = mUidStats.size();
         out.writeInt(NU);
         for (int iu = 0; iu < NU; iu++) {
@@ -3404,6 +3466,8 @@
         mFullTimers.clear();
         mWindowTimers.clear();
 
+        sNumSpeedSteps = in.readInt();
+
         int numUids = in.readInt();
         mUidStats.clear();
         for (int i = 0; i < numUids; i++) {
@@ -3484,7 +3548,9 @@
                 out.writeInt(0);
             }
         }
-        
+
+        out.writeInt(sNumSpeedSteps);
+
         int size = mUidStats.size();
         out.writeInt(size);
         for (int i = 0; i < size; i++) {
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 94f703ad..4b4b717 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -47,14 +47,9 @@
     public static final String POWER_CPU_IDLE = "cpu.idle";
 
     /**
-     * Power consumption when CPU is running at normal speed.
+     * Power consumption when CPU is in power collapse mode.
      */
-    public static final String POWER_CPU_NORMAL = "cpu.normal";
-
-    /**
-     * Power consumption when CPU is running at full speed.
-     */
-    public static final String POWER_CPU_FULL = "cpu.full";
+    public static final String POWER_CPU_ACTIVE = "cpu.active";
 
     /**
      * Power consumption when WiFi driver is scanning for networks.
@@ -124,6 +119,8 @@
      */
     public static final String POWER_VIDEO = "dsp.video";
 
+    public static final String POWER_CPU_SPEEDS = "cpu.speeds";
+
     static final HashMap<String, Object> sPowerMap = new HashMap<String, Object>();
 
     private static final String TAG_DEVICE = "device";
@@ -214,10 +211,10 @@
     }
     
     /**
-     * Returns the average current in mA consumed by the subsystem for the given level. 
+     * Returns the average current in mA consumed by the subsystem for the given level.
      * @param type the subsystem type
      * @param level the level of power at which the subsystem is running. For instance, the
-     *  signal strength of the cell network between 0 and 4 (if there are 4 bars max.).
+     *  signal strength of the cell network between 0 and 4 (if there are 4 bars max.)
      *  If there is no data for multiple levels, the level is ignored.
      * @return the average current in milliAmps.
      */
@@ -240,4 +237,12 @@
             return 0;
         }
     }
+
+    public int getNumSpeedSteps() {
+        Object value = sPowerMap.get(POWER_CPU_SPEEDS);
+        if (value != null && value instanceof Double[]) {
+            return ((Double[])value).length;
+        }
+        return 1; // Only one speed
+    }
 }
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index fe01866..4987775 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -42,6 +42,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.CheckBox;
+import android.widget.FasttrackBadgeWidget;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -64,15 +65,13 @@
     private TextView mDisplayNameView;
     private TextView mPhoneticNameView;
     private CheckBox mStarredView;
-    private ImageView mPhotoView;
+    private FasttrackBadgeWidget mPhotoView;
     private ImageView mPresenceView;
     private TextView mStatusView;
     private int mNoPhotoResource;
     private QueryHandler mQueryHandler;
 
-    protected long mContactId;
     protected Uri mContactUri;
-    protected Uri mStatusUri;
 
     protected String[] mExcludeMimes = null;
 
@@ -94,6 +93,8 @@
         Contacts.STARRED,
         Contacts.PHOTO_ID,
         Contacts.PRESENCE_STATUS,
+        Contacts._ID,
+        Contacts.LOOKUP_KEY,
     };
     protected static final int HEADER_DISPLAY_NAME_COLUMN_INDEX = 0;
     //TODO: We need to figure out how we're going to get the phonetic name.
@@ -101,6 +102,8 @@
     protected static final int HEADER_STARRED_COLUMN_INDEX = 1;
     protected static final int HEADER_PHOTO_ID_COLUMN_INDEX = 2;
     protected static final int HEADER_PRESENCE_STATUS_COLUMN_INDEX = 3;
+    protected static final int HEADER_CONTACT_ID_COLUMN_INDEX = 4;
+    protected static final int HEADER_LOOKUP_KEY_COLUMN_INDEX = 5;
 
     //Projection used for finding the most recent social status.
     protected static final String[] SOCIAL_PROJECTION = new String[] {
@@ -113,18 +116,29 @@
     //Projection used for looking up contact id from phone number
     protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
         PhoneLookup._ID,
+        PhoneLookup.LOOKUP_KEY,
     };
     protected static final int PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX = 0;
+    protected static final int PHONE_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX = 1;
 
     //Projection used for looking up contact id from email address
     protected static final String[] EMAIL_LOOKUP_PROJECTION = new String[] {
         RawContacts.CONTACT_ID,
+        Contacts.LOOKUP_KEY,
     };
     protected static final int EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX = 0;
+    protected static final int EMAIL_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX = 1;
 
+    protected static final String[] CONTACT_LOOKUP_PROJECTION = new String[] {
+        Contacts._ID,
+    };
+    protected static final int CONTACT_LOOKUP_ID_COLUMN_INDEX = 0;
 
     private static final int TOKEN_CONTACT_INFO = 0;
     private static final int TOKEN_SOCIAL = 1;
+    private static final int TOKEN_PHONE_LOOKUP = 2;
+    private static final int TOKEN_EMAIL_LOOKUP = 3;
+    private static final int TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY = 4;
 
     public ContactHeaderWidget(Context context) {
         this(context, null);
@@ -151,8 +165,7 @@
         mStarredView = (CheckBox)findViewById(R.id.star);
         mStarredView.setOnClickListener(this);
 
-        mPhotoView = (ImageView)findViewById(R.id.photo);
-        mPhotoView.setOnClickListener(this);
+        mPhotoView = (FasttrackBadgeWidget) findViewById(R.id.photo);
         mPhotoView.setOnLongClickListener(this);
 
         mPresenceView = (ImageView) findViewById(R.id.presence);
@@ -217,12 +230,50 @@
         @Override
         protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
             try{
-                if (token == TOKEN_CONTACT_INFO) {
-                    bindContactInfo(cursor);
-                    invalidate();
-                } else if (token == TOKEN_SOCIAL) {
-                    bindSocial(cursor);
-                    invalidate();
+                switch (token) {
+                    case TOKEN_CONTACT_INFO: {
+                        bindContactInfo(cursor);
+                        invalidate();
+                        break;
+                    }
+                    case TOKEN_SOCIAL: {
+                        bindSocial(cursor);
+                        invalidate();
+                        break;
+                    }
+                    case TOKEN_PHONE_LOOKUP: {
+                        if (cursor != null && cursor.moveToFirst()) {
+                            long contactId = cursor.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
+                            String lookupKey = cursor.getString(
+                                    PHONE_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
+                            bindFromContactUri(Contacts.getLookupUri(contactId, lookupKey));
+                        } else {
+                            String phoneNumber = (String) cookie;
+                            setDisplayName(phoneNumber, null);
+                            mPhotoView.assignContactFromPhone(phoneNumber, true);
+                        }
+                        break;
+                    }
+                    case TOKEN_EMAIL_LOOKUP: {
+                        if (cursor != null && cursor.moveToFirst()) {
+                            long contactId = cursor.getLong(EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX);
+                            String lookupKey = cursor.getString(
+                                    EMAIL_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
+                            bindFromContactUri(Contacts.getLookupUri(contactId, lookupKey));
+                        } else {
+                            String emailAddress = (String) cookie;
+                            setDisplayName(emailAddress, null);
+                            mPhotoView.assignContactFromEmail(emailAddress, true);
+                        }
+                        break;
+                    }
+                    case TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY: {
+                        if (cursor != null && cursor.moveToFirst()) {
+                            long contactId = cursor.getLong(CONTACT_LOOKUP_ID_COLUMN_INDEX);
+                            startSocialQuery(ContentUris.withAppendedId(
+                                    Activities.CONTENT_CONTACT_STATUS_URI, contactId));
+                        }
+                    }
                 }
             } finally {
                 if (cursor != null) {
@@ -300,33 +351,31 @@
      * Convenience method for binding all available data from an existing
      * contact.
      *
-     * @param contactId the contact id of the contact whose info should be displayed.
+     * @param conatctUri a {Contacts.CONTENT_LOOKUP_URI} style URI.
      */
-    public void bindFromContactId(long contactId) {
-        mContactId = contactId;
-        mContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, mContactId);
+    public void bindFromContactLookupUri(Uri contactLookupUri) {
+        mContactUri = contactLookupUri;
 
-        bindContactUri(mContactUri);
-        bindSocialUri(ContentUris.withAppendedId(Activities.CONTENT_CONTACT_STATUS_URI, mContactId));
+        // Query for the contactId so we can do the social query.
+        mQueryHandler.startQuery(TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY, null, contactLookupUri,
+                CONTACT_LOOKUP_PROJECTION, null, null, null);
+
+        startContactQuery(contactLookupUri);
     }
 
     /**
-     * Convenience method for binding {@link Contacts} header details from a
-     * {@link Contacts#CONTENT_URI} reference.
+     * Convenience method for binding all available data from an existing
+     * contact.
+     *
+     * @param conatctUri a {Contacts.CONTENT_URI} style URI.
      */
-    public void bindContactUri(Uri contactUri) {
-        mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, HEADER_PROJECTION,
-                null, null, null);
-    }
+    public void bindFromContactUri(Uri contactUri) {
+        mContactUri = contactUri;
+        long contactId = ContentUris.parseId(contactUri);
 
-    /**
-     * Convenience method for binding {@link Activities} header details from a
-     * {@link Activities#CONTENT_CONTACT_STATUS_URI}.
-     */
-    public void bindSocialUri(Uri contactSocial) {
-        mStatusUri = contactSocial;
-        mQueryHandler.startQuery(TOKEN_SOCIAL, null, mStatusUri, SOCIAL_PROJECTION, null, null,
-                null);
+        startContactQuery(contactUri);
+        startSocialQuery(ContentUris.withAppendedId(
+                Activities.CONTENT_CONTACT_STATUS_URI, contactId));
     }
 
     /**
@@ -338,21 +387,9 @@
      * address, one of them will be chosen to bind to.
      */
     public void bindFromEmail(String emailAddress) {
-        Cursor c = null;
-        try {
-            c = mContentResolver.query(Uri.withAppendedPath(Email.CONTENT_FILTER_EMAIL_URI, Uri
-                    .encode(emailAddress)), EMAIL_LOOKUP_PROJECTION, null, null, null);
-            if (c != null && c.moveToFirst()) {
-                long contactId = c.getLong(EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX);
-                bindFromContactId(contactId);
-            } else {
-                setDisplayName(emailAddress, null);
-            }
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
+        mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP, emailAddress,
+                Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(emailAddress)),
+                EMAIL_LOOKUP_PROJECTION, null, null, null);
     }
 
     /**
@@ -364,22 +401,19 @@
      * number, one of them will be chosen to bind to.
      */
     public void bindFromPhoneNumber(String number) {
-        Cursor c = null;
-        try {
-            c = mContentResolver.query(
-                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
-                    PHONE_LOOKUP_PROJECTION, null, null, null);
-            if (c != null && c.moveToFirst()) {
-                long contactId = c.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
-                bindFromContactId(contactId);
-            } else {
-                setDisplayName(number, null);
-            }
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
+        mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP, number,
+                Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
+                PHONE_LOOKUP_PROJECTION, null, null, null);
+    }
+
+    private void startSocialQuery(Uri contactSocial) {
+        mQueryHandler.startQuery(TOKEN_SOCIAL, null, contactSocial, SOCIAL_PROJECTION, null, null,
+                null);
+    }
+
+    private void startContactQuery(Uri contactUri) {
+        mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, HEADER_PROJECTION,
+                null, null, null);
     }
 
     /**
@@ -390,6 +424,8 @@
 
         // TODO: Bring back phonetic name
         final String displayName = c.getString(HEADER_DISPLAY_NAME_COLUMN_INDEX);
+        final long contactId = c.getLong(HEADER_CONTACT_ID_COLUMN_INDEX);
+        final String lookupKey = c.getString(HEADER_LOOKUP_KEY_COLUMN_INDEX);
         final String phoneticName = null;
         this.setDisplayName(displayName, null);
 
@@ -402,6 +438,7 @@
             photoBitmap = loadPlaceholderPhoto(null);
         }
         mPhotoView.setImageBitmap(photoBitmap);
+        mPhotoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey));
 
         //Set the presence status
         int presence = c.getInt(HEADER_PRESENCE_STATUS_COLUMN_INDEX);
@@ -423,27 +460,11 @@
             return;
         }
 
-        switch (view.getId()) {
-            case R.id.star: {
-                // Toggle "starred" state
-                final ContentValues values = new ContentValues(1);
-                values.put(Contacts.STARRED, mStarredView.isChecked());
-                mContentResolver.update(mContactUri, values, null, null);
-                break;
-            }
-            case R.id.photo: {
-                // Photo launches contact detail action
-                final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, mContactUri);
-                final Rect target = getTargetRect(view);
-                intent.putExtra(Intents.EXTRA_TARGET_RECT, target);
-                intent.putExtra(Intents.EXTRA_MODE, Intents.MODE_SMALL);
-                if (mExcludeMimes != null) {
-                    // Exclude specific MIME-types when requested
-                    intent.putExtra(Intents.EXTRA_EXCLUDE_MIMES, mExcludeMimes);
-                }
-                mContext.startActivity(intent);
-                break;
-            }
+        if (view.getId() == R.id.star) {
+            // Toggle "starred" state
+            final ContentValues values = new ContentValues(1);
+            values.put(Contacts.STARRED, mStarredView.isChecked());
+            mContentResolver.update(mContactUri, values, null, null);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java
index 7b940c9..f610211 100644
--- a/core/java/com/android/internal/widget/RotarySelector.java
+++ b/core/java/com/android/internal/widget/RotarySelector.java
@@ -19,16 +19,15 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.os.Vibrator;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.SoundEffectConstants;
 import android.view.animation.AccelerateInterpolator;
-
+import static android.view.animation.AnimationUtils.currentAnimationTimeMillis;
 import com.android.internal.R;
 
 
@@ -67,15 +66,10 @@
     // state of the animation used to bring the handle back to its start position when
     // the user lets go before triggering an action
     private boolean mAnimating = false;
-    private long mAnimationEndTime;
-    private int mAnimatingDelta;
-    AccelerateInterpolator mInterpolator;
-
-    /**
-     * True after triggering an action if the user of {@link OnDialTriggerListener} wants to
-     * freeze the UI (until they transition to another screen).
-     */
-    private boolean mFrozen = false;
+    private long mAnimationStartTime; // set to the end point of the animatino
+    private long mAnimationDuration;
+    private int mAnimatingDeltaXStart;   // the animation will interpolate from this delta down to zero
+    private AccelerateInterpolator mInterpolator;
 
     /**
      * If the user is currently dragging something.
@@ -96,12 +90,6 @@
     private static final long VIBRATE_SHORT = 60;  // msec
     private static final long VIBRATE_LONG = 100;  // msec
 
-    // Various tweakable layout or behavior parameters:
-
-    // How close to the edge of the screen, we let the handle get before
-    // triggering an action:
-    private static final int EDGE_THRESHOLD_DIP = 70;
-
     /**
      * The drawable for the arrows need to be scrunched this many dips towards the rotary bg below
      * it.
@@ -114,13 +102,27 @@
     private static final int EDGE_PADDING_DIP = 9;
 
     /**
+     * How far from the edge of the screen the user must drag to trigger the event.
+     */
+    private static final int EDGE_TRIGGER_DIP = 100;
+
+    /**
      * Dimensions of arc in background drawable.
      */
     static final int OUTER_ROTARY_RADIUS_DIP = 390;
     static final int ROTARY_STROKE_WIDTH_DIP = 83;
-    private static final int ANIMATION_DURATION_MILLIS = 300;
+    static final int SNAP_BACK_ANIMATION_DURATION_MILLIS = 300;
+    static final int SPIN_ANIMATION_DURATION_MILLIS = 800;
 
     private static final boolean DRAW_CENTER_DIMPLE = false;
+    private int mEdgeTriggerThresh;
+    private int mDimpleWidth;
+    private int mBackgroundWidth;
+    private int mBackgroundHeight;
+
+    public RotarySelector(Context context) {
+        this(context, null);
+    }
 
     /**
      * Constructor used when this widget is created from a layout file.
@@ -132,8 +134,6 @@
         Resources r = getResources();
         mDensity = r.getDisplayMetrics().density;
         if (DBG) log("- Density: " + mDensity);
-        // Density is 1.0 on HVGA (like Dream), and 1.5 on WVGA.
-        // Usage: raw_pixel_value = (int) (dpi_value * mDensity + 0.5f)
 
         // Assets (all are BitmapDrawables).
         mBackground = r.getDrawable(R.drawable.jog_dial_bg_cropped);
@@ -143,7 +143,23 @@
         mArrowLongRight = r.getDrawable(R.drawable.jog_dial_arrow_long_right_red);
         mArrowShortLeftAndRight = r.getDrawable(R.drawable.jog_dial_arrow_short_left_and_right);
 
+        // Arrows:
+        // All arrow assets are the same size (they're the full width of
+        // the screen) regardless of which arrows are actually visible.
+        int arrowW = mArrowShortLeftAndRight.getIntrinsicWidth();
+        int arrowH = mArrowShortLeftAndRight.getIntrinsicHeight();
+        mArrowShortLeftAndRight.setBounds(0, 0, arrowW, arrowH);
+        mArrowLongLeft.setBounds(0, 0, arrowW, arrowH);
+        mArrowLongRight.setBounds(0, 0, arrowW, arrowH);
+
         mInterpolator = new AccelerateInterpolator();
+
+        mEdgeTriggerThresh = (int) (mDensity * EDGE_TRIGGER_DIP);
+
+        mDimpleWidth = mDimple.getIntrinsicWidth();
+
+        mBackgroundWidth = mBackground.getIntrinsicWidth();
+        mBackgroundHeight = mBackground.getIntrinsicHeight();
     }
 
     /**
@@ -203,7 +219,7 @@
         final int width = MeasureSpec.getSize(widthMeasureSpec);  // screen width
 
         final int arrowH = mArrowShortLeftAndRight.getIntrinsicHeight();
-        final int backgroundH = mBackground.getIntrinsicHeight();
+        final int backgroundH = mBackgroundHeight;
 
         // by making the height less than arrow + bg, arrow and bg will be scrunched together,
         // overlaying somewhat (though on transparent portions of the drawable).
@@ -217,9 +233,9 @@
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
 
-        mLeftHandleX = (int) (EDGE_PADDING_DIP * mDensity) + mDimple.getIntrinsicWidth() / 2;
+        mLeftHandleX = (int) (EDGE_PADDING_DIP * mDensity) + mDimpleWidth / 2;
         mRightHandleX =
-                getWidth() - (int) (EDGE_PADDING_DIP * mDensity) - mDimple.getIntrinsicWidth() / 2;
+                getWidth() - (int) (EDGE_PADDING_DIP * mDensity) - mDimpleWidth / 2;
     }
 
 //    private Paint mPaint = new Paint();
@@ -228,30 +244,33 @@
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
         if (DBG) {
-            log(String.format("onDraw: mAnimating=%s, mTouchDragOffset=%d, mGrabbedState=%d," +
-                    "mFrozen=%s",
-                    mAnimating, mTouchDragOffset, mGrabbedState, mFrozen));
+            log(String.format("onDraw: mAnimating=%s, mTouchDragOffset=%d, mGrabbedState=%d",
+                    mAnimating, mTouchDragOffset, mGrabbedState));
         }
 
         final int height = getHeight();
 
         // update animating state before we draw anything
-        if (mAnimating && !mFrozen) {
-            long millisLeft = mAnimationEndTime - System.currentTimeMillis();
+        if (mAnimating) {
+            final long millisSoFar = currentAnimationTimeMillis() - mAnimationStartTime;
+            final long millisLeft = mAnimationDuration - millisSoFar;
             if (DBG) log("millisleft for animating: " + millisLeft);
             if (millisLeft <= 0) {
                 reset();
             } else {
+                // we always use the snap back duration as the denominator for interpolation
+                // to get a consistent velocity (bascially this makes us happy for the snap back
+                // and the spin around one).
+                final long denom = SNAP_BACK_ANIMATION_DURATION_MILLIS; // mAnimationDuration
                 float interpolation = mInterpolator.getInterpolation(
-                        (float) millisLeft / ANIMATION_DURATION_MILLIS);
-                mTouchDragOffset = (int) (mAnimatingDelta * interpolation);
+                        (float) millisLeft / denom);
+                mTouchDragOffset = (int) (mAnimatingDeltaXStart * interpolation);
             }
         }
 
-
         // Background:
-        final int backgroundW = mBackground.getIntrinsicWidth();
-        final int backgroundH = mBackground.getIntrinsicHeight();
+        final int backgroundW = mBackgroundWidth;
+        final int backgroundH = mBackgroundHeight;
         final int backgroundY = height - backgroundH;
         if (DBG) log("- Background INTRINSIC: " + backgroundW + " x " + backgroundH);
         mBackground.setBounds(0, backgroundY,
@@ -259,17 +278,12 @@
         if (DBG) log("  Background BOUNDS: " + mBackground.getBounds());
         mBackground.draw(canvas);
 
-        // Arrows:
-        // All arrow assets are the same size (they're the full width of
-        // the screen) regardless of which arrows are actually visible.
-        int arrowW = mArrowShortLeftAndRight.getIntrinsicWidth();
-        int arrowH = mArrowShortLeftAndRight.getIntrinsicHeight();
 
         // Draw the correct arrow(s) depending on the current state:
         Drawable currentArrow;
         switch (mGrabbedState) {
             case NOTHING_GRABBED:
-                currentArrow  = mArrowShortLeftAndRight;
+                currentArrow  = null; //mArrowShortLeftAndRight;
                 break;
             case LEFT_HANDLE_GRABBED:
                 currentArrow = mArrowLongLeft;
@@ -280,8 +294,7 @@
             default:
                 throw new IllegalStateException("invalid mGrabbedState: " + mGrabbedState);
         }
-        currentArrow.setBounds(0, 0, arrowW, arrowH);
-        currentArrow.draw(canvas);
+        if (currentArrow != null) currentArrow.draw(canvas);
 
         // debug: draw circle that should match the outer arc (good sanity check)
 //        mPaint.setColor(Color.RED);
@@ -302,7 +315,9 @@
                     xOffset);
 
             drawCentered(mDimple, canvas, xOffset, drawableY + bgTop);
-            drawCentered(mLeftHandleIcon, canvas, xOffset, drawableY + bgTop);
+            if (mGrabbedState != RIGHT_HANDLE_GRABBED) {
+                drawCentered(mLeftHandleIcon, canvas, xOffset, drawableY + bgTop);
+            }
         }
 
         if (DRAW_CENTER_DIMPLE) {
@@ -325,7 +340,9 @@
                     xOffset);
 
             drawCentered(mDimple, canvas, xOffset, drawableY + bgTop);
-            drawCentered(mRightHandleIcon, canvas, xOffset, drawableY + bgTop);
+            if (mGrabbedState != LEFT_HANDLE_GRABBED) {
+                drawCentered(mRightHandleIcon, canvas, xOffset, drawableY + bgTop);
+            }
         }
 
         if (mAnimating) invalidate();
@@ -375,70 +392,98 @@
      */
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        if (mAnimating || mFrozen) {
+        if (mAnimating) {
             return true;
         }
 
         final int eventX = (int) event.getX();
-        final int hitWindow = mDimple.getIntrinsicWidth();
+        final int hitWindow = mDimpleWidth;
 
-        if (event.getAction() == MotionEvent.ACTION_DOWN) {
-            if (DBG) log("touch-down");
-            mTriggered = false;
-            if (mGrabbedState != RotarySelector.NOTHING_GRABBED) {
+        final int action = event.getAction();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                if (DBG) log("touch-down");
+                mTriggered = false;
+                if (mGrabbedState != NOTHING_GRABBED) {
+                    reset();
+                    invalidate();
+                }
+                if (eventX < mLeftHandleX + hitWindow) {
+                    mTouchDragOffset = eventX - mLeftHandleX;
+                    mGrabbedState = LEFT_HANDLE_GRABBED;
+                    invalidate();
+                    vibrate(VIBRATE_SHORT);
+                } else if (eventX > mRightHandleX - hitWindow) {
+                    mTouchDragOffset = eventX - mRightHandleX;
+                    mGrabbedState = RIGHT_HANDLE_GRABBED;
+                    invalidate();
+                    vibrate(VIBRATE_SHORT);
+                }
+                break;
+
+            case MotionEvent.ACTION_MOVE:
+                if (DBG) log("touch-move");
+                if (mGrabbedState == LEFT_HANDLE_GRABBED) {
+                    mTouchDragOffset = eventX - mLeftHandleX;
+                    invalidate();
+                    if (eventX >= getRight() - mEdgeTriggerThresh && !mTriggered) {
+                        mTriggered = true;
+                        dispatchTriggerEvent(OnDialTriggerListener.LEFT_HANDLE);
+                        // set up "spin around animation"
+                        mAnimating = true;
+                        mAnimationStartTime = currentAnimationTimeMillis();
+                        mAnimationDuration = SPIN_ANIMATION_DURATION_MILLIS;
+                        mAnimatingDeltaXStart = -mBackgroundWidth*3;
+                        mTouchDragOffset = 0;
+                        mGrabbedState = NOTHING_GRABBED;
+                        invalidate();
+
+                    }
+                } else if (mGrabbedState == RIGHT_HANDLE_GRABBED) {
+                    mTouchDragOffset = eventX - mRightHandleX;
+                    invalidate();
+                    if (eventX <= mEdgeTriggerThresh && !mTriggered) {
+                        mTriggered = true;
+                        dispatchTriggerEvent(OnDialTriggerListener.RIGHT_HANDLE);
+                        // set up "spin around animation"
+                        mAnimating = true;
+                        mAnimationStartTime = currentAnimationTimeMillis();
+                        mAnimationDuration = SPIN_ANIMATION_DURATION_MILLIS;
+                        mAnimatingDeltaXStart = mBackgroundWidth*3;
+                        mTouchDragOffset = 0;
+                        mGrabbedState = NOTHING_GRABBED;
+                        invalidate();
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+                if (DBG) log("touch-up");
+                // handle animating back to start if they didn't trigger
+                if (mGrabbedState == LEFT_HANDLE_GRABBED
+                        && Math.abs(eventX - mLeftHandleX) > 5) {
+                    // set up "snap back" animation
+                    mAnimating = true;
+                    mAnimationStartTime = currentAnimationTimeMillis();
+                    mAnimationDuration = SNAP_BACK_ANIMATION_DURATION_MILLIS;
+                    mAnimatingDeltaXStart = eventX - mLeftHandleX;
+                } else if (mGrabbedState == RIGHT_HANDLE_GRABBED
+                        && Math.abs(eventX - mRightHandleX) > 5) {
+                    // set up "snap back" animation
+                    mAnimating = true;
+                    mAnimationStartTime = currentAnimationTimeMillis();
+                    mAnimationDuration = SNAP_BACK_ANIMATION_DURATION_MILLIS;
+                    mAnimatingDeltaXStart = eventX - mRightHandleX;
+                }
+
+                mTouchDragOffset = 0;
+                mGrabbedState = NOTHING_GRABBED;
+                invalidate();
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                if (DBG) log("touch-cancel");
                 reset();
                 invalidate();
-            }
-            if (eventX < mLeftHandleX + hitWindow) {
-                mTouchDragOffset = eventX - mLeftHandleX;
-                mGrabbedState = RotarySelector.LEFT_HANDLE_GRABBED;
-                invalidate();
-                vibrate(VIBRATE_SHORT);
-            } else if (eventX > mRightHandleX - hitWindow) {
-                mTouchDragOffset = eventX - mRightHandleX;
-                mGrabbedState = RotarySelector.RIGHT_HANDLE_GRABBED;
-                invalidate();
-                vibrate(VIBRATE_SHORT);
-            }
-        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
-            if (DBG) log("touch-move");
-            if (mGrabbedState == RotarySelector.LEFT_HANDLE_GRABBED) {
-                mTouchDragOffset = eventX - mLeftHandleX;
-                invalidate();
-                if (eventX >= mRightHandleX - EDGE_PADDING_DIP && !mTriggered) {
-                    mTriggered = true;
-                    mFrozen = dispatchTriggerEvent(OnDialTriggerListener.LEFT_HANDLE);
-                }
-            } else if (mGrabbedState == RotarySelector.RIGHT_HANDLE_GRABBED) {
-                mTouchDragOffset = eventX - mRightHandleX;
-                invalidate();
-                if (eventX <= mLeftHandleX + EDGE_PADDING_DIP && !mTriggered) {
-                    mTriggered = true;
-                    mFrozen = dispatchTriggerEvent(OnDialTriggerListener.RIGHT_HANDLE);
-                }
-            }
-        } else if ((event.getAction() == MotionEvent.ACTION_UP)) {
-            if (DBG) log("touch-up");
-            // handle animating back to start if they didn't trigger
-            if (mGrabbedState == RotarySelector.LEFT_HANDLE_GRABBED
-                    && Math.abs(eventX - mLeftHandleX) > 5) {
-                mAnimating = true;
-                mAnimationEndTime = System.currentTimeMillis() + ANIMATION_DURATION_MILLIS;
-                mAnimatingDelta = eventX - mLeftHandleX;
-            } else if (mGrabbedState == RotarySelector.RIGHT_HANDLE_GRABBED
-                    && Math.abs(eventX - mRightHandleX) > 5) {
-                mAnimating = true;
-                mAnimationEndTime = System.currentTimeMillis() + ANIMATION_DURATION_MILLIS;
-                mAnimatingDelta = eventX - mRightHandleX;
-            }
-
-            mTouchDragOffset = 0;
-            mGrabbedState = RotarySelector.NOTHING_GRABBED;
-            invalidate();
-        } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
-            if (DBG) log("touch-cancel");
-            reset();
-            invalidate();
+                break;
         }
         return true;
     }
@@ -446,7 +491,7 @@
     private void reset() {
         mAnimating = false;
         mTouchDragOffset = 0;
-        mGrabbedState = RotarySelector.NOTHING_GRABBED;
+        mGrabbedState = NOTHING_GRABBED;
         mTriggered = false;
     }
 
@@ -489,12 +534,11 @@
     /**
      * Dispatches a trigger event to our listener.
      */
-    private boolean dispatchTriggerEvent(int whichHandle) {
+    private void dispatchTriggerEvent(int whichHandle) {
         vibrate(VIBRATE_LONG);
         if (mOnDialTriggerListener != null) {
-            return mOnDialTriggerListener.onDialTrigger(this, whichHandle);
+            mOnDialTriggerListener.onDialTrigger(this, whichHandle);
         }
-        return false;
     }
 
     /**
@@ -515,22 +559,13 @@
         public static final int RIGHT_HANDLE = 2;
 
         /**
-         * @hide
-         * The center handle is currently unused.
-         */
-        public static final int CENTER_HANDLE = 3;
-
-        /**
          * Called when the dial is triggered.
          *
          * @param v The view that was triggered
          * @param whichHandle  Which "dial handle" the user grabbed,
-         *        either {@link #LEFT_HANDLE}, {@link #RIGHT_HANDLE}, or
-         *        {@link #CENTER_HANDLE}.
-         * @return Whether the widget should freeze (e.g when the action goes to another screen,
-         *         you want the UI to stay put until the transition occurs).
+         *        either {@link #LEFT_HANDLE}, {@link #RIGHT_HANDLE}.
          */
-        boolean onDialTrigger(View v, int whichHandle);
+        void onDialTrigger(View v, int whichHandle);
     }
 
 
diff --git a/core/java/com/google/android/gdata/client/AndroidGDataClient.java b/core/java/com/google/android/gdata/client/AndroidGDataClient.java
index 998f940..9a2a51d 100644
--- a/core/java/com/google/android/gdata/client/AndroidGDataClient.java
+++ b/core/java/com/google/android/gdata/client/AndroidGDataClient.java
@@ -19,6 +19,7 @@
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.entity.AbstractHttpEntity;
+import org.apache.http.entity.ByteArrayEntity;
 
 import android.content.ContentResolver;
 import android.content.Context;
@@ -26,6 +27,7 @@
 import android.text.TextUtils;
 import android.util.Config;
 import android.util.Log;
+import android.os.SystemProperties;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -55,6 +57,10 @@
 
     private static final int MAX_REDIRECTS = 10;
 
+    // boolean system property that can be used to control whether or not
+    // requests/responses are gzip'd.
+    private static final String NO_GZIP_SYSTEM_PROPERTY = "sync.nogzip";
+
     private final GoogleHttpClient mHttpClient;
     private ContentResolver mResolver;
 
@@ -212,7 +218,10 @@
 
             HttpUriRequest request = creator.createRequest(uri);
 
-            AndroidHttpClient.modifyRequestToAcceptGzipResponse(request);
+            if (!SystemProperties.getBoolean(NO_GZIP_SYSTEM_PROPERTY, false)) {
+                AndroidHttpClient.modifyRequestToAcceptGzipResponse(request);
+            }
+
             // only add the auth token if not null (to allow for GData feeds that do not require
             // authentication.)
             if (!TextUtils.isEmpty(authToken)) {
@@ -487,7 +496,12 @@
             }
         }
 
-        AbstractHttpEntity entity = AndroidHttpClient.getCompressedEntity(entryBytes, mResolver);
+        AbstractHttpEntity entity;
+        if (SystemProperties.getBoolean(NO_GZIP_SYSTEM_PROPERTY, false)) {
+            entity = new ByteArrayEntity(entryBytes);
+        } else {
+            entity = AndroidHttpClient.getCompressedEntity(entryBytes, mResolver);
+        }
         entity.setContentType(entry.getContentType());
         return entity;
     }
diff --git a/core/java/com/google/android/gdata2/client/AndroidGDataClient.java b/core/java/com/google/android/gdata2/client/AndroidGDataClient.java
index 6ba791d..3721fa4 100644
--- a/core/java/com/google/android/gdata2/client/AndroidGDataClient.java
+++ b/core/java/com/google/android/gdata2/client/AndroidGDataClient.java
@@ -22,6 +22,7 @@
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.entity.AbstractHttpEntity;
+import org.apache.http.entity.ByteArrayEntity;
 
 import android.content.ContentResolver;
 import android.content.Context;
@@ -29,6 +30,7 @@
 import android.text.TextUtils;
 import android.util.Config;
 import android.util.Log;
+import android.os.SystemProperties;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -59,6 +61,9 @@
     private static final int MAX_REDIRECTS = 10;
     private static String DEFAULT_GDATA_VERSION = "2.0";
 
+    // boolean system property that can be used to control whether or not
+    // requests/responses are gzip'd.
+    private static final String NO_GZIP_SYSTEM_PROPERTY = "sync.nogzip";
 
     private String mGDataVersion; 
     private final GoogleHttpClient mHttpClient;
@@ -213,7 +218,7 @@
         HttpResponse response = null;
         int status = 500;
         int redirectsLeft = MAX_REDIRECTS;
-        
+
         URI uri;
         try {
             uri = new URI(uriString);
@@ -230,7 +235,10 @@
 
             HttpUriRequest request = creator.createRequest(uri);
 
-            AndroidHttpClient.modifyRequestToAcceptGzipResponse(request);
+            if (!SystemProperties.getBoolean(NO_GZIP_SYSTEM_PROPERTY, false)) {
+                AndroidHttpClient.modifyRequestToAcceptGzipResponse(request);
+            }
+
             // only add the auth token if not null (to allow for GData feeds that do not require
             // authentication.)
             if (!TextUtils.isEmpty(authToken)) {
@@ -547,7 +555,13 @@
             }
         }
 
-        AbstractHttpEntity entity = AndroidHttpClient.getCompressedEntity(entryBytes, mResolver);
+        AbstractHttpEntity entity;
+        if (SystemProperties.getBoolean(NO_GZIP_SYSTEM_PROPERTY, false)) {
+            entity = new ByteArrayEntity(entryBytes);
+        } else {
+            entity = AndroidHttpClient.getCompressedEntity(entryBytes, mResolver);
+        }
+
         entity.setContentType(entry.getContentType());
         return entity;
     }
@@ -587,4 +601,3 @@
         throw new IOException("Unable to process batch request.");
     }
 }   
-
diff --git a/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java
index df91ea6..568aeb7 100644
--- a/core/java/com/google/android/mms/pdu/PduPersister.java
+++ b/core/java/com/google/android/mms/pdu/PduPersister.java
@@ -810,7 +810,7 @@
     public void updateHeaders(Uri uri, SendReq sendReq) {
         PDU_CACHE_INSTANCE.purge(uri);
 
-        ContentValues values = new ContentValues(9);
+        ContentValues values = new ContentValues(10);
         byte[] contentType = sendReq.getContentType();
         if (contentType != null) {
             values.put(Mms.CONTENT_TYPE, toIsoString(contentType));
@@ -856,6 +856,11 @@
             values.put(Mms.SUBJECT, toIsoString(subject.getTextString()));
             values.put(Mms.SUBJECT_CHARSET, subject.getCharacterSet());
         }
+        
+        long messageSize = sendReq.getMessageSize();
+        if (messageSize > 0) {
+            values.put(Mms.MESSAGE_SIZE, messageSize);
+        }
 
         PduHeaders headers = sendReq.getPduHeaders();
         HashSet<String> recipients = new HashSet<String>();
diff --git a/core/java/com/google/android/mms/pdu/SendReq.java b/core/java/com/google/android/mms/pdu/SendReq.java
index 9081b0c..9ea6e47 100644
--- a/core/java/com/google/android/mms/pdu/SendReq.java
+++ b/core/java/com/google/android/mms/pdu/SendReq.java
@@ -206,6 +206,26 @@
     }
 
     /**
+     * Get X-Mms-MessageSize value.
+     *
+     * Expiry-value = size of message
+     *
+     * @return the value
+     */
+    public long getMessageSize() {
+        return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE);
+    }
+
+    /**
+     * Set X-Mms-MessageSize value.
+     *
+     * @param value the value
+     */
+    public void setMessageSize(long value) {
+        mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE);
+    }
+
+    /**
      * Get From value.
      * From-value = Value-length
      *      (Address-present-token Encoded-string-value | Insert-address-token)
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index ce2b10c..6b92994 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -55,7 +55,7 @@
 
     jobject     mCameraJObjectWeak;     // weak reference to java object
     jclass      mCameraJClass;          // strong reference to java class
-    sp<Camera>  mCamera;                // strong reference to native object 
+    sp<Camera>  mCamera;                // strong reference to native object
     Mutex       mLock;
 };
 
@@ -391,20 +391,26 @@
     }
 }
 
-static jint android_hardware_Camera_lock(JNIEnv *env, jobject thiz)
+static void android_hardware_Camera_lock(JNIEnv *env, jobject thiz)
 {
     LOGV("lock");
     sp<Camera> camera = get_native_camera(env, thiz, NULL);
-    if (camera == 0) return INVALID_OPERATION;
-    return (jint) camera->lock();
+    if (camera == 0) return;
+
+    if (camera->lock() != NO_ERROR) {
+        jniThrowException(env, "java/lang/RuntimeException", "lock failed");
+    }
 }
 
-static jint android_hardware_Camera_unlock(JNIEnv *env, jobject thiz)
+static void android_hardware_Camera_unlock(JNIEnv *env, jobject thiz)
 {
     LOGV("unlock");
     sp<Camera> camera = get_native_camera(env, thiz, NULL);
-    if (camera == 0) return INVALID_OPERATION;
-    return (jint) camera->unlock();
+    if (camera == 0) return;
+
+    if (camera->unlock() != NO_ERROR) {
+        jniThrowException(env, "java/lang/RuntimeException", "unlock failed");
+    }
 }
 
 //-------------------------------------------------
@@ -450,10 +456,10 @@
     "()V",
     (void*)android_hardware_Camera_reconnect },
   { "lock",
-    "()I",
+    "()V",
     (void*)android_hardware_Camera_lock },
   { "unlock",
-    "()I",
+    "()V",
     (void*)android_hardware_Camera_unlock },
 };
 
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index a185d8d..ba13519 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -133,23 +133,13 @@
     LOGV(__FUNCTION__);
     if (nat) {
         const char *c_path = env->GetStringUTFChars(path, NULL);
-        DBusError err;
-        dbus_error_init(&err);
 
-        DBusMessage *reply =
-                dbus_func_args_timeout(env, nat->conn, -1, c_path,
-                               "org.bluez.AudioSink", "Connect",
-                                DBUS_TYPE_INVALID);
+        bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
+                                    c_path, "org.bluez.AudioSink", "Connect",
+                                    DBUS_TYPE_INVALID);
+
         env->ReleaseStringUTFChars(path, c_path);
-
-        if (!reply && dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-            return JNI_FALSE;
-        } else if (!reply) {
-            LOGE("DBus reply is NULL in function %s", __FUNCTION__);
-            return JNI_FALSE;
-        }
-        return JNI_TRUE;
+        return ret ? JNI_TRUE : JNI_FALSE;
     }
 #endif
     return JNI_FALSE;
@@ -161,23 +151,13 @@
     LOGV(__FUNCTION__);
     if (nat) {
         const char *c_path = env->GetStringUTFChars(path, NULL);
-        DBusError err;
-        dbus_error_init(&err);
 
-        DBusMessage *reply =
-              dbus_func_args_timeout(env, nat->conn, -1, c_path,
-                                     "org.bluez.AudioSink", "Disconnect",
-                                     DBUS_TYPE_INVALID);
+        bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
+                                    c_path, "org.bluez.AudioSink", "Disconnect",
+                                    DBUS_TYPE_INVALID);
+
         env->ReleaseStringUTFChars(path, c_path);
-
-        if (!reply && dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-            return JNI_FALSE;
-        } else if (!reply) {
-            LOGE("DBus reply is NULL in function %s", __FUNCTION__);
-            return JNI_FALSE;
-        }
-        return JNI_TRUE;
+        return ret ? JNI_TRUE : JNI_FALSE;
     }
 #endif
     return JNI_FALSE;
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index e703ed8..e37e832 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -48,6 +48,8 @@
 static jmethodID method_onDeviceDisconnectRequested;
 
 static jmethodID method_onCreatePairedDeviceResult;
+static jmethodID method_onCreateDeviceResult;
+static jmethodID method_onDiscoverServicesResult;
 static jmethodID method_onGetDeviceServiceChannelResult;
 
 static jmethodID method_onRequestPinCode;
@@ -92,6 +94,10 @@
 
     method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
                                                          "(Ljava/lang/String;I)V");
+    method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult",
+                                                         "(Ljava/lang/String;Z)V");
+    method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult",
+                                                         "(Ljava/lang/String;Z)V");
 
     method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize",
                                                "(Ljava/lang/String;Ljava/lang/String;)Z");
@@ -1097,6 +1103,54 @@
     free(user);
 }
 
+void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
+    LOGV(__FUNCTION__);
+
+    native_data_t *nat = (native_data_t *)n;
+    const char *address= (const char *)user;
+    DBusError err;
+    dbus_error_init(&err);
+    JNIEnv *env;
+    nat->vm->GetEnv((void**)&env, nat->envVer);
+
+    LOGV("... Address = %s", address);
+
+    bool result = JNI_TRUE;
+    if (dbus_set_error_from_message(&err, msg)) {
+        LOG_AND_FREE_DBUS_ERROR(&err);
+        result = JNI_FALSE;
+    }
+    env->CallVoidMethod(nat->me,
+                        method_onCreateDeviceResult,
+                        env->NewStringUTF(address),
+                        result);
+    free(user);
+}
+
+void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
+    LOGV(__FUNCTION__);
+
+    native_data_t *nat = (native_data_t *)n;
+    const char *path = (const char *)user;
+    DBusError err;
+    dbus_error_init(&err);
+    JNIEnv *env;
+    nat->vm->GetEnv((void**)&env, nat->envVer);
+
+    LOGV("... Device Path = %s", path);
+
+    bool result = JNI_TRUE;
+    if (dbus_set_error_from_message(&err, msg)) {
+        LOG_AND_FREE_DBUS_ERROR(&err);
+        result = JNI_FALSE;
+    }
+    env->CallVoidMethod(nat->me,
+                        method_onDiscoverServicesResult,
+                        env->NewStringUTF(path),
+                        result);
+    free(user);
+}
+
 void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
     LOGV(__FUNCTION__);
 
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index 0b71acb..c2f93eea 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -66,6 +66,8 @@
                                             DBusMessage *msg,
                                             void *data);
 void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
+void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
+void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
 
 
 /** Get native data stored in the opaque (Java code maintained) pointer mNativeData
@@ -385,33 +387,24 @@
 
 static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
     LOGV(__FUNCTION__);
-    jboolean result = JNI_FALSE;
 #ifdef HAVE_BLUETOOTH
     native_data_t *nat = get_native_data(env, object);
     if (nat) {
         const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
-        DBusError err;
-        dbus_error_init(&err);
-        DBusMessage *reply =
-            dbus_func_args_error(env, nat->conn, &err,
-                                 get_adapter_path(env, object),
-                                 DBUS_ADAPTER_IFACE, "RemoveDevice",
-                                 DBUS_TYPE_OBJECT_PATH, &c_object_path,
-                                 DBUS_TYPE_INVALID);
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            } else
-                LOGE("DBus reply is NULL in function %s", __FUNCTION__);
-            result = JNI_FALSE;
-        } else {
-            result = JNI_TRUE;
-        }
+        bool ret = dbus_func_args_async(env, nat->conn, -1,
+                                        NULL,
+                                        NULL,
+                                        NULL,
+                                        get_adapter_path(env, object),
+                                        DBUS_ADAPTER_IFACE,
+                                        "RemoveDevice",
+                                        DBUS_TYPE_OBJECT_PATH, &c_object_path,
+                                        DBUS_TYPE_INVALID);
         env->ReleaseStringUTFChars(object_path, c_object_path);
-        if (reply) dbus_message_unref(reply);
+        return ret ? JNI_TRUE : JNI_FALSE;
     }
 #endif
-    return result;
+    return JNI_FALSE;
 }
 
 static jint enableNative(JNIEnv *env, jobject object) {
@@ -757,6 +750,75 @@
 #endif
 }
 
+
+static jboolean createDeviceNative(JNIEnv *env, jobject object,
+                                                jstring address) {
+    LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+    native_data_t *nat = get_native_data(env, object);
+    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
+    struct event_loop_native_data_t *eventLoopNat =
+            get_EventLoop_native_data(env, eventLoop);
+
+    if (nat && eventLoopNat) {
+        const char *c_address = env->GetStringUTFChars(address, NULL);
+        LOGV("... address = %s", c_address);
+        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
+        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
+
+        bool ret = dbus_func_args_async(env, nat->conn, -1,
+                                        onCreateDeviceResult,
+                                        context_address,
+                                        eventLoopNat,
+                                        get_adapter_path(env, object),
+                                        DBUS_ADAPTER_IFACE,
+                                        "CreateDevice",
+                                        DBUS_TYPE_STRING, &c_address,
+                                        DBUS_TYPE_INVALID);
+        env->ReleaseStringUTFChars(address, c_address);
+        return ret ? JNI_TRUE : JNI_FALSE;
+    }
+#endif
+    return JNI_FALSE;
+}
+
+static jboolean discoverServicesNative(JNIEnv *env, jobject object,
+                                               jstring path, jstring pattern) {
+    LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+    native_data_t *nat = get_native_data(env, object);
+    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
+    struct event_loop_native_data_t *eventLoopNat =
+            get_EventLoop_native_data(env, eventLoop);
+
+    if (nat && eventLoopNat) {
+        const char *c_path = env->GetStringUTFChars(path, NULL);
+        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
+        int len = env->GetStringLength(path) + 1;
+        char *context_path = (char *)calloc(len, sizeof(char));
+        strlcpy(context_path, c_path, len);  // for callback
+
+        LOGV("... Object Path = %s", c_path);
+        LOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern));
+
+        bool ret = dbus_func_args_async(env, nat->conn, -1,
+                                        onDiscoverServicesResult,
+                                        context_path,
+                                        eventLoopNat,
+                                        c_path,
+                                        DBUS_DEVICE_IFACE,
+                                        "DiscoverServices",
+                                        DBUS_TYPE_STRING, &c_pattern,
+                                        DBUS_TYPE_INVALID);
+        env->ReleaseStringUTFChars(path, c_path);
+        env->ReleaseStringUTFChars(pattern, c_pattern);
+        return ret ? JNI_TRUE : JNI_FALSE;
+    }
+#endif
+    return JNI_FALSE;
+}
+
+
 static JNINativeMethod sMethods[] = {
      /* name, signature, funcPtr */
     {"classInitNative", "()V", (void*)classInitNative},
@@ -797,6 +859,8 @@
             (void *)cancelPairingUserInputNative},
     {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
             (void *)setDevicePropertyBooleanNative},
+    {"createDeviceNative", "(Ljava/lang/String;)Z", (void *)createDeviceNative},
+    {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
 };
 
 int register_android_server_BluetoothService(JNIEnv *env) {
diff --git a/core/res/res/anim/recent_enter.xml b/core/res/res/anim/recent_enter.xml
new file mode 100644
index 0000000..54ae73b
--- /dev/null
+++ b/core/res/res/anim/recent_enter.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator">
+    <scale android:fromXScale="2.0" android:toXScale="1.0"
+           android:fromYScale="2.0" android:toYScale="1.0"
+           android:pivotX="50%" android:pivotY="50%"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/core/res/res/anim/recent_exit.xml b/core/res/res/anim/recent_exit.xml
new file mode 100644
index 0000000..32d64a4
--- /dev/null
+++ b/core/res/res/anim/recent_exit.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="1.0" android:toXScale="2.0"
+           android:fromYScale="1.0" android:toYScale="2.0"
+           android:pivotX="50%" android:pivotY="50%"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/core/res/res/drawable-hdpi/dark_header.9.png b/core/res/res/drawable-hdpi/dark_header.9.png
index a2fa569..3e63fa6 100644
--- a/core/res/res/drawable-hdpi/dark_header.9.png
+++ b/core/res/res/drawable-hdpi/dark_header.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_horizontal_bright.9.png b/core/res/res/drawable-hdpi/divider_horizontal_bright.9.png
index c7803a2..99a67b9 100644
--- a/core/res/res/drawable-hdpi/divider_horizontal_bright.9.png
+++ b/core/res/res/drawable-hdpi/divider_horizontal_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_horizontal_bright_opaque.9.png b/core/res/res/drawable-hdpi/divider_horizontal_bright_opaque.9.png
index d8d8aa9..cfe258b 100644
--- a/core/res/res/drawable-hdpi/divider_horizontal_bright_opaque.9.png
+++ b/core/res/res/drawable-hdpi/divider_horizontal_bright_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_horizontal_dark.9.png b/core/res/res/drawable-hdpi/divider_horizontal_dark.9.png
index 63859f7..30a68d0 100644
--- a/core/res/res/drawable-hdpi/divider_horizontal_dark.9.png
+++ b/core/res/res/drawable-hdpi/divider_horizontal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png b/core/res/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png
index ced2832..8f35315 100644
--- a/core/res/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png
+++ b/core/res/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_vertical_bright.9.png b/core/res/res/drawable-hdpi/divider_vertical_bright.9.png
index 1035656..99a67b9 100644
--- a/core/res/res/drawable-hdpi/divider_vertical_bright.9.png
+++ b/core/res/res/drawable-hdpi/divider_vertical_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_bright_opaque.9.png b/core/res/res/drawable-hdpi/divider_vertical_bright_opaque.9.png
similarity index 100%
rename from core/res/res/drawable/divider_vertical_bright_opaque.9.png
rename to core/res/res/drawable-hdpi/divider_vertical_bright_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_vertical_dark.9.png b/core/res/res/drawable-hdpi/divider_vertical_dark.9.png
new file mode 100644
index 0000000..30a68d0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/divider_vertical_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_dark_opaque.9.png b/core/res/res/drawable-hdpi/divider_vertical_dark_opaque.9.png
similarity index 100%
rename from core/res/res/drawable/divider_vertical_dark_opaque.9.png
rename to core/res/res/drawable-hdpi/divider_vertical_dark_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_emergency.png b/core/res/res/drawable-hdpi/ic_emergency.png
index a2dd372..b4465ff 100644
--- a/core/res/res/drawable-hdpi/ic_emergency.png
+++ b/core/res/res/drawable-hdpi/ic_emergency.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lock_ringer_off.png b/core/res/res/drawable-hdpi/ic_lock_ringer_off.png
new file mode 100644
index 0000000..e7cb234
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_ringer_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lock_ringer_on.png b/core/res/res/drawable-hdpi/ic_lock_ringer_on.png
new file mode 100644
index 0000000..ce0cfab9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_ringer_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/light_header.9.png b/core/res/res/drawable-hdpi/light_header.9.png
index 27db59d..6fc53ca 100644
--- a/core/res/res/drawable-hdpi/light_header.9.png
+++ b/core/res/res/drawable-hdpi/light_header.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/title_bar_medium.png b/core/res/res/drawable-hdpi/title_bar_medium.png
new file mode 100644
index 0000000..c13dd26
--- /dev/null
+++ b/core/res/res/drawable-hdpi/title_bar_medium.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dark_header.9.png b/core/res/res/drawable-mdpi/dark_header.9.png
index 7242b61..f4a14f1d 100644
--- a/core/res/res/drawable-mdpi/dark_header.9.png
+++ b/core/res/res/drawable-mdpi/dark_header.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_bright_opaque.9.png b/core/res/res/drawable-mdpi/divider_vertical_bright_opaque.9.png
similarity index 100%
copy from core/res/res/drawable/divider_vertical_bright_opaque.9.png
copy to core/res/res/drawable-mdpi/divider_vertical_bright_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_dark.9.png b/core/res/res/drawable-mdpi/divider_vertical_dark.9.png
similarity index 100%
rename from core/res/res/drawable/divider_vertical_dark.9.png
rename to core/res/res/drawable-mdpi/divider_vertical_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_dark_opaque.9.png b/core/res/res/drawable-mdpi/divider_vertical_dark_opaque.9.png
similarity index 100%
copy from core/res/res/drawable/divider_vertical_dark_opaque.9.png
copy to core/res/res/drawable-mdpi/divider_vertical_dark_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_ringer_off.png b/core/res/res/drawable-mdpi/ic_lock_ringer_off.png
new file mode 100644
index 0000000..98cfb11
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_ringer_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_ringer_on.png b/core/res/res/drawable-mdpi/ic_lock_ringer_on.png
new file mode 100644
index 0000000..691b99e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_ringer_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/title_bar_medium.png b/core/res/res/drawable-mdpi/title_bar_medium.png
new file mode 100644
index 0000000..9d01f79
--- /dev/null
+++ b/core/res/res/drawable-mdpi/title_bar_medium.png
Binary files differ
diff --git a/core/res/res/layout/contact_header.xml b/core/res/res/layout/contact_header.xml
index 8d7e470..e800dfa 100644
--- a/core/res/res/layout/contact_header.xml
+++ b/core/res/res/layout/contact_header.xml
@@ -19,17 +19,17 @@
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
-    android:background="@drawable/title_bar_tall"
+    android:background="@drawable/title_bar_medium"
     android:paddingRight="5dip"
     android:gravity="center_vertical">
     
-    <ImageView android:id="@+id/photo"
-        android:layout_width="56dip"
-        android:layout_height="62dip"
+    <android.widget.FasttrackBadgeWidget android:id="@+id/photo"
+        android:layout_alignParentLeft="true"
+        android:layout_centerVertical="true"
         android:layout_marginRight="10dip"
         android:layout_marginLeft="10dip"
-        android:scaleType="fitCenter"
-        android:background="@drawable/fasttrack_badge_middle_large"/>
+        style="@*android:style/Widget.FasttrackBadgeWidget.WindowSmall" />
+    />
     
     <LinearLayout
         android:layout_width="0dip"
diff --git a/core/res/res/layout/keyguard_screen_rotary_unlock.xml b/core/res/res/layout/keyguard_screen_rotary_unlock.xml
index cf97d04..9f18124 100644
--- a/core/res/res/layout/keyguard_screen_rotary_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_rotary_unlock.xml
@@ -83,6 +83,7 @@
         android:layout_marginTop="6dip"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="?android:attr/textColorSecondary"
+        android:drawablePadding="4dip"
         />
 
     <TextView
@@ -94,6 +95,7 @@
         android:layout_marginTop="6dip"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="?android:attr/textColorSecondary"
+        android:drawablePadding="4dip"
         />
 
     <TextView
@@ -108,15 +110,15 @@
         android:layout_marginTop="12dip"
         />
 
-    <!-- By having the rotary selector hang below "screen locked" text, we get a layout more
-         robust for different screen sizes.  On wvga, the widget should be flush with the bottom.-->
+    <!-- By having the rotary selector hang from the top, we get a layout more
+         robust for different screen sizes.  On hvga, the widget should be flush with the bottom.-->
     <com.android.internal.widget.RotarySelector
         android:id="@+id/rotary"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        android:layout_below="@id/screenLocked"
         android:layout_centerHorizontal="true"
-        android:layout_marginTop="24dip"
+        android:layout_alignParentTop="true"
+        android:layout_marginTop="286dip"
         />
 
     <!-- emergency call button shown when sim is missing or PUKd -->
diff --git a/core/res/res/layout/keyguard_screen_unlock_landscape.xml b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
index 929d0a2..6dd2949 100644
--- a/core/res/res/layout/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
@@ -21,7 +21,8 @@
      the user how to unlock their device, or make an emergency call.  This
      is the portrait layout.  -->
 
-<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="horizontal"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
@@ -34,31 +35,70 @@
             android:layout_width="0dip"
             android:layout_height="fill_parent"
             android:layout_weight="1.0"
+            android:gravity="center_horizontal"
             >
+        <TextView
+            android:id="@+id/carrier"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="5dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            />
+        <TextView
+            android:id="@+id/centerDot"
+            android:visibility="gone"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="5dip"
+            android:layout_marginRight="5dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="17sp"
+            />
+        <TextView
+            android:id="@+id/time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            android:layout_marginTop="5dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textSize="35sp"
+            />
+        <TextView
+            android:id="@+id/date"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:layout_marginTop="-12dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="17sp"
+            />
 
-        <!-- lock icon next to header text -->
-        <LinearLayout
-                android:orientation="horizontal"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="3dip"
-                android:gravity="center"
-                >
-            <ImageView android:id="@+id/unlockLockIcon"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:layout_marginRight="3dip"
-                       android:baselineAligned="true"
-                       android:gravity="center"
-                       android:src="@android:drawable/ic_lock_idle_lock"
-                    />
 
-            <TextView android:id="@+id/headerText"
-                      android:layout_width="wrap_content"
-                      android:layout_height="wrap_content"
-                      android:gravity="center"
-                      android:textSize="18sp"/>
-        </LinearLayout>
+        <View
+            android:id="@+id/divider"
+            android:layout_width="fill_parent"
+            android:layout_height="1dip"
+            android:layout_centerHorizontal="true"
+            android:background="@android:drawable/divider_horizontal_dark"
+                />
+
+        <!-- lock icon and header message -->
+        <TextView
+            android:id="@+id/headerText"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dip"
+            android:layout_centerHorizontal="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="17sp"
+            android:drawableLeft="@drawable/ic_lock_idle_lock"
+            android:drawablePadding="4dip"
+            android:gravity="center"
+            />
 
 
         <!-- fill space between header and button below -->
@@ -82,7 +122,7 @@
                 <Button android:id="@+id/emergencyCallAlone"
                     android:layout_width="fill_parent"
                     android:layout_height="wrap_content"
-                    android:text="@android:string/lockscreen_emergency_call"
+                    android:text="@string/lockscreen_emergency_call"
                     android:textSize="14sp"
                     android:drawableLeft="@drawable/ic_emergency"
                     android:drawablePadding="8dip"
@@ -105,7 +145,7 @@
                 <Button android:id="@+id/emergencyCallTogether"
                     android:layout_width="fill_parent"
                     android:layout_height="wrap_content"
-                    android:text="@android:string/lockscreen_emergency_call"
+                    android:text="@string/lockscreen_emergency_call"
                     android:textSize="14sp"
                     android:drawableLeft="@drawable/ic_emergency"
                     android:drawablePadding="8dip"
@@ -115,7 +155,7 @@
     </LinearLayout>
 
     <View
-         android:background="@android:drawable/code_lock_left"
+         android:background="@drawable/code_lock_left"
          android:layout_width="2dip"
          android:layout_height="fill_parent" />
 
@@ -124,4 +164,4 @@
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" />
 
-</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
+</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
\ No newline at end of file
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index a6c31b6..a5d44fc 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -23,54 +23,93 @@
 <com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
-    android:layout_width="wrap_content"
+    android:layout_width="fill_parent"
     android:layout_height="fill_parent"
+    android:gravity="center_horizontal"
     android:background="#A0000000"
         >
 
-    <!-- lock icon and header message -->
     <LinearLayout
+        android:id="@+id/carrierAndDate"
         android:orientation="horizontal"
-        android:layout_width="fill_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1.0"
-        android:gravity="center"
-            >
-
-        <ImageView android:id="@+id/unlockLockIcon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="13dip"
+        >
+        <TextView
+            android:id="@+id/carrier"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginRight="6dip"
-            android:baselineAligned="true"
-            android:gravity="center"
-            android:src="@android:drawable/ic_lock_idle_lock"
-        />
-
-        <TextView android:id="@+id/headerText"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="17sp"
+            />
+        <TextView
+            android:id="@+id/centerDot"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:gravity="center"
-            android:textSize="18sp"/>
+            android:layout_marginLeft="5dip"
+            android:layout_marginRight="5dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="17sp"
+            />
+        <TextView
+            android:id="@+id/date"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="17sp"
+            />
     </LinearLayout>
 
+    <TextView
+        android:id="@+id/time"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="-9dip"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textSize="48sp"
+        />
+
     <View
-         android:background="@android:drawable/code_lock_top"
-         android:layout_width="fill_parent"
-         android:layout_height="2dip" />
-    <com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
-         android:layout_width="wrap_content"
-         android:layout_height="wrap_content"
+        android:id="@+id/divider"
+        android:layout_width="fill_parent"
+        android:layout_height="1dip"
+        android:layout_marginTop="-4dip"
+        android:layout_centerHorizontal="true"
+        android:background="@android:drawable/divider_horizontal_dark"
+            />
+
+    <!-- lock icon and header message -->
+    <TextView
+        android:id="@+id/headerText"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="3dip"
+        android:layout_centerHorizontal="true"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="?android:attr/textColorSecondary"
+        android:textSize="17sp"
+        android:drawableLeft="@drawable/ic_lock_idle_lock"
+        android:drawablePadding="4dip"
+        />
+
+    <com.android.internal.widget.LockPatternView
+        android:id="@+id/lockPattern"
+        android:layout_width="fill_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:layout_marginTop="2dip"
          />
-    <View
-         android:background="@android:drawable/code_lock_bottom"
-         android:layout_width="fill_parent"
-         android:layout_height="8dip" />
 
     <!-- footer -->
     <FrameLayout
         android:layout_width="fill_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1.0"
+        android:layout_height="wrap_content"
         >
 
         <!-- option 1: a single emergency call button -->
@@ -82,8 +121,8 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_centerInParent="true"
-                android:text="@android:string/lockscreen_emergency_call"
-                android:textSize="14sp"
+                android:text="@string/lockscreen_emergency_call"
+                android:textAppearance="?android:attr/textAppearanceSmall"
                 android:drawableLeft="@drawable/ic_emergency"
                 android:drawablePadding="8dip"
                 />
@@ -105,8 +144,8 @@
                 android:layout_marginBottom="4dip"
                 android:layout_marginLeft="4dip"
                 android:layout_marginRight="2dip"
-                android:text="@android:string/lockscreen_emergency_call"
-                android:textSize="14sp"
+                android:text="@string/lockscreen_emergency_call"
+                android:textAppearance="?android:attr/textAppearanceSmall"
                 android:drawableLeft="@drawable/ic_emergency"
                 android:drawablePadding="8dip"
                 />
@@ -118,7 +157,7 @@
                 android:layout_marginBottom="4dip"
                 android:layout_marginLeft="2dip"
                 android:layout_marginRight="4dip"
-                android:textSize="14sp"
+                android:textAppearance="?android:attr/textAppearanceSmall"
                 android:visibility="invisible"
                 />
         </LinearLayout>
diff --git a/core/res/res/layout/tab_indicator.xml b/core/res/res/layout/tab_indicator.xml
index e3ea555..71e4001 100644
--- a/core/res/res/layout/tab_indicator.xml
+++ b/core/res/res/layout/tab_indicator.xml
@@ -18,8 +18,8 @@
     android:layout_width="0dip"
     android:layout_height="64dip"
     android:layout_weight="1"
-    android:layout_marginLeft="-4px"
-    android:layout_marginRight="-4px"
+    android:layout_marginLeft="-3dip"
+    android:layout_marginRight="-3dip"
     android:orientation="vertical"
     android:background="@android:drawable/tab_indicator">
 
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 85e10072..fba6c08 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"K souboru nelze získat přístup."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Požadovaný soubor nebyl nalezen."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Je zpracováváno příliš mnoho požadavků. Opakujte akci později."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Chyba přihlášení"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Synchronizace"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronizace"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Příliš mnoho smazaných položek služby <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"změna statistických údajů o baterii"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Umožňuje změnu shromážděných statistických údajů o baterii. Není určeno pro běžné aplikace."</string>
     <string name="permlab_backup" msgid="470013022865453920">"ovládání zálohování a obnovy systému"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Umožňuje aplikaci ovládat systémový mechanizmus pro zálohování a obnovu dat. Není určeno pro běžné aplikace."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"zálohování a obnovení dat aplikace"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Umožňuje aplikaci podílet se na systémovém mechanizmu zálohování a obnovení."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"zobrazení nepovolených oken"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Umožňuje vytvoření oken, která mají být použita interním systémem uživatelského rozhraní. Běžné aplikace toto nastavení nepoužívají."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"zobrazení upozornění systémové úrovně"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"změna globálních nastavení systému"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Umožňuje aplikaci upravit data nastavení systému. Škodlivé aplikace mohou poškodit konfiguraci vašeho systému."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"změny zabezpečených nastavení systému"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Umožňuje aplikaci změnit data zabezpečených nastavení systému. Běžné aplikace toto nastavení nevyužívají."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"změna mapy služeb Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Umožňuje aplikaci změnit mapu služeb Google. Běžné aplikace toto nastavení nevyužívají."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"automatické spuštění při startu"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Umožňuje aplikaci bez vašeho zásahu volat na telefonní čísla. Škodlivé aplikace mohou na váš telefonní účet připsat neočekávané hovory. Toto nastavení aplikaci neumožňuje volat na tísňové linky."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"přímé volání na libovolná telefonní čísla"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Umožňuje aplikaci bez vašeho zásahu vytočit jakékoli telefonní číslo, včetně čísel tísňového volání. Škodlivé aplikace mohou provádět zbytečná a nezákonná volání na tísňové linky."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"přímo spustit nastavení telefonu CDMA"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Umožňuje aplikaci zahájit zřizování CDMA. Škodlivé aplikace mohou zřizování CDMA zahájit samovolně."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"ovládání oznámení o aktualizaci polohy"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Umožňuje povolit či zakázat aktualizace polohy prostřednictvím bezdrátového připojení. Aplikace toto nastavení obvykle nepoužívají."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"přístup k vlastnostem Checkin"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"<xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své bezpečnostní gesto. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení telefonu pomocí přihlášení do účtu Google."\n\n" Akci prosím opakujte za několik sekund (<xliff:g id="NUMBER_2">%d</xliff:g>)."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Sekundy zbývající do dalšího pokusu: <xliff:g id="NUMBER">%d</xliff:g>."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Zapomněli jste gesto?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Odemčení účtu"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Gesta: Příliš mnoho pokusů"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Chcete-li telefon odemknout, přihlaste se pomocí svého účtu Google"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Uživatelské jméno (e-mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Heslo"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Přihlásit se"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neplatné uživatelské jméno nebo heslo."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Probíhá kontrola..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Vymazat"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Prosím připojte dobíjecí zařízení"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Baterie je vybitá:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"zbývá méně než <xliff:g id="NUMBER">%d%%</xliff:g>."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Využití baterie"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Test továrního nastavení se nezdařil"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Test FACTORY_TEST lze provést pouze u balíčků nainstalovaných ve složce /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nebyl nalezen žádný balíček umožňující test FACTORY_TEST."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"zítra"</item>
     <item quantity="other" msgid="2973062968038355991">"zbývající počet dní: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"dne <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"v <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"roku <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"den"</string>
     <string name="days" msgid="4774547661021344602">"d."</string>
     <string name="hour" msgid="2126771916426189481">"hodina"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Kopírovat vše"</string>
     <string name="paste" msgid="5629880836805036433">"Vložit"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Kopírovat adresu URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Metoda zadávání dat"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Přidat slovo „<xliff:g id="WORD">%s</xliff:g>“ do slovníku"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Úpravy textu"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Málo paměti"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"V telefonu zbývá málo místa pro ukládání dat."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Před vypnutím úložiště USB se přesvědčte, zda byl hostitel USB odpojen. Úložiště USB vypnete volbou Vypnout."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Vypnout"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Zrušit"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Při vypínání úložiště USB došlo k problémům. Zkontrolujte, zda byl hostitel USB odpojen, a zkuste to znovu."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formátovat kartu SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Opravdu chcete kartu SD naformátovat? Všechna data na kartě budou ztracena."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formátovat"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes rozhraní USB připojeno"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"K vašemu telefonu je připojen počítač."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Výběr metody zadávání dat"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Vytvořit kontakt"\n"pro <xliff:g id="NUMBER">%s</xliff:g>."</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"Zaškrtnuto"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"Nezaškrtnuto"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Uvedené aplikace od <xliff:g id="APPLICATION">%2$s</xliff:g> požadují oprávnění přistupovat k přihlašovacím údajům účtu <xliff:g id="ACCOUNT">%1$s</xliff:g>. Chcete toto oprávnění udělit? Pokud je udělíte, vaše odpověď se uloží a tato výzva se již nebude zobrazovat."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Uvedené aplikace požadují od <xliff:g id="APPLICATION">%3$s</xliff:g> oprávnění přistupovat k přihlašovacím údajům (typ: <xliff:g id="TYPE">%1$s</xliff:g>) účtu <xliff:g id="ACCOUNT">%2$s</xliff:g>. Chcete toto oprávnění udělit? Pokud je udělíte, vaše odpověď se uloží a tato výzva se již nebude zobrazovat."</string>
     <string name="allow" msgid="7225948811296386551">"Povolit"</string>
     <string name="deny" msgid="2081879885755434506">"Odepřít"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Požadováno oprávnění"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Metoda zadávání dat"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Synchronizace"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Usnadnění"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Změnit tapetu"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ec4c911..99f8ec9 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Der kunne ikke oprettes adgang til filen."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Den anmodede fil blev ikke fundet."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Der behandles for mange anmodninger. Prøv igen senere."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Loginfejl"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Synkroniser"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synkroniser"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"For mange <xliff:g id="CONTENT_TYPE">%s</xliff:g> sletninger"</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"rediger batteristatistikker"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Tillader ændring af indsamlede batteristatistikker. Ikke til brug for normale programmer."</string>
     <string name="permlab_backup" msgid="470013022865453920">"kontroller sikkerhedskopiering af system, og gendan"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Tillader et program at kontrollere systemets sikkerhedskopierings- og gendannelsesmekanisme. Ikke til brug til normale programmer."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"Sikkerhedskopier og gendan programmets data"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Tillader et program at kontrollere systemets sikkerhedskopierings- og gendannelsesmekanisme."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"vis uautoriserede vinduer"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Tillader oprettelse af vinduer, der er beregnet til at blive brugt af den interne systembrugergrænseflade. Ikke til brug for normale programmer."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"vis underretninger på systemniveau"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"rediger globale systemindstillinger"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Tillader et program at ændre systemets indstillingsdata. Ondsindede programmer kan skade systemets konfiguration."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"rediger sikre systemindstillinger"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Tillader et program at ændre systemernes sikre indstillingsdata. Ikke til brug til almindelige programmer."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"rediger kortet over Google-tjenester"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Tillader et program at ændre kortet over Google-tjenester. Ikke til brug til normale programmer."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"start automatisk ved opstart"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Tillader programmet at ringe til telefonnumre uden din indgriben. Ondsindede programmer kan forårsage uventede opkald på din telefonregning. Vær opmærksom på, at det ikke tillader programmet at ringe til nødnumre."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"ring direkte op til alle telefonnumre"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Tillader programmet at ringe til alle telefonnumre inklusive nødnumre uden din indgriben. Ondsindede programmer kan eventuelt foretage unødvendige og ulovlige opkald til nødtjenester."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"start CDMA-telefonopsætning direkte"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Tillader, at programmet starter CDMA-levering. Onsindede programmer kan starte unødvendig CDMA-levering"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"kontroller meddelelser om placeringsopdatering"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Tillader aktivering/deaktivering af placeringsdata fra radioen. Ikke til brug til normale programmer."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"egenskaber for adgangskontrol"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Du har tegnet dit mønster til at låse op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> forsøg mere vil du blive bedt om at låse din telefon op ved hjælp af dit Google-login"\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Prøv igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Har du glemt mønster?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Oplåsning af konto"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"For mange mønsterforsøg!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"For at låse op skal du logge ind med din Google-konto"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Brugernavn (e-mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Adgangskode"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Log ind"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ugyldigt brugernavn eller ugyldig adgangskode."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Kontrollerer ..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ryd"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Forbind oplader"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Batteriet er ved at blive tomt:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"mindre end <xliff:g id="NUMBER">%d%%</xliff:g> tilbage."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Batteriforbrug"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabrikstest mislykkedes"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Handlingen FACTORY_TEST understøttes kun af pakker installeret i /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Der blev ikke fundet nogen pakke, som leverer handlingen FACTORY_TEST."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"i morgen"</item>
     <item quantity="other" msgid="2973062968038355991">"om <xliff:g id="COUNT">%d</xliff:g> dage"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"til <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"kl. <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"i <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"dag"</string>
     <string name="days" msgid="4774547661021344602">"dage"</string>
     <string name="hour" msgid="2126771916426189481">"time"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Kopier alle"</string>
     <string name="paste" msgid="5629880836805036433">"Indsæt"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Kopier webadresse"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Inputmetode"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Føj \"<xliff:g id="WORD">%s</xliff:g>\" til ordbog"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Rediger tekst"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Der er ikke så meget plads tilbage"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Der er næsten ikke mere plads på telefonen."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Inden du slår USB-lagringen fra, skal du sørge for, at du demonterer USB-værten. Vælg \"Slå fra\" for at slå USB-lagringen fra."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Slå fra"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Annuller"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Der opstod et problem med at slå USB-lagringen fra. Sørg for, at du har demonteret USB-værten, og prøv så igen."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formater SD-kort"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Er du sikker på, du ønsker at formatere SD-kortet? Alle data på kortet mistes."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formater"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning forbundet"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Der er forbundet en computer til din telefon."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Vælg inputmetode"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Opret kontakt"\n"ved hjælp af <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"kontrolleret"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"ikke kontrolleret"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"De nævnte programmer beder om tilladelse til at få adgang til loginoplysningerne til kontoen <xliff:g id="ACCOUNT">%1$s</xliff:g> fra <xliff:g id="APPLICATION">%2$s</xliff:g>. Ønsker du at give denne tilladelse? Hvis ja, så huskes dit svar, og du vil ikke blive spurgt om det igen."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"De nævnte programmer beder om tilladelse til at få adgang til <xliff:g id="TYPE">%1$s</xliff:g>-loginoplysningerne til kontoen <xliff:g id="ACCOUNT">%2$s</xliff:g> fra <xliff:g id="APPLICATION">%3$s</xliff:g>. Vil du give denne tilladelse? Hvis ja, så huskes dit svar, og du vil ikke blive spurgt om det igen."</string>
     <string name="allow" msgid="7225948811296386551">"Tillad"</string>
     <string name="deny" msgid="2081879885755434506">"Afvis"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Der er anmodet om tilladelse"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Inputmetode"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Synkroniser"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgængelighed"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapet"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Skift tapet"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 8792dd1..02f685a 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Auf die Datei konnte nicht zugegriffen werden."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Die angeforderte Datei wurde nicht gefunden."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Es werden zurzeit zu viele Anfragen verarbeitet. Versuchen Sie es später erneut."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Fehler bei der Anmeldung"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Synchronisieren"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronisieren"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Zu viele <xliff:g id="CONTENT_TYPE">%s</xliff:g> gelöscht."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"Akku-Daten ändern"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Ermöglicht die Änderung von gesammelten Akku-Daten. Nicht für normale Anwendungen vorgesehen."</string>
     <string name="permlab_backup" msgid="470013022865453920">"Systemsicherung und -wiederherstellung kontrollieren"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Der Anwendung wird die Steuerung des Sicherungs- und Wiederherstellungsmechanismus des Systems ermöglicht. Nicht für normale Anwendungen vorgesehen."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"Anwendungsdaten sichern und wiederherstellen"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Der Anwendung wird die Teilnahme am Sicherungs- und Wiederherstellungsmechanismus des Systems ermöglicht."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"nicht autorisierte Fenster anzeigen"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Ermöglicht die Erstellung von Fenstern, die von der Benutzeroberfläche des internen Systems verwendet werden. Nicht für normale Anwendungen geeignet."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"Warnungen auf Systemebene anzeigen"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"Allgemeine Systemeinstellungen ändern"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Ermöglicht einer Anwendung, die Einstellungsdaten des Systems zu ändern. Schädliche Anwendungen können so die Systemkonfiguration beschädigen."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"Sicherheitseinstellungen für das System ändern"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Der Anwendung wird das Ändern der Sicherheitseinstellungsdaten des Systems ermöglicht. Nicht für normale Anwendungen vorgesehen."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"Google Services Map ändern"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Ermöglicht einer Anwendung, Änderungen an der Google Services Map vorzunehmen. Nicht für normale Anwendungen vorgesehen."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"Automatisch nach dem Booten starten"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Ermöglicht dem Anwendungen, Rufnummern ohne Ihr Eingreifen zu wählen. Schädliche Anwendungen können für unerwartete Anrufe auf Ihrer Telefonrechnung verantwortlich sein. Das Wählen von Notrufnummern ist allerdings nicht möglich."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"Alle Telefonnummern direkt anrufen"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Ermöglicht der Anwendung, ohne Ihr Eingreifen eine beliebige Telefonnummer zu wählen, einschließlich Notfallnummern. Schädliche Anwendungen können so unnötige und illegale Anrufe an Notdienste tätigen."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"CDMA-Telefoneinrichtung direkt starten"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Der Anwendung wird der Start der CDMA-Bereitstellung ermöglicht. Schädliche Anwendungen können die CDMA-Bereitstellung unnötigerweise starten."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"Benachrichtigungen für Standortaktualisierung steuern"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Ermöglicht die Aktivierung/Deaktivierung der Mobilfunkbenachrichtigungen über Standort-Updates. Nicht für normale Anwendungen vorgesehen."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"Auf Check-In-Eigenschaften zugreifen"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe Ihrer Google-Anmeldeinformationen zu entsperren. "\n\n"Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Versuchen Sie es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden erneut."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Muster vergessen?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Kontoentsperrung"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Zu viele Versuche!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Melden Sie sich zum Entsperren mit Ihrem Google-Konto an."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nutzername (E-Mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Passwort"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Anmelden"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ungültiger  Nutzername oder ungültiges Passwort."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Überprüfung..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Löschen"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Ladegerät anschließen"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Akku ist fast leer."</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"Nur noch weniger als <xliff:g id="NUMBER">%d%%</xliff:g> vorhanden."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Akkuverbrauch"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Werkstest fehlgeschlagen"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Die Aktion FACTORY_TEST wird nur für unter \"/system/app\" gespeicherte Pakete unterstützt."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Es wurden kein Paket mit der Aktion FACTORY_TEST gefunden."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"morgen"</item>
     <item quantity="other" msgid="2973062968038355991">"in <xliff:g id="COUNT">%d</xliff:g> Tagen"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"am <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"um <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"im Jahr <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"Tag"</string>
     <string name="days" msgid="4774547661021344602">"Tage"</string>
     <string name="hour" msgid="2126771916426189481">"Stunde"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Alles kopieren"</string>
     <string name="paste" msgid="5629880836805036433">"Einfügen"</string>
     <string name="copyUrl" msgid="2538211579596067402">"URL kopieren"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Eingabemethode"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"\"<xliff:g id="WORD">%s</xliff:g>\" zum Wörterbuch hinzufügen"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Text bearbeiten"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Geringer Speicher"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Kaum noch freier Telefonspeicher verfügbar."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Bevor Sie den USB-Speicher deaktivieren, stellen Sie sicher, dass Sie Ihn vom USB-Host getrennt haben. Wählen Sie \"Deaktivieren\", um den USB-Speicher zu deaktivieren."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Ausschalten"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Abbrechen"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Beim Deaktivieren des USB-Speichers wurde ein Problem festgestellt. Überprüfen Sie, ob Sie den USB-Host getrennt haben, und versuchen Sie es erneut."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"SD-Karte formatieren"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Möchten Sie die SD-Karte wirklich formatieren? Alle Daten auf Ihrer Karte gehen dann verloren."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging verbunden"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Ihr Telefon ist mit einem Computer verbunden."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Eingabemethode auswählen"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Neuer Kontakt"\n"mit <xliff:g id="NUMBER">%s</xliff:g> erstellen"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"aktiviert"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"nicht aktiviert"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Die aufgelisteten Anwendungen fordern eine Berechtigung zum Zugriff auf die Anmeldeinformationen für das Konto <xliff:g id="ACCOUNT">%1$s</xliff:g> von <xliff:g id="APPLICATION">%2$s</xliff:g> an. Möchten Sie diese Berechtigung erteilen? Wenn ja, wird Ihre Antwort gespeichert und Sie erhalten keine erneute Aufforderung."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Die aufgelisteten Anwendungen fordern eine Berechtigung zum Zugriff auf die <xliff:g id="TYPE">%1$s</xliff:g>-Anmeldeinformationen für das Konto <xliff:g id="APPLICATION">%3$s</xliff:g> von <xliff:g id="ACCOUNT">%2$s</xliff:g> an. Möchten Sie diese Berechtigung erteilen? Wenn ja, wird Ihre Antwort gespeichert und Sie erhalten keine erneute Aufforderung."</string>
     <string name="allow" msgid="7225948811296386551">"Zulassen"</string>
     <string name="deny" msgid="2081879885755434506">"Ablehnen"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Berechtigung angefordert"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Eingabemethode"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Synchronisieren"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Eingabehilfen"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Hintergrund"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Hintergrundbild ändern"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 6516883..23c6565 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Η πρόσβαση στο αρχείο δεν ήταν δυνατή."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Το αρχείο που ζητήθηκε δεν βρέθηκε."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Πραγματοποιείται επεξεργασία πάρα πολλών αιτημάτων. Προσπαθήστε ξανά αργότερα."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Σφάλμα σύνδεσης"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Συγχρονισμός"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Συγχρονισμός"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Πάρα πολλές <xliff:g id="CONTENT_TYPE">%s</xliff:g> διαγραφές."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"τροποποίηση στατιστικών μπαταρίας"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Επιτρέπει την τροποποίηση στατιστικών μπαταρίας που έχουν συλλεχθεί. Δεν πρέπει να χρησιμοποιείται από συνήθεις εφαρμογές."</string>
     <string name="permlab_backup" msgid="470013022865453920">"αντίγραφο ασφαλείας και επαναφορά συστήματος"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Επιτρέπει στην εφαρμογή τον έλεγχο του μηχανισμού δημιουργίας αντιγράφων ασφαλείας και επαναφοράς του συστήματος. Δεν προορίζεται για χρήση από κανονικές εφαρμογές."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"δημιουργία αντιγράφων ασφαλείας και επαναφορά δεδομένων εφαρμογής"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Επιτρέπει στην εφαρμογή να συμμετέχει στον μηχανισμό δημιουργίας αντιγράφων ασφαλείας και επαναφοράς του συστήματος."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"προβολή μη εξουσιοδοτημένων παραθύρων"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Επιτρέπει τη δημιουργία παραθύρων που πρόκειται να χρησιμοποιηθούν από την εσωτερική διεπαφή χρήστη του συστήματος. Δεν πρέπει να χρησιμοποιείται από κανονικές εφαρμογές."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"εμφάνιση ειδοποιήσεων επιπέδου συστήματος"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"τροποποίηση καθολικών ρυθμίσεων συστήματος"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Επιτρέπει σε μια εφαρμογή την τροποποίηση των δεδομένων των ρυθμίσεων του συστήματος. Κακόβουλες εφαρμογές μπορούν να καταστρέψουν τη διαμόρφωση του συστήματός σας."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"τροποποίηση ασφαλών ρυθμίσεων συστήματος"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Επιτρέπει σε μια εφαρμογή να τροποποιεί τα δεδομένα ρυθμίσεων ασφαλείας του συστήματος. Δεν προορίζεται για χρήση από κανονικές εφαρμογές."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"μετατροπή του χάρτη υπηρεσιών Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Επιτρέπει σε μια εφαρμογή την τροποποίηση του χάρτη υπηρεσιών Google. Δεν πρέπει να χρησιμοποιείται από κανονικές εφαρμογές."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"αυτόματη εκκίνηση κατά την εκκίνηση του υπολογιστή"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Επιτρέπει σε μια εφαρμογή την κλήση τηλεφωνικών αριθμών χωρίς την παρέμβασή σας. Κακόβουλες εφαρμογές ενδέχεται να ευθύνονται για μη αναμενόμενες κλήσεις στον λογαριασμό τηλεφώνου σας. Λάβετε υπόψη ότι αυτό δεν επιτρέπει την κλήση αριθμών έκτακτης ανάγκης."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"απευθείας κλήση τηλεφωνικών αριθμών"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Επιτρέπει στην εφαρμογή την κλήση τηλεφωνικού αριθμού, συμπεριλαμβανομένων και αριθμών έκτακτης ανάγκης, χωρίς την παρέμβασή σας. Κακόβουλες εφαρμογές ενδέχεται να πραγματοποιήσουν μη αναγκαίες και παράνομες κλήσεις σε υπηρεσίες έκτακτης ανάγκης."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"άμεση έναρξη της εγκατάστασης τηλεφώνου CDMA"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Επιτρέπει στην εφαρμογή να ξεκινήσει την παροχή CDMA. Κακόβουλες εφαρμογές ενδέχεται να ξεκινήσουν την παροχή CDMA χωρίς λόγο"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"έλεγχος ειδοποιήσεων ενημέρωσης τοποθεσίας"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Επιτρέπει την ενεργοποίηση/απενεργοποίηση ειδοποιήσεων ενημέρωσης τοποθεσίας από τον πομπό. Δεν πρέπει να χρησιμοποιείται από κανονικές εφαρμογές."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"πρόσβαση σε ιδιότητες ελέγχου εισόδου"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση της σύνδεσής σας Google."\n\n" Προσπαθήστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> \nδευτερόλεπτα."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Προσπαθήστε ξανά σε <xliff:g id="NUMBER">%d</xliff:g> δευτερόλεπτα."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Ξεχάσατε το μοτίβο;"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Ξεκλείδωμα λογαριασμού"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Πάρα πολλές προσπάθειες μοτίβου!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Για ξεκλείδωμα, συνδεθείτε με τον λογαριασμό σας Google"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Όνομα χρήστη (διεύθυνση ηλεκτρονικού ταχυδρομείου)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Κωδικός πρόσβασης"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Σύνδεση"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Μη έγκυρο όνομα χρήστη ή κωδικός πρόσβασης."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Έλεγχος..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Εκκαθάριση"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Συνδέστε τον φορτιστή"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Η στάθμη της μπαταρίας είναι χαμηλή:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"απομένουν λιγότερο από <xliff:g id="NUMBER">%d%%</xliff:g>."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Χρήση μπαταρίας"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Η εργοστασιακή δοκιμή απέτυχε"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Η ενέργεια FACTORY_TEST υποστηρίζεται μόνο για πακέτα που είναι εγκατεστημένα στον κατάλογο /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Δεν βρέθηκε πακέτο που να παρέχει την ενέργεια FACTORY_TEST."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"αύριο"</item>
     <item quantity="other" msgid="2973062968038355991">"σε <xliff:g id="COUNT">%d</xliff:g> ημέρες"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"στις <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"στις <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"το <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"ημέρα"</string>
     <string name="days" msgid="4774547661021344602">"ημέρες"</string>
     <string name="hour" msgid="2126771916426189481">"ώρα"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Αντιγραφή όλων"</string>
     <string name="paste" msgid="5629880836805036433">"Επικόλληση"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Αντιγραφή διεύθυνσης URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Μέθοδος εισόδου"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Προσθήκη της λέξης \"<xliff:g id="WORD">%s</xliff:g>\" στο λεξικό"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Επεξεργασία κειμένου"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Απομένει λίγος ελεύθερος χώρος"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Έχει απομείνει λίγος ελεύθερος αποθηκευτικός χώρος στο τηλέφωνο."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Πριν από την απενεργοποίηση του αποθηκευτικού χώρου USB, βεβαιωθείτε ότι έχετε αποπροσαρτήσει την υποδοχή USB. Επιλέξτε \"Απενεργοποίηση\" για να απενεργοποιήσετε τον αποθηκευτικό χώρο USB."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Απενεργοποίηση"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Ακύρωση"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Παρουσιάστηκε ένα πρόβλημα κατά την απενεργοποίηση του αποθηκευτικού χώρου USB. Βεβαιωθείτε ότι έχετε αποσυνδέσει την υποδοχή USB και προσπαθήστε ξανά."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Διαμόρφωση κάρτας SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Είστε βέβαιοι ότι θέλετε να διαμορφώσετε την κάρτα SD; Όλα τα δεδομένα στην κάρτα σας θα χαθούν."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Διαμόρφωση"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Ένας υπολογιστής είναι συνδεδεμένος στο τηλέφωνό σας."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Επιλογή μεθόδου εισόδου"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"υποψήφιοι"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Δημιουργία επαφής"\n"με τη χρήση του <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"επιλεγμένο"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"δεν ελέγχθηκε"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Οι εφαρμογές που παραθέτονται στη λίστα ζητούν άδεια για να αποκτήσουν πρόσβαση στα διαπιστευτήρια σύνδεσης για τον λογαριασμό <xliff:g id="ACCOUNT">%1$s</xliff:g> από <xliff:g id="APPLICATION">%2$s</xliff:g>. Θα αποδεχτείτε το αίτημα; Εάν το αποδεχτείτε, η απάντησή σας θα αποθηκευτεί και δεν θα ερωτηθείτε ξανά."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Οι εφαρμογές που παραθέτονται στη λίστα ζητούν άδεια για να αποκτήσουν πρόσβαση στα διαπιστευτήρια σύνδεσης <xliff:g id="TYPE">%1$s</xliff:g> για τον λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g> από <xliff:g id="APPLICATION">%3$s</xliff:g>. Θα αποδεχτείτε το αίτημα; Εάν το αποδεχτείτε, η απάντησή σας θα αποθηκευτεί και δεν θα ερωτηθείτε ξανά."</string>
     <string name="allow" msgid="7225948811296386551">"Να επιτρέπεται"</string>
     <string name="deny" msgid="2081879885755434506">"Άρνηση"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Απαιτείται άδεια"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Μέθοδος εισόδου"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Συγχρονισμός"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Προσβασιμότητα"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Ταπετσαρία"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Αλλαγή ταπετσαρίας"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1b6c838..e2059d8 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"No se ha podido acceder al archivo."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"No se ha encontrado el archivo solicitado."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Se están procesando demasiadas solicitudes. Vuelve a intentarlo más tarde."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Error al iniciar la sesión"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Sincronización"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronización"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminaciones de <xliff:g id="CONTENT_TYPE">%s</xliff:g>"</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"modificar la estadística de la batería"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Admite la modificación de estadísticas recopiladas sobre la batería. Las aplicaciones normales no deben utilizarlo."</string>
     <string name="permlab_backup" msgid="470013022865453920">"copia de seguridad y restauración del sistema de control"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Permite a la aplicación controlar el mecanismo de restauración y copia de seguridad de los sistemas. No es para uso de las aplicaciones normales."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"hacer una copia de seguridad y restaurar los datos de aplicación"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Permite a la aplicación participar en la copia de seguridad del sistema y restaurar el mecanismo."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"mostrar ventanas no autorizadas"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Permite la creación de ventanas que la interfaz interna del usuario del sistema pretenda utilizar. Las aplicaciones normales no deben utilizarlo."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"mostrar alertas a nivel del sistema"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuración global del sistema"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Admite una aplicación que modifica los datos de configuración del sistema. Las aplicaciones maliciosas pueden corromper la configuración de tu sistema."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"modificar la configuración segura del sistema"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Permite a una aplicación modificar los datos de la configuración segura de los sistemas. Las aplicaciones normales no deben utilizarlo."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"modificar el mapa de servicios de Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Admite una aplicación que modifica el mapa de servicios de Google. Las aplicaciones normales no deben utilizarlo."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"iniciar automáticamente durante la inicialización"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Admite que la aplicación llame a ciertos números de teléfono sin tu permiso. Las aplicaciones maliciosas pueden ocasionar llamadas imprevistas en tu factura telefónica. Ten en cuenta que esto no admite que la aplicación llame a los números de emergencia."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"llamar directamente a cualquier número de teléfono"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Admite que la aplicación llame a cualquier número de teléfono, incluidos los números de emergencia, sin tu intervención. Las aplicaciones maliciosas pueden realizar llamadas innecesarias e ilegales a los servicios de emergencia."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"comienza directamente la configuración CDMA del teléfono"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Admite la aplicación para comenzar con el aprovisionamiento CDMA. Las aplicaciones maliciosas pueden comenzar con el aprovisionamiento CDMA sin necesidad."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"controlar las notificaciones de actualización de ubicación"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Permite activar y desactivar las notificaciones de actualización de ubicación de la radio. Las aplicaciones normales no deben utilizarlo."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"acceder a las propiedades de protección"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Has extraído incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu teléfono al iniciar sesión en Google. "\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"¿Olvidaste el patrón?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Desbloquear cuenta"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Demasiados intentos de patrón."</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Para desbloquear, regístrate en tu cuenta de Google"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nombre de usuario (correo electrónico)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Contraseña"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Inicia sesión"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nombre de usuario o contraseña incorrecta."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Comprobando..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Conecta el cargador"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Hay poca batería:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"menos de <xliff:g id="NUMBER">%d%%</xliff:g> restante."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Uso de la batería"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Error en la prueba de fábrica"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"La acción FACTORY_TEST se admite solamente en paquetes instalados en /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No se ha encontrado ningún paquete que proporcione la acción FACTORY_TEST ."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"mañana"</item>
     <item quantity="other" msgid="2973062968038355991">"en <xliff:g id="COUNT">%d</xliff:g> días"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"encendido <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"a las <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"en <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"día"</string>
     <string name="days" msgid="4774547661021344602">"días"</string>
     <string name="hour" msgid="2126771916426189481">"hora"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Copiar todo"</string>
     <string name="paste" msgid="5629880836805036433">"Pegar"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Agregar \"<xliff:g id="WORD">%s</xliff:g>\" al diccionario"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Editar texto"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Poco espacio de almacenamiento"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Hay poco espacio de almacenamiento en el teléfono."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Antes de desactivar el almacenamiento USB, asegúrate de haberlo desmontado en el servidor USB al seleccionar \"Desactivar\"."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Apagar"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Cancelar"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Se ha producido un problema al desactivar el almacenamiento USB. Verifica para asegurarte de haber desmontado el servidor USB, luego vuelve a intentarlo."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formatear tarjeta SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"¿Estás seguro de que quieres formatear la tarjeta SD? Se perderán todos los datos de tu tarjeta."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formato"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración de USB conectada"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Hay una computadora conectada a tu teléfono."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Seleccionar método de entrada"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Crear contacto "\n"con <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"verificado"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"no verificado"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Las aplicaciones enumeradas requieren permiso para acceder a las credenciales de inicio de sesión para la cuenta <xliff:g id="ACCOUNT">%1$s</xliff:g> desde <xliff:g id="APPLICATION">%2$s</xliff:g> ¿Deseas otorgar este permiso? Si es así, el sistema recordará tu respuesta y no volverá a solicitarla."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Las aplicaciones enumeradas requieren permiso para acceder a las <xliff:g id="TYPE">%1$s</xliff:g> credenciales de inicio de sesión para la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g> desde <xliff:g id="APPLICATION">%3$s</xliff:g>.¿Deseas otorgar este permiso? Si es así, el sistema recordará tu respuesta y no volverá a solicitarla."</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Denegar"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Permiso solicitado"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sincronización"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilidad"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Papel tapiz"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambiar fondo de pantalla"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 215666a..74f7e11 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"No se ha podido acceder al archivo."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"No se ha encontrado el archivo solicitado."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Se están procesando demasiadas solicitudes. Vuelve a intentarlo más tarde."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Error de acceso"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Sincronización"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronización"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminaciones de <xliff:g id="CONTENT_TYPE">%s</xliff:g>"</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"modificar estadísticas de la batería"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Permite la modificación de estadísticas recopiladas sobre la batería. No está destinado al uso por parte de aplicaciones normales."</string>
     <string name="permlab_backup" msgid="470013022865453920">"controlar las copias de seguridad y las restauraciones del sistema"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Permite que la aplicación controle el mecanismo de copia de seguridad y restauración del sistema. Este permiso no está destinado a aplicaciones normales."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"crear una copia de seguridad de los datos de la aplicación y restaurarlos"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Permite que la aplicación participe en el mecanismo de copia de seguridad y restauración del sistema."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"mostrar ventanas no autorizadas"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Permite la creación de ventanas destinadas al uso por parte de la interfaz de usuario interna del sistema. No está destinado al uso por parte de aplicaciones normales."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"mostrar alertas de nivel del sistema"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuración global del sistema"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Permite que una aplicación modifique los datos de configuración del sistema. Las aplicaciones malintencionadas pueden dañar la configuración del sistema."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"modificar la configuración segura del sistema"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Permite que una aplicación modifique los datos de configuración segura del sistema. No está destinado al uso por parte de aplicaciones normales."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"modificar la asignación de servicios de Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Permite que una aplicación modifique la asignación de servicios de Google. No está destinado al uso por parte de aplicaciones normales."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"ejecutar automáticamente al iniciar"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Permite que la aplicación llame a números de teléfono sin la intervención del usuario. Las aplicaciones malintencionadas pueden originar llamadas inesperadas en la factura telefónica. Ten en cuenta que con este permiso la aplicación no puede realizar llamadas a números de emergencia."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"llamar directamente a cualquier número de teléfono"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Permite que la aplicación llame a cualquier número de teléfono, incluidos los números de emergencia, sin que el usuario intervenga. Las aplicaciones malintencionadas pueden realizar llamadas innecesarias e ilícitas a los servicios de emergencias."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"iniciar directamente el método de acceso CDMA del teléfono"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Permite que la aplicación inicie el método de acceso CDMA. Las aplicaciones malintencionadas pueden iniciar el método CDMA de forma innecesaria."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"controlar las notificaciones de actualización de la ubicación"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Permite habilitar/inhabilitar las notificaciones de actualización de la señal móvil. No está destinado al uso por parte de aplicaciones normales."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"acceder a propiedades de registro"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Has realizado <xliff:g id="NUMBER_0">%d</xliff:g> intentos fallidos de creación del patrón de desbloqueo. Si realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos fallidos más, se te pedirá que desbloquees el teléfono con tus credenciales de acceso de Google."\n\n" Espera <xliff:g id="NUMBER_2">%d</xliff:g> segundos e inténtalo de nuevo."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Espera <xliff:g id="NUMBER">%d</xliff:g> segundos y vuelve a intentarlo."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"¿Has olvidado el patrón?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Desbloqueo de cuenta"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Se han realizado demasiados intentos incorrectos de creación del patrón."</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Para desbloquear el teléfono, accede a tu cuenta de Google."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nombre de usuario (correo electrónico)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Contraseña"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Acceder"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nombre de usuario o contraseña no válido"</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Comprobando..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Conecta el cargador"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Se está agotando la batería:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"menos del <xliff:g id="NUMBER">%d%%</xliff:g> disponible."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Uso de la batería"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fallo en la prueba de fábrica"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"La acción FACTORY_TEST sólo es compatible con los paquetes instalados en /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No se ha encontrado ningún paquete que proporcione la acción FACTORY_TEST."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"mañana"</item>
     <item quantity="other" msgid="2973062968038355991">"dentro de <xliff:g id="COUNT">%d</xliff:g> días"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"el <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"a las <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"en <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"día"</string>
     <string name="days" msgid="4774547661021344602">"días"</string>
     <string name="hour" msgid="2126771916426189481">"hora"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Copiar todo"</string>
     <string name="paste" msgid="5629880836805036433">"Pegar"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Método de introducción de texto"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Añadir \"<xliff:g id="WORD">%s</xliff:g>\" al diccionario"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Editar texto"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Poco espacio"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Se está agotando el espacio de almacenamiento del teléfono."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Antes de desactivar el almacenamiento USB, asegúrate de haber desactivado el host USB. Selecciona \"Desactivar\" para desactivar el almacenamiento USB."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Desactivar"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Cancelar"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Se ha producido un problema al desactivar el almacenamiento USB. Asegúrate de que has desactivado el host USB e inténtalo de nuevo."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formatear tarjeta SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"¿Estás seguro de que quieres formatear la tarjeta SD? Se perderán todos los datos de la tarjeta."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formato"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Dispositivo de depuración USB conectado"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Hay un equipo conectado al teléfono."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Seleccionar método de introducción de texto"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Crear un contacto"\n"a partir de <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"seleccionado"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"no seleccionado"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Las aplicaciones de la lista están solicitando permiso para acceder a las credenciales de acceso de la cuenta <xliff:g id="ACCOUNT">%1$s</xliff:g> desde <xliff:g id="APPLICATION">%2$s</xliff:g>. ¿Deseas conceder este permiso? En tal caso, se recordará tu respuesta y no se te volverá a preguntar."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Las aplicaciones de la lista están solicitando permiso para acceder a las credenciales de acceso (<xliff:g id="TYPE">%1$s</xliff:g>) de la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g> desde <xliff:g id="APPLICATION">%3$s</xliff:g>. ¿Deseas conceder este permiso? En tal caso, se recordará tu respuesta y no se te volverá a preguntar."</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Denegar"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Permiso solicitado"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Método de introducción de texto"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sincronización"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilidad"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fondo de pantalla"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambiar fondo de pantalla"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a0cc5a3..c0f59f2 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Impossible d\'accéder au fichier."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Le fichier demandé est introuvable."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Trop de requêtes sont en cours de traitement. Veuillez réessayer ultérieurement."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Erreur de connexion"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Synchroniser"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronisation"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Trop de contenus supprimés (<xliff:g id="CONTENT_TYPE">%s</xliff:g>)."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"Modification des statistiques de la batterie"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Autoriser la modification des statistiques de la batterie. Les applications normales n\'utilisent pas cette fonctionnalité."</string>
     <string name="permlab_backup" msgid="470013022865453920">"contrôler la sauvegarde et la restauration du système"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Autorise l\'application à contrôler le mécanisme de sauvegarde et de restauration du système. Ne pas utiliser pour les applications standard."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"sauvegarder et rétablir les données de l\'application"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Autorise l\'application à participer au mécanisme de sauvegarde et de restauration du système."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"Affichage de fenêtres non autorisées"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Permet de créer des fenêtres conçues pour l\'interface utilisateur du système interne. Les applications normales n\'utilisent pas cette fonctionnalité."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"Affichage d\'alertes système"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"Modification des paramètres généraux du système"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Permet à une application de modifier les données des paramètres système. Des applications malveillantes peuvent utiliser cette fonctionnalité pour endommager la configuration de votre système."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"Modifier les paramètres de sécurité du système"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Permet à une application de modifier les données des paramètres de sécurité du système. Cette fonction ne peut être utilisée par une application standard."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"Modification de la carte des services Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Permet à une application de modifier la carte des services Google. Les applications normales n\'utilisent pas cette fonctionnalité."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"Lancement automatique au démarrage"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Permet à l\'application d\'appeler des numéros sans votre intervention. Des applications malveillantes peuvent ainsi passer des appels à votre insu qui s\'ajoutent à votre facture téléphonique. Cette fonctionnalité ne permet pas à l\'application d\'appeler des numéros d\'urgence."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"Appel direct de tout numéro de téléphone"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Permet à une application d\'appeler tout numéro de téléphone (y compris les numéros d\'urgence) sans votre intervention. Des applications malveillantes peuvent passer des appels non nécessaires ou illégitimes à des services d\'urgence."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"démarrer directement la configuration du téléphone CDMA"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Autorise l\'application à lancer le déploiement CDMA. Des applications malveillantes sont susceptibles elles aussi de lancer le déploiement CDMA."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"Contrôle des notifications de mise à jour de position géo."</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Permet l\'activation/la désactivation des notifications de mises à jour de la position géographique provenant du signal radio. Les applications normales n\'utilisent pas cette fonctionnalité."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"Accès aux propriétés d\'enregistrement"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Vous avez mal saisi le schéma de déverrouillage <xliff:g id="NUMBER_0">%d</xliff:g> fois. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> tentatives supplémentaires, vous devrez débloquer votre téléphone à l\'aide de votre identifiant Google."\n\n"Merci de réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Schéma oublié ?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Déverrouillage du compte"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Trop de tentatives !"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Pour déverrouiller le téléphone, connectez-vous à l\'aide de votre compte Google."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nom d\'utilisateur (e-mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Mot de passe"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Se connecter"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nom d\'utilisateur ou mot de passe incorrect."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Vérification..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Effacer"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Branchez le chargeur"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Le niveau de la batterie est bas :"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"Batterie restante inférieure à <xliff:g id="NUMBER">%d%%</xliff:g>."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Utilisation de la batterie"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Échec du test usine"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"L\'action FACTORY_TEST est uniquement prise en charge pour les paquets de données installés dans in/system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Impossible de trouver un paquet proposant l\'action FACTORY_TEST."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"demain"</item>
     <item quantity="other" msgid="2973062968038355991">"dans <xliff:g id="COUNT">%d</xliff:g> jours"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"le <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"à <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"en <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"jour"</string>
     <string name="days" msgid="4774547661021344602">"jours"</string>
     <string name="hour" msgid="2126771916426189481">"heure"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Tout copier"</string>
     <string name="paste" msgid="5629880836805036433">"Coller"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Copier l\'URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Mode de saisie"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Ajouter \"<xliff:g id="WORD">%s</xliff:g>\" au dictionnaire"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Modifier le texte"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Espace disponible faible"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"La mémoire du téléphone commence à être pleine."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Avant d\'éteindre le périphérique de stockage USB, assurez-vous d\'avoir désactivé l\'hôte USB. Sélectionnez \"Éteindre\" pour éteindre le périphérique de stockage USB."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Éteindre"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Annuler"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Un problème est survenu lors de la mise hors tension du périphérique de stockage USB. Assurez-vous que l\'hôte USB a bien été désactivé, puis essayez à nouveau."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formater la carte SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Voulez-vous vraiment formater la carte SD ? Toutes les données de cette carte seront perdues."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Un ordinateur est connecté à votre téléphone."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Sélectionner un mode de saisie"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Ajouter un contact"\n"en utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"sélectionné"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"non sélectionné"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Les applications répertoriées demandent l\'autorisation d\'accéder aux informations d\'identification du compte <xliff:g id="ACCOUNT">%1$s</xliff:g> depuis <xliff:g id="APPLICATION">%2$s</xliff:g>. Souhaitez-vous accorder cette autorisation ? Si vous acceptez, votre choix sera enregistré et cette question ne vous sera plus posée."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Les applications répertoriées demandent l\'autorisation d\'accéder aux informations d\'identification des <xliff:g id="TYPE">%1$s</xliff:g> associés au compte <xliff:g id="ACCOUNT">%2$s</xliff:g> depuis <xliff:g id="APPLICATION">%3$s</xliff:g>. Souhaitez-vous accorder cette autorisation ? Si vous acceptez, votre choix sera enregistré et cette question ne vous sera plus posée."</string>
     <string name="allow" msgid="7225948811296386551">"Autoriser"</string>
     <string name="deny" msgid="2081879885755434506">"Refuser"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Autorisation demandée"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Mode de saisie"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Synchronisation"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilité"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fond d\'écran"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Changer de fond d\'écran"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 6fdf1b3..d62625f 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Impossibile accedere al file."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Impossibile trovare il file richiesto."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Troppe richieste in fase di elaborazione. Riprova più tardi."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Errore di accesso"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Sinc"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronizzazione"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Troppe eliminazioni di <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"modifica statistiche batteria"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Consente la modifica delle statistiche sulla batteria raccolte. Da non usare per normali applicazioni."</string>
     <string name="permlab_backup" msgid="470013022865453920">"controllo del backup di sistema e ripristino"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Consente all\'applicazione di controllare il meccanismo di backup e ripristino del sistema. Da non usare per normali applicazioni."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"effettuare il backup e il ripristino dei dati dell\'applicazione"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Consente all\'applicazione di partecipare al meccanismo di backup e ripristino del sistema."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"visualizzazione finestre non autorizzate"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Consente la creazione di finestre destinate all\'uso nell\'interfaccia utente di sistema interna. Da non usare per normali applicazioni."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"visualizzazione avvisi di sistema"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modifica impostazioni di sistema globali"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Consente la modifica in un\'applicazione dei dati delle impostazioni del sistema. Le applicazioni dannose possono danneggiare la configurazione del sistema."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"modificare le impostazioni di protezione del sistema"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Consente a un\'applicazione di modificare i dati delle impostazioni di protezione del sistema. Da non usare per normali applicazioni."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"modifica mappa servizi Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Consente a un\'applicazione di modificare la mappa dei servizi Google. Da non usare per normali applicazioni."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"apertura automatica all\'avvio"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Consente all\'applicazione di chiamare numeri automaticamente. Le applicazioni dannose potrebbero far risultare chiamate impreviste sulla bolletta telefonica. Questa autorizzazione non consente all\'applicazione di chiamare numeri di emergenza."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"chiamata diretta di tutti i n. telefono"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Consente all\'applicazione di chiamare qualsiasi numero, compresi quelli di emergenza, automaticamente. Le applicazioni dannose potrebbero effettuare chiamate non necessarie e illegali a servizi di emergenza."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"avviare direttamente la configurazione del telefono CDMA"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Consente all\'applicazione di avviare il servizio di CDMA provisioning. Le applicazioni dannose potrebbero avviare il servizio di CDMA provisioning quando non è necessario"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"controllo notifiche aggiornamento posizione"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Consente l\'attivazione/disattivazione delle notifiche di aggiornamento della posizione dal segnale cellulare. Da non usare per normali applicazioni."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"accesso a proprietà di archiviazione"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono tramite i dati di accesso di Google."\n\n"Riprova fra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Riprova fra <xliff:g id="NUMBER">%d</xliff:g> secondi."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Hai dimenticato la sequenza?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Sblocco account"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Troppi tentativi di inserimento della sequenza."</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Per sbloccare, accedi tramite il tuo account Google"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nome utente (email)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Accedi"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Password o nome utente non valido."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Controllo in corso..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Cancella"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Collegare il caricabatterie"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Batteria quasi scarica:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"energia residua inferiore a <xliff:g id="NUMBER">%d%%</xliff:g>."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Utilizzo batteria"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Test di fabbrica non riuscito"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"L\'azione FACTORY_TEST è supportata soltanto per i pacchetti installati in /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nessun pacchetto trovato che fornisca l\'azione FACTORY_TEST."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"domani"</item>
     <item quantity="other" msgid="2973062968038355991">"tra <xliff:g id="COUNT">%d</xliff:g> giorni"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"in data <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"alle ore <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"nel <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"giorno"</string>
     <string name="days" msgid="4774547661021344602">"giorni"</string>
     <string name="hour" msgid="2126771916426189481">"ora"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Copia tutto"</string>
     <string name="paste" msgid="5629880836805036433">"Incolla"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Copia URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Metodo inserimento"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Aggiungi \"<xliff:g id="WORD">%s</xliff:g>\" al dizionario"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Modifica testo"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Spazio in esaurimento"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Spazio di archiviazione del telefono in esaurimento."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Prima di disattivare l\'archivio USB, verifica di aver smontato l\'host USB. A tale scopo, seleziona \"Disattiva\"."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Disattiva"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Annulla"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Abbiamo riscontrato un problema durante la disattivazione dell\'archivio USB. Verifica di aver smontato l\'host USB e riprova."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formatta scheda SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Formattare la scheda SD? Tutti i dati sulla scheda verranno persi."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatta"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Un computer è collegato al tuo cellulare."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Seleziona metodo di inserimento"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidati"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Crea contatto"\n"utilizzando <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"selezionato"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"non selezionato"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Le applicazioni elencate richiedono l\'autorizzazione per accedere alle credenziali di accesso per l\'account <xliff:g id="ACCOUNT">%1$s</xliff:g> da <xliff:g id="APPLICATION">%2$s</xliff:g>. Concedere questa autorizzazione? In tal caso la tua risposta verrà memorizzata e questa domanda non ti verrà più posta."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Le applicazioni elencate richiedono l\'autorizzazione per accedere alle credenziali di accesso <xliff:g id="TYPE">%1$s</xliff:g> per l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g> da <xliff:g id="APPLICATION">%3$s</xliff:g>. Concedere questa autorizzazione? In tal caso la tua risposta verrà memorizzata e questa domanda non ti verrà più posta."</string>
     <string name="allow" msgid="7225948811296386551">"Consenti"</string>
     <string name="deny" msgid="2081879885755434506">"Nega"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Autorizzazione richiesta"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <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="wallpaper_binding_label" msgid="1240087844304687662">"Sfondo"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambia sfondo"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 9b7e09f..55e6b50 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"ファイルにアクセスできませんでした。"</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"要求されたファイルが見つかりませんでした。"</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"処理中のリクエストが多すぎます。しばらくしてからもう一度試してください。"</string>
-    <string name="notification_title" msgid="4254304601929719937">"ログインエラー"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"同期"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"同期"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"<xliff:g id="CONTENT_TYPE">%s</xliff:g>での削除が多すぎます。"</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"電池統計情報の変国"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"収集した電池統計情報の変更を許可します。通常のアプリケーションでは使用しません。"</string>
     <string name="permlab_backup" msgid="470013022865453920">"システムのバックアップと復元を制御する"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"システムのバックアップと復元メカニズムの制御をアプリケーションに許可します。通常のアプリケーションでは使用しません。"</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"アプリケーションデータのバックアップと復元"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"システムのバックアップと復元メカニズムへのアプリケーションの参加を許可します。"</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"未許可のウィンドウの表示"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"内部システムのユーザーインターフェースで使用するためのウィンドウ作成を許可します。通常のアプリケーションでは使用しません。"</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"システムレベルの警告の表示"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"システムの全般設定の変更"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"システム設定データの変更をアプリケーションに許可します。悪意のあるアプリケーションがシステム設定を破壊する恐れがあります。"</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"システムのセキュリティ設定の変更"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"システムのセキュリティ設定の変更をアプリケーションに許可します。通常のアプリケーションでは使用しません。"</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"Googleサービスの地図の変更"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Googleサービスマップの変更をアプリケーションに許可します。通常のアプリケーションでは使用しません。"</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"起動時に自動的に開始"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"電話番号の自動発信をアプリケーションに許可します。悪意のあるアプリケーションが意図しない電話をかけて料金が発生する恐れがあります。緊急通報への発信は許可しません。"</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"電話番号発信"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"緊急通報を含めあらゆる電話番号に自動発信することをアプリケーションに許可します。悪意のあるアプリケーションが緊急サービスに不正な通報をする恐れがあります。"</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"CDMA携帯電話のセットアップを直接開始"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"アプリケーションにCDMAプロビジョニングの開始を許可します。悪意のあるアプリケーションが不要なCDMAプロビジョニングを開始する恐れがあります。"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"位置情報の更新通知"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"無線通信からの位置更新通知を有効/無効にすることを許可します。通常のアプリケーションでは使用しません。"</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"チェックインプロパティへのアクセス"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"指定したパターンは<xliff:g id="NUMBER_0">%d</xliff:g>回とも正しくありません。あと<xliff:g id="NUMBER_1">%d</xliff:g>回指定に失敗すると、携帯電話のロックの解除にGoogleへのログインが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度指定してください。"</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g>秒後にやり直してください。"</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"パターンを忘れた場合"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"アカウントのロック解除"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"パターンのエラーが多すぎます"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Googleアカウントでログインしてロック解除"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ユーザー名 (メール)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"パスワード"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ログイン"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ユーザー名またはパスワードが正しくありません。"</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"確認中..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"通知を消去"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"充電してください"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"電池が残り少なくなっています:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"残量<xliff:g id="NUMBER">%d%%</xliff:g>以下"</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"電池使用量"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"出荷時試験が失敗"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST操作は、/system/appにインストールされたパッケージのみが対象です。"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST操作を行うパッケージは見つかりませんでした。"</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"明日"</item>
     <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g>日後"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"<xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g>年"</string>
     <string name="day" msgid="8144195776058119424">"日"</string>
     <string name="days" msgid="4774547661021344602">"日"</string>
     <string name="hour" msgid="2126771916426189481">"時間"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"すべてコピー"</string>
     <string name="paste" msgid="5629880836805036433">"貼り付け"</string>
     <string name="copyUrl" msgid="2538211579596067402">"URLをコピー"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"入力方法"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"辞書に「<xliff:g id="WORD">%s</xliff:g>」を追加"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"テキストを編集"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"空き容量低下"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"携帯電話の空き容量が少なくなっています。"</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"USBストレージをOFFにする前にUSBホストのマウントを解除したことを確認してください。USBストレージをOFFにするには[OFF]を選択します。"</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"OFF"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"キャンセル"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"USBストレージをOFFにする際に問題が発生しました。USBホストのマウントが解除されていることを確認してからもう一度お試しください。"</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"SDカードをフォーマット"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"SDカードをフォーマットしてもよろしいですか?カード内のすべてのデータが失われます。"</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"フォーマット"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"コンピュータが携帯に接続されました。"</string>
-    <string name="select_input_method" msgid="2086499663193509436">"入力方法の選択"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>を使って"\n"連絡先を新規登録"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"オン"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"オフ"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"リストされているアプリケーションが、アカウント<xliff:g id="ACCOUNT">%1$s</xliff:g>のログイン認証情報に<xliff:g id="APPLICATION">%2$s</xliff:g>からアクセスする権限をリクエストしています。この権限を許可しますか?許可すると、入力が記録され、次回以降はこのメッセージが表示されなくなります。"</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"リストされているアプリケーションが、アカウント<xliff:g id="ACCOUNT">%2$s</xliff:g>の<xliff:g id="TYPE">%1$s</xliff:g>ログイン認証情報に<xliff:g id="APPLICATION">%3$s</xliff:g>からアクセスする権限をリクエストしています。この権限を許可しますか?許可すると、入力は記録され、次回以降はこのメッセージが表示されなくなります。"</string>
     <string name="allow" msgid="7225948811296386551">"許可"</string>
     <string name="deny" msgid="2081879885755434506">"拒否"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"リクエスト済み権限"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"入力方法"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"同期"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"アクセシビリティ"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"壁紙"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"壁紙を変更"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 8030cad..3db36fc 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"파일에 액세스할 수 없습니다."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"요청한 파일을 찾을 수 없습니다."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"처리 중인 요청이 너무 많습니다. 잠시 후에 다시 시도해 주세요."</string>
-    <string name="notification_title" msgid="4254304601929719937">"로그인 오류"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"동기화"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"동기화"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"<xliff:g id="CONTENT_TYPE">%s</xliff:g> 삭제가 너무 많습니다."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"배터리 통계 수정"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"수집된 배터리 통계를 수정할 수 있도록 합니다. 일반 응용프로그램에서는 사용할 수 없습니다."</string>
     <string name="permlab_backup" msgid="470013022865453920">"시스템 백업 및 복원 관리"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"응용프로그램이 시스템의 백업 및 복원 매커니즘을 제어할 수 있도록 합니다. 일반 응용프로그램에서는 사용하지 않습니다."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"응용프로그램 데이터 백업 및 복원"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"응용프로그램이 시스템의 백업 및 복원 매커니즘에 참여할 수 있도록 합니다."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"인증되지 않은 창 표시"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"내부 시스템 사용자 인터페이스에서 사용하는 창을 만들 수 있도록 합니다. 일반 응용프로그램에서는 사용하지 않습니다."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"시스템 수준 경고 표시"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"전체 시스템 설정 수정"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"응용프로그램이 시스템의 설정 데이터를 수정할 수 있도록 합니다. 이 경우 악성 응용프로그램이 시스템 구성을 손상시킬 수 있습니다."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"보안 시스템 설정 수정"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"응용프로그램이 시스템의 보안 설정값 데이터를 수정할 수 있도록 합니다. 일반 응용프로그램에서는 사용하지 않습니다."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"Google 서비스 지도 수정"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"응용프로그램이 Google 서비스 지도를 수정할 수 있도록 합니다. 일반 응용프로그램에서는 사용하지 않습니다."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"부팅할 때 자동 시작"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"응용프로그램이 사용자의 조작 없이 전화번호로 전화를 걸 수 있도록 합니다. 이 경우 악성 응용프로그램으로 인해 예상치 못한 통화 요금이 부과될 수 있습니다. 이 권한으로 응용프로그램이 비상 전화를 걸게 할 수는 없습니다."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"전화번호로 직접 전화걸기"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"응용프로그램이 사용자의 조작 없이 비상 번호를 포함한 전화번호로 전화를 걸 수 있도록 합니다. 이 경우 악성 응용프로그램이 응급 서비스를 불필요하거나 불법적으로 호출할 수 있습니다."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"직접 CDMA 전화 설정 시작"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"응용프로그램이 CDMA 프로비저닝을 시작할 수 있도록 합니다. 이 경우 악성 응용프로그램이 불필요하게 CDMA 프로비저닝을 시작할 수 있습니다."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"위치 업데이트 알림 제어"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"무선의 위치 업데이트 알림을 사용하거나 사용 중지할 수 있도록 합니다. 일반 응용프로그램에서는 사용하지 않습니다."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"체크인 속성 액세스"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 Google 로그인을 통해 휴대전화를 잠금해제하도록 요청됩니다. "\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도하세요."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g>초 후에 다시 시도하세요."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"패턴을 잊으셨나요?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"계정 잠금 해제"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"패턴을 너무 많이 시도했습니다."</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"잠금해제하려면 Google 계정으로 로그인하세요."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"사용자 이름(이메일)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"비밀번호"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"로그인"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"사용자 이름 또는 비밀번호가 잘못되었습니다."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"확인 중..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"지우기"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"충전기를 연결하세요."</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"배터리 전원이 부족합니다."</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"<xliff:g id="NUMBER">%d%%</xliff:g> 미만 남음"</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"배터리 사용"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"출고 테스트 불합격"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST 작업은 /system/app 디렉토리에 설치된 패키지에 대해서만 지원됩니다."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST 작업을 제공하는 패키지가 없습니다."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"내일"</item>
     <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g>일 후"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"<xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g>년"</string>
     <string name="day" msgid="8144195776058119424">"일"</string>
     <string name="days" msgid="4774547661021344602">"일"</string>
     <string name="hour" msgid="2126771916426189481">"시간"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"모두 복사"</string>
     <string name="paste" msgid="5629880836805036433">"붙여넣기"</string>
     <string name="copyUrl" msgid="2538211579596067402">"URL 복사"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"입력 방법"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"사전에 \'<xliff:g id="WORD">%s</xliff:g>\' 추가"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"텍스트 수정"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"저장공간 부족"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"휴대전화 저장공간이 부족합니다."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"USB 저장소를 끄기 전에 반드시 USB 호스트에서 마운트 해제하세요. USB 저장소를 끄려면 \'끄기\'를 선택하세요."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"USB 저장소 끄기"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"취소"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"USB 저장소를 끄는 동안 문제가 발생했습니다. USB 호스트를 마운트 해제했는지 확인한 다음 다시 시도하세요."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"SD 카드 포맷"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"SD 카드를 포맷하시겠습니까? 포맷하면 카드의 모든 데이터를 잃게 됩니다."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"포맷"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"컴퓨터가 휴대전화에 연결되어 있습니다."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"입력 방법 선택"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"가능한 원인"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"전화번호부에"\n"<xliff:g id="NUMBER">%s</xliff:g> 추가"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"선택함"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"선택 안함"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"나열된 응용프로그램이 <xliff:g id="APPLICATION">%2$s</xliff:g>에서 <xliff:g id="ACCOUNT">%1$s</xliff:g> 계정의 로그인 자격증명에 액세스할 수 있는 권한을 요청 중입니다. 권한을 부여하시겠습니까? 권한을 부여하면 응답 내용이 저장되며 메시지가 다시 표시되지 않습니다."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"나열된 응용프로그램이 <xliff:g id="APPLICATION">%3$s</xliff:g>에서 <xliff:g id="ACCOUNT">%2$s</xliff:g> 계정의 <xliff:g id="TYPE">%1$s</xliff:g> 로그인 자격증명에 액세스할 수 있는 권한을 요청 중입니다. 권한을 부여하시겠습니까? 권한을 부여하면 응답 내용이 저장되며 메시지가 다시 표시되지 않습니다."</string>
     <string name="allow" msgid="7225948811296386551">"허용"</string>
     <string name="deny" msgid="2081879885755434506">"거부"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"권한 요청"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"입력 방법"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"동기화"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"접근성"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"배경화면"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"배경화면 변경"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index c4d8292..19524d8 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Kunne ikke åpne filen."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Fant ikke den forespurte filen."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"For mange forespørsler blir behandlet. Prøv igjen senere."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Påloggingsfeil"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Synkronisering"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synkronisering"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"For mange slettinger av <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"endre batteristatistikk"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Lar applikasjonen endre på innsamlet batteristatistikk. Ikke ment for vanlige applikasjoner."</string>
     <string name="permlab_backup" msgid="470013022865453920">"kontrollere backup og gjenoppretting"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Gir programmet tillatelse til å kontrollere systemets mekanismer for sikkerhetskopiering gjenoppretting. Ikke beregnet på vanlige programmer."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"sikkerhetskopier og gjenopprett programmets data"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Gir programmet tillatelse til å ta del i systemets mekanismer for sikkerhetskopiering og gjenoppretting."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"vis uautoriserte vinduer"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Tillater at det opprettes vinduer ment for bruk av systemets interne brukergrensesnitt. Ikke ment for vanlige applikasjoner."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"vise advarsler på systemnivå"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"endre globale systeminnstillinger"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Lar applikasjonen endre systemets innstillingsdata. Ondsinnede applikasjoner kan skade systemets innstillinger."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"endre sikre systeminnstillinger"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Gir programmet tillatelse til å endre systemets data for sikkerhetsinnstilling. Ikke beregnet på vanlige programmer."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"redigere Google-tjenestekartet"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Lar applikasjonen redigere Google-tjenestekartet. Ikke ment for bruk av vanlige applikasjoner."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"starte automatisk sammen med systemet"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Lar applikasjonen ringe telefonnummer uten inngripen fra brukeren. Ondsinnede applikasjoner kan forårsake uventede oppringinger på telefonregningen. Merk at dette ikke gir applikasjonen lov til å ringe nødnummer."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"ringe vilkårlige telefonnummer direkte"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Lar applikasjonen ringe hvilket som helst telefonnummer, inkludert nødnummer, uten inngripen fra brukeren. Ondsinnede applikasjoner kan forårsake unødvendige og ulovlige samtaler til nødtjenester."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"start CDMA-telefonoppsett direkte"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Gir programmet tillatelse til å starte klargjøring av CDMA. Skadelige programmer kan starte klargjøring av CDMA uten grunn"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"kontrollere varsling for plasseringsendring"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Lar applikasjonen slå av/på varsling om plasseringsendringer fra radioen. Ikke ment for vanlige applikasjoner."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"få tilgang til egenskaper for innsjekking"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in."\n\n" Please try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Prøv igjen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Glemt mønsteret?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Opplåsing av konto"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"For mange mønsterforsøk!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"For å låse opp, logg på med Google-kontoen din"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Brukernavn (e-post)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Passord"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logg på"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ugyldig brukernavn eller passord."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Kontrollerer ..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Fjern"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Koble til en lader"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Batteriet er nesten tomt:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"mindre enn <xliff:g id="NUMBER">%d%%</xliff:g> igjen."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Batteribruk"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Factory test failed"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"i morgen"</item>
     <item quantity="other" msgid="2973062968038355991">"om <xliff:g id="COUNT">%d</xliff:g> d"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"den <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"kl. <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"i <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"dag"</string>
     <string name="days" msgid="4774547661021344602">"dager"</string>
     <string name="hour" msgid="2126771916426189481">"time"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Kopier alt"</string>
     <string name="paste" msgid="5629880836805036433">"Lim inn"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Kopier URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Inndatametode"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Legg «<xliff:g id="WORD">%s</xliff:g>» til ordlisten"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Rediger tekst"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Lite plass"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Det begynner å bli lite lagringsplass på telefonen."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Før du slår av USB-lagring, sjekk at du har avmontert enheten i USB-verten. Velg «slå av» for å slå av USB-lagring."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Slå av"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Avbryt"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Det har oppstått et problem ved deaktiveringen av USB-lagring. Kontroller at du har demontert USB-verten, og prøv igjen."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formatere minnekort"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Er du sikker på at du ønsker å formatere minnekortet? Alle data på kortet vil gå tapt."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-debugging tilkoblet"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"En datamaskin er koblet til telefonen."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Velg inndatametode"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
     <string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Lag kontakt"\n"med nummeret <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"valgt"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"ikke valgt"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Det nevnte programmet ber om tilgangstillatelse til påloggingsopplysningene for konto <xliff:g id="ACCOUNT">%1$s</xliff:g> fra <xliff:g id="APPLICATION">%2$s</xliff:g>. Vil du gi denne tillatelsen? I så fall vil svaret ditt bli lagret, og du vil ikke bli spurt flere ganger."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Det nevnte programmet ber om tilgangstillatelse til <xliff:g id="TYPE">%1$s</xliff:g>-påloggingsopplysningene for konto <xliff:g id="ACCOUNT">%2$s</xliff:g> fra <xliff:g id="APPLICATION">%3$s</xliff:g>. Vil du gi denne tillatelsen? I så fall vil svaret ditt bli lagret, og du vil ikke bli spurt flere ganger."</string>
     <string name="allow" msgid="7225948811296386551">"Tillat"</string>
     <string name="deny" msgid="2081879885755434506">"Avslå"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Tillatelse forespurt"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Inndatametode"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Synkronisering"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgjengelighet"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Bakgrunnsbilde"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Endre bakgrunnsbilde"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 9a65f95..085a99c 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Het bestand kan niet worden geopend."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Het opgevraagde bestand is niet gevonden."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Er worden te veel aanvragen verwerkt. Probeer het later opnieuw."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Fout bij aanmelding"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Synchroniseren"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchroniseren"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Te veel verwijderen voor <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
@@ -210,12 +211,9 @@
     <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>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <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="permlab_backup_data" msgid="4057625941707926463">"back-up maken en de gegevens van de toepassing herstellen"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Hiermee kan de toepassing deelnemen aan het beheer van het mechanisme voor systeemback-up en -herstel."</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>
@@ -261,8 +259,7 @@
     <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="permlab_writeSecureSettings" msgid="204676251876718288">"beveiligde systeeminstellingen wijzigen"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Hiermee kan een toepassing beveiligde systeeminstellingen wijzigen. Niet voor gebruik door normale toepassingen."</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="permlab_receiveBootCompleted" msgid="7776779842866993377">"automatisch starten bij opstarten"</string>
@@ -319,10 +316,8 @@
     <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="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>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"meteen starten met CDMA-telefooninstelling"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Hiermee kan de toepassing starten met CDMA-levering. Schadelijke toepassingen kunnen de CDMA-levering 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>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen, wordt u gevraagd om uw telefoon te ontgrendelen met uw Google aanmelding."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Probeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Patroon vergeten?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Account ontgrendelen"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Te veel patroonpogingen!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Om te ontgrendelen, moet U zich eerst bij uw Google-account aanmelden"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Gebruikersnaam (e-mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Wachtwoord"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Aanmelden"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Gebruikersnaam of wachtwoord ongeldig."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Controleren..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wissen"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Sluit de oplader aan"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"De accu raakt op:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"minder dan <xliff:g id="NUMBER">%d%%</xliff:g> resterend."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Accugebruik"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabriekstest mislukt"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"De actie FACTORY_TEST wordt alleen ondersteund voor pakketten die zijn geïnstalleerd in /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Er is geen pakket gevonden dat de actie FACTORY_TEST levert."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"morgen"</item>
     <item quantity="other" msgid="2973062968038355991">"over <xliff:g id="COUNT">%d</xliff:g> dagen"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"op <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"om <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"in <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"dag"</string>
     <string name="days" msgid="4774547661021344602">"dagen"</string>
     <string name="hour" msgid="2126771916426189481">"uur"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Alles kopiëren"</string>
     <string name="paste" msgid="5629880836805036433">"Plakken"</string>
     <string name="copyUrl" msgid="2538211579596067402">"URL kopiëren"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Invoermethode"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"\' <xliff:g id="WORD">%s</xliff:g>\' toevoegen aan woordenboek"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Tekst bewerken"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Weinig ruimte"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Opslagruimte van telefoon raakt op."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Voordat u de USB-opslag uitschakelt, moet u de koppeling met de USB-host verbreken. Selecteer \'Uitschakelen\' om USB-opslag uit te schakelen."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Uitschakelen"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Annuleren"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Er is een probleem opgetreden tijdens het uitschakelen van de USB-opslag. Controleer of u de USB-host heeft losgekoppeld en probeer het opnieuw."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"SD-kaart formatteren"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Weet u zeker dat u de SD-kaart wilt formatteren? Alle gegevens op uw kaart gaan dan verloren."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatteren"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Uw telefoon heeft verbinding met een computer."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Invoermethode selecteren"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Contact maken"\n"met <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"aangevinkt"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"niet aangevinkt"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"De weergegeven toepassingen vragen toestemming voor toegang tot de aanmeldingsgegevens voor account \'<xliff:g id="ACCOUNT">%1$s</xliff:g>\' van <xliff:g id="APPLICATION">%2$s</xliff:g>. Wilt u deze toestemming verlenen? Als u dit wilt doen, wordt uw antwoord onthouden en wordt dit niet opnieuw gevraagd."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"De weergegeven toepassingen vragen toestemming voor toegang tot de aanmeldingsgegevens voor <xliff:g id="TYPE">%1$s</xliff:g> van het account \'<xliff:g id="ACCOUNT">%2$s</xliff:g>\' van <xliff:g id="APPLICATION">%3$s</xliff:g>. Wilt u deze toestemming verlenen? Als u dit wilt doen, wordt uw antwoord onthouden en wordt dit niet opnieuw gevraagd."</string>
     <string name="allow" msgid="7225948811296386551">"Toestaan"</string>
     <string name="deny" msgid="2081879885755434506">"Weigeren"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Toestemming gevraagd"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Invoermethode"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Synchroniseren"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Toegankelijkheid"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Achtergrond"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Achtergrond wijzigen"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index de1221a..145deda 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Nie można uzyskać dostępu do pliku."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Nie znaleziono żądanego pliku."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Zbyt wiele żądań jest przetwarzanych. Spróbuj ponownie później."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Błąd logowania"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Synchronizacja"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronizuj"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Zbyt wiele usuwanych <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"zmienianie statystyk dotyczących baterii"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Pozwala na zmianę zebranych statystyk dotyczących baterii. Nie do wykorzystania przez normalne aplikacje."</string>
     <string name="permlab_backup" msgid="470013022865453920">"kontrolowanie tworzenia i przywracania kopii zapasowych systemu"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Zezwala aplikacji na kontrolowanie mechanizmu tworzenia i przywracania kopii zapasowych systemu. Opcja nie jest przeznaczona dla zwykłych aplikacji."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"Tworzenie i przywracanie kopii zapasowej danych aplikacji"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Zezwala aplikacji na działanie w ramach mechanizmu tworzenia i przywracania kopii zapasowych systemu."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"wyświetlanie nieuwierzytelnionych okien"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Pozwala na tworzenie okien, które przeznaczone są do wykorzystania przez wewnętrzny interfejs użytkownika systemu. Nie do wykorzystania przez normalne aplikacje."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"wyświetlanie ostrzeżeń systemowych"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modyfikowanie ogólnych ustawień systemu"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Pozwala aplikacji na zmianę danych ustawień systemowych. Szkodliwe aplikacje mogą uszkodzić konfigurację systemu."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"modyfikowanie ustawień systemu dotyczących zabezpieczeń"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Zezwala aplikacji na modyfikowanie bezpiecznych danych ustawień zabezpieczeń. Opcja nie jest przeznaczona dla zwykłych aplikacji."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"zmienianie mapy usług Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Pozwala aplikacji na modyfikowanie mapy usług Google. Nie wykorzystywane przez normalne aplikacje."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"automatyczne uruchamianie podczas uruchamiania urządzenia"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Pozwala aplikacjom na dzwonienie pod numery telefonów bez interwencji użytkownika. Szkodliwe aplikacje mogą powodować występowanie niespodziewanych połączeń na rachunku telefonicznym. Należy zauważyć, że aplikacje nie mogą dzwonić na numery alarmowe."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"bezpośrednie wybieranie dowolnych numerów telefonu"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Pozwala aplikacji dzwonić na dowolny numer telefonu, włącznie z numerami alarmowymi, bez interwencji użytkownika. Szkodliwe aplikacje mogą wykonywać niepotrzebne i nielegalne połączenia z usługami alarmowymi."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"Bezpośrednio rozpocznij konfigurację telefonu CDMA"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Zezwala aplikacji na rozpoczęcie obsługi CDMA. Złośliwe aplikacje mogą bez potrzeby rozpoczynać obsługę CDMA."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"kontrolowanie powiadomień o aktualizacjach lokalizacji"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Pozwala włączyć/wyłączyć powiadomienia o aktualizacjach lokalizacji przez sieć bezprzewodową. Nie wykorzystywane przez normalne aplikacje."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"dostęp do właściwości usługi rezerwacji"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Wzór odblokowania został narysowany nieprawidłowo <xliff:g id="NUMBER_0">%d</xliff:g> razy. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach telefon trzeba będzie odblokować przez zalogowanie na koncie Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> sekund."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Spróbuj ponownie za <xliff:g id="NUMBER">%d</xliff:g> sekund."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Zapomniałeś wzoru?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Odblokowanie konta"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Zbyt wiele prób narysowania wzoru!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Aby odblokować, zaloguj się za pomocą konta Google"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nazwa użytkownika (e-mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Hasło"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Zaloguj"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Błędna nazwa użytkownika lub hasło."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Trwa sprawdzanie..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wyczyść"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Podłącz ładowarkę"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Bateria się rozładowuje:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"pozostało mniej niż <xliff:g id="NUMBER">%d%%</xliff:g>."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Użycie baterii"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Nieudany test fabryczny"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Czynność FACTORY_TEST jest obsługiwana tylko dla pakietów zainstalowanych w katalogu /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nie znaleziono żadnego pakietu, który zapewnia działanie FACTORY_TEST."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"jutro"</item>
     <item quantity="other" msgid="2973062968038355991">"za <xliff:g id="COUNT">%d</xliff:g> dni"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"w dniu <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"o godzinie <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"w <xliff:g id="YEAR">%s</xliff:g> r."</string>
     <string name="day" msgid="8144195776058119424">"dzień"</string>
     <string name="days" msgid="4774547661021344602">"dni"</string>
     <string name="hour" msgid="2126771916426189481">"godzina"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Kopiuj wszystko"</string>
     <string name="paste" msgid="5629880836805036433">"Wklej"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Kopiuj adres URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Metoda wprowadzania"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Dodaj termin „<xliff:g id="WORD">%s</xliff:g>” do słownika"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Edytuj tekst"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Mało miejsca"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Maleje ilość dostępnej pamięci telefonu."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Przed wyłączeniem nośnika USB upewnij się, że odłączono go od hosta USB. Wybierz „Wyłącz”, aby wyłączyć nośnik USB."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Wyłącz"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Anuluj"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Napotkano problem podczas wyłączania nośnika USB. Sprawdź, czy host USB został odłączony, a następnie spróbuj ponownie."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formatuj kartę SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Czy na pewno sformatować kartę SD? Wszystkie dane na karcie zostaną utracone."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatuj"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Komputer jest połączony z telefonem."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Sposób wprowadzania tekstu"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandydaci"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Utwórz kontakt"\n"dla numeru <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"zaznaczone"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"niezaznaczone"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Wymienione aplikacje żądają pozwolenia na dostęp do danych logowania dla konta <xliff:g id="ACCOUNT">%1$s</xliff:g> powiązanego z aplikacją <xliff:g id="APPLICATION">%2$s</xliff:g>. Czy chcesz udzielić takiego pozwolenia? Jeśli tak, odpowiedź zostanie zapamiętana i to pytanie nie będzie już wyświetlane."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Wymienione aplikacje żądają pozwolenia na dostęp do danych logowania dotyczących funkcji <xliff:g id="TYPE">%1$s</xliff:g> dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g> powiązanego z aplikacją <xliff:g id="APPLICATION">%3$s</xliff:g>. Czy chcesz udzielić takiego pozwolenia? Jeśli tak, odpowiedź zostanie zapamiętana i to pytanie nie będzie już wyświetlane."</string>
     <string name="allow" msgid="7225948811296386551">"Zezwól"</string>
     <string name="deny" msgid="2081879885755434506">"Odmów"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Żądane pozwolenie"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Metoda wprowadzania"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Synchronizacja"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Ułatwienia dostępu"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Zmień tapetę"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 3e389ef4..4e9a0a8 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Não foi possível aceder ao ficheiro."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Não foi possível localizar o ficheiro pedido."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Existem demasiados pedidos em processamento. Tente novamente mais tarde."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Erro de início de sessão"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Sincronização"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronização"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminações de <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"modificar estatísticas da bateria"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Permite a modificação das estatísticas recolhidas sobre a bateria. Não se destina a utilização por aplicações normais."</string>
     <string name="permlab_backup" msgid="470013022865453920">"controlar a cópia de segurança e restauro do sistema"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Permite que a aplicação controle o mecanismo de cópia de segurança e restauro do sistema. Não deve ser utilizado por aplicações normais."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"fazer uma cópia de segurança e restaurar os dados da aplicação"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Permite que a aplicação participe no mecanismo de cópia de segurança e restauro do sistema."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"apresentar janelas não autorizadas"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Permite a criação de janelas destinadas a utilização pela interface de utilizador interna do sistema. Não se destina a utilização por aplicações normais."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"apresentar alertas ao nível do sistema"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificar definições globais do sistema"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Permite a uma aplicação modificar os dados das definições do sistema. Algumas aplicações maliciosas podem danificar as configurações do sistema."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"modificar definições seguras do sistema"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Permite que uma aplicação modifique os dados de definições seguras do sistema. Não deve ser utilizado por aplicações normais."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"modificar o mapa de serviços do Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Permite a uma aplicação modificar o mapa de serviços do Google. Não se destina a utilização por aplicações normais."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"iniciar automaticamente no arranque"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Permite à aplicação marcar números de telefone sem a intervenção do utilizador. Algumas aplicações maliciosas podem provocar o aparecimento de chamadas inesperadas na sua conta telefónica. Tenha em atenção que isto não permite à aplicação marcar números de emergência."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"marcar directamente quaisquer números de telefone"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Permite à aplicação marcar qualquer número de telefone, incluindo números de emergência, sem a intervenção do utilizador. Algumas aplicações maliciosas podem efectuar chamadas desnecessárias e ilegais para serviços de emergência."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"iniciar directamente a configuração do telefone CDMA"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Permite que a aplicação inicie o aprovisionamento CDMA. As aplicações mal intencionadas podem iniciar o aprovisionamento CDMA desnecessariamente"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"controlar notificações de actualização de localização"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Permite a activação/desactivação de notificações de actualização de localização a partir do rádio. Não se destina a utilização por aplicações normais."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"aceder a propriedades de verificação"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Efectuou incorrectamente o seu padrão de desbloqueio <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após outras <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telefone utilizando o seu início de sessão no Google."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Tente novamente dentro de <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Esqueceu-se do padrão?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Desbloqueio da conta"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Demasiadas tentativas de efectuar o padrão!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Para desbloquear, inicie sessão com a sua Conta Google"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nome de utilizador (e-mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Palavra-passe"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Iniciar sessão"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nome de utilizador ou palavra-passe inválidos."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"A verificar..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Ligue o carregador"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"A bateria está a ficar fraca:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"resta menos de <xliff:g id="NUMBER">%d%%</xliff:g>."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Utilização da bateria"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"O teste de fábrica falhou"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"A acção FACTORY_TEST apenas é suportada para pacotes instalados em /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Não foi localizado qualquer pacote que forneça a acção FACTORY_TEST."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"amanhã"</item>
     <item quantity="other" msgid="2973062968038355991">"daqui a <xliff:g id="COUNT">%d</xliff:g> dias"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"a <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"às <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"em <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"dia"</string>
     <string name="days" msgid="4774547661021344602">"dias"</string>
     <string name="hour" msgid="2126771916426189481">"hora"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Copiar tudo"</string>
     <string name="paste" msgid="5629880836805036433">"Colar"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Adicionar \"<xliff:g id="WORD">%s</xliff:g>\" ao dicionário"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Editar texto"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Pouco espaço livre"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"O espaço de armazenamento do telefone está a ficar reduzido."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Antes de desactivar o armazenamento USB, certifique-se de que o desmontou no anfitrião USB. Seleccione \"Desactivar\" para desactivar o armazenamento USB."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Desactivar"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Cancelar"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Detectámos um problema ao desactivar o armazenamento USB. Verifique para se certificar de que desmontou o anfitrião USB e, em seguida, tente novamente."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formatar cartão SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Tem a certeza de que pretende formatar o cartão SD? Perder-se-ão todos os dados no cartão."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"O telefone está ligado a um computador."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Seleccionar método de entrada"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Criar contacto"\n"utilizando <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"verificado"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"não verificado"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"As aplicações listadas estão a pedir autorização para aceder às credenciais de início de sessão da conta <xliff:g id="ACCOUNT">%1$s</xliff:g> a partir de <xliff:g id="APPLICATION">%2$s</xliff:g>. Pretende conceder esta autorização? Em caso afirmativo, a sua resposta será memorizada e não lhe será solicitado que responda novamente."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"As aplicações listadas estão a pedir autorização para aceder às credenciais de início de sessão <xliff:g id="TYPE">%1$s</xliff:g> para a conta <xliff:g id="ACCOUNT">%2$s</xliff:g> a partir de <xliff:g id="APPLICATION">%3$s</xliff:g>. Pretende conceder esta autorização? Em caso afirmativo, a sua resposta será memorizada e não lhe será solicitado que responda novamente."</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Recusar"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Autorização Solicitada"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sincronização"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Acessibilidade"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Imagem de fundo"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar imagem de fundo"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 06bf879..72990a1 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Não foi possível acessar o arquivo."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"O arquivo solicitado não foi encontrado."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Há muitas solicitações sendo processadas. Tente novamente mais tarde."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Erro de login"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Sincronizar"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronizar"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Muitas exclusões de <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"modificar estatísticas da bateria"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Permite a modificação das estatísticas de bateria coletadas. Não deve ser usado por aplicativos normais."</string>
     <string name="permlab_backup" msgid="470013022865453920">"controlar backup e restauração do sistema"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Permite que o aplicativo controle o mecanismo de backup e restauração do sistema. Não deve ser usado por aplicativos normais."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"fazer backup e restaurar os dados do aplicativo"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Permite que o aplicativo participe no mecanismo de backup e restauração do sistema."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"exibir janelas não autorizadas"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Permite a criação de janelas destinadas ao uso pela interface de usuário do sistema interno. Não deve ser usado por aplicativos normais."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"exibir alertas de nível do sistema"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificar configurações globais do sistema"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Permite que um aplicativo modifique os dados de configuração do sistema. Aplicativos maliciosos podem corromper a configuração do seu sistema."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"modificar configurações do sistema de segurança"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Permite que um aplicativo modifique os dados de configuração de segurança do sistema. Não deve ser usado por aplicativos normais."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"modificar o mapa de serviços do Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Permite que um aplicativo modifique o mapa de serviços do Google. Não deve ser usado por aplicativos normais."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"iniciar automaticamente na inicialização"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Permite que o aplicativo ligue para números de telefones sem a sua intervenção. Aplicativos maliciosos podem causar chamadas inesperadas na conta do seu telefone. Observe que isso não permite que o aplicativo ligue para números de emergência."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"chamar diretamente quaisquer números de telefone"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Permite que o aplicativo ligue para qualquer número de telefone, incluindo números de emergência, sem a sua intervenção. Aplicativos maliciosos podem fazer chamadas desnecessárias e ilegais para serviços de emergência."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"iniciar a configuração do telefone CDMA diretamente"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Permite que o aplicativo inicie o provisionamento CDMA. Aplicativos maliciosos podem iniciar o provisionamento CDMA desnecessariamente"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"controlar as notificações de atualização do local"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Permite a ativação/desativação de notificações de atualização do local a partir do rádio. Não deve ser usado por aplicativos normais."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"acessar propriedades de verificação"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Você desenhou o seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas e você receberá uma solicitação para desbloquear o seu telefone usando o seu login do Google."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Esqueceu o padrão?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Desbloqueio de conta"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Muitas tentativas de padrão!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Para desbloquear, faça login com a sua Conta do Google."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nome de usuário (e-mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Senha"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Fazer login"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nome de usuário ou senha inválida."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Verificando..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Conecte o carregador"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"A bateria está ficando baixa:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"menos de <xliff:g id="NUMBER">%d%%</xliff:g> restantes."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Uso da bateria"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Falha no teste de fábrica"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"A ação FACTORY_TEST é suportada apenas para pacotes instalados em /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nenhum pacote que forneça a ação FACTORY_TEST foi encontrado."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"amanhã"</item>
     <item quantity="other" msgid="2973062968038355991">"em <xliff:g id="COUNT">%d</xliff:g> dias"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"em <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"às <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"em <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"dia"</string>
     <string name="days" msgid="4774547661021344602">"dias"</string>
     <string name="hour" msgid="2126771916426189481">"hora"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Copiar tudo"</string>
     <string name="paste" msgid="5629880836805036433">"Colar"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Adicionar \"<xliff:g id="WORD">%s</xliff:g>\" ao dicionário"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Editar texto"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Pouco espaço"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"O espaço de armazenamento do telefone está ficando baixo."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Antes de desativar o armazenamento USB, desmonte o host USB. Selecione \"Desativar\" para desativar o armazenamento USB."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Desativar"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Cancelar"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Encontramos um problema ao desativar o armazenamento USB. Verifique se desmontou o host USB e tente novamente."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formatar cartão SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Tem certeza de que deseja formatar o cartão SD? Todos os dados no seu cartão serão perdidos."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Um computador está conectado ao seu telefone."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Selecionar método de entrada"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Criar contato "\n"usando <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"selecionado"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"não selecionado"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Os aplicativos listados estão solicitando autorização para acessar as credenciais de login para a conta <xliff:g id="ACCOUNT">%1$s</xliff:g> de <xliff:g id="APPLICATION">%2$s</xliff:g>. Deseja conceder essa autorização? Em caso afirmativo, sua resposta será lembrada e essa pergunta não será feita novamente."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Os aplicativos listados estão solicitando autorização para acessar as credenciais de login <xliff:g id="TYPE">%1$s</xliff:g> para a conta <xliff:g id="ACCOUNT">%2$s</xliff:g> de <xliff:g id="APPLICATION">%3$s</xliff:g>. Deseja conceder essa autorização? Em caso afirmativo, sua resposta será lembrada e essa pergunta não será feita novamente."</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Negar"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Autorização solicitada"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sincronizar"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Acessibilidade"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Papel de parede"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar papel de parede"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 24d1573..a286312 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Не удается получить доступ к файлу."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Не удалось найти указанные файлы."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Обрабатывается слишком много запросов. Повторите попытку позднее."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Ошибка входа"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Синхр."</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Синхр."</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Слишком много удалений <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"изменять статистику батареи"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Позволяет изменять собранную статистику батареи. Не предназначено для использования обычными приложениями."</string>
     <string name="permlab_backup" msgid="470013022865453920">"управление резервным копированием и восстановлением системы"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Разрешает приложению контролировать механизмы резервного копирования и восстановления системы. Не используется обычными приложениями."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"создать резервную копию и восстановить данные приложения"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Позволяет приложению участвовать в механизме резервного копирования и восстановления системы."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"показывать неавторизованные окна"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Разрешает создание окон, предназначенных для использования внутренним пользовательским интерфейсом системы. Не предназначено для использования обычными приложениями."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"показывать оповещения системного уровня"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"изменять общие настройки системы"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Позволяет приложению изменять данные настроек системы. Вредоносные приложения могут повредить конфигурацию системы."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"изменять настройки системы безопасности"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Позволяет приложению изменять данные настроек безопасности системы. Не предназначено для использования обычными приложениями."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"изменять карту служб Google"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Позволяет приложению изменять карту служб Google. Не предназначено для использования обычными приложениями."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"автоматически запускать при загрузке"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Позволяет приложению вызывать телефонные номера без вмешательства пользователя. Вредоносные приложения могут осуществлять нежелательные вызовы. Это разрешение не позволяет приложению совершать вызовы служб экстренной помощи."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"посылать прямые вызовы на любые номера"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Позволяет приложению осуществлять вызов любого номера, включая номера экстренной помощи, без вмешательства пользователя. Вредоносные приложения могут осуществить нежелательные или незаконные вызовы служб экстренной помощи."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"прямой запуск настройки телефона CDMA"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Позволяет приложению запустить настройку CDMA. Вредоносное ПО может запустить настройку CDMA"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"управлять уведомлениями об обновлении местоположения"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Позволяет включать/отключать отправку уведомлений об обновлениях местоположения по радиосвязи. Не предназначено для использования обычными приложениями."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"получать доступ к свойствам регистрации"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Количество неудачных попыток ввода графического ключа разблокировки: <xliff:g id="NUMBER_0">%d</xliff:g>. После <xliff:g id="NUMBER_1">%d</xliff:g> неудачных попыток вам будет предложено разблокировать телефон с помощью учетных данных Google.\n "\n\n" Повторите попытку через <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Повторите попытку через <xliff:g id="NUMBER">%d</xliff:g> с."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Забыли графический ключ?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Снятие блокировки аккаунта"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Слишком много попыток ввода графического ключа!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Для разблокировки войдите с помощью своего аккаунта Google"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Имя пользователя (электронная почта)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Пароль"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Вход"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Неверное имя пользователя или пароль."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Проверка..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Очистить"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Подключите зарядное устройство"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Батарея разряжена:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"осталось менее <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Расход заряда батареи"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Не удалось провести стандартный тест"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Действие FACTORY_TEST поддерживается только для пакетов, установленных в /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Пакет, обеспечивающий действие FACTORY_TEST, не найден."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"завтра"</item>
     <item quantity="other" msgid="2973062968038355991">"через <xliff:g id="COUNT">%d</xliff:g> дн."</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"в <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"в <xliff:g id="YEAR">%s</xliff:g> г."</string>
     <string name="day" msgid="8144195776058119424">"дн."</string>
     <string name="days" msgid="4774547661021344602">"дн."</string>
     <string name="hour" msgid="2126771916426189481">"ч."</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Копировать все"</string>
     <string name="paste" msgid="5629880836805036433">"Вставить"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Копировать URL"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Способ ввода"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Добавить \"<xliff:g id="WORD">%s</xliff:g>\" в словарь"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Изменить текст"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Недостаточно места"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Заканчивается место в памяти телефона."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Перед выключением USB-накопителя обязательно отключите USB-хост. Выберите \"Выключить\", чтобы выключить USB-накопитель."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Выключить"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Отмена"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"При выключении USB-накопителя произошла неполадка. Убедитесь, что USB-хост отключен, и повторите попытку."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Форматировать карту SD"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Отформатировать карту SD? Все данные, находящиеся на карте, будут уничтожены."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Формат"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка USB подключена"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Компьютер подключен к телефону."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Выберите способ ввода"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"варианты"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"Создать контакт"\n"с номером <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"отмечено"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"не проверено"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Перечисленные приложения запрашивают разрешение на доступ к регистрационном данным аккаунта <xliff:g id="ACCOUNT">%1$s</xliff:g> из <xliff:g id="APPLICATION">%2$s</xliff:g>. Разрешить доступ? Если да, ваш ответ будет сохранен и это сообщение больше не будет выводиться."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Перечисленные приложения запрашивают разрешение на доступ к регистрационном данным <xliff:g id="TYPE">%1$s</xliff:g> аккаунта <xliff:g id="ACCOUNT">%2$s</xliff:g> из <xliff:g id="APPLICATION">%3$s</xliff:g>. Разрешить доступ? Если да, ваш ответ будет сохранен и это сообщение больше не будет выводиться."</string>
     <string name="allow" msgid="7225948811296386551">"Разрешить"</string>
     <string name="deny" msgid="2081879885755434506">"Отклонить"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Разрешение запрошено"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Способ ввода"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Синхр."</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Специальные возможности"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Фоновый рисунок"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Изменить фоновый рисунок"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index cfe5ef9..0f0d966 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Det gick inte att komma åt filen."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Den begärda filen hittades inte."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"För många begäranden bearbetas. Försök igen senare."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Fel vid inloggningen"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Synkronisera"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synkronisera"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"För många <xliff:g id="CONTENT_TYPE">%s</xliff:g>-borttagningar."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"ändra batteristatistik"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Tillåter att samlad batteristatistik ändras. Används inte av vanliga program."</string>
     <string name="permlab_backup" msgid="470013022865453920">"kontrollera säkerhetskopiering och återställning av systemet"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Tillåter att programmet styr över systemets mekanism för säkerhetskopiering och återställning. Används inte av vanliga program."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"Säkerhetskopiera och återställ programmets data"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Tillåter att programmet deltar i systemets mekanism för säkerhetskopiering och återställning."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"visa otillåtna fönster"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Tillåter att fönster skapas och används av det interna systemgränssnittet. Används inte av vanliga program."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"visa varningar på systemnivå"</string>
@@ -261,8 +259,7 @@
     <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>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ändra skyddade systeminställningar"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Tillåter att ett program ändrar systemets data för skyddade inställningar. Används inte av vanliga program."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"ändra kartan för Googles tjänster"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Tillåter att ett program ändrar kartan för Google-tjänster. Används inte av vanliga program."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"starta automatiskt vid systemstart"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Tillåter att programmet ringer telefonnummer utan åtgärd från dig. Skadliga program kan orsaka oväntade samtal på din telefonräkning. Observera att programmet inte tillåts att ringa nödsamtal."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"ringa telefonnummer direkt"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Tillåter att programmet ringer ett telefonnummer, inklusive nödnummer, utan att du behöver göra något. Skadliga program kan ringa onödiga och olagliga samtal till räddningtjänsten."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"starta CDMA-telefoninställningar direkt"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Tillåter att programmet startar CDMA-anslutning. Skadliga program kan skada CDMA-anslutningar i onödan."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"styra meddelanden för platsuppdatering"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Tillåter aktivering och inaktivering av avisering om platsuppdatering i radion. Används inte av vanliga program."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"få åtkomst till incheckningsegenskaper"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> försök till kommer du att uppmanas att låsa upp telefonen med din Google-inloggning."\n\n" Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Försök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Glömt ditt grafiska lösenord?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Lås upp konto"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"För många försök med grafiskt lösenord!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Logga in med ditt Google-konto om du vill låsa upp"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Användarnamn (e-post)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Lösenord"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logga in"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ogiltigt användarnamn eller lösenord."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Kontrollerar ..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ta bort"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Anslut laddaren"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Batteriet håller på att ta slut:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"Mindre än <xliff:g id="NUMBER">%d%%</xliff:g> återstår."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Batteriförbrukning"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Det gick fel vid fabrikstestet"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Åtgärden FACTORY_TEST stöds endast för paket som har installerats i /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Vi hittade inget paket som erbjuder åtgärden FACTORY_TEST."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"imorgon"</item>
     <item quantity="other" msgid="2973062968038355991">"om <xliff:g id="COUNT">%d</xliff:g> dagar"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"den <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"kl. <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"dag"</string>
     <string name="days" msgid="4774547661021344602">"dagar"</string>
     <string name="hour" msgid="2126771916426189481">"timme"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Kopiera alla"</string>
     <string name="paste" msgid="5629880836805036433">"Klistra in"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Kopiera webbadress"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Indatametod"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"Lägg till \"<xliff:g id="WORD">%s</xliff:g>\" i ordlistan"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Redigera text"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Dåligt med utrymme"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Telefonens lagringsutrymme håller på att ta slut."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"Innan du inaktiverar USB-lagring måste du kontrollera att du har demonterat USB-värden. Välj Inaktivera om du vill inaktivera USB-lagring."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Inaktivera"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Avbryt"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Ett problem uppstod när USB-lagringsplatsen skulle inaktiveras. Kontrollera att USB-värden har demonterats och försök igen."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"Formatera SD-kort"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"Vill du formatera SD-kortet? Alla data på ditt kort kommer att gå förlorade."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"En dator är ansluten till din telefon."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Välj indatametod"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
@@ -738,23 +726,16 @@
     <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>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Programmen begär åtkomst till inloggningsuppgifterna för kontot <xliff:g id="ACCOUNT">%1$s</xliff:g> från <xliff:g id="APPLICATION">%2$s</xliff:g>. Vill du bevilja behörighet? Om du gör det kommer vi ihåg det och du blir inte tillfrågad igen."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Programmen begär åtkomst till inloggningsuppgifterna <xliff:g id="TYPE">%1$s</xliff:g> för kontot <xliff:g id="ACCOUNT">%2$s</xliff:g> från <xliff:g id="APPLICATION">%3$s</xliff:g>. Vill du bevilja behörighet? Om du gör det kommer vi ihåg det och du blir inte tillfrågad igen."</string>
     <string name="allow" msgid="7225948811296386551">"Tillåt"</string>
     <string name="deny" msgid="2081879885755434506">"Neka"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Begärd behörighet"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Indatametod"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Synkronisera"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Tillgänglighet"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Bakgrund"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Ändra bakgrund"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 1f73bab..a63a387 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"Dosyaya erişilemedi."</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"İstenen dosya bulunamadı."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Çok fazla sayıda istek işleniyor. Daha sonra yeniden deneyin."</string>
-    <string name="notification_title" msgid="4254304601929719937">"Oturum açma hatası"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"Senk."</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Senk."</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Çok fazla <xliff:g id="CONTENT_TYPE">%s</xliff:g> silme var."</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"pil istatistiklerini değiştir"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"Toplanan pil istatistiklerinin değiştirilmesine izin verir. Normal uygulamalarda kullanılmamalıdır."</string>
     <string name="permlab_backup" msgid="470013022865453920">"sistem yedeğini kontrol et ve geri yükle"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"Uygulamaya sistem yedekleme ve geri yükleme mekanizmasını denetleme izni verir. Normal uygulamalar tarafından kullanım için değildir."</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"uygulamanın verilerini yedekle ve geri yükle"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"Uygulamaya, sistem yedekleme ve geri yükleme mekanizmasına katılma izni verir."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"yetkisiz pencereleri görüntüle"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Dahili sistem kullanıcı arayüzü tarafından kullanılmak üzere tasarlanmış pencerelerin oluşturulmasına izin verir. Normal uygulamalarda kullanılmaz."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"sistem düzeyi uyarıları görüntüle"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"genel sistem ayarlarını değiştir"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"Uygulamaların sistem ayar verilerini değiştirmesine izin verir. Kötü amaçlı uygulamalar sisteminizin yapılandırmasını bozabilir."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"güvenli sistem ayarlarını değiştir"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"Bir uygulamaya sistemin güvenlik ayarları verilerini değiştirme izni verir. Normal uygulamalar tarafından kullanım için değildir."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"Google hizmetler haritasını değiştir"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"Uygulamanın, Google hizmetleri haritasını değiştirmesine izin verir. Normal uygulamalarda kullanılmaz."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"açılışta otomatik başlat"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"Uygulamanın müdahaleniz olmadan telefon numaralarını aramasına izin verir. Kötü amaçlı uygulamalar, telefon faturanızda beklenmedik görüşmeler çıkmasına neden olabilir. Bu işlev, uygulamanın acil numara aramasına izin vermez."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"herhangi bir telefon numarasını doğrudan ara"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"Uygulamanın, siz müdahale etmeden acil numaralar dahil herhangi bir numarayı aramasına izin verir. Kötü amaçlı uygulamalar acil servisleri gereksiz yere ve yasal olmayan şekilde arayabilir."</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"CDMA telefon kurulumunu doğrudan başlat"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Uygulamaya CDMA hazırlığını başlatma izni verir. Kötü niyetli uygulamalar CDMA hazırlığını gereksiz yere başlatabilir"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"konum güncelleme bildirimlerini denetle"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Radyo ile alınan konum güncelleme bildirimlerini etkinleştirmeye/devreden çıkarmaya izin verir. Normal uygulamalarda kullanılmamalıdır."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"erişim giriş özellikleri"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu Google oturum açma bilgilerinizi kullanarak açmanız istenir."\n\n" Lütfen <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde yeniden deneyin."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> saniye içinde yeniden deneyin."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Deseni unuttunuz mu?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Hesap kilidini açma"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Çok fazla sayıda desen denemesi yapıldı!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Kilidi açmak için Google hesabınızla oturum açın"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Kullanıcı adı (e-posta)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Şifre"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Oturum aç"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Geçersiz kullanıcı adı veya şifre."</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Kontrol ediliyor..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Temizle"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"Lütfen şarj cihazını takın"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"Pil tükeniyor:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"<xliff:g id="NUMBER">%d%%</xliff:g> adetten daha az kaldı."</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"Pil kullanımı"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabrika testi yapılamadı"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST işlemi yalnızca /system/app dizinine yüklenmiş paketler için desteklenir."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST işlemini sağlayan hiçbir paket bulunamadı."</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"yarın"</item>
     <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> gün içinde"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g> tarihinde"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"<xliff:g id="TIME">%s</xliff:g> saatinde"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g> yılında"</string>
     <string name="day" msgid="8144195776058119424">"gün"</string>
     <string name="days" msgid="4774547661021344602">"gün"</string>
     <string name="hour" msgid="2126771916426189481">"saat"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"Tümünü kopyala"</string>
     <string name="paste" msgid="5629880836805036433">"Yapıştır"</string>
     <string name="copyUrl" msgid="2538211579596067402">"URL\'yi kopyala"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"Giriş yöntemi"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"\"<xliff:g id="WORD">%s</xliff:g>\" kelimesini sözlüğe ekle"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"Metin düzenle"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Yer az"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"Telefonun depolama alanı azalıyor."</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"USB depolama birimini kapatmadan önce USB ana makinesinde bağlantıyı kestiğinizden emin olun. USB depolama birimini kapatmak için \"Kapat\"ı seçin."</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Kapat"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"İptal"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"USB depolama birimini kapatırken bir sorunla karşılaştık. USB ana makinesinin bağlantısını kestiğinizden emin olduktan sonra tekrar deneyin."</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"SD kartı biçimlendir"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"SD kartı biçimlendirmek istediğinizden emin misiniz? Kartınızdaki tüm veriler yok olacak."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Biçimlendir"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"Telefonunuza bir bilgisayar bağlanmış."</string>
-    <string name="select_input_method" msgid="2086499663193509436">"Giriş Yöntemini Seç"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>"\n" ile kişi oluştur"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"seçildi"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"seçilmedi"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Listelenen uygulamalar, <xliff:g id="APPLICATION">%2$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%1$s</xliff:g> hesabı için giriş bilgilerine erişim izni istiyor. Bu izni vermek istiyor musunuz? İstiyorsanız yanıtınız kaydedilecek ve tekrar sorulmayacaktır."</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Listelenen uygulamalar, <xliff:g id="APPLICATION">%3$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabı için <xliff:g id="TYPE">%1$s</xliff:g> girişi bilgilerine erişim izni istiyor. Bu izni vermek istiyor musunuz? İstiyorsanız yanıtınız kaydedilecek ve tekrar sorulmayacaktır."</string>
     <string name="allow" msgid="7225948811296386551">"İzin Ver"</string>
     <string name="deny" msgid="2081879885755434506">"Reddet"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"İzin İstendi"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Giriş yöntemi"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Senkronizasyon"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Erişebilirlik"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Duvar Kağıdı"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Duvar kağıdını değiştir"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 86807dd..2974203 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"无法访问该文件。"</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"找不到请求的文件。"</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"正在处理的请求太多,请稍后重试。"</string>
-    <string name="notification_title" msgid="4254304601929719937">"登录错误"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"同步"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"同步"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"太多<xliff:g id="CONTENT_TYPE">%s</xliff:g>删除项。"</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"修改电池使用情况统计信息"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"允许修改收集的电池使用情况统计信息。普通应用程序不能使用此权限。"</string>
     <string name="permlab_backup" msgid="470013022865453920">"控制系统备份和还原"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"允许应用程序控制系统的备份和还原机制。不适用于普通应用程序。"</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"备份与还原应用程序数据"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"允许应用程序参与系统的备份和还原机制。"</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"显示未授权的窗口"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"允许创建专供内部系统用户界面使用的窗口。普通应用程序不能使用此权限。"</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"显示系统级警报"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"修改全局系统设置"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"允许应用程序修改系统的设置数据。恶意应用程序可借此破坏您的系统配置。"</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"修改安全系统设置"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"允许应用程序修改系统的安全设置数据。不适用于普通应用程序。"</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"修改 Google 服务地图"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"允许应用程序修改 Google 服务地图。普通应用程序不能使用此权限。"</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"开机时自动启动"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"允许应用程序在没有您干预的情况下呼叫电话号码。恶意应用程序可借此在您的话费单上产生意外通话费。请注意,此权限不允许应用程序呼叫紧急电话号码。"</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"直接呼叫任何电话号码"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"允许应用程序在没有您干预的情况下呼叫任何电话号码(包括紧急电话号码)。恶意应用程序可借此对紧急服务拨打骚扰电话和非法电话。"</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"直接启动 CDMA 电话设置"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"允许应用程序启动 CDMA 服务。恶意应用程序可能会无端启动 CDMA 服务"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"控制位置更新通知"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"允许启用/停用收音机的位置更新通知。普通应用程序不能使用此权限。"</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"访问检入属性"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统会要求您使用自己的 Google 登录信息解锁手机。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> 秒后重试。"</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"忘记了图案?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"帐户解锁"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"图案尝试次数过多!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"要解除锁定,请使用您的 Google 帐户登录"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"用户名(电子邮件)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"密码"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"登录"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"用户名或密码无效。"</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"正在检查..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="AMPM">%P</xliff:g><xliff:g id="HOUR">%-l</xliff:g>点"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="AMPM">%p</xliff:g><xliff:g id="HOUR">%-l</xliff:g>点"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"清除"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"请连接充电器"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"电量在减少:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"剩余电量不足 <xliff:g id="NUMBER">%d%%</xliff:g>。"</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"电量使用情况"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"出厂测试失败"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"只有 /system/app 中安装的包支持 FACTORY_TEST 操作。"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"未发现支持 FACTORY_TEST 操作的包。"</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"明天"</item>
     <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> 天后"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"日期:<xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"时间:<xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"年份:<xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"天"</string>
     <string name="days" msgid="4774547661021344602">"天"</string>
     <string name="hour" msgid="2126771916426189481">"小时"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"全部复制"</string>
     <string name="paste" msgid="5629880836805036433">"粘贴"</string>
     <string name="copyUrl" msgid="2538211579596067402">"复制网址"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"输入法"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"将“<xliff:g id="WORD">%s</xliff:g>”添加到词典"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"编辑文字"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"空间不足"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"手机存储空间正在减少。"</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"在关闭 USB 存储设备前,请确保您已卸载了 USB 主设备。选择“关闭”关闭 USB 存储设备。"</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"关闭"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"取消"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"关闭 USB 存储设备时遇到问题。请检查是否卸载了 USB 主设备,然后重试。"</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"格式化 SD 卡"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"您确定要格式化 SD 卡?卡上的所有数据都会丢失。"</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"格式化"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接 USB 调试接口"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"计算机已与手机相连。"</string>
-    <string name="select_input_method" msgid="2086499663193509436">"选择输入法"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"候选"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"创建电话号码为"\n"<xliff:g id="NUMBER">%s</xliff:g> 的联系人"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"已选中"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"未选中"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"所列应用程序正在请求相应的权限,以便从<xliff:g id="APPLICATION">%2$s</xliff:g>访问 <xliff:g id="ACCOUNT">%1$s</xliff:g> 帐户的登录凭据。是否要授予这种权限?如果授予,系统会记住您所做的选择,且不再提示。"</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"所列应用程序正在请求相应的权限,以便从<xliff:g id="APPLICATION">%3$s</xliff:g>访问 <xliff:g id="ACCOUNT">%2$s</xliff:g> 帐户的<xliff:g id="TYPE">%1$s</xliff:g>登录凭据。是否要授予这种权限?如果授予,系统会记住您所做的选择,且不再提示。"</string>
     <string name="allow" msgid="7225948811296386551">"允许"</string>
     <string name="deny" msgid="2081879885755434506">"拒绝"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"已请求权限"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"输入法"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"同步"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"辅助功能"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"壁纸"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"更改壁纸"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 4ee4544..8f9f310 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -111,7 +111,8 @@
     <string name="httpErrorFile" msgid="8250549644091165175">"無法存取此檔案。"</string>
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"找不到要求的檔案。"</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"太多執行要求。請稍後再試一次。"</string>
-    <string name="notification_title" msgid="4254304601929719937">"登入錯誤"</string>
+    <!-- no translation found for notification_title (1259940370369187045) -->
+    <skip />
     <string name="contentServiceSync" msgid="8353523060269335667">"同步處理"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"同步處理"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"同時刪除太多 <xliff:g id="CONTENT_TYPE">%s</xliff:g>。"</string>
@@ -210,12 +211,9 @@
     <string name="permlab_batteryStats" msgid="7863923071360031652">"編輯電池狀態"</string>
     <string name="permdesc_batteryStats" msgid="5847319823772230560">"允許修改電池狀態。一般應用程式不會使用此功能。"</string>
     <string name="permlab_backup" msgid="470013022865453920">"控制系統備份與還原"</string>
-    <!-- no translation found for permdesc_backup (4837493065154256525) -->
-    <skip />
-    <!-- no translation found for permlab_backup_data (4057625941707926463) -->
-    <skip />
-    <!-- no translation found for permdesc_backup_data (8274426305151227766) -->
-    <skip />
+    <string name="permdesc_backup" msgid="4837493065154256525">"允許應用程式控制系統備份與還原機制 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_backup_data" msgid="4057625941707926463">"備份及還原應用程式資料"</string>
+    <string name="permdesc_backup_data" msgid="8274426305151227766">"允許應用程式加入系統備份與還原機制。"</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"顯示未授權視窗"</string>
     <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"允許內部系統使用介面建立視窗。一般應用程式不會使用此功能。"</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"顯示系統警示"</string>
@@ -261,8 +259,7 @@
     <string name="permlab_writeSettings" msgid="1365523497395143704">"編輯全域系統設定"</string>
     <string name="permdesc_writeSettings" msgid="838789419871034696">"允許應用程式修改系統設定。請注意:惡意程式可能使用此功能損毀系統設定。"</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"編輯安全系統設定"</string>
-    <!-- no translation found for permdesc_writeSecureSettings (5497873143539034724) -->
-    <skip />
+    <string name="permdesc_writeSecureSettings" msgid="5497873143539034724">"允許應用程式修改系統安全設定資料 (不建議一般應用程式使用)。"</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"修改 Google 服務地圖"</string>
     <string name="permdesc_writeGservices" msgid="6602362746516676175">"允許應用程式修改 Google 服務地圖。一般應用程式不會使用此功能。"</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"開機時自動啟用"</string>
@@ -319,10 +316,8 @@
     <string name="permdesc_callPhone" msgid="3369867353692722456">"允許應用程式自行撥打電話。請注意:惡意程式可能任意撥打電話,造成預期外的支出。但此選項並不允許應用程式撥打緊急電話號碼。"</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"直接撥打任何電話號碼"</string>
     <string name="permdesc_callPrivileged" msgid="244405067160028452">"允許應用程式自行撥打任何電話號碼,包括緊急電話號碼。請注意:惡意程式可能利用此功能濫用緊急服務,撥打不必要或違法的電話。"</string>
-    <!-- no translation found for permlab_performCdmaProvisioning (5604848095315421425) -->
-    <skip />
-    <!-- no translation found for permdesc_performCdmaProvisioning (6457447676108355905) -->
-    <skip />
+    <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"直接起始 CDMA 手機設定程序"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"允許應用程式啟動 CDMA 服務 (惡意應用程式可能會在非必要的情況下啟動 CDMA 服務)。"</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"控制位置更新通知"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"允許啟用/停用無線通訊位置更新通知。一般應用程式不會使用此功能。"</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"存取登機選項"</string>
@@ -465,16 +460,14 @@
     <string name="lockscreen_failed_attempts_almost_glogin" msgid="3351013842320127827">"畫出解鎖圖形已錯誤 <xliff:g id="NUMBER_0">%d</xliff:g> 次。再錯誤 <xliff:g id="NUMBER_1">%d</xliff:g> 次後,系統會要求使用 Google 登入來解鎖。"\n\n" 請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"忘記解鎖圖形?"</string>
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"解除封鎖帳戶"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"解鎖圖形出錯次數過多!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"如要解除鎖定,請使用 Google 帳戶登入"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"使用者名稱 (電子郵件)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"密碼"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"登入"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"使用者名稱或密碼錯誤。"</string>
-    <!-- no translation found for lockscreen_glogin_checking_password (6758890536332363322) -->
-    <skip />
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"檢查中..."</string>
     <string name="hour_ampm" msgid="4329881288269772723">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
     <string name="hour_cap_ampm" msgid="1829009197680861107">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"清除"</string>
@@ -486,8 +479,7 @@
     <string name="battery_low_title" msgid="7923774589611311406">"請連接充電器"</string>
     <string name="battery_low_subtitle" msgid="7388781709819722764">"電池電量即將不足:"</string>
     <string name="battery_low_percent_format" msgid="6564958083485073855">"電池電量不到 <xliff:g id="NUMBER">%d%%</xliff:g>。"</string>
-    <!-- no translation found for battery_low_why (7279169609518386372) -->
-    <skip />
+    <string name="battery_low_why" msgid="7279169609518386372">"電池使用狀況"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"出廠測試失敗"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"只有安裝在 /system/app 裡的程式才能支援 FACTORY_TEST 操作。"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"找不到提供 FACTORY_TEST 的程式。"</string>
@@ -578,12 +570,9 @@
     <item quantity="one" msgid="2178576254385739855">"明天"</item>
     <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> 天內"</item>
   </plurals>
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
+    <string name="preposition_for_date" msgid="9093949757757445117">"於 <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"於<xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"於 <xliff:g id="YEAR">%s</xliff:g> 年"</string>
     <string name="day" msgid="8144195776058119424">"天"</string>
     <string name="days" msgid="4774547661021344602">"天"</string>
     <string name="hour" msgid="2126771916426189481">"小時"</string>
@@ -621,10 +610,8 @@
     <string name="copyAll" msgid="2590829068100113057">"全部複製"</string>
     <string name="paste" msgid="5629880836805036433">"貼上"</string>
     <string name="copyUrl" msgid="2538211579596067402">"複製網址"</string>
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for addToDictionary (8793624991686948709) -->
-    <skip />
+    <string name="inputMethod" msgid="1653630062304567879">"輸入方式"</string>
+    <string name="addToDictionary" msgid="8793624991686948709">"將「<xliff:g id="WORD">%s</xliff:g>」新增至字典"</string>
     <string name="editTextMenuTitle" msgid="1672989176958581452">"編輯文字"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"儲存空間即將不足"</string>
     <string name="low_internal_storage_view_text" msgid="635106544616378836">"手機儲存空間即將不足。"</string>
@@ -700,14 +687,15 @@
     <string name="usb_storage_stop_message" msgid="2390958966725232848">"關閉 USB 儲存裝置之前,請確定先從 USB Host 卸載。選取 [關閉] 即可關閉 USB 儲存裝置。"</string>
     <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"關閉"</string>
     <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"取消"</string>
-    <!-- no translation found for usb_storage_stop_error_message (3746037090369246731) -->
-    <skip />
+    <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"關閉 USB 儲存裝置時發生問題。請檢查您是否已卸載 USB Host,然後再試一次。"</string>
     <string name="extmedia_format_title" msgid="8663247929551095854">"將 SD 卡格式化"</string>
     <string name="extmedia_format_message" msgid="3621369962433523619">"確定要將 SD 卡格式化嗎?該 SD 卡中的所有資料將會遺失。"</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"格式化"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 偵錯模式已啟用"</string>
-    <string name="adb_active_notification_message" msgid="4661997077344501389">"您的手機已連接至電腦。"</string>
-    <string name="select_input_method" msgid="2086499663193509436">"選取輸入法"</string>
+    <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+    <skip />
+    <!-- no translation found for select_input_method (6865512749462072765) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string>
@@ -738,23 +726,16 @@
     <string name="create_contact_using" msgid="4947405226788104538">"建立手機號碼為 <xliff:g id="NUMBER">%s</xliff:g>"\n"的聯絡人"</string>
     <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"已勾選"</string>
     <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"未勾選"</string>
-    <!-- no translation found for grant_credentials_permission_message_desc (6883276587034335667) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_with_authtokenlabel_desc (3159007601893584687) -->
-    <skip />
+    <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"這些應用程式要求存取「<xliff:g id="APPLICATION">%2$s</xliff:g>」的 <xliff:g id="ACCOUNT">%1$s</xliff:g> 帳戶登入認證的權限,您要授予此權限嗎?如果確定授予,系統會記住您的選擇,不會再次詢問您。"</string>
+    <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"這些應用程式要求存取「<xliff:g id="APPLICATION">%3$s</xliff:g>」的 <xliff:g id="ACCOUNT">%2$s</xliff:g> 帳戶「<xliff:g id="TYPE">%1$s</xliff:g>」登入認證的權限,您要授予此權限嗎?如果確定授予,系統會記住您的選擇,不會再次詢問您。"</string>
     <string name="allow" msgid="7225948811296386551">"允許"</string>
     <string name="deny" msgid="2081879885755434506">"拒絕"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"已要求權限"</string>
-    <!-- no translation found for permission_request_notification_subtitle (21911977892390675) -->
+    <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) -->
     <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
+    <string name="input_method_binding_label" msgid="1283557179944992649">"輸入方式"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"同步處理"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"協助工具"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"桌布"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"變更桌布"</string>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a1a179b..e7b379a 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -102,9 +102,9 @@
         <!-- Text color, typeface, size, and style for "small" inverse text. Defaults to secondary inverse text color. -->
         <attr name="textAppearanceSmallInverse" format="reference" />
 
-        <!-- Text color, typeface, size, and style for system search result title. Defaults to primary inverse text color. @hide -->
+        <!-- Text color, typeface, size, and style for system search result title. Defaults to primary inverse text color. -->
         <attr name="textAppearanceSearchResultTitle" format="reference" />
-        <!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. @hide -->
+        <!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. -->
         <attr name="textAppearanceSearchResultSubtitle" format="reference" />
 
 
@@ -530,6 +530,11 @@
              lines, the IME should provide multiple lines if it can.  Corresponds to
              {@link android.text.InputType#TYPE_TEXT_FLAG_IME_MULTI_LINE}. -->
         <flag name="textImeMultiLine" value="0x00040001" />
+        <!-- Can be combined with <var>text</var> and its variations to
+             indicate that the IME should not show any
+             dictionary-based word suggestions.  Corresponds to
+             {@link android.text.InputType#TYPE_TEXT_FLAG_NO_SUGGESTIONS}. -->
+        <flag name="textNoSuggestions" value="0x00080001" />
         <!-- Text that will be used as a URI.  Corresponds to
              {@link android.text.InputType#TYPE_CLASS_TEXT} |
              {@link android.text.InputType#TYPE_TEXT_VARIATION_URI}. -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 62a230c..15841a8 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -18,8 +18,8 @@
 */
 -->
 <resources>
-	<drawable name="screen_background_light">#fff9f9f9</drawable>
-	<drawable name="screen_background_dark">#ff202020</drawable>
+	<drawable name="screen_background_light">#ffffffff</drawable>
+	<drawable name="screen_background_dark">#ff000000</drawable>
     <drawable name="status_bar_closed_default_background">#ff000000</drawable>
     <drawable name="status_bar_opened_default_background">#ff000000</drawable>
     <drawable name="search_bar_default_color">#ff000000</drawable>
@@ -36,7 +36,7 @@
     <color name="white">#ffffffff</color>
     <color name="black">#ff000000</color>
     <color name="transparent">#00000000</color>
-    <color name="background_dark">#ff202020</color>
+    <color name="background_dark">#ff000000</color>
     <color name="bright_foreground_dark">#ffffffff</color>
     <color name="bright_foreground_dark_disabled">#80ffffff</color>
     <color name="bright_foreground_dark_inverse">#ff000000</color>
@@ -45,7 +45,7 @@
     <color name="dim_foreground_dark_inverse">#323232</color>
     <color name="dim_foreground_dark_inverse_disabled">#80323232</color>
     <color name="hint_foreground_dark">#808080</color>
-    <color name="background_light">#fff9f9f9</color>
+    <color name="background_light">#ffffffff</color>
     <color name="bright_foreground_light">#ff000000</color>
     <color name="bright_foreground_light_inverse">#ffffffff</color>
     <color name="bright_foreground_light_disabled">#80000000</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b710acb6..7695503 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -78,6 +78,20 @@
          A value of -1 means no change in orientation by default. -->
     <integer name="config_carDockRotation">-1</integer>
 
+    <!-- Control whether being in the desk dock (and powered) always
+         keeps the screen on.  By default it doesn't.  Set to true to make it. -->
+    <bool name="config_deskDockKeepsScreenOn">false</bool>
+
+    <!-- Control whether being in the car dock (and powered) always
+         keeps the screen on.  By default it does.  Set to false to not keep on. -->
+    <bool name="config_carDockKeepsScreenOn">true</bool>
+
+    <!-- Control whether being in the desk dock should enable accelerometer based screen orientation -->
+    <bool name="config_deskDockEnablesAccelerometer">false</bool>
+
+    <!-- Control whether being in the car dock should enable accelerometer based screen orientation -->
+    <bool name="config_carDockEnablesAccelerometer">false</bool>
+
     <!-- Indicate whether the lid state impacts the accessibility of
          the physical keyboard.  0 means it doesn't, 1 means it is accessible
          when the lid is open, 2 means it is accessible when the lid is
@@ -105,5 +119,7 @@
         <item>20</item>
         <item>30</item>
     </integer-array>
-    
+
+    <bool name="config_use_strict_phone_number_comparation">false</bool>
+
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2bc2a0f..89581e6 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1164,12 +1164,16 @@
   <public type="attr" name="restoreNeedsApplication" />
   <public type="attr" name="smallIcon" />
   <public type="attr" name="accountPreferences" />
+  <public type="attr" name="textAppearanceSearchResultSubtitle" />
+  <public type="attr" name="textAppearanceSearchResultTitle" />
 
   <public type="style" name="Theme.Wallpaper" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar.Fullscreen" />
   <public type="style" name="Theme.WallpaperSettings" />
   <public type="style" name="Theme.Light.WallpaperSettings" />
+  <public type="style" name="TextAppearance.SearchResult.Title" />
+  <public type="style" name="TextAppearance.SearchResult.Subtitle" />
   
   <!-- Semi-transparent background that can be used when placing a dark
        themed UI on top of some arbitrary background (such as the
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index bd79c75..a1a0102 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1391,6 +1391,9 @@
     <!-- Title of the WebView save password dialog.  If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. -->
     <string name="save_password_label">Confirm</string>
 
+    <!-- Toast for double-tap -->
+    <string name="double_tap_toast">Tip: double-tap to zoom in and out.</string>
+
     <!-- Title of an application permission, listed so the user can choose whether
         they want to allow the application to do this. -->
     <string name="permlab_readHistoryBookmarks">read Browser\'s history and bookmarks</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 69612e9..35db8ee 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -177,6 +177,13 @@
         <item name="windowExitAnimation">@anim/wallpaper_exit</item>
     </style>
 
+    <!-- A special animation we can use for recent applications,
+         for devices that can support it (do alpha transformations). -->
+    <style name="Animation.RecentApplications">
+        <item name="windowEnterAnimation">@anim/recent_enter</item>
+        <item name="windowExitAnimation">@anim/recent_exit</item>
+    </style>
+
     <!-- Status Bar Styles -->
 
     <style name="TextAppearance.StatusBarTitle">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 1aa48ee..b29e571 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -59,11 +59,7 @@
         <item name="textAppearanceLargeInverse">@android:style/TextAppearance.Large.Inverse</item>
         <item name="textAppearanceMediumInverse">@android:style/TextAppearance.Medium.Inverse</item>
         <item name="textAppearanceSmallInverse">@android:style/TextAppearance.Small.Inverse</item>
-
-        <!-- @hide -->
         <item name="textAppearanceSearchResultTitle">@android:style/TextAppearance.SearchResult.Title</item>
-        
-        <!-- @hide -->
         <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.SearchResult.Subtitle</item>
         
         <item name="textAppearanceButton">@android:style/TextAppearance.Widget.Button</item>
@@ -500,4 +496,10 @@
         <item name="windowContentOverlay">@null</item>
         <item name="textAppearance">@style/TextAppearance.Theme.Dialog.AppError</item>
     </style>
+    
+    <!-- Special theme for the recent apps dialog, to allow customization
+         with overlays. -->
+    <style name="Theme.Dialog.RecentApplications">
+    </style>
+    
 </resources>
diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml
index 859902e..710b71e 100644
--- a/core/res/res/xml/power_profile.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -26,15 +26,24 @@
   <item name="wifi.on">0.1</item>
   <item name="wifi.active">0.1</item>
   <item name="wifi.scan">0.1</item>
-  <item name="cpu.idle">0.1</item>
-  <item name="cpu.normal">0.2</item>
-  <item name="cpu.full">1</item>
   <item name="dsp.audio">0.1</item>
   <item name="dsp.video">0.1</item>
   <item name="radio.active">1</item>
   <item name="gps.on">1</item>
+  <!-- Current consumed by the radio at different signal strengths, when paging -->
   <array name="radio.on"> <!-- Strength 0 to BINS-1 -->
       <value>1</value>
       <value>0.1</value>
   </array>
+  <!-- Different CPU speeds as reported in
+       /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state -->
+  <array name="cpu.speeds">
+      <value>400000</value> <!-- 400 MHz CPU speed -->
+  </array>
+  <!-- Power consumption when CPU is idle -->
+  <item name="cpu.idle">0.1</item>
+  <!-- Power consumption at different speeds -->
+  <array name="cpu.active">
+      <value>0.2</value>
+  </array>
 </device>
diff --git a/data/etc/Android.mk b/data/etc/Android.mk
index a32d8ea..041c5d3 100644
--- a/data/etc/Android.mk
+++ b/data/etc/Android.mk
@@ -32,3 +32,20 @@
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 
 include $(BUILD_PREBUILT)
+
+########################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := required_hardware.xml
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_MODULE_CLASS := ETC
+
+# This will install the file in /system/etc/permissions
+#
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
diff --git a/data/etc/android.hardware.camera.flash-autofocus.xml b/data/etc/android.hardware.camera.flash-autofocus.xml
new file mode 100644
index 0000000..55f1900
--- /dev/null
+++ b/data/etc/android.hardware.camera.flash-autofocus.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- This is the standard set of features for a camera with a flash.  Note
+     that this currently requires having auto-focus as well. -->
+<permissions>
+    <feature name="android.hardware.camera" />
+    <feature name="android.hardware.camera.autofocus" />
+    <feature name="android.hardware.camera.flash" />
+</permissions>
diff --git a/data/etc/android.hardware.sensor.light.xml b/data/etc/android.hardware.sensor.light.xml
new file mode 100644
index 0000000..78b0fec
--- /dev/null
+++ b/data/etc/android.hardware.sensor.light.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- Feature for devices with an ambient light sensor. -->
+<permissions>
+    <feature name="android.hardware.sensor.light" />
+</permissions>
diff --git a/data/etc/android.hardware.sensor.proximity.xml b/data/etc/android.hardware.sensor.proximity.xml
new file mode 100644
index 0000000..d1948de
--- /dev/null
+++ b/data/etc/android.hardware.sensor.proximity.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- Feature for devices with a proximity sensor. -->
+<permissions>
+    <feature name="android.hardware.sensor.proximity" />
+</permissions>
diff --git a/data/etc/android.hardware.telephony.cdma.xml b/data/etc/android.hardware.telephony.cdma.xml
new file mode 100644
index 0000000..72e0485
--- /dev/null
+++ b/data/etc/android.hardware.telephony.cdma.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- This is the standard set of features for a CDMA phone. -->
+<permissions>
+    <feature name="android.hardware.telephony" />
+    <feature name="android.hardware.telephony.cdma" />
+</permissions>
diff --git a/data/etc/android.hardware.telephony.gsm.xml b/data/etc/android.hardware.telephony.gsm.xml
new file mode 100644
index 0000000..ffde433
--- /dev/null
+++ b/data/etc/android.hardware.telephony.gsm.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- This is the standard set of features for a GSM phone. -->
+<permissions>
+    <feature name="android.hardware.telephony" />
+    <feature name="android.hardware.telephony.gsm" />
+</permissions>
diff --git a/data/etc/required_hardware.xml b/data/etc/required_hardware.xml
new file mode 100644
index 0000000..896a148
--- /dev/null
+++ b/data/etc/required_hardware.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- These are the hardware features that all devices must possess.
+     These are always added for you by the build system, you do not need
+     to add them yourself. -->
+<permissions>
+    <feature name="android.hardware.sensor.compass" />
+    <feature name="android.hardware.sensor.accelerometer" />
+    <feature name="android.hardware.bluetooth" />
+    <feature name="android.hardware.wifi" />
+</permissions>
diff --git a/graphics/java/android/graphics/PixelFormat.java b/graphics/java/android/graphics/PixelFormat.java
index 221c2f8..c76cee7 100644
--- a/graphics/java/android/graphics/PixelFormat.java
+++ b/graphics/java/android/graphics/PixelFormat.java
@@ -60,6 +60,13 @@
      */
     public static final int YCbCr_420_SP= 0x11;
 
+    /** YCbCr format used for images, which uses YUYV (YUY2) encoding format.
+     *  This is an alternative format for camera preview images. Whether this
+     *  format is supported by the camera hardware can be determined by
+     *  {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
+     */
+    public static final int YCbCr_422_I = 0x14;
+
     /**
      * Encoded formats.  These are not necessarily supported by the hardware.
      */
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 3266f1e..c6f57d4 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -36,7 +36,6 @@
     private Drawable mCurrDrawable;
     private int mAlpha = 0xFF;
     private ColorFilter mColorFilter;
-    private boolean mDither = DEFAULT_DITHER;
 
     private int mCurIndex = -1;
     private boolean mMutated;
@@ -83,10 +82,10 @@
 
     @Override
     public void setDither(boolean dither) {
-        if (mDither != dither) {
-            mDither = dither;
+        if (mDrawableContainerState.mDither != dither) {
+            mDrawableContainerState.mDither = dither;
             if (mCurrDrawable != null) {
-                mCurrDrawable.setDither(mDither);
+                mCurrDrawable.setDither(mDrawableContainerState.mDither);
             }
         }
     }
@@ -212,7 +211,7 @@
             if (d != null) {
                 d.setVisible(isVisible(), true);
                 d.setAlpha(mAlpha);
-                d.setDither(mDither);
+                d.setDither(mDrawableContainerState.mDither);
                 d.setColorFilter(mColorFilter);
                 d.setState(getState());
                 d.setLevel(getLevel());
@@ -285,6 +284,8 @@
         boolean     mCanConstantState;
 
         boolean     mPaddingChecked = false;
+        
+        boolean     mDither = DEFAULT_DITHER;        
 
         DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
                 Resources res) {
@@ -323,6 +324,8 @@
                 mOpacity = orig.mOpacity;
                 mHaveStateful = orig.mHaveStateful;
                 mStateful = orig.mStateful;
+                
+                mDither = orig.mDither;
 
             } else {
                 mDrawables = new Drawable[10];
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 89db4fa..d35c5e3 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -140,6 +140,8 @@
     native void nScriptSetTimeZone(int script, byte[] timeZone);
     native void nScriptSetType(int type, boolean writable, String name, int slot);
     native void nScriptSetRoot(boolean isRoot);
+    native void nScriptSetInvokable(String name, int slot);
+    native void nScriptInvoke(int id, int slot);
 
     native void nScriptCBegin();
     native void nScriptCSetScript(byte[] script, int offset, int length);
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index a402471..35791a3 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -25,6 +25,22 @@
     boolean mIsRoot;
     Type[] mTypes;
     boolean[] mWritable;
+    Invokable[] mInvokables;
+
+    public static class Invokable {
+        RenderScript mRS;
+        Script mScript;
+        int mSlot;
+        String mName;
+
+        Invokable() {
+            mSlot = -1;
+        }
+
+        public void execute() {
+            mRS.nScriptInvoke(mScript.mID, mSlot);
+        }
+    }
 
     Script(int id, RenderScript rs) {
         super(rs);
@@ -61,12 +77,15 @@
         Type[] mTypes;
         String[] mNames;
         boolean[] mWritable;
+        int mInvokableCount = 0;
+        Invokable[] mInvokables;
 
         Builder(RenderScript rs) {
             mRS = rs;
             mTypes = new Type[MAX_SLOT];
             mNames = new String[MAX_SLOT];
             mWritable = new boolean[MAX_SLOT];
+            mInvokables = new Invokable[MAX_SLOT];
         }
 
         public void setType(Type t, int slot) {
@@ -79,6 +98,15 @@
             mNames[slot] = name;
         }
 
+        public Invokable addInvokable(String func) {
+            Invokable i = new Invokable();
+            i.mName = func;
+            i.mRS = mRS;
+            i.mSlot = mInvokableCount;
+            mInvokables[mInvokableCount++] = i;
+            return i;
+        }
+
         public void setType(boolean writable, int slot) {
             mWritable[slot] = writable;
         }
@@ -90,11 +118,20 @@
                     mRS.nScriptSetType(mTypes[ct].mID, mWritable[ct], mNames[ct], ct);
                 }
             }
+            for(int ct=0; ct < mInvokableCount; ct++) {
+                mRS.nScriptSetInvokable(mInvokables[ct].mName, ct);
+            }
         }
 
         void transferObject(Script s) {
             s.mIsRoot = mIsRoot;
             s.mTypes = mTypes;
+            s.mInvokables = new Invokable[mInvokableCount];
+            for(int ct=0; ct < mInvokableCount; ct++) {
+                s.mInvokables[ct] = mInvokables[ct];
+                s.mInvokables[ct].mScript = s;
+            }
+            s.mInvokables = null;
         }
 
         public void setRoot(boolean r) {
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 90b5958..c7b5448 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -255,28 +255,24 @@
 
 static void * SF_SaveInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
 {
-    LOGE("Save Int");
     _env->SetIntField(_obj, _field, ((int32_t *)buffer)[0]);
     return ((uint8_t *)buffer) + 4;
 }
 
 static void * SF_SaveShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
 {
-    LOGE("Save Short");
     _env->SetShortField(_obj, _field, ((int16_t *)buffer)[0]);
     return ((uint8_t *)buffer) + 2;
 }
 
 static void * SF_SaveByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
 {
-    LOGE("Save Byte");
     _env->SetByteField(_obj, _field, ((int8_t *)buffer)[0]);
     return ((uint8_t *)buffer) + 1;
 }
 
 static void * SF_SaveFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
 {
-    LOGE("Save Float");
     _env->SetFloatField(_obj, _field, ((float *)buffer)[0]);
     return ((uint8_t *)buffer) + 4;
 }
@@ -601,11 +597,8 @@
     void * buf = bufAlloc;
     rsAllocationRead(con, (RsAllocation)alloc, bufAlloc);
 
-    LOGE("size %i, ", tc->size);
-
     for (int ct=0; ct < tc->fieldCount; ct++) {
         const TypeFieldCache *tfc = &tc->fields[ct];
-        LOGE("ct=%i, buf=%p", ct, buf);
         buf = tfc->readPtr(_env, _o, tfc->field, buf);
     }
     free(bufAlloc);
@@ -891,6 +884,29 @@
 }
 
 static void
+nScriptSetInvoke(JNIEnv *_env, jobject _this, jstring _str, jint slot)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptSetInvoke, con(%p)", con);
+    const char* n = NULL;
+    if (_str) {
+        n = _env->GetStringUTFChars(_str, NULL);
+    }
+    rsScriptSetInvoke(con, n, slot);
+    if (n) {
+        _env->ReleaseStringUTFChars(_str, n);
+    }
+}
+
+static void
+nScriptInvoke(JNIEnv *_env, jobject _this, jint obj, jint slot)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
+    rsScriptInvoke(con, (RsScript)obj, slot);
+}
+
+static void
 nScriptSetRoot(JNIEnv *_env, jobject _this, jboolean isRoot)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -1366,6 +1382,8 @@
 {"nScriptSetTimeZone",             "(I[B)V",                               (void*)nScriptSetTimeZone },
 {"nScriptSetType",                 "(IZLjava/lang/String;I)V",             (void*)nScriptSetType },
 {"nScriptSetRoot",                 "(Z)V",                                 (void*)nScriptSetRoot },
+{"nScriptSetInvokable",            "(Ljava/lang/String;I)V",               (void*)nScriptSetInvoke },
+{"nScriptInvoke",                  "(II)V",                                (void*)nScriptInvoke },
 
 {"nScriptCBegin",                  "()V",                                  (void*)nScriptCBegin },
 {"nScriptCSetScript",              "([BII)V",                              (void*)nScriptCSetScript },
diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h
index 8b0f154..c02b2e7 100644
--- a/include/private/ui/SharedBufferStack.h
+++ b/include/private/ui/SharedBufferStack.h
@@ -69,12 +69,6 @@
 
 // ----------------------------------------------------------------------------
 
-struct FlatRegion { // 12 bytes
-    static const unsigned int NUM_RECT_MAX = 1;
-    uint32_t    count;
-    uint16_t    rects[4*NUM_RECT_MAX];
-};
-
 // should be 128 bytes (32 longs)
 class SharedBufferStack
 {
@@ -84,6 +78,18 @@
     friend class SharedBufferServer;
 
 public:
+    struct FlatRegion { // 12 bytes
+        static const unsigned int NUM_RECT_MAX = 1;
+        uint32_t    count;
+        uint16_t    rects[4*NUM_RECT_MAX];
+    };
+    
+    struct Statistics { // 4 longs
+        typedef int32_t usecs_t;
+        usecs_t  totalTime;
+        usecs_t  reserved[3];
+    };
+    
     SharedBufferStack();
     void init(int32_t identity);
     status_t setDirtyRegion(int buffer, const Region& reg);
@@ -100,7 +106,8 @@
     volatile int32_t reallocMask;
 
     int32_t     identity;       // surface's identity (const)
-    int32_t     reserved32[13];
+    int32_t     reserved32[9];
+    Statistics  stats;
     FlatRegion  dirtyRegion[NUM_BUFFER_MAX];    // 12*4=48 bytes
 };
 
@@ -223,7 +230,7 @@
     status_t queue(int buf);
     bool needNewBuffer(int buffer) const;
     status_t setDirtyRegion(int buffer, const Region& reg);
-
+    
 private:
     friend struct Condition;
     friend struct DequeueCondition;
@@ -257,6 +264,8 @@
     };
 
     int32_t tail;
+    // statistics...
+    nsecs_t mDequeueTime[NUM_BUFFER_MAX];
 };
 
 // ----------------------------------------------------------------------------
@@ -275,6 +284,9 @@
     
     Region getDirtyRegion(int buffer) const;
 
+    SharedBufferStack::Statistics getStats() const;
+    
+
 private:
     struct UnlockUpdate : public UpdateBase {
         const int lockedBuffer;
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index 68144b5..8ea3ab9 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -54,6 +54,7 @@
 
     bool isUpdateOnDemand() const { return mUpdateOnDemand; }
     status_t setUpdateRectangle(const Rect& updateRect);
+    status_t compositionComplete();
     
 private:
     friend class LightRefBase<FramebufferNativeWindow>;    
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
new file mode 100644
index 0000000..43042c0b
--- /dev/null
+++ b/keystore/java/android/security/Credentials.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2009 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.security;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import java.security.KeyPair;
+
+/**
+ * {@hide}
+ */
+public class Credentials {
+    private static final String LOGTAG = "Credentials";
+
+    public static final String UNLOCK_ACTION = "android.credentials.UNLOCK";
+
+    public static final String INSTALL_ACTION = "android.credentials.INSTALL";
+
+    public static final String SYSTEM_INSTALL_ACTION = "android.credentials.SYSTEM_INSTALL";
+
+    /** Key prefix for CA certificates. */
+    public static final String CA_CERTIFICATE = "CACERT_";
+
+    /** Key prefix for user certificates. */
+    public static final String USER_CERTIFICATE = "USRCERT_";
+
+    /** Key prefix for user private keys. */
+    public static final String USER_PRIVATE_KEY = "USRPKEY_";
+
+    /** Key prefix for VPN. */
+    public static final String VPN = "VPN_";
+
+    /** Key prefix for WIFI. */
+    public static final String WIFI = "WIFI_";
+
+    /** Data type for public keys. */
+    public static final String PUBLIC_KEY = "KEY";
+
+    /** Data type for private keys. */
+    public static final String PRIVATE_KEY = "PKEY";
+
+    /** Data type for certificates. */
+    public static final String CERTIFICATE = "CERT";
+
+    /** Data type for PKCS12. */
+    public static final String PKCS12 = "PKCS12";
+
+    private static Credentials singleton;
+
+    public static Credentials getInstance() {
+        if (singleton == null) {
+            singleton = new Credentials();
+        }
+        return singleton;
+    }
+
+    public void unlock(Context context) {
+        try {
+            Intent intent = new Intent(UNLOCK_ACTION);
+            context.startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            Log.w(LOGTAG, e.toString());
+        }
+    }
+
+    public void install(Context context, KeyPair pair) {
+        try {
+            Intent intent = new Intent(INSTALL_ACTION);
+            intent.putExtra(PRIVATE_KEY, pair.getPrivate().getEncoded());
+            intent.putExtra(PUBLIC_KEY, pair.getPublic().getEncoded());
+            context.startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            Log.w(LOGTAG, e.toString());
+        }
+    }
+
+    public void install(Context context, String type, byte[] value) {
+        try {
+            Intent intent = new Intent(INSTALL_ACTION);
+            intent.putExtra(type, value);
+            context.startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            Log.w(LOGTAG, e.toString());
+        }
+    }
+
+    public void installFromSdCard(Context context) {
+        try {
+            context.startActivity(new Intent(INSTALL_ACTION));
+        } catch (ActivityNotFoundException e) {
+            Log.w(LOGTAG, e.toString());
+        }
+    }
+}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
new file mode 100644
index 0000000..a47534b
--- /dev/null
+++ b/keystore/java/android/security/KeyStore.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2009 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.security;
+
+import android.net.LocalSocketAddress;
+import android.net.LocalSocket;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+/**
+ * {@hide}
+ */
+public class KeyStore {
+    public static int NO_ERROR = 1;
+    public static int LOCKED = 2;
+    public static int UNINITIALIZED = 3;
+    public static int SYSTEM_ERROR = 4;
+    public static int PROTOCOL_ERROR = 5;
+    public static int PERMISSION_DENIED = 6;
+    public static int KEY_NOT_FOUND = 7;
+    public static int VALUE_CORRUPTED = 8;
+    public static int UNDEFINED_ACTION = 9;
+    public static int WRONG_PASSWORD = 10;
+
+    private static final LocalSocketAddress sAddress = new LocalSocketAddress(
+            "keystore", LocalSocketAddress.Namespace.RESERVED);
+
+    private int mError = NO_ERROR;
+
+    private KeyStore() {}
+
+    public static KeyStore getInstance() {
+        return new KeyStore();
+    }
+
+    public int test() {
+        execute('t');
+        return mError;
+    }
+
+    public byte[] get(byte[] key) {
+        byte[][] values = execute('g', key);
+        return (values == null) ? null : values[0];
+    }
+
+    public String get(String key) {
+        byte[] value = get(key.getBytes());
+        return (value == null) ? null : new String(value);
+    }
+
+    public boolean put(byte[] key, byte[] value) {
+        execute('i', key, value);
+        return mError == NO_ERROR;
+    }
+
+    public boolean put(String key, String value) {
+        return put(key.getBytes(), value.getBytes());
+    }
+
+    public boolean delete(byte[] key) {
+        execute('d', key);
+        return mError == NO_ERROR;
+    }
+
+    public boolean delete(String key) {
+        return delete(key.getBytes());
+    }
+
+    public boolean contains(byte[] key) {
+        execute('e', key);
+        return mError == NO_ERROR;
+    }
+
+    public boolean contains(String key) {
+        return contains(key.getBytes());
+    }
+
+    public byte[][] saw(byte[] prefix) {
+        return execute('s', prefix);
+    }
+
+    public String[] saw(String prefix) {
+        byte[][] values = saw(prefix.getBytes());
+        if (values == null) {
+            return null;
+        }
+        String[] strings = new String[values.length];
+        for (int i = 0; i < values.length; ++i) {
+            strings[i] = new String(values[i]);
+        }
+        return strings;
+    }
+
+    public boolean reset() {
+        execute('r');
+        return mError == NO_ERROR;
+    }
+
+    public boolean password(byte[] oldPassword, byte[] newPassword) {
+        execute('p', oldPassword, newPassword);
+        return mError == NO_ERROR;
+    }
+
+    public boolean password(String oldPassword, String newPassword) {
+        return password(oldPassword.getBytes(), newPassword.getBytes());
+    }
+
+    public boolean password(byte[] password) {
+        return password(password, password);
+    }
+
+    public boolean password(String password) {
+        return password(password.getBytes());
+    }
+
+    public boolean lock() {
+        execute('l');
+        return mError == NO_ERROR;
+    }
+
+    public boolean unlock(byte[] password) {
+        execute('u', password);
+        return mError == NO_ERROR;
+    }
+
+    public boolean unlock(String password) {
+        return unlock(password.getBytes());
+    }
+
+    public int getLastError() {
+        return mError;
+    }
+
+    private byte[][] execute(int code, byte[]... parameters) {
+        mError = PROTOCOL_ERROR;
+
+        for (byte[] parameter : parameters) {
+            if (parameter == null || parameter.length > 65535) {
+                return null;
+            }
+        }
+
+        LocalSocket socket = new LocalSocket();
+        try {
+            socket.connect(sAddress);
+
+            OutputStream out = socket.getOutputStream();
+            out.write(code);
+            for (byte[] parameter : parameters) {
+                out.write(parameter.length >> 8);
+                out.write(parameter.length);
+                out.write(parameter);
+            }
+            out.flush();
+            socket.shutdownOutput();
+
+            InputStream in = socket.getInputStream();
+            code = in.read();
+            if (code == -1) {
+                return null;
+            }
+
+            ArrayList<byte[]> results = new ArrayList<byte[]>();
+            while (true) {
+                int i, j;
+                if ((i = in.read()) == -1) {
+                    break;
+                }
+                if ((j = in.read()) == -1) {
+                    return null;
+                }
+                byte[] result = new byte[i << 8 | j];
+                for (i = 0; i < result.length; i += j) {
+                    if ((j = in.read(result, i, result.length - i)) == -1) {
+                        return null;
+                    }
+                }
+                results.add(result);
+            }
+            mError = code;
+            return results.toArray(new byte[results.size()][]);
+        } catch (IOException e) {
+            // ignore
+        } finally {
+            try {
+                socket.close();
+            } catch (IOException e) {}
+        }
+        return null;
+    }
+}
diff --git a/keystore/java/android/security/ServiceCommand.java b/keystore/java/android/security/ServiceCommand.java
index ee80014..9923011 100644
--- a/keystore/java/android/security/ServiceCommand.java
+++ b/keystore/java/android/security/ServiceCommand.java
@@ -49,8 +49,6 @@
 
     public static final int BUFFER_LENGTH = 4096;
 
-    private static final boolean DBG = true;
-
     private String mServiceName;
     private String mTag;
     private InputStream mIn;
@@ -61,7 +59,6 @@
         if (mSocket != null) {
             return true;
         }
-        if (DBG) Log.d(mTag, "connecting...");
         try {
             mSocket = new LocalSocket();
 
@@ -80,7 +77,6 @@
     }
 
     private void disconnect() {
-        if (DBG) Log.d(mTag,"disconnecting...");
         try {
             if (mSocket != null) mSocket.close();
         } catch (IOException ex) { }
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index add358b..e534447 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -307,6 +307,9 @@
     if (lStatus == NO_ERROR) {
         trackHandle = new TrackHandle(track);
     } else {
+        // remove local strong reference to Client before deleting the Track so that the Client
+        // destructor is called by the TrackBase destructor with mLock held
+        client.clear();
         track.clear();
     }
 
@@ -707,10 +710,10 @@
     }
 }
 
-void AudioFlinger::removeClient(pid_t pid)
+// removeClient_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::removeClient_l(pid_t pid)
 {
-    LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
-    Mutex::Autolock _l(mLock);
+    LOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
     mClients.removeItem(pid);
 }
 
@@ -2078,7 +2081,10 @@
         }
     }
     mCblkMemory.clear();            // and free the shared memory
-    mClient.clear();
+    if (mClient != NULL) {
+        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
+        mClient.clear();
+    }
 }
 
 void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
@@ -2712,9 +2718,10 @@
     // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
 }
 
+// Client destructor must be called with AudioFlinger::mLock held
 AudioFlinger::Client::~Client()
 {
-    mAudioFlinger->removeClient(mPid);
+    mAudioFlinger->removeClient_l(mPid);
 }
 
 const sp<MemoryDealer>& AudioFlinger::Client::heap() const
@@ -2820,6 +2827,9 @@
                                                    format, channelCount, frameCount, flags);
     }
     if (recordTrack->getCblk() == NULL) {
+        // remove local strong reference to Client before deleting the RecordTrack so that the Client
+        // destructor is called by the TrackBase destructor with mLock held
+        client.clear();
         recordTrack.clear();
         lStatus = NO_MEMORY;
         goto Exit;
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 7a6641f..3699019 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -189,6 +189,8 @@
         virtual             ~Client();
         const sp<MemoryDealer>&     heap() const;
         pid_t               pid() const { return mPid; }
+        sp<AudioFlinger>    audioFlinger() { return mAudioFlinger; }
+
     private:
                             Client(const Client&);
                             Client& operator = (const Client&);
@@ -641,7 +643,7 @@
     friend class PlaybackThread::Track;
 
 
-                void        removeClient(pid_t pid);
+                void        removeClient_l(pid_t pid);
 
 
     // record thread
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index ac2e738..87ad97c 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -297,6 +297,16 @@
 	param const char * name
 	}
 
+ScriptSetInvoke {
+	param const char * name
+	param uint32_t slot
+	}
+
+ScriptInvoke {
+	param RsScript s
+	param uint32_t slot
+	}
+
 ScriptSetRoot {
 	param bool isRoot
 	}
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index fde31a1..99a085d 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -27,6 +27,8 @@
     mEnviroment.mClearColor[2] = 0;
     mEnviroment.mClearColor[3] = 1;
     mEnviroment.mClearDepth = 1;
+    mEnviroment.mClearStencil = 0;
+    mEnviroment.mIsRoot = false;
 }
 
 Script::~Script()
@@ -83,10 +85,23 @@
     }
 }
 
+void rsi_ScriptSetInvoke(Context *rsc, const char *name, uint32_t slot)
+{
+    ScriptCState *ss = &rsc->mScriptC;
+    ss->mInvokableNames[slot] = name;
+}
+
+void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot)
+{
+    Script *s = static_cast<Script *>(vs);
+    s->mEnviroment.mInvokables[slot]();
+}
+
+
 void rsi_ScriptSetRoot(Context * rsc, bool isRoot)
 {
     ScriptCState *ss = &rsc->mScriptC;
-    ss->mEnviroment.mIsRoot = isRoot;
+    ss->mScript->mEnviroment.mIsRoot = isRoot;
 }
 
 
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 60f83a6..e40531e 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -34,6 +34,7 @@
 class Script : public ObjectBase
 {
 public:
+    typedef void (* InvokeFunc_t)(void);
 
     Script();
     virtual ~Script();
@@ -52,17 +53,22 @@
         ObjectBaseRef<ProgramFragment> mFragment;
         //ObjectBaseRef<ProgramRaster> mRaster;
         ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
-
+        InvokeFunc_t mInvokables[MAX_SCRIPT_BANKS];
+        const char * mScriptText;
+        uint32_t mScriptTextLength;
     };
     Enviroment_t mEnviroment;
 
     uint32_t mCounstantBufferCount;
 
+
     ObjectBaseRef<Allocation> mSlots[MAX_SCRIPT_BANKS];
     ObjectBaseRef<const Type> mTypes[MAX_SCRIPT_BANKS];
     String8 mSlotNames[MAX_SCRIPT_BANKS];
     bool mSlotWritable[MAX_SCRIPT_BANKS];
 
+
+
     virtual bool run(Context *, uint32_t launchID) = 0;
 };
 
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 8230cbc..108ae5a 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -82,36 +82,27 @@
 
 ScriptCState::ScriptCState()
 {
+    mScript = NULL;
     clear();
 }
 
 ScriptCState::~ScriptCState()
 {
-    if (mAccScript) {
-        accDeleteScript(mAccScript);
-    }
+    delete mScript;
+    mScript = NULL;
 }
 
 void ScriptCState::clear()
 {
-    memset(&mProgram, 0, sizeof(mProgram));
-
     for (uint32_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
         mConstantBufferTypes[ct].clear();
         mSlotNames[ct].setTo("");
+        mInvokableNames[ct].setTo("");
         mSlotWritable[ct] = false;
     }
 
-    memset(&mEnviroment, 0, sizeof(mEnviroment));
-    mEnviroment.mClearColor[0] = 0;
-    mEnviroment.mClearColor[1] = 0;
-    mEnviroment.mClearColor[2] = 0;
-    mEnviroment.mClearColor[3] = 1;
-    mEnviroment.mClearDepth = 1;
-    mEnviroment.mClearStencil = 0;
-    mEnviroment.mIsRoot = false;
-
-    mAccScript = NULL;
+    delete mScript;
+    mScript = new ScriptC();
 
     mInt32Defines.clear();
     mFloatDefines.clear();
@@ -127,9 +118,9 @@
     return NULL;
 }
 
-void ScriptCState::runCompiler(Context *rsc)
+void ScriptCState::runCompiler(Context *rsc, ScriptC *s)
 {
-    mAccScript = accCreateScript();
+    s->mAccScript = accCreateScript();
     String8 tmp;
 
     rsc->appendNameDefines(&tmp);
@@ -139,44 +130,51 @@
     appendTypes(&tmp);
     tmp.append("#line 1\n");
 
-    const char* scriptSource[] = {tmp.string(), mProgram.mScriptText};
-    int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ;
-    accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
-    accRegisterSymbolCallback(mAccScript, symbolLookup, NULL);
-    accCompileScript(mAccScript);
-    accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript);
-    accGetScriptLabel(mAccScript, "init", (ACCvoid**) &mProgram.mInit);
-    rsAssert(mProgram.mScript);
+    const char* scriptSource[] = {tmp.string(), s->mEnviroment.mScriptText};
+    int scriptLength[] = {tmp.length(), s->mEnviroment.mScriptTextLength} ;
+    accScriptSource(s->mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
+    accRegisterSymbolCallback(s->mAccScript, symbolLookup, NULL);
+    accCompileScript(s->mAccScript);
+    accGetScriptLabel(s->mAccScript, "main", (ACCvoid**) &s->mProgram.mScript);
+    accGetScriptLabel(s->mAccScript, "init", (ACCvoid**) &s->mProgram.mInit);
+    rsAssert(s->mProgram.mScript);
 
-    if (!mProgram.mScript) {
+    if (!s->mProgram.mScript) {
         ACCchar buf[4096];
         ACCsizei len;
-        accGetScriptInfoLog(mAccScript, sizeof(buf), &len, buf);
+        accGetScriptInfoLog(s->mAccScript, sizeof(buf), &len, buf);
         LOGE(buf);
     }
 
-    if (mProgram.mInit) {
-        mProgram.mInit();
+    if (s->mProgram.mInit) {
+        s->mProgram.mInit();
     }
 
     for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
         if (mSlotNames[ct].length() > 0) {
-            accGetScriptLabel(mAccScript,
+            accGetScriptLabel(s->mAccScript,
                               mSlotNames[ct].string(),
-                              (ACCvoid**) &mProgram.mSlotPointers[ct]);
-            LOGE("var  %s  %p", mSlotNames[ct].string(), mProgram.mSlotPointers[ct]);
+                              (ACCvoid**) &s->mProgram.mSlotPointers[ct]);
         }
     }
 
-    mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
-    mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
-    mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
+    for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
+        if (mInvokableNames[ct].length() > 0) {
+            accGetScriptLabel(s->mAccScript,
+                              mInvokableNames[ct].string(),
+                              (ACCvoid**) &s->mEnviroment.mInvokables[ct]);
+        }
+    }
 
-    if (mProgram.mScript) {
+    s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
+    s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
+    s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
+
+    if (s->mProgram.mScript) {
         const static int pragmaMax = 16;
         ACCsizei pragmaCount;
         ACCchar * str[pragmaMax];
-        accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]);
+        accGetPragmas(s->mAccScript, &pragmaCount, pragmaMax, &str[0]);
 
         for (int ct=0; ct < pragmaCount; ct+=2) {
             if (!strcmp(str[ct], "version")) {
@@ -188,12 +186,12 @@
                     continue;
                 }
                 if (!strcmp(str[ct+1], "parent")) {
-                    mEnviroment.mVertex.clear();
+                    s->mEnviroment.mVertex.clear();
                     continue;
                 }
                 ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]);
                 if (pv != NULL) {
-                    mEnviroment.mVertex.set(pv);
+                    s->mEnviroment.mVertex.set(pv);
                     continue;
                 }
                 LOGE("Unreconized value %s passed to stateVertex", str[ct+1]);
@@ -208,12 +206,12 @@
                     continue;
                 }
                 if (!strcmp(str[ct+1], "parent")) {
-                    mEnviroment.mFragment.clear();
+                    s->mEnviroment.mFragment.clear();
                     continue;
                 }
                 ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]);
                 if (pf != NULL) {
-                    mEnviroment.mFragment.set(pf);
+                    s->mEnviroment.mFragment.set(pf);
                     continue;
                 }
                 LOGE("Unreconized value %s passed to stateFragment", str[ct+1]);
@@ -224,13 +222,13 @@
                     continue;
                 }
                 if (!strcmp(str[ct+1], "parent")) {
-                    mEnviroment.mFragmentStore.clear();
+                    s->mEnviroment.mFragmentStore.clear();
                     continue;
                 }
                 ProgramFragmentStore * pfs =
                     (ProgramFragmentStore *)rsc->lookupName(str[ct+1]);
                 if (pfs != NULL) {
-                    mEnviroment.mFragmentStore.set(pfs);
+                    s->mEnviroment.mFragmentStore.set(pfs);
                     continue;
                 }
                 LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]);
@@ -351,33 +349,6 @@
             s.append(";\n");
             LOGD(s);
             str->append(s);
-#if 0
-            for (size_t ct2=0; ct2 < e->getComponentCount(); ct2++) {
-                const Component *c = e->getComponent(ct2);
-                tmp.setTo("#define ");
-                tmp.append(mSlotNames[ct]);
-                tmp.append("_");
-                tmp.append(c->getComponentName());
-                switch (c->getType()) {
-                case Component::FLOAT:
-                    tmp.append(" loadF(");
-                    break;
-                case Component::SIGNED:
-                    sprintf(buf, " loadI%i(", c->getBits());
-                    tmp.append(buf);
-                    break;
-                case Component::UNSIGNED:
-                    sprintf(buf, " loadU%i(", c->getBits());
-                    tmp.append(buf);
-                    break;
-                }
-                sprintf(buf, "%i, %i)\n", ct, ct2);
-                tmp.append(buf);
-
-                LOGD(tmp);
-                str->append(tmp);
-            }
-#endif
         }
     }
 }
@@ -394,15 +365,16 @@
 
 void rsi_ScriptCSetScript(Context * rsc, void *vp)
 {
-    ScriptCState *ss = &rsc->mScriptC;
-    ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp);
+    rsAssert(0);
+    //ScriptCState *ss = &rsc->mScriptC;
+    //ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp);
 }
 
 void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
 {
     ScriptCState *ss = &rsc->mScriptC;
-    ss->mProgram.mScriptText = text;
-    ss->mProgram.mScriptTextLength = len;
+    ss->mScript->mEnviroment.mScriptText = text;
+    ss->mScript->mEnviroment.mScriptTextLength = len;
 }
 
 
@@ -410,14 +382,11 @@
 {
     ScriptCState *ss = &rsc->mScriptC;
 
-    ss->runCompiler(rsc);
+    ScriptC *s = ss->mScript;
+    ss->mScript = NULL;
 
-    ScriptC *s = new ScriptC();
+    ss->runCompiler(rsc, s);
     s->incUserRef();
-    s->mAccScript = ss->mAccScript;
-    ss->mAccScript = NULL;
-    s->mEnviroment = ss->mEnviroment;
-    s->mProgram = ss->mProgram;
     for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
         s->mTypes[ct].set(ss->mConstantBufferTypes[ct].get());
         s->mSlotNames[ct] = ss->mSlotNames[ct];
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 8aa99ef..355f0c3 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -67,17 +67,15 @@
     ScriptCState();
     ~ScriptCState();
 
-    ACCscript* mAccScript;
-
-    ScriptC::Program_t mProgram;
-    Script::Enviroment_t mEnviroment;
+    ScriptC *mScript;
 
     ObjectBaseRef<const Type> mConstantBufferTypes[MAX_SCRIPT_BANKS];
     String8 mSlotNames[MAX_SCRIPT_BANKS];
     bool mSlotWritable[MAX_SCRIPT_BANKS];
+    String8 mInvokableNames[MAX_SCRIPT_BANKS];
 
     void clear();
-    void runCompiler(Context *rsc);
+    void runCompiler(Context *rsc, ScriptC *s);
     void appendVarDefines(String8 *str);
     void appendTypes(String8 *str);
 
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index d10076b..6dc3e8b 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -321,6 +321,16 @@
     return v * v;
 }
 
+static float SC_fracf(float v)
+{
+    return v - floorf(v);
+}
+
+static float SC_roundf(float v)
+{
+    return floorf(v + 0.4999999999);
+}
+
 static float SC_distf2(float x1, float y1, float x2, float y2)
 {
     float x = x2 - x1;
@@ -1014,8 +1024,12 @@
         "float", "(float, float)" },
     { "floorf", (void *)&floorf,
         "float", "(float)" },
+    { "fracf", (void *)&SC_fracf,
+        "float", "(float)" },
     { "ceilf", (void *)&ceilf,
         "float", "(float)" },
+    { "roundf", (void *)&SC_roundf,
+        "float", "(float)" },
     { "expf", (void *)&expf,
         "float", "(float)" },
     { "logf", (void *)&logf,
diff --git a/libs/surfaceflinger/BlurFilter.cpp b/libs/surfaceflinger/BlurFilter.cpp
index 5dc0ba0..1ffbd5b 100644
--- a/libs/surfaceflinger/BlurFilter.cpp
+++ b/libs/surfaceflinger/BlurFilter.cpp
@@ -111,6 +111,50 @@
     }
 };
 
+template <int FACTOR = 0>
+struct BlurColor888X
+{
+    typedef uint32_t type;
+    int r, g, b;    
+    inline BlurColor888X() { }
+    inline BlurColor888X(uint32_t v) {
+        v = BLUR_RGBA_TO_HOST(v);
+        r = v & 0xFF;
+        g = (v >>  8) & 0xFF;
+        b = (v >> 16) & 0xFF;
+    }
+    inline void clear() { r=g=b=0; }
+    inline uint32_t to(int shift, int last, int dither) const {
+        int R = r;
+        int G = g;
+        int B = b;
+        if  (UNLIKELY(last)) {
+            if (FACTOR>0) {
+                int L = (R+G+G+B)>>2;
+                R += ((L - R) * FACTOR) >> 8;
+                G += ((L - G) * FACTOR) >> 8;
+                B += ((L - B) * FACTOR) >> 8;
+            }
+        }
+        R >>= shift;
+        G >>= shift;
+        B >>= shift;
+        return BLUR_HOST_TO_RGBA((0xFF<<24) | (B<<16) | (G<<8) | R);
+    }    
+    inline BlurColor888X& operator += (const BlurColor888X& rhs) {
+        r += rhs.r;
+        g += rhs.g;
+        b += rhs.b;
+        return *this;
+    }
+    inline BlurColor888X& operator -= (const BlurColor888X& rhs) {
+        r -= rhs.r;
+        g -= rhs.g;
+        b -= rhs.b;
+        return *this;
+    }
+};
+
 struct BlurGray565
 {
     typedef uint16_t type;
@@ -316,7 +360,13 @@
         int kernelSizeUser,
         int repeat)
 {
-    return blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat);
+    status_t err = BAD_VALUE;
+    if (image->format == GGL_PIXEL_FORMAT_RGB_565) {
+        err = blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat);
+    } else if (image->format == GGL_PIXEL_FORMAT_RGBX_8888) {
+        err = blurFilter< BlurColor888X<0x80> >(image, image, kernelSizeUser, repeat);
+    }
+    return err;
 }
 
 } // namespace android
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index d893f0a..7bdf885 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -174,6 +174,13 @@
 
     surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
 
+    if (mFlags & UPDATE_ON_DEMAND) {
+        // if we have update on demand, we definitely don't need to
+        // preserve the backbuffer, which is usually costly.
+        eglSurfaceAttrib(display, surface,
+                EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+    }
+
     if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
         if (dummy == EGL_BUFFER_PRESERVED) {
             mFlags |= BUFFER_PRESERVED;
@@ -290,9 +297,9 @@
     return mPageFlipCount;
 }
 
-/*
- * "Flip" the front and back buffers.
- */
+status_t DisplayHardware::compositionComplete() const {
+    return mNativeWindow->compositionComplete();
+}
 
 void DisplayHardware::flip(const Region& dirty) const
 {
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index 8972d51..b7f1cdb 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -80,6 +80,8 @@
     EGLDisplay getEGLDisplay() const { return mDisplay; }
     overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
     
+    status_t compositionComplete() const;
+    
     Rect bounds() const {
         return Rect(mWidth, mHeight);
     }
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 1e7f1e6..5ff9284 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -88,7 +88,6 @@
         mBuffers[i].clear();
         mWidth = mHeight = 0;
     }
-    mSurface.clear();
 }
 
 sp<LayerBaseClient::Surface> Layer::createSurface() const
@@ -99,7 +98,8 @@
 status_t Layer::ditch()
 {
     // the layer is not on screen anymore. free as much resources as possible
-    destroy();
+    //destroy();
+    mSurface.clear();
     return NO_ERROR;
 }
 
@@ -176,7 +176,7 @@
                     // this failed, for instance, because we don't support
                     // NPOT.
                     // FIXME: do something!
-                    LOGD("layer=%p, glEGLImageTargetTexture2DOES(%d) "
+                    LOGD("layer=%p, glEGLImageTargetTexture2DOES(%p) "
                          "failed err=0x%04x",
                          this, mTextures[index].image, error);
                     mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
@@ -256,11 +256,17 @@
         w = mWidth;
         h = mHeight;
         buffer = mBuffers[index];
+        
+        // destroy() could have been called before we get here, we log it
+        // because it's uncommon, and the code below should handle it
+        LOGW_IF(buffer==0, 
+                "mBuffers[%d] is null (mWidth=%d, mHeight=%d)",
+                index, w, h);
+        
         mBuffers[index].clear();
     }
 
-
-    if (buffer->getStrongCount() == 1) {
+    if (buffer!=0 && buffer->getStrongCount() == 1) {
         err = buffer->reallocate(w, h, mFormat, usage, mBufferFlags);
     } else {
         // here we have to reallocate a new buffer because we could have a
@@ -303,7 +309,6 @@
 
     // Index of the back buffer
     const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
-
     if (backbufferChanged) {
         // the size changed, we need to ask our client to request a new buffer
         LOGD_IF(DEBUG_RESIZE,
@@ -318,17 +323,6 @@
         // buffer, it'll get the new size.
         setDrawingSize(temp.w, temp.h);
 
-        // all buffers need reallocation
-        lcblk->reallocate();
-
-        // recompute the visible region
-        // FIXME: ideally we would do that only when we have received
-        // a buffer of the right size
-        flags |= Layer::eVisibleRegion;
-        this->contentDirty = true;
-        
-#if 0 
-        // FIXME: handle freeze lock
         // we're being resized and there is a freeze display request,
         // acquire a freeze lock, so that the screen stays put
         // until we've redrawn at the new size; this is to avoid
@@ -340,7 +334,12 @@
                 mFreezeLock = mFlinger->getFreezeLock();
             }
         }
-#endif
+
+        // recompute the visible region
+        flags |= Layer::eVisibleRegion;
+        this->contentDirty = true;
+        // all buffers need reallocation
+        lcblk->reallocate();
     }
 
     if (temp.sequence != front.sequence) {
@@ -382,6 +381,13 @@
     const Region dirty(lcblk->getDirtyRegion(buf));
     mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
 
+
+    const Layer::State& front(drawingState());
+    if (newFrontBuffer->getWidth() == front.w &&
+        newFrontBuffer->getHeight() ==front.h) {
+        mFreezeLock.clear();
+    }
+
     // FIXME: signal an event if we have more buffers waiting
     // mFlinger->signalEvent();
 
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index e14f35b..0ef663f 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -40,9 +40,9 @@
 
 LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
         const sp<Client>& client, int32_t i)
-     : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
-     mRefreshCache(true), mCacheAge(0), mTextureName(-1U), 
-     mWidthScale(1.0f), mHeightScale(1.0f)
+: LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
+mRefreshCache(true), mCacheAge(0), mTextureName(-1U), 
+mWidthScale(1.0f), mHeightScale(1.0f)
 {
 }
 
@@ -136,6 +136,13 @@
         // create the texture name the first time
         // can't do that in the ctor, because it runs in another thread.
         glGenTextures(1, &mTextureName);
+        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat);
+        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType);
+        if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) {
+            mReadFormat = GL_RGBA;
+            mReadType = GL_UNSIGNED_BYTE;
+            mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888;
+        }
     }
 
     Region::const_iterator it = clip.begin();
@@ -143,33 +150,39 @@
     if (it != end) {
         glEnable(GL_TEXTURE_2D);
         glBindTexture(GL_TEXTURE_2D, mTextureName);
-    
+
         if (mRefreshCache) {
             mRefreshCache = false;
             mAutoRefreshPending = false;
-            
-            // allocate enough memory for 4-bytes (2 pixels) aligned data
-            const int32_t s = (w + 1) & ~1;
-            uint16_t* const pixels = (uint16_t*)malloc(s*h*2);
+
+            int32_t pixelSize = 4;
+            int32_t s = w;
+            if (mReadType == GL_UNSIGNED_SHORT_5_6_5) {
+                // allocate enough memory for 4-bytes (2 pixels) aligned data
+                s = (w + 1) & ~1;
+                pixelSize = 2;
+            }
+
+            uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize);
 
             // This reads the frame-buffer, so a h/w GL would have to
             // finish() its rendering first. we don't want to do that
             // too often. Read data is 4-bytes aligned.
-            glReadPixels(X, Y, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
-            
+            glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels);
+
             // blur that texture.
             GGLSurface bl;
             bl.version = sizeof(GGLSurface);
             bl.width = w;
             bl.height = h;
             bl.stride = s;
-            bl.format = GGL_PIXEL_FORMAT_RGB_565;
+            bl.format = mBlurFormat;
             bl.data = (GGLubyte*)pixels;            
             blurFilter(&bl, 8, 2);
 
             if (mFlags & (DisplayHardware::NPOT_EXTENSION)) {
-                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
-                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0,
+                        mReadFormat, mReadType, pixels);
                 mWidthScale  = 1.0f / w;
                 mHeightScale =-1.0f / h;
                 mYOffset = 0;
@@ -178,10 +191,10 @@
                 GLuint th = 1 << (31 - clz(h));
                 if (tw < w) tw <<= 1;
                 if (th < h) th <<= 1;
-                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0,
-                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
+                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0,
+                        mReadFormat, mReadType, NULL);
                 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, 
-                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+                        mReadFormat, mReadType, pixels);
                 mWidthScale  = 1.0f / tw;
                 mHeightScale =-1.0f / th;
                 mYOffset = th-h;
@@ -189,7 +202,7 @@
 
             free((void*)pixels);
         }
-        
+
         const State& s = drawingState();
         if (UNLIKELY(s.alpha < 0xFF)) {
             const GGLfixed alpha = (s.alpha << 16)/255;
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
index bf36ae4..2e9d7c6 100644
--- a/libs/surfaceflinger/LayerBlur.h
+++ b/libs/surfaceflinger/LayerBlur.h
@@ -59,6 +59,9 @@
     mutable GLfloat mWidthScale;
     mutable GLfloat mHeightScale;
     mutable GLfloat mYOffset;
+    mutable GLint   mReadFormat;
+    mutable GLint   mReadType;
+    mutable uint32_t mBlurFormat;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 38a897d..667571b 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -595,6 +595,7 @@
 
     *overlayRef = new OverlayRef(mOverlayHandle, channel,
             mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
+    mLayer.mFlinger->signalEvent();
 }
 
 LayerBuffer::OverlaySource::~OverlaySource()
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index a352431..831c446 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -495,6 +495,9 @@
         // repaint the framebuffer (if needed)
         handleRepaint();
 
+        // inform the h/w that we're done compositing
+        hw.compositionComplete();
+
         // release the clients before we flip ('cause flip might block)
         unlockClients();
 
@@ -1081,9 +1084,12 @@
 
 status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
 {
-    // remove the layer from the main list (through a transaction).
+    // First add the layer to the purgatory list, which makes sure it won't 
+    // go away, then remove it from the main list (through a transaction).
     ssize_t err = removeLayer_l(layerBase);
-
+    if (err >= 0) {
+        mLayerPurgatory.add(layerBase);
+    }
     // it's possible that we don't find a layer, because it might
     // have been destroyed already -- this is not technically an error
     // from the user because there is a race between BClient::destroySurface(),
@@ -1356,8 +1362,18 @@
              * to use the purgatory.
              */
             status_t err = flinger->removeLayer_l(l);
-            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
-                    "error removing layer=%p (%s)", l.get(), strerror(-err));
+            if (err == NAME_NOT_FOUND) {
+                // The surface wasn't in the current list, which means it was
+                // removed already, which means it is in the purgatory, 
+                // and need to be removed from there.
+                // This needs to happen from the main thread since its dtor
+                // must run from there (b/c of OpenGL ES). Additionally, we
+                // can't really acquire our internal lock from 
+                // destroySurface() -- see postMessage() below.
+                ssize_t idx = flinger->mLayerPurgatory.remove(l);
+                LOGE_IF(idx < 0,
+                        "layer=%p is not in the purgatory list", l.get());
+            }
             return true;
         }
     };
@@ -1521,6 +1537,7 @@
             /*** Layer ***/
             sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get());
             if (l != 0) {
+                SharedBufferStack::Statistics stats = l->lcblk->getStats();
                 result.append( l->lcblk->dump("      ") );
                 sp<const Buffer> buf0(l->getBuffer(0));
                 sp<const Buffer> buf1(l->getBuffer(1));
@@ -1539,10 +1556,10 @@
                 snprintf(buffer, SIZE,
                         "      "
                         "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
-                        " freezeLock=%p\n",
+                        " freezeLock=%p, dq-q-time=%u us\n",
                         l->pixelFormat(),
                         w0, h0, s0, w1, h1, s1,
-                        l->getFreezeLock().get());
+                        l->getFreezeLock().get(), stats.totalTime);
                 result.append(buffer);
                 buffer[0] = 0;
             }
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index f207f85..a34889a 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -312,6 +312,7 @@
     volatile    int32_t                 mTransactionCount;
                 Condition               mTransactionCV;
                 bool                    mResizeTransationPending;
+                SortedVector< sp<LayerBase> > mLayerPurgatory;
                 
                 // protected by mStateLock (but we could use another lock)
                 Tokenizer                               mTokens;
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 90b5163..fc2e2f6 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -158,6 +158,14 @@
     return fbDev->setUpdateRect(fbDev, r.left, r.top, r.width(), r.height());
 }
 
+status_t FramebufferNativeWindow::compositionComplete()
+{
+    if (fbDev->compositionComplete) {
+        return fbDev->compositionComplete(fbDev);
+    }
+    return INVALID_OPERATION;
+}
+
 int FramebufferNativeWindow::setSwapInterval(
         android_native_window_t* window, int interval) 
 {
diff --git a/libs/ui/SharedBufferStack.cpp b/libs/ui/SharedBufferStack.cpp
index 7789a3f..9ad4349 100644
--- a/libs/ui/SharedBufferStack.cpp
+++ b/libs/ui/SharedBufferStack.cpp
@@ -276,6 +276,8 @@
         LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
                 tail, stack.head, stack.available, stack.queued);
     }
+        
+    const nsecs_t dequeueTime = systemTime(SYSTEM_TIME_THREAD);
 
     //LOGD("[%d] about to dequeue a buffer",
     //        mSharedStack->identity);
@@ -296,6 +298,8 @@
     LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail=%d, %s",
             dequeued, tail, dump("").string());
 
+    mDequeueTime[dequeued] = dequeueTime; 
+
     return dequeued;
 }
 
@@ -312,7 +316,7 @@
 status_t SharedBufferClient::lock(int buf)
 {
     LockCondition condition(this, buf);
-    status_t err = waitForCondition(condition);    
+    status_t err = waitForCondition(condition);
     return err;
 }
 
@@ -321,6 +325,9 @@
     QueueUpdate update(this);
     status_t err = updateCondition( update );
     LOGD_IF(DEBUG_ATOMICS, "queued=%d, %s", buf, dump("").string());
+    SharedBufferStack& stack( *mSharedStack );
+    const nsecs_t now = systemTime(SYSTEM_TIME_THREAD);
+    stack.stats.totalTime = ns2us(now - mDequeueTime[buf]);
     return err;
 }
 
@@ -393,5 +400,12 @@
     return stack.getDirtyRegion(buffer);
 }
 
+SharedBufferStack::Statistics SharedBufferServer::getStats() const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.stats;
+}
+
+
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index f80843d..a5a8cc9 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1740,7 +1740,11 @@
     const int e = Res_GETENTRY(resID);
 
     if (p < 0) {
-        LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        if (Res_GETPACKAGE(resID)+1 == 0) {
+            LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        } else {
+            LOGW("Resources don't contain pacakge for resource number 0x%08x", resID);
+        }
         return false;
     }
     if (t < 0) {
@@ -1786,7 +1790,11 @@
     const int e = Res_GETENTRY(resID);
 
     if (p < 0) {
-        LOGW("No package identifier when getting value for resource number 0x%08x", resID);
+        if (Res_GETPACKAGE(resID)+1 == 0) {
+            LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        } else {
+            LOGW("Resources don't contain pacakge for resource number 0x%08x", resID);
+        }
         return BAD_INDEX;
     }
     if (t < 0) {
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 73b6483..29409ab 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -63,12 +63,12 @@
 
     private String mFilename;
     private HashMap<String, String> mAttributes;
-    private boolean mHasThumbnail = false;
+    private boolean mHasThumbnail;
 
     // Because the underlying implementation (jhead) uses static variables,
     // there can only be one user at a time for the native functions (and
     // they cannot keep state in the native code across function calls). We
-    // use sLock the serialize the accesses.
+    // use sLock to serialize the accesses.
     private static Object sLock = new Object();
 
     /**
@@ -81,7 +81,7 @@
 
     /**
      * Returns the value of the specified tag or {@code null} if there
-     * is no such tag in the file.
+     * is no such tag in the JPEG file.
      *
      * @param tag the name of the tag.
      */
@@ -90,6 +90,24 @@
     }
 
     /**
+     * Returns the integer value of the specified tag. If there is no such tag
+     * in the JPEG file or the value cannot be parsed as integer, return
+     * @{code defaultValue}.
+     *
+     * @param tag the name of the tag.
+     * @param defaultValue the value to return if the tag is not available.
+     */
+    public int getAttributeInt(String tag, int defaultValue) {
+        String value = mAttributes.get(tag);
+        if (value == null) return defaultValue;
+        try {
+            return Integer.valueOf(value);
+        } catch (NumberFormatException ex) {
+            return defaultValue;
+        }
+    }
+
+    /**
      * Set the value of the specified tag.
      *
      * @param tag the name of the tag.
@@ -109,7 +127,7 @@
      * This function also initialize mHasThumbnail to indicate whether the
      * file has a thumbnail inside.
      */
-    private void loadAttributes() {
+    private void loadAttributes() throws IOException {
         // format of string passed from native C code:
         // "attrCnt attr1=valueLen value1attr2=value2Len value2..."
         // example:
@@ -153,9 +171,9 @@
     /**
      * Save the tag data into the JPEG file. This is expensive because it involves
      * copying all the JPG data from one file to another and deleting the old file
-     * and renaming the other. It's best to use {@link #setAttribute(String,String)} to set all
-     * attributes to write and make a single call rather than multiple calls for
-     * each attribute.
+     * and renaming the other. It's best to use {@link #setAttribute(String,String)}
+     * to set all attributes to write and make a single call rather than multiple
+     * calls for each attribute.
      */
     public void saveAttributes() throws IOException {
         // format of string passed to native C code:
@@ -195,6 +213,8 @@
 
     /**
      * Returns the thumbnail inside the JPEG file, or {@code null} if there is no thumbnail.
+     * The returned data is in JPEG format and can be decoded using
+     * {@link android.graphics.BitmapFactory#decodeByteArray(byte[],int,int)}
      */
     public byte[] getThumbnail() {
         synchronized (sLock) {
@@ -203,98 +223,23 @@
     }
 
     /**
-     * Returns a human-readable string describing the white balance value. Returns empty
-     * string if there is no white balance value or it is not recognized.
+     * Stores the latitude and longitude value in a float array. The first element is
+     * the latitude, and the second element is the longitude. Returns false if the
+     * Exif tags are not available.
      */
-    public String getWhiteBalanceString() {
-        String value = getAttribute(TAG_WHITE_BALANCE);
-        if (value == null) return "";
-
-        int whitebalance;
-        try {
-            whitebalance = Integer.parseInt(value);
-        } catch (NumberFormatException ex) {
-            return "";
-        }
-
-        switch (whitebalance) {
-            case WHITEBALANCE_AUTO:
-                return "Auto";
-            case WHITEBALANCE_MANUAL:
-                return "Manual";
-            default:
-                return "";
-        }
-    }
-
-    /**
-     * Returns a human-readable string describing the orientation value. Returns empty
-     * string if there is no orientation value or it it not recognized.
-     */
-    public String getOrientationString() {
-        // TODO: this function needs to be localized.
-        String value = getAttribute(TAG_ORIENTATION);
-        if (value == null) return "";
-
-        int orientation;
-        try {
-            orientation = Integer.parseInt(value);
-        } catch (NumberFormatException ex) {
-            return "";
-        }
-
-        String orientationString;
-        switch (orientation) {
-            case ORIENTATION_NORMAL:
-                orientationString = "Normal";
-                break;
-            case ORIENTATION_FLIP_HORIZONTAL:
-                orientationString = "Flipped horizontal";
-                break;
-            case ORIENTATION_ROTATE_180:
-                orientationString = "Rotated 180 degrees";
-                break;
-            case ORIENTATION_FLIP_VERTICAL:
-                orientationString = "Upside down mirror";
-                break;
-            case ORIENTATION_TRANSPOSE:
-                orientationString = "Transposed";
-                break;
-            case ORIENTATION_ROTATE_90:
-                orientationString = "Rotated 90 degrees";
-                break;
-            case ORIENTATION_TRANSVERSE:
-                orientationString = "Transversed";
-                break;
-            case ORIENTATION_ROTATE_270:
-                orientationString = "Rotated 270 degrees";
-                break;
-            default:
-                orientationString = "Undefined";
-                break;
-        }
-        return orientationString;
-    }
-
-    /**
-     * Returns the latitude and longitude value in a float array. The first element is
-     * the latitude, and the second element is the longitude.
-     */
-    public float[] getLatLong() {
+    public boolean getLatLong(float output[]) {
         String latValue = mAttributes.get(ExifInterface.TAG_GPS_LATITUDE);
         String latRef = mAttributes.get(ExifInterface.TAG_GPS_LATITUDE_REF);
         String lngValue = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE);
         String lngRef = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE_REF);
-        float[] latlng = null;
 
-        if (latValue != null && latRef != null
-                && lngValue != null && lngRef != null) {
-            latlng = new float[2];
-            latlng[0] = convertRationalLatLonToFloat(latValue, latRef);
-            latlng[1] = convertRationalLatLonToFloat(lngValue, lngRef);
+        if (latValue != null && latRef != null && lngValue != null && lngRef != null) {
+            output[0] = convertRationalLatLonToFloat(latValue, latRef);
+            output[1] = convertRationalLatLonToFloat(lngValue, lngRef);
+            return true;
+        } else {
+            return false;
         }
-
-        return latlng;
     }
 
     private static SimpleDateFormat sFormatter =
@@ -303,6 +248,7 @@
     /**
      * Returns number of milliseconds since Jan. 1, 1970, midnight GMT.
      * Returns -1 if the date time information if not available.
+     * @hide
      */
     public long getDateTime() {
         String dateTimeString = mAttributes.get(TAG_DATETIME);
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index d9127e7..37a3bd5 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -726,8 +726,8 @@
                     // exif is null
                 }
                 if (exif != null) {
-                    float[] latlng = exif.getLatLong();
-                    if (latlng != null) {
+                    float[] latlng = new float[2];
+                    if (exif.getLatLong(latlng)) {
                         values.put(Images.Media.LATITUDE, latlng[0]);
                         values.put(Images.Media.LONGITUDE, latlng[1]);
                     }
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index ba4c4c7..c4c6149 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1148,6 +1148,13 @@
                     CODEC_LOGV("Finished flushing both ports, now continuing from"
                          " seek-time.");
 
+                    // Clear this flag in case the decoder sent us either
+                    // the EVENT_BUFFER_FLAG(1) or an output buffer with
+                    // the EOS flag set _while_ flushing. Since we're going
+                    // to submit "fresh" input data now, this flag no longer
+                    // applies to our future.
+                    mNoMoreOutputData = false;
+
                     drainInputBuffers();
                     fillOutputBuffers();
                 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index ef211b3..9b7ff6c 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -490,17 +490,17 @@
   
   //Streaming test files
   public static final String STREAM_H264_480_360_1411k = 
-      "http://sridharg.googlejunta.com/yslau/stress_media/h264_regular.mp4"; 
+      "http://75.17.48.204:10088/yslau/stress_media/h264_regular.mp4";
   public static final String STREAM_WMV = 
-      "http://sridharg.googlejunta.com/yslau/stress_media/bugs.wmv"; 
+      "http://75.17.48.204:10088/yslau/stress_media/bugs.wmv";
   public static final String STREAM_H263_176x144_325k = 
-      "http://sridharg.googlejunta.com/yslau/stress_media/h263_regular.3gp";
+      "http://75.17.48.204:10088/yslau/stress_media/h263_regular.3gp";
   public static final String STREAM_H264_352x288_1536k = 
-      "http://sridharg.googlejunta.com/yslau/stress_media/h264_highBitRate.mp4";
+      "http://75.17.48.204:10088/yslau/stress_media/h264_highBitRate.mp4";
   public static final String STREAM_MP3= 
-      "http://sridharg.googlejunta.com/yslau/stress_media/mp3_regular.mp3";
+      "http://75.17.48.204:10088/yslau/stress_media/mp3_regular.mp3";
   public static final String STREAM_MPEG4_QVGA_128k = 
-      "http://sridharg.googlejunta.com/yslau/stress_media/mpeg4_qvga_24fps.3gp";
+      "http://75.17.48.204:10088/yslau/stress_media/mpeg4_qvga_24fps.3gp";
   public static final int STREAM_H264_480_360_1411k_DURATION = 46000;
   public static final int VIDEO_H263_AAC_DURATION = 501000;
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
index 39846c6..b4d265d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
@@ -214,8 +214,11 @@
             Log.v(TAG, "before getduration");
             mOutputDuration = mediaPlayer.getDuration();
             Log.v(TAG, "get video dimension");
-            mOutputVideoHeight = CodecTest.videoHeight(outputFilePath);
-            mOutputVideoWidth = CodecTest.videoWidth(outputFilePath);
+            Thread.sleep(1000);
+            mOutputVideoHeight = mediaPlayer.getVideoHeight();
+            mOutputVideoWidth = mediaPlayer.getVideoWidth();
+            //mOutputVideoHeight = CodecTest.videoHeight(outputFilePath);
+            //mOutputVideoWidth = CodecTest.videoWidth(outputFilePath);
             mediaPlayer.release();    
         } catch (Exception e) {
             Log.v(TAG, e.toString());
@@ -321,10 +324,10 @@
             recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.H263,
                     MediaRecorder.OutputFormat.THREE_GPP, 
                     MediaNames.RECORDED_PORTRAIT_H263, true);
-            videoRecordedResult = 
-                validateVideo(MediaNames.RECORDED_PORTRAIT_H263, 352, 288);
             mCamera.lock();
             mCamera.release();
+            videoRecordedResult =
+                validateVideo(MediaNames.RECORDED_PORTRAIT_H263, 352, 288);
         } catch (Exception e) {
             Log.v(TAG, e.toString());
         }
@@ -414,7 +417,8 @@
                MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);      
         assertTrue("Invalid video Size", isTestInvalidVideoSizeSuccessful);
     }
-    
+
+    @Suppress
     @LargeTest
     public void testInvalidFrameRate() throws Exception {       
         boolean isTestInvalidFrameRateSuccessful = false;
@@ -453,4 +457,3 @@
         }
     }
 }
-
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
index 69e93a1..10796f1 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -16,6 +16,7 @@
 
 package com.android.mediaframeworktest.stress;
 
+
 import com.android.mediaframeworktest.MediaFrameworkTest;
 
 import java.io.BufferedWriter;
@@ -26,6 +27,7 @@
 import android.hardware.Camera;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
+import android.os.Looper;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
@@ -54,7 +56,14 @@
     private static final String OUTPUT_FILE_EXT = ".3gp";
     private static final String MEDIA_STRESS_OUTPUT =
         "/sdcard/mediaStressOutput.txt";
-    
+    private Looper mCameraLooper = null;
+    private Looper mRecorderLooper = null;
+    private final Object lock = new Object();
+    private final Object recorderlock = new Object();
+    private static int WAIT_FOR_COMMAND_TO_COMPLETE = 10000;  // Milliseconds.
+    private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
+    private final RecorderErrorCallback mRecorderErrorCallback = new RecorderErrorCallback();
+
     public MediaRecorderStressTest() {
         super("com.android.mediaframeworktest", MediaFrameworkTest.class);
     }
@@ -63,41 +72,129 @@
         getActivity();
         super.setUp();      
     }
-       
+
+    private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
+        public void onError(int error, android.hardware.Camera camera) {
+            if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) {
+                assertTrue("Camera test mediaserver died", false);
+            }
+        }
+    }
+
+    private final class RecorderErrorCallback implements MediaRecorder.OnErrorListener {
+        public void onError(MediaRecorder mr, int what, int extra) {
+            // fail the test case no matter what error come up
+            assertTrue("mediaRecorder error", false);
+        }
+    }
+
+    private void initializeCameraMessageLooper() {
+        Log.v(TAG, "start looper");
+        new Thread() {
+            @Override
+            public void run() {
+                // Set up a looper to be used by camera.
+                Looper.prepare();
+                Log.v(TAG, "start loopRun");
+                mCameraLooper = Looper.myLooper();
+                mCamera = Camera.open();
+                synchronized (lock) {
+                    lock.notify();
+                }
+                Looper.loop();
+                Log.v(TAG, "initializeMessageLooper: quit.");
+            }
+        }.start();
+    }
+
+    private void initializeRecorderMessageLooper() {
+        Log.v(TAG, "start looper");
+        new Thread() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                Log.v(TAG, "start loopRun");
+                mRecorderLooper = Looper.myLooper();
+                mRecorder = new MediaRecorder();
+                synchronized (recorderlock) {
+                    recorderlock.notify();
+                }
+                Looper.loop();  // Blocks forever until Looper.quit() is called.
+                Log.v(TAG, "initializeMessageLooper: quit.");
+            }
+        }.start();
+    }
+
+    /*
+     * Terminates the message looper thread.
+     */
+    private void terminateCameraMessageLooper() {
+        mCameraLooper.quit();
+        try {
+            Thread.sleep(1000);
+        } catch (Exception e){
+            Log.v(TAG, e.toString());
+        }
+        mCamera.release();
+    }
+
+    /*
+     * Terminates the message looper thread.
+     */
+    private void terminateRecorderMessageLooper() {
+        mRecorderLooper.quit();
+        try {
+            Thread.sleep(1000);
+        } catch (Exception e){
+            Log.v(TAG, e.toString());
+        }
+        mRecorder.release();
+    }
+
     //Test case for stressing the camera preview.
     @LargeTest
     public void testStressCamera() throws Exception {
-        SurfaceHolder mSurfaceHolder;             
+        SurfaceHolder mSurfaceHolder;
         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
         File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
         Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
         output.write("Camera start preview stress:\n");
-        output.write("Total number of loops:" + 
+        output.write("Total number of loops:" +
                 NUMBER_OF_CAMERA_STRESS_LOOPS + "\n");
-        try {        
+        try {
             Log.v(TAG, "Start preview");
             output.write("No of loop: ");
+
             for (int i = 0; i< NUMBER_OF_CAMERA_STRESS_LOOPS; i++){
-                mCamera = Camera.open();
+                synchronized (lock) {
+                    initializeCameraMessageLooper();
+                    try {
+                        lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+                    } catch(Exception e) {
+                        Log.v(TAG, "wait was interrupted.");
+                    }
+                }
+                mCamera.setErrorCallback(mCameraErrorCallback);
                 mCamera.setPreviewDisplay(mSurfaceHolder);
                 mCamera.startPreview();
                 Thread.sleep(WAIT_TIME_CAMERA_TEST);
                 mCamera.stopPreview();
-                mCamera.release();
+                terminateCameraMessageLooper();
                 output.write(" ," + i);
             }
         } catch (Exception e) {
-                Log.v(TAG, e.toString());
+            assertTrue("CameraStressTest", false);
+            Log.v(TAG, e.toString());
         }
         output.write("\n\n");
         output.close();
     }
-    
+
     //Test case for stressing the camera preview.
     @LargeTest
     public void testStressRecorder() throws Exception {
         String filename;
-        SurfaceHolder mSurfaceHolder;             
+        SurfaceHolder mSurfaceHolder;
         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
         File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
         Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
@@ -108,12 +205,20 @@
             output.write("No of loop: ");
             Log.v(TAG, "Start preview");
             for (int i = 0; i < NUMBER_OF_RECORDER_STRESS_LOOPS; i++){
+                synchronized (recorderlock) {
+                    initializeRecorderMessageLooper();
+                    try {
+                        recorderlock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+                    } catch(Exception e) {
+                        Log.v(TAG, "wait was interrupted.");
+                    }
+                }
                 Log.v(TAG, "counter = " + i);
                 filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
                 Log.v(TAG, filename);
-                mRecorder = new MediaRecorder();
+                mRecorder.setOnErrorListener(mRecorderErrorCallback);
                 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);          
+                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                 mRecorder.setOutputFile(filename);
                 mRecorder.setVideoFrameRate(20);
                 mRecorder.setVideoSize(176,144);
@@ -125,47 +230,63 @@
                 Log.v(TAG, "prepare");
                 mRecorder.prepare();
                 Log.v(TAG, "before release");
-                Thread.sleep(WAIT_TIME_RECORDER_TEST);  
+                Thread.sleep(WAIT_TIME_RECORDER_TEST);
                 mRecorder.reset();
-                mRecorder.release();
+                terminateRecorderMessageLooper();
                 output.write(", " + i);
             }
         } catch (Exception e) {
-                Log.v(TAG, e.toString());
+            assertTrue("Recorder Stress test", false);
+            Log.v(TAG, e.toString());
         }
         output.write("\n\n");
         output.close();
     }
-    
-    
+
     //Stress test case for switching camera and video recorder preview.
     @LargeTest
     public void testStressCameraSwitchRecorder() throws Exception {
         String filename;
-        SurfaceHolder mSurfaceHolder;             
+        SurfaceHolder mSurfaceHolder;
         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
         File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
         Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
         output.write("Camera and video recorder preview switching\n");
         output.write("Total number of loops:"
                 + NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER + "\n");
-        try {    
+        try {
             Log.v(TAG, "Start preview");
             output.write("No of loop: ");
             for (int i = 0; i < NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER; i++){
-                mCamera = Camera.open();
+                synchronized (lock) {
+                    initializeCameraMessageLooper();
+                    try {
+                        lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+                    } catch(Exception e) {
+                        Log.v(TAG, "wait was interrupted.");
+                    }
+                }
+                mCamera.setErrorCallback(mCameraErrorCallback);
                 mCamera.setPreviewDisplay(mSurfaceHolder);
                 mCamera.startPreview();
                 Thread.sleep(WAIT_TIME_CAMERA_TEST);
                 mCamera.stopPreview();
-                mCamera.release();
+                terminateCameraMessageLooper();
                 mCamera = null;
                 Log.v(TAG, "release camera");
                 filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
                 Log.v(TAG, filename);
-                mRecorder = new MediaRecorder();
+                synchronized (recorderlock) {
+                    initializeRecorderMessageLooper();
+                    try {
+                        recorderlock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+                    } catch(Exception e) {
+                        Log.v(TAG, "wait was interrupted.");
+                    }
+                }
+                mRecorder.setOnErrorListener(mRecorderErrorCallback);
                 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);          
+                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                 mRecorder.setOutputFile(filename);
                 mRecorder.setVideoFrameRate(20);
                 mRecorder.setVideoSize(176,144);
@@ -176,23 +297,24 @@
                 Log.v(TAG, "prepare");
                 mRecorder.prepare();
                 Log.v(TAG, "before release");
-                Thread.sleep(WAIT_TIME_CAMERA_TEST);  
-                mRecorder.release();
+                Thread.sleep(WAIT_TIME_CAMERA_TEST);
+                terminateRecorderMessageLooper();
                 Log.v(TAG, "release video recorder");
                 output.write(", " + i);
             }
         } catch (Exception e) {
+            assertTrue("Camer and recorder switch mode", false);
                 Log.v(TAG, e.toString());
         }
         output.write("\n\n");
         output.close();
     }
-    
+
     //Stress test case for record a video and play right away.
     @LargeTest
     public void testStressRecordVideoAndPlayback() throws Exception {
         String filename;
-        SurfaceHolder mSurfaceHolder;             
+        SurfaceHolder mSurfaceHolder;
         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
         File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
         Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
@@ -204,10 +326,18 @@
             for (int i = 0; i < NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS; i++){
                 filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
                 Log.v(TAG, filename);
-                mRecorder = new MediaRecorder();
+                synchronized (recorderlock) {
+                    initializeRecorderMessageLooper();
+                    try {
+                        recorderlock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+                    } catch(Exception e) {
+                        Log.v(TAG, "wait was interrupted.");
+                    }
+                }
+                mRecorder.setOnErrorListener(mRecorderErrorCallback);
                 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
-                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);          
+                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                 mRecorder.setOutputFile(filename);
                 mRecorder.setVideoFrameRate(20);
                 mRecorder.setVideoSize(352,288);
@@ -216,11 +346,11 @@
                 Log.v(TAG, "mediaRecorder setPreview");
                 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
                 mRecorder.prepare();
-                mRecorder.start();               
+                mRecorder.start();
                 Thread.sleep(WAIT_TIME_RECORD);
                 Log.v(TAG, "Before stop");
                 mRecorder.stop();
-                mRecorder.release();
+                terminateRecorderMessageLooper();
                 //start the playback
                 MediaPlayer mp = new MediaPlayer();
                 mp.setDataSource(filename);
@@ -232,10 +362,10 @@
                 output.write(", " + i);
             }
         } catch (Exception e) {
+            assertTrue("record and playback", false);
                 Log.v(TAG, e.toString());
         }
         output.write("\n\n");
         output.close();
-    }   
+    }
 }
-
diff --git a/obex/javax/obex/HeaderSet.java b/obex/javax/obex/HeaderSet.java
index 8b457f6..b89b707 100644
--- a/obex/javax/obex/HeaderSet.java
+++ b/obex/javax/obex/HeaderSet.java
@@ -35,7 +35,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Calendar;
-import java.util.Random;
+import java.security.SecureRandom;
 
 /**
  * This class implements the javax.obex.HeaderSet interface for OBEX over
@@ -209,7 +209,7 @@
 
     private Long[] mIntegerUserDefined; // 4 byte unsigned integer
 
-    private final Random mRandom;
+    private final SecureRandom mRandom;
 
     /*package*/ byte[] nonce;
 
@@ -231,7 +231,7 @@
         mByteUserDefined = new Byte[16];
         mIntegerUserDefined = new Long[16];
         responseCode = -1;
-        mRandom = new Random();
+        mRandom = new SecureRandom();
     }
 
     /**
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index d51b333..7e7da1b 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -222,19 +222,28 @@
     }
 }
 
-void *Loader::load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask)
+void *Loader::load_driver(const char* driver_absolute_path,
+        gl_hooks_t* hooks, uint32_t mask)
 {
-    void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL);
-    if (dso == 0)
+    if (access(driver_absolute_path, R_OK)) {
+        // this happens often, we don't want to log an error
         return 0;
+    }
 
-    LOGD("loaded %s", driver);
+    void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
+    if (dso == 0) {
+        const char* err = dlerror();
+        LOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown");
+        return 0;
+    }
+
+    LOGD("loaded %s", driver_absolute_path);
 
     if (mask & EGL) {
         getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
 
         LOGE_IF(!getProcAddress, 
-                "can't find eglGetProcAddress() in %s", driver);        
+                "can't find eglGetProcAddress() in %s", driver_absolute_path);
 
         gl_hooks_t::egl_t* egl = &hooks->egl;
         __eglMustCastToProperFunctionPointerType* curr =
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index f969a46..f97d347 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -21,8 +21,8 @@
 #include <sys/resource.h>
 
 #include <EGL/egl.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 
 #include <utils/Timers.h>
 
@@ -31,103 +31,267 @@
 
 using namespace android;
 
-static void printGLString(const char *name, GLenum s)
-{
-     fprintf(stderr, "printGLString %s, %d\n", name, s);
-     const char *v = (const char *)glGetString(s);
-     int error = glGetError();
-     fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
-         (unsigned int)v);
-     if ((v < (const char*) 0) || (v > (const char*) 0x1000))
-         fprintf(stderr, "GL %s = %s\n", name, v);
-     else
-         fprintf(stderr, "GL %s = (null)\n", name);
+static void printGLString(const char *name, GLenum s) {
+    // fprintf(stderr, "printGLString %s, %d\n", name, s);
+    const char *v = (const char *) glGetString(s);
+    // int error = glGetError();
+    // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
+    //        (unsigned int) v);
+    // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
+    //    fprintf(stderr, "GL %s = %s\n", name, v);
+    // else
+    //    fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+    fprintf(stderr, "GL %s = %s\n", name, v);
 }
 
 static const char* eglErrorToString[] = {
-    "EGL_SUCCESS",      // 0x3000 12288
-    "EGL_NOT_INITIALIZED",
-    "EGL_BAD_ACCESS",   // 0x3002 12290
-    "EGL_BAD_ALLOC",
-    "EGL_BAD_ATTRIBUTE",
-    "EGL_BAD_CONFIG",
-    "EGL_BAD_CONTEXT",  // 0x3006 12294
-    "EGL_BAD_CURRENT_SURFACE",
-    "EGL_BAD_DISPLAY",
-    "EGL_BAD_MATCH",
-    "EGL_BAD_NATIVE_PIXMAP",
-    "EGL_BAD_NATIVE_WINDOW",
-    "EGL_BAD_PARAMETER",  // 0x300c 12300
-    "EGL_BAD_SURFACE"
-};
+        "EGL_SUCCESS", // 0x3000 12288
+        "EGL_NOT_INITIALIZED",
+        "EGL_BAD_ACCESS", // 0x3002 12290
+        "EGL_BAD_ALLOC", "EGL_BAD_ATTRIBUTE",
+        "EGL_BAD_CONFIG",
+        "EGL_BAD_CONTEXT", // 0x3006 12294
+        "EGL_BAD_CURRENT_SURFACE", "EGL_BAD_DISPLAY", "EGL_BAD_MATCH",
+        "EGL_BAD_NATIVE_PIXMAP", "EGL_BAD_NATIVE_WINDOW", "EGL_BAD_PARAMETER", // 0x300c 12300
+        "EGL_BAD_SURFACE" };
 
-static void checkEglError(const char* op) {
-    for(EGLint error = eglGetError();
-		error != EGL_SUCCESS;
-	error = eglGetError()) {
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+    if (returnVal != EGL_TRUE) {
+        fprintf(stderr, "%s() returned %d\n", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
         const char* errorString = "unknown";
         if (error >= EGL_SUCCESS && error <= EGL_BAD_SURFACE) {
             errorString = eglErrorToString[error - EGL_SUCCESS];
         }
-        fprintf(stderr, "%s() returned eglError %s (0x%x)\n", op,
-            errorString, error);
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, errorString,
+                error);
     }
 }
 
-int main(int argc, char** argv)
-{
-    EGLint s_configAttribs[] = {
-         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-         EGL_RED_SIZE,       5,
-         EGL_GREEN_SIZE,     6,
-         EGL_BLUE_SIZE,      5,
-         EGL_NONE
-     };
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
+    }
+}
 
-     EGLint numConfigs = -1;
-     EGLint majorVersion;
-     EGLint minorVersion;
-     EGLConfig config;
-     EGLContext context;
-     EGLSurface surface;
-     EGLint w, h;
+static const char gVertexShader[] = "attribute vec4 vPosition;\n"
+    "void main() {\n"
+    "  gl_Position = vPosition;\n"
+    "}\n";
 
-     EGLDisplay dpy;
+static const char gFragmentShader[] = "precision mediump float;\n"
+    "void main() {\n"
+    "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+    "}\n";
 
-     EGLNativeWindowType window = 0;
-     window = android_createDisplaySurface();
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+    GLuint shader = glCreateShader(shaderType);
+    if (shader) {
+        glShaderSource(shader, 1, &pSource, NULL);
+        glCompileShader(shader);
+        GLint compiled = 0;
+        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen) {
+                char* buf = (char*) malloc(infoLen);
+                if (buf) {
+                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                    fprintf(stderr, "Could not compile shader %d:\n%s\n",
+                            shaderType, buf);
+                    free(buf);
+                }
+                glDeleteShader(shader);
+                shader = 0;
+            }
+        }
+    }
+    return shader;
+}
 
-     checkEglError("<init>");
-     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-     checkEglError("eglGetDisplay");
-     eglInitialize(dpy, &majorVersion, &minorVersion);
-     checkEglError("eglInitialize");
-     fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
-     EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
-     fprintf(stderr, "Chosen config: 0x%08x\n", (unsigned long) config);
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+    if (!vertexShader) {
+        return 0;
+    }
 
-     checkEglError("EGLUtils::selectConfigForNativeWindow");
-     surface = eglCreateWindowSurface(dpy, config, window, NULL);
-     checkEglError("eglCreateWindowSurface");
+    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+    if (!pixelShader) {
+        return 0;
+    }
 
-     EGLint gl2_0Attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+    GLuint program = glCreateProgram();
+    if (program) {
+        glAttachShader(program, vertexShader);
+        checkGlError("glAttachShader");
+        glAttachShader(program, pixelShader);
+        checkGlError("glAttachShader");
+        glLinkProgram(program);
+        GLint linkStatus = GL_FALSE;
+        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+        if (linkStatus != GL_TRUE) {
+            GLint bufLength = 0;
+            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+            if (bufLength) {
+                char* buf = (char*) malloc(bufLength);
+                if (buf) {
+                    glGetProgramInfoLog(program, bufLength, NULL, buf);
+                    fprintf(stderr, "Could not link program:\n%s\n", buf);
+                    free(buf);
+                }
+            }
+            glDeleteProgram(program);
+            program = 0;
+        }
+    }
+    return program;
+}
 
-     context = eglCreateContext(dpy, config, NULL, gl2_0Attribs);
-     checkEglError("eglCreateContext");
-     eglMakeCurrent(dpy, surface, surface, context);
-     checkEglError("eglMakeCurrent");
-     eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
-     checkEglError("eglQuerySurface");
-     eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
-     checkEglError("eglQuerySurface");
-     GLint dim = w<h ? w : h;
+GLuint gProgram;
+GLuint gvPositionHandle;
 
-     fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+bool setupGraphics(int w, int h) {
+    gProgram = createProgram(gVertexShader, gFragmentShader);
+    if (!gProgram) {
+        return false;
+    }
+    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+    checkGlError("glGetAttribLocation");
+    fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n",
+            gvPositionHandle);
 
-     printGLString("Version", GL_VERSION);
-     printGLString("Vendor", GL_VENDOR);
-     printGLString("Renderer", GL_RENDERER);
-     printGLString("Extensions", GL_EXTENSIONS);
+    glViewport(0, 0, w, h);
+    checkGlError("glViewport");
+    return true;
+}
 
-     return 0;
+const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+        0.5f, -0.5f };
+
+void renderFrame() {
+    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    checkGlError("glClearColor");
+    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    checkGlError("glClear");
+
+    glUseProgram(gProgram);
+    checkGlError("glUseProgram");
+
+    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+    checkGlError("glVertexAttribPointer");
+    glEnableVertexAttribArray(gvPositionHandle);
+    checkGlError("glEnableVertexAttribArray");
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+    checkGlError("glDrawArrays");
+}
+
+int main(int argc, char** argv) {
+    EGLBoolean returnValue;
+    EGLConfig configs[2];
+    EGLint config_count;
+
+    EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+    EGLint s_configAttribs[] = { EGL_BUFFER_SIZE, EGL_DONT_CARE, EGL_RED_SIZE,
+            5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 8,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
+
+    EGLint s_configAttribs2[] =
+    {
+            EGL_DEPTH_SIZE,     16,
+            EGL_NONE
+    };
+
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLSurface surface;
+    EGLint w, h;
+
+    EGLDisplay dpy;
+
+    EGLNativeWindowType window = 0;
+    window = android_createDisplaySurface();
+
+    checkEglError("<init>");
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+    if (dpy == EGL_NO_DISPLAY) {
+        printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+        return 0;
+    }
+
+    returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+    checkEglError("eglInitialize", returnValue);
+    fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+    if (returnValue != EGL_TRUE) {
+        printf("eglInitialize failed\n");
+        return 0;
+    }
+
+    returnValue = eglGetConfigs(dpy, configs, 2, &config_count);
+    checkEglError("eglGetConfigs", returnValue);
+    fprintf(stderr, "Config count: %d\n", config_count);
+    for (int i = 0; i < config_count; i++) {
+        fprintf(stderr, "%d: 0x%08x\n", i, (unsigned int) configs[i]);
+    }
+
+#if 0
+    EGLConfig config;
+    EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
+#else
+    int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs2, configs, 2,
+            &config_count);
+    checkEglError("eglChooseConfig", chooseConfigResult);
+    if (chooseConfigResult != EGL_TRUE) {
+        printf("eglChooseConfig failed\n");
+        return 0;
+    }
+#endif
+
+    surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
+    checkEglError("eglCreateWindowSurface");
+    if (surface == EGL_NO_SURFACE) {
+        printf("gelCreateWindowSurface failed.\n");
+        return 0;
+    }
+    EGLint gl2_0Attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+
+    context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
+    checkEglError("eglCreateContext");
+    if (context == EGL_NO_CONTEXT) {
+        printf("eglCreateContext failed\n");
+        return 0;
+    }
+    eglMakeCurrent(dpy, surface, surface, context);
+    checkEglError("eglMakeCurrent");
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+    checkEglError("eglQuerySurface");
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+    checkEglError("eglQuerySurface");
+    GLint dim = w < h ? w : h;
+
+    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);
+
+    if(!setupGraphics(w, h)) {
+        fprintf(stderr, "Could not set up graphics.\n");
+        return 0;
+    }
+
+    for (;;) {
+        renderFrame();
+        eglSwapBuffers(dpy, surface);
+    }
+
+    return 0;
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 8cfd956..c4acf33 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -54,15 +54,17 @@
 
     private static final String KEY_SYSTEM = "system";
     private static final String KEY_SECURE = "secure";
-    private static final String KEY_SYNC = "sync_providers";
     private static final String KEY_LOCALE = "locale";
 
+    // Versioning of the state file.  Increment this version
+    // number any time the set of state items is altered.
+    private static final int STATE_VERSION = 1;
+
     private static final int STATE_SYSTEM = 0;
     private static final int STATE_SECURE = 1;
-    private static final int STATE_SYNC   = 2;
-    private static final int STATE_LOCALE = 3;
-    private static final int STATE_WIFI   = 4;
-    private static final int STATE_SIZE   = 5; // The number of state items
+    private static final int STATE_LOCALE = 2;
+    private static final int STATE_WIFI   = 3;
+    private static final int STATE_SIZE   = 4; // The number of state items
 
     private static String[] sortedSystemKeys = null;
     private static String[] sortedSecureKeys = null;
@@ -101,7 +103,6 @@
 
         byte[] systemSettingsData = getSystemSettings();
         byte[] secureSettingsData = getSecureSettings();
-        byte[] syncProviders = mSettingsHelper.getSyncProviders();
         byte[] locale = mSettingsHelper.getLocaleData();
         byte[] wifiData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
 
@@ -111,8 +112,6 @@
                 writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data);
         stateChecksums[STATE_SECURE] =
                 writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
-        stateChecksums[STATE_SYNC] =
-                writeIfChanged(stateChecksums[STATE_SYNC], KEY_SYNC, syncProviders, data);
         stateChecksums[STATE_LOCALE] =
                 writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
         stateChecksums[STATE_WIFI] =
@@ -143,8 +142,6 @@
                 // retain the previous WIFI state.
                 enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
                         retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
-            } else if (KEY_SYNC.equals(key)) {
-                mSettingsHelper.setSyncProviders(data);
             } else if (KEY_LOCALE.equals(key)) {
                 byte[] localeData = new byte[size];
                 data.readEntityData(localeData, 0, size);
@@ -160,12 +157,17 @@
 
         DataInputStream dataInput = new DataInputStream(
                 new FileInputStream(oldState.getFileDescriptor()));
-        for (int i = 0; i < STATE_SIZE; i++) {
-            try {
-                stateChecksums[i] = dataInput.readLong();
-            } catch (EOFException eof) {
-                break;
+
+        try {
+            int stateVersion = dataInput.readInt();
+            if (stateVersion == STATE_VERSION) {
+                for (int i = 0; i < STATE_SIZE; i++) {
+                    stateChecksums[i] = dataInput.readLong();
+                }
             }
+        } catch (EOFException eof) {
+            // With the default 0 checksum we'll wind up forcing a backup of
+            // any unhandled data sets, which is appropriate.
         }
         dataInput.close();
         return stateChecksums;
@@ -175,6 +177,8 @@
             throws IOException {
         DataOutputStream dataOutput = new DataOutputStream(
                 new FileOutputStream(newState.getFileDescriptor()));
+
+        dataOutput.writeInt(STATE_VERSION);
         for (int i = 0; i < STATE_SIZE; i++) {
             dataOutput.writeLong(checksums[i]);
         }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 39084a7..77da8f1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -116,43 +116,6 @@
         }
     }
 
-    byte[] getSyncProviders() {
-        byte[] sync = new byte[1 + PROVIDERS.length];
-        // TODO: Sync backup needs to be moved to SystemBackupAgent
-        /*
-        try {
-            sync[0] = (byte) (mContentService.getListenForNetworkTickles() ? 1 : 0);
-            for (int i = 0; i < PROVIDERS.length; i++) {
-                sync[i + 1] = (byte) 
-                        (mContentService.getSyncAutomatically(PROVIDERS[i]) ? 1 : 0);
-            }
-        } catch (RemoteException re) {
-            Log.w(TAG, "Unable to backup sync providers");
-            return sync;
-        }
-        */
-        return sync;
-    }
-
-    void setSyncProviders(BackupDataInput backup) {
-        byte[] sync = new byte[backup.getDataSize()];
-
-        try {
-            backup.readEntityData(sync, 0, sync.length);
-            // TODO: Sync backup needs to be moved to SystemBackupAgent
-            /*
-            mContentService.setListenForNetworkTickles(sync[0] == 1);
-            for (int i = 0; i < PROVIDERS.length; i++) {
-                mContentService.setSyncProviderAutomatically(PROVIDERS[i], sync[i + 1] > 0);
-            }
-        } catch (RemoteException re) {
-            Log.w(TAG, "Unable to restore sync providers");
-            */
-        } catch (java.io.IOException ioe) {
-            Log.w(TAG, "Unable to read sync settings");
-        }
-    }
-
     byte[] getLocaleData() {
         Configuration conf = mContext.getResources().getConfiguration();
         final Locale loc = conf.locale;
diff --git a/packages/SubscribedFeedsProvider/res/values-cs/strings.xml b/packages/SubscribedFeedsProvider/res/values-cs/strings.xml
index b570a3f..5b06f7b 100644
--- a/packages/SubscribedFeedsProvider/res/values-cs/strings.xml
+++ b/packages/SubscribedFeedsProvider/res/values-cs/strings.xml
@@ -16,6 +16,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="5400580392303600842">"Synchronizace zdrojů"</string>
-    <!-- no translation found for provider_label (3669714991966737047) -->
-    <skip />
+    <string name="provider_label" msgid="3669714991966737047">"Zobrazit odběry"</string>
 </resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-da/strings.xml b/packages/SubscribedFeedsProvider/res/values-da/strings.xml
new file mode 100644
index 0000000..f8867a2
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-da/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"Synkroniser feeds"</string>
+    <string name="provider_label" msgid="3669714991966737047">"Push-abonnementer"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-de/strings.xml b/packages/SubscribedFeedsProvider/res/values-de/strings.xml
index f1430e1..8bfd721 100644
--- a/packages/SubscribedFeedsProvider/res/values-de/strings.xml
+++ b/packages/SubscribedFeedsProvider/res/values-de/strings.xml
@@ -16,6 +16,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="5400580392303600842">"Feedsynchronisierung"</string>
-    <!-- no translation found for provider_label (3669714991966737047) -->
-    <skip />
+    <string name="provider_label" msgid="3669714991966737047">"Push-Abos"</string>
 </resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-el/strings.xml b/packages/SubscribedFeedsProvider/res/values-el/strings.xml
new file mode 100644
index 0000000..11a3486
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-el/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"Συγχρονισμός ροών δεδομένων"</string>
+    <string name="provider_label" msgid="3669714991966737047">"Προώθηση συνδρομών"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-es-rUS/strings.xml b/packages/SubscribedFeedsProvider/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..75f1b9f
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-es-rUS/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"Canales de sincronización"</string>
+    <string name="provider_label" msgid="3669714991966737047">"Suscripciones de inserción"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-es/strings.xml b/packages/SubscribedFeedsProvider/res/values-es/strings.xml
index d04206d..59d1693 100644
--- a/packages/SubscribedFeedsProvider/res/values-es/strings.xml
+++ b/packages/SubscribedFeedsProvider/res/values-es/strings.xml
@@ -16,6 +16,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="5400580392303600842">"Sincronización de feeds"</string>
-    <!-- no translation found for provider_label (3669714991966737047) -->
-    <skip />
+    <string name="provider_label" msgid="3669714991966737047">"Enviar suscripciones"</string>
 </resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-fr/strings.xml b/packages/SubscribedFeedsProvider/res/values-fr/strings.xml
index 1db303d..ab1aae9 100644
--- a/packages/SubscribedFeedsProvider/res/values-fr/strings.xml
+++ b/packages/SubscribedFeedsProvider/res/values-fr/strings.xml
@@ -16,6 +16,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="5400580392303600842">"Synchronisation des flux"</string>
-    <!-- no translation found for provider_label (3669714991966737047) -->
-    <skip />
+    <string name="provider_label" msgid="3669714991966737047">"Abonnements Push"</string>
 </resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-it/strings.xml b/packages/SubscribedFeedsProvider/res/values-it/strings.xml
index fc893ae..2a6dd54 100644
--- a/packages/SubscribedFeedsProvider/res/values-it/strings.xml
+++ b/packages/SubscribedFeedsProvider/res/values-it/strings.xml
@@ -16,6 +16,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="5400580392303600842">"Sincronizzazione feed"</string>
-    <!-- no translation found for provider_label (3669714991966737047) -->
-    <skip />
+    <string name="provider_label" msgid="3669714991966737047">"Sottoscrizioni push"</string>
 </resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-ja/strings.xml b/packages/SubscribedFeedsProvider/res/values-ja/strings.xml
index 4026b26..6a0812a 100644
--- a/packages/SubscribedFeedsProvider/res/values-ja/strings.xml
+++ b/packages/SubscribedFeedsProvider/res/values-ja/strings.xml
@@ -16,6 +16,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="5400580392303600842">"フィードの同期"</string>
-    <!-- no translation found for provider_label (3669714991966737047) -->
-    <skip />
+    <string name="provider_label" msgid="3669714991966737047">"プッシュ型登録"</string>
 </resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-ko/strings.xml b/packages/SubscribedFeedsProvider/res/values-ko/strings.xml
new file mode 100644
index 0000000..0912732
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-ko/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"피드 동기화"</string>
+    <string name="provider_label" msgid="3669714991966737047">"구독정보 푸시"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-nb/strings.xml b/packages/SubscribedFeedsProvider/res/values-nb/strings.xml
new file mode 100644
index 0000000..30a2c5ea
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-nb/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"Strømsynkronisering"</string>
+    <string name="provider_label" msgid="3669714991966737047">"Push-abonnementer"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-nl/strings.xml b/packages/SubscribedFeedsProvider/res/values-nl/strings.xml
index 2537b64..b74e66b 100644
--- a/packages/SubscribedFeedsProvider/res/values-nl/strings.xml
+++ b/packages/SubscribedFeedsProvider/res/values-nl/strings.xml
@@ -16,6 +16,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="5400580392303600842">"Feeds synchroniseren"</string>
-    <!-- no translation found for provider_label (3669714991966737047) -->
-    <skip />
+    <string name="provider_label" msgid="3669714991966737047">"Abonnementen doorvoeren"</string>
 </resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-pl/strings.xml b/packages/SubscribedFeedsProvider/res/values-pl/strings.xml
index 86d1c3e..ed6c1d0 100644
--- a/packages/SubscribedFeedsProvider/res/values-pl/strings.xml
+++ b/packages/SubscribedFeedsProvider/res/values-pl/strings.xml
@@ -16,6 +16,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="5400580392303600842">"Synchronizowanie kanałów"</string>
-    <!-- no translation found for provider_label (3669714991966737047) -->
-    <skip />
+    <string name="provider_label" msgid="3669714991966737047">"Subskrypcje w trybie push"</string>
 </resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-pt-rPT/strings.xml b/packages/SubscribedFeedsProvider/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..a52fd20
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-pt-rPT/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"Sincronizar feeds"</string>
+    <string name="provider_label" msgid="3669714991966737047">"Subscrições de Emissão"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-pt/strings.xml b/packages/SubscribedFeedsProvider/res/values-pt/strings.xml
new file mode 100644
index 0000000..081190d
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-pt/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"Sincronizar feeds"</string>
+    <string name="provider_label" msgid="3669714991966737047">"Enviar inscrições"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-ru/strings.xml b/packages/SubscribedFeedsProvider/res/values-ru/strings.xml
new file mode 100644
index 0000000..24ead0a
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-ru/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"Фиды синхронизации"</string>
+    <string name="provider_label" msgid="3669714991966737047">"Подписки Push"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-sv/strings.xml b/packages/SubscribedFeedsProvider/res/values-sv/strings.xml
new file mode 100644
index 0000000..55499c5
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-sv/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"Synkroniseringsflöden"</string>
+    <string name="provider_label" msgid="3669714991966737047">"Push-prenumerationer"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-tr/strings.xml b/packages/SubscribedFeedsProvider/res/values-tr/strings.xml
new file mode 100644
index 0000000..baa33300
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-tr/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"Senkronizasyon Yayınları"</string>
+    <string name="provider_label" msgid="3669714991966737047">"Abonelik Şart Koş"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-zh-rCN/strings.xml b/packages/SubscribedFeedsProvider/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..05edb80
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values-zh-rCN/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5400580392303600842">"同步供稿"</string>
+    <string name="provider_label" msgid="3669714991966737047">"推送订阅"</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/res/values-zh-rTW/strings.xml b/packages/SubscribedFeedsProvider/res/values-zh-rTW/strings.xml
index 87d93e4..5e5bcc5 100644
--- a/packages/SubscribedFeedsProvider/res/values-zh-rTW/strings.xml
+++ b/packages/SubscribedFeedsProvider/res/values-zh-rTW/strings.xml
@@ -16,6 +16,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="5400580392303600842">"同步資訊提供"</string>
-    <!-- no translation found for provider_label (3669714991966737047) -->
-    <skip />
+    <string name="provider_label" msgid="3669714991966737047">"預先載入訂閱項目"</string>
 </resources>
diff --git a/packages/VpnServices/res/values-cs/strings.xml b/packages/VpnServices/res/values-cs/strings.xml
index f5469a1..9e20c19 100644
--- a/packages/VpnServices/res/values-cs/strings.xml
+++ b/packages/VpnServices/res/values-cs/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Služby VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je připojena"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> odpojena"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotykem se znovu připojíte k síti VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-da/strings.xml b/packages/VpnServices/res/values-da/strings.xml
index 8f65e25..fb5ddf9 100644
--- a/packages/VpnServices/res/values-da/strings.xml
+++ b/packages/VpnServices/res/values-da/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPN-tjenester"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN forbundet"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN afbrudt"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tryk for at oprette forbindelse til et VPN igen."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-de/strings.xml b/packages/VpnServices/res/values-de/strings.xml
index b21ad72..f120253 100644
--- a/packages/VpnServices/res/values-de/strings.xml
+++ b/packages/VpnServices/res/values-de/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPN-Dienste"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> mit VPN verbunden"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> von VPN getrennt"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Zur Wiederherstellung der Verbindung mit einem VPN berühren"</string>
 </resources>
diff --git a/packages/VpnServices/res/values-el/strings.xml b/packages/VpnServices/res/values-el/strings.xml
index ea03865..06f907c 100644
--- a/packages/VpnServices/res/values-el/strings.xml
+++ b/packages/VpnServices/res/values-el/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Υπηρεσίες VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> συνδέθηκε"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> αποσυνδέθηκε"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Πατήστε για να επανασυνδεθείτε σε ένα VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-es-rUS/strings.xml b/packages/VpnServices/res/values-es-rUS/strings.xml
index 9a904cb..f6ace53d 100644
--- a/packages/VpnServices/res/values-es-rUS/strings.xml
+++ b/packages/VpnServices/res/values-es-rUS/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Servicios VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN conectados"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN desconectada"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tocar para volver a conectarse a una VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-es/strings.xml b/packages/VpnServices/res/values-es/strings.xml
index 9d8e23b..2864c75 100644
--- a/packages/VpnServices/res/values-es/strings.xml
+++ b/packages/VpnServices/res/values-es/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Servicios VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toca para volver a conectarte a una red VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-fr/strings.xml b/packages/VpnServices/res/values-fr/strings.xml
index eda660e..519a9ab 100644
--- a/packages/VpnServices/res/values-fr/strings.xml
+++ b/packages/VpnServices/res/values-fr/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Services VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN \n<xliff:g id="PROFILENAME">%s</xliff:g> connecté"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> déconnecté"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Touchez l\'écran pour vous reconnecter à un VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-it/strings.xml b/packages/VpnServices/res/values-it/strings.xml
index 95eaddb..fd6e76b 100644
--- a/packages/VpnServices/res/values-it/strings.xml
+++ b/packages/VpnServices/res/values-it/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Servizi VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> collegata"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> scollegata"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tocca per riconnetterti a una rete VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-ja/strings.xml b/packages/VpnServices/res/values-ja/strings.xml
index 8174d44..2bad0e3 100644
--- a/packages/VpnServices/res/values-ja/strings.xml
+++ b/packages/VpnServices/res/values-ja/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPNサービス"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNが接続されました"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNが切断されました"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"タップしてVPNに再接続してください。"</string>
 </resources>
diff --git a/packages/VpnServices/res/values-ko/strings.xml b/packages/VpnServices/res/values-ko/strings.xml
index f89516d..a48eff6 100644
--- a/packages/VpnServices/res/values-ko/strings.xml
+++ b/packages/VpnServices/res/values-ko/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPN 서비스"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결됨"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결 끊김"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"VPN에 다시 연결하려면 터치하세요."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-nb/strings.xml b/packages/VpnServices/res/values-nb/strings.xml
index 2b43b87..506f999 100644
--- a/packages/VpnServices/res/values-nb/strings.xml
+++ b/packages/VpnServices/res/values-nb/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPN-tjenester"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> er VPN-tilkoblet"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> er VPN-frakoblet"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Trykk for å koble til et VPN på nytt"</string>
 </resources>
diff --git a/packages/VpnServices/res/values-nl/strings.xml b/packages/VpnServices/res/values-nl/strings.xml
index 3e4cb29..d5a55e8 100644
--- a/packages/VpnServices/res/values-nl/strings.xml
+++ b/packages/VpnServices/res/values-nl/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPN-services"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> verbonden via VPN"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN-verbinding met <xliff:g id="PROFILENAME">%s</xliff:g> verbroken"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Raak aan om opnieuw verbinding te maken met een VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-pl/strings.xml b/packages/VpnServices/res/values-pl/strings.xml
index 8568bbd..6626c69 100644
--- a/packages/VpnServices/res/values-pl/strings.xml
+++ b/packages/VpnServices/res/values-pl/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Usługi VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Połączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Rozłączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotknij, aby ponownie połączyć się z siecią VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-pt-rPT/strings.xml b/packages/VpnServices/res/values-pt-rPT/strings.xml
index f2bdd4e..182e600 100644
--- a/packages/VpnServices/res/values-pt-rPT/strings.xml
+++ b/packages/VpnServices/res/values-pt-rPT/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Serviços VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> ligado"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desligado"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toque para voltar a ligar a uma VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-pt/strings.xml b/packages/VpnServices/res/values-pt/strings.xml
index 5b24830..a2877d6 100644
--- a/packages/VpnServices/res/values-pt/strings.xml
+++ b/packages/VpnServices/res/values-pt/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Serviços de VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toque para reconectar-se a uma VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-ru/strings.xml b/packages/VpnServices/res/values-ru/strings.xml
index 94a807f..7458f0c 100644
--- a/packages/VpnServices/res/values-ru/strings.xml
+++ b/packages/VpnServices/res/values-ru/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"Службы VPN"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) подключена"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) отключена"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Нажмите, чтобы повторно подключиться к VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-sv/strings.xml b/packages/VpnServices/res/values-sv/strings.xml
index c086d24..ba541b8 100644
--- a/packages/VpnServices/res/values-sv/strings.xml
+++ b/packages/VpnServices/res/values-sv/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPN-tjänster"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN anslutet"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN frånkopplat"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tryck här om du vill återansluta till ett VPN."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-tr/strings.xml b/packages/VpnServices/res/values-tr/strings.xml
index b4369ba..41a0b4e 100644
--- a/packages/VpnServices/res/values-tr/strings.xml
+++ b/packages/VpnServices/res/values-tr/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPN Hizmetleri"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlandı"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlantısı kesildi"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Bir VPN\'ye tekrar bağlanmak için dokunun."</string>
 </resources>
diff --git a/packages/VpnServices/res/values-zh-rCN/strings.xml b/packages/VpnServices/res/values-zh-rCN/strings.xml
index 450ecb5..4de0f38 100644
--- a/packages/VpnServices/res/values-zh-rCN/strings.xml
+++ b/packages/VpnServices/res/values-zh-rCN/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPN 服务"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已连接"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 连接已断开"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"触摸可重新连接 VPN。"</string>
 </resources>
diff --git a/packages/VpnServices/res/values-zh-rTW/strings.xml b/packages/VpnServices/res/values-zh-rTW/strings.xml
index 14b72de..931d4ed 100644
--- a/packages/VpnServices/res/values-zh-rTW/strings.xml
+++ b/packages/VpnServices/res/values-zh-rTW/strings.xml
@@ -16,9 +16,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4589592829302498102">"VPN 服務"</string>
-    <!-- no translation found for vpn_notification_title_connected (8598654486956133580) -->
-    <skip />
-    <!-- no translation found for vpn_notification_title_disconnected (6216572264382192027) -->
-    <skip />
+    <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已連線"</string>
+    <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已中斷連線"</string>
     <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"輕觸即可重新連線至 VPN。"</string>
 </resources>
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 0e60dd6..854a6f9 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -649,11 +649,21 @@
         int N = packages.size();
         for (int a = N-1; a >= 0; a--) {
             PackageInfo pkg = packages.get(a);
-            ApplicationInfo app = pkg.applicationInfo;
-            if (((app.flags&ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
-                    || app.backupAgentName == null
-                    || (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
-                            pkg.packageName) != PackageManager.PERMISSION_GRANTED)) {
+            try {
+                ApplicationInfo app = pkg.applicationInfo;
+                if (((app.flags&ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
+                        || app.backupAgentName == null
+                        || (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
+                                pkg.packageName) != PackageManager.PERMISSION_GRANTED)) {
+                    packages.remove(a);
+                }
+                else {
+                    // we will need the shared library path, so look that up and store it here
+                    app = mPackageManager.getApplicationInfo(pkg.packageName,
+                            PackageManager.GET_SHARED_LIBRARY_FILES);
+                    pkg.applicationInfo.sharedLibraryFiles = app.sharedLibraryFiles;
+                }
+            } catch (NameNotFoundException e) {
                 packages.remove(a);
             }
         }
@@ -877,8 +887,12 @@
                         mPackageManager, allAgentPackages());
                 BackupRequest pmRequest = new BackupRequest(new ApplicationInfo(), false);
                 pmRequest.appInfo.packageName = PACKAGE_MANAGER_SENTINEL;
-                processOneBackup(pmRequest,
-                        IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
+
+                // If we haven't stored anything yet, we need to do an init
+                // operation along with recording the metadata blob.
+                boolean needInit = (mEverStoredApps.size() == 0);
+                processOneBackup(pmRequest, IBackupAgent.Stub.asInterface(pmAgent.onBind()),
+                        mTransport, needInit);
 
                 // Now run all the backups in our queue
                 int count = mQueue.size();
@@ -924,7 +938,7 @@
                 try {
                     agent = bindToAgentSynchronous(request.appInfo, mode);
                     if (agent != null) {
-                        processOneBackup(request, agent, transport);
+                        processOneBackup(request, agent, transport, false);
                     }
 
                     // unbind even on timeout, just in case
@@ -939,11 +953,11 @@
             }
         }
 
-        void processOneBackup(BackupRequest request, IBackupAgent agent, IBackupTransport transport) {
+        void processOneBackup(BackupRequest request, IBackupAgent agent,
+                IBackupTransport transport, boolean doInit) {
             final String packageName = request.appInfo.packageName;
-            if (DEBUG) Log.d(TAG, "processOneBackup doBackup() on " + packageName);
+            if (DEBUG) Log.d(TAG, "processOneBackup doBackup(" + doInit + ") on " + packageName);
 
-            // !!! TODO: get the state file dir from the transport
             File savedStateName = new File(mStateDir, packageName);
             File backupDataName = new File(mDataDir, packageName + ".data");
             File newStateName = new File(mStateDir, packageName + ".new");
@@ -1008,7 +1022,15 @@
                     backupData = ParcelFileDescriptor.open(backupDataName,
                             ParcelFileDescriptor.MODE_READ_ONLY);
 
-                    if (!transport.performBackup(packInfo, backupData)) throw new Exception();
+                    // TODO - We call finishBackup() for each application backed up, because
+                    // we need to know now whether it succeeded or failed.  Instead, we should
+                    // hold off on finishBackup() until the end, which implies holding off on
+                    // renaming *all* the output state files (see below) until that happens.
+
+                    if (!transport.performBackup(packInfo, backupData, doInit) ||
+                        !transport.finishBackup()) {
+                        throw new Exception("Backup transport failed");
+                    }
                 } else {
                     if (DEBUG) Log.i(TAG, "no backup data written; not calling transport");
                 }
@@ -1369,7 +1391,21 @@
                 agent.doRestore(backupData, appVersionCode, newState);
 
                 // if everything went okay, remember the recorded state now
-                newStateName.renameTo(savedStateName);
+                //
+                // !!! TODO: the restored data should be migrated on the server
+                // side into the current dataset.  In that case the new state file
+                // we just created would reflect the data already extant in the
+                // backend, so there'd be nothing more to do.  Until that happens,
+                // however, we need to make sure that we record the data to the
+                // current backend dataset.  (Yes, this means shipping the data over
+                // the wire in both directions.  That's bad, but consistency comes
+                // first, then efficiency.)  Once we introduce server-side data
+                // migration to the newly-restored device's dataset, we will change
+                // the following from a discard of the newly-written state to the
+                // "correct" operation of renaming into the canonical state blob.
+                newStateName.delete();                      // TODO: remove; see above comment
+                //newStateName.renameTo(savedStateName);    // TODO: replace with this
+
                 int size = (int) backupDataName.length();
                 EventLog.writeEvent(RESTORE_PACKAGE_EVENT, packageName, size);
             } catch (Exception e) {
@@ -1407,11 +1443,13 @@
                 stateFile.delete();
 
                 // Tell the transport to remove all the persistent storage for the app
+                // STOPSHIP TODO - need to handle failures
                 mTransport.clearBackupData(mPackage);
             } catch (RemoteException e) {
                 // can't happen; the transport is local
             } finally {
                 try {
+                    // STOPSHIP TODO - need to handle failures
                     mTransport.finishBackup();
                 } catch (RemoteException e) {
                     // can't happen; the transport is local
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 26fee89..d78d886 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -26,7 +26,6 @@
 import android.content.pm.PackageManager;
 import android.os.BatteryManager;
 import android.os.Binder;
-import android.os.Debug;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -333,16 +332,16 @@
         
         int icon = getIcon(mBatteryLevel);
 
-        intent.putExtra("status", mBatteryStatus);
-        intent.putExtra("health", mBatteryHealth);
-        intent.putExtra("present", mBatteryPresent);
-        intent.putExtra("level", mBatteryLevel);
-        intent.putExtra("scale", BATTERY_SCALE);
-        intent.putExtra("icon-small", icon);
-        intent.putExtra("plugged", mPlugType);
-        intent.putExtra("voltage", mBatteryVoltage);
-        intent.putExtra("temperature", mBatteryTemperature);
-        intent.putExtra("technology", mBatteryTechnology);
+        intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryStatus);
+        intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryHealth);
+        intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryPresent);
+        intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryLevel);
+        intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
+        intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
+        intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
+        intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryVoltage);
+        intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryTemperature);
+        intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology);
 
         if (false) {
             Log.d(TAG, "updateBattery level:" + mBatteryLevel +
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 408a4d2..63845e9 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -809,6 +809,8 @@
                     intent.putExtra(ConnectivityManager.
                             EXTRA_OTHER_NETWORK_INFO, switchTo);
                 } else {
+                    intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,
+                            true);
                     newNet.reconnect();
                 }
             } else {
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 60195b9..8a4b45d 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -16,7 +16,9 @@
 
 package com.android.server;
 
+import android.app.Activity;
 import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
@@ -44,6 +46,43 @@
     private final Context mContext;
 
     private PowerManagerService mPowerManager;
+    
+    // The broadcast receiver which receives the result of the ordered broadcast sent when
+    // the dock state changes. The original ordered broadcast is sent with an initial result
+    // code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
+    // to RESULT_CANCELED, then the intent to start a dock app will not be sent.
+    private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (getResultCode() != Activity.RESULT_OK) {
+                return;
+            }
+            
+            // Launch a dock activity
+            String category;
+            switch (mDockState) {
+                case Intent.EXTRA_DOCK_STATE_CAR:
+                    category = Intent.CATEGORY_CAR_DOCK;
+                    break;
+                case Intent.EXTRA_DOCK_STATE_DESK:
+                    category = Intent.CATEGORY_DESK_DOCK;
+                    break;
+                default:
+                    category = null;
+                    break;
+            }
+            if (category != null) {
+                intent = new Intent(Intent.ACTION_MAIN);
+                intent.addCategory(category);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                try {
+                    mContext.startActivity(intent);
+                } catch (ActivityNotFoundException e) {
+                    Log.w(TAG, e.getCause());
+                }
+            }
+        }
+    };
 
     public DockObserver(Context context, PowerManagerService pm) {
         mContext = context;
@@ -111,31 +150,15 @@
                 mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
                 Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
                 intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
-                mContext.sendStickyBroadcast(intent);
-
-                // Launch a dock activity
-                String category;
-                switch (mDockState) {
-                    case Intent.EXTRA_DOCK_STATE_CAR:
-                        category = Intent.CATEGORY_CAR_DOCK;
-                        break;
-                    case Intent.EXTRA_DOCK_STATE_DESK:
-                        category = Intent.CATEGORY_DESK_DOCK;
-                        break;
-                    default:
-                        category = null;
-                        break;
-                }
-                if (category != null) {
-                    intent = new Intent(Intent.ACTION_MAIN);
-                    intent.addCategory(category);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    try {
-                        mContext.startActivity(intent);
-                    } catch (ActivityNotFoundException e) {
-                        Log.w(TAG, e.getCause());
-                    }
-                }
+                
+                // Send the ordered broadcast; the result receiver will receive after all
+                // broadcasts have been sent. If any broadcast receiver changes the result
+                // code from the initial value of RESULT_OK, then the result receiver will
+                // not launch the corresponding dock application. This gives apps a chance
+                // to override the behavior and stay in their app even when the device is
+                // placed into a dock.
+                mContext.sendStickyOrderedBroadcast(
+                        intent, mResultReceiver, null, Activity.RESULT_OK, null, null);
             }
         }
     };
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index af60556..f6a1be7 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -1069,13 +1069,13 @@
             return mIntent;
         }
 
-        boolean isInProximity(double latitude, double longitude) {
+        boolean isInProximity(double latitude, double longitude, float accuracy) {
             Location loc = new Location("");
             loc.setLatitude(latitude);
             loc.setLongitude(longitude);
 
             double radius = loc.distanceTo(mLocation);
-            return radius <= mRadius;
+            return radius <= Math.max(mRadius,accuracy);
         }
         
         @Override
@@ -1115,6 +1115,7 @@
             long now = System.currentTimeMillis();
             double latitude = loc.getLatitude();
             double longitude = loc.getLongitude();
+            float accuracy = loc.getAccuracy();
             ArrayList<PendingIntent> intentsToRemove = null;
 
             for (ProximityAlert alert : mProximityAlerts.values()) {
@@ -1124,7 +1125,7 @@
                 if ((expiration == -1) || (now <= expiration)) {
                     boolean entered = mProximitiesEntered.contains(alert);
                     boolean inProximity =
-                        alert.isInProximity(latitude, longitude);
+                        alert.isInProximity(latitude, longitude, accuracy);
                     if (!entered && inProximity) {
                         if (LOCAL_LOGV) {
                             Log.v(TAG, "Entered alert");
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 45e0ceb..323a11f 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -6376,7 +6376,10 @@
                 if (mBackupSettingsFilename.exists()) {
                     mBackupSettingsFilename.delete();
                 }
-                mSettingsFilename.renameTo(mBackupSettingsFilename);
+                if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
+                    Log.w(TAG, "Unable to backup package manager settings, current changes will be lost at reboot");
+                    return;
+                }
             }
 
             mPastSignatures.clear();
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 35f508b8..656d6ba 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -304,10 +304,7 @@
                     // temporarily set mUserActivityAllowed to true so this will work
                     // even when the keyguard is on.
                     synchronized (mLocks) {
-                        boolean savedActivityAllowed = mUserActivityAllowed;
-                        mUserActivityAllowed = true;
-                        userActivity(SystemClock.uptimeMillis(), false);
-                        mUserActivityAllowed = savedActivityAllowed;
+                        forceUserActivityLocked();
                     }
                 }
             }
@@ -957,9 +954,6 @@
 
     private void sendNotificationLocked(boolean on, int why)
     {
-        if (mProximitySensorActive) {
-            why = WindowManagerPolicy.OFF_BECAUSE_OF_PROXIMITY_SENSOR;
-        }
         if (!on) {
             mStillNeedSleepNotification = false;
         }
@@ -1717,6 +1711,13 @@
         }
     }
 
+    private void forceUserActivityLocked() {
+        boolean savedActivityAllowed = mUserActivityAllowed;
+        mUserActivityAllowed = true;
+        userActivity(SystemClock.uptimeMillis(), false);
+        mUserActivityAllowed = savedActivityAllowed;
+    }
+
     public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
         userActivity(time, noChangeLights, OTHER_EVENT, force);
@@ -2117,7 +2118,12 @@
             Log.d(TAG, "disableProximityLockLocked");
         }
         mSensorManager.unregisterListener(this);
-        mProximitySensorActive = false;
+        synchronized (mLocks) {
+            if (mProximitySensorActive) {
+                mProximitySensorActive = false;
+                forceUserActivityLocked();
+            }
+        }
     }
 
     public void onSensorChanged(SensorEvent event) {
@@ -2138,10 +2144,7 @@
                     Log.d(TAG, "onSensorChanged: proximity inactive, distance: " + distance);
                 }
                 mProximitySensorActive = false;
-                boolean savedActivityAllowed = mUserActivityAllowed;
-                mUserActivityAllowed = true;
-                userActivity(milliseconds, false);
-                mUserActivityAllowed = savedActivityAllowed;
+                forceUserActivityLocked();
             }
         }
     }
diff --git a/services/java/com/android/server/ProcessStats.java b/services/java/com/android/server/ProcessStats.java
index af80e20..ac3b723 100644
--- a/services/java/com/android/server/ProcessStats.java
+++ b/services/java/com/android/server/ProcessStats.java
@@ -30,6 +30,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.StringTokenizer;
 
 public class ProcessStats {
     private static final String TAG = "ProcessStats";
@@ -138,7 +139,22 @@
     private boolean mFirst = true;
 
     private byte[] mBuffer = new byte[256];
-     
+
+    /**
+     * The time in microseconds that the CPU has been running at each speed.
+     */
+    private long[] mCpuSpeedTimes;
+
+    /**
+     * The relative time in microseconds that the CPU has been running at each speed.
+     */
+    private long[] mRelCpuSpeedTimes;
+
+    /**
+     * The different speeds that the CPU can be running at.
+     */
+    private long[] mCpuSpeeds;
+
     public static class Stats {
         public final int pid;
         final String statFile;
@@ -460,6 +476,70 @@
         return 0;
     }
 
+    /**
+     * Returns the times spent at each CPU speed, since the last call to this method. If this
+     * is the first time, it will return 1 for each value.
+     * @return relative times spent at different speed steps.
+     */
+    public long[] getLastCpuSpeedTimes() {
+        if (mCpuSpeedTimes == null) {
+            mCpuSpeedTimes = getCpuSpeedTimes(null);
+            mRelCpuSpeedTimes = new long[mCpuSpeedTimes.length];
+            for (int i = 0; i < mCpuSpeedTimes.length; i++) {
+                mRelCpuSpeedTimes[i] = 1; // Initialize
+            }
+        } else {
+            getCpuSpeedTimes(mRelCpuSpeedTimes);
+            for (int i = 0; i < mCpuSpeedTimes.length; i++) {
+                long temp = mRelCpuSpeedTimes[i];
+                mRelCpuSpeedTimes[i] -= mCpuSpeedTimes[i];
+                mCpuSpeedTimes[i] = temp;
+            }
+        }
+        return mRelCpuSpeedTimes;
+    }
+
+    private long[] getCpuSpeedTimes(long[] out) {
+        long[] tempTimes = out;
+        long[] tempSpeeds = mCpuSpeeds;
+        final int MAX_SPEEDS = 20;
+        if (out == null) {
+            tempTimes = new long[MAX_SPEEDS]; // Hopefully no more than that
+            tempSpeeds = new long[MAX_SPEEDS];
+        }
+        int speed = 0;
+        String file = readFile("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state", '\0');
+        // Note: file may be null on kernels without cpufreq (i.e. the emulator's)
+        if (file != null) {
+            StringTokenizer st = new StringTokenizer(file, "\n ");
+            while (st.hasMoreElements()) {
+                String token = st.nextToken();
+                try {
+                    long val = Long.parseLong(token);
+                    tempSpeeds[speed] = val;
+                    token = st.nextToken();
+                    val = Long.parseLong(token);
+                    tempTimes[speed] = val;
+                    speed++;
+                    if (speed == MAX_SPEEDS) break; // No more
+                    if (localLOGV && out == null) {
+                        Log.v(TAG, "First time : Speed/Time = " + tempSpeeds[speed - 1]
+                              + "\t" + tempTimes[speed - 1]);
+                    }
+                } catch (NumberFormatException nfe) {
+                    Log.i(TAG, "Unable to parse time_in_state");
+                }
+            }
+        }
+        if (out == null) {
+            out = new long[speed];
+            mCpuSpeeds = new long[speed];
+            System.arraycopy(tempSpeeds, 0, mCpuSpeeds, 0, speed);
+            System.arraycopy(tempTimes, 0, out, 0, speed);
+        }
+        return out;
+    }
+
     final public int getLastUserTime() {
         return mRelUserTime;
     }
diff --git a/services/java/com/android/server/SystemBackupAgent.java b/services/java/com/android/server/SystemBackupAgent.java
index 17d0f1d..8903ebd 100644
--- a/services/java/com/android/server/SystemBackupAgent.java
+++ b/services/java/com/android/server/SystemBackupAgent.java
@@ -32,23 +32,33 @@
 import java.io.IOException;
 
 /**
- * Backup agent for various system-managed data
+ * Backup agent for various system-managed data, currently just the system wallpaper
  */
 public class SystemBackupAgent extends BackupHelperAgent {
     private static final String TAG = "SystemBackupAgent";
 
+    // These paths must match what the WallpaperManagerService uses
     private static final String WALLPAPER_IMAGE = "/data/data/com.android.settings/files/wallpaper";
     private static final String WALLPAPER_INFO = "/data/system/wallpaper_info.xml";
 
     @Override
-    public void onCreate() {
+    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+            ParcelFileDescriptor newState) throws IOException {
+        // We only back up the data under the current "wallpaper" schema with metadata
         addHelper("wallpaper", new AbsoluteFileBackupHelper(SystemBackupAgent.this,
                 new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }));
+        super.onBackup(oldState, data, newState);
     }
 
     @Override
     public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
             throws IOException {
+        // On restore, we also support a previous data schema "system_files"
+        addHelper("wallpaper", new AbsoluteFileBackupHelper(SystemBackupAgent.this,
+                new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }));
+        addHelper("system_files", new AbsoluteFileBackupHelper(SystemBackupAgent.this,
+                new String[] { WALLPAPER_IMAGE }));
+
         boolean success = false;
         try {
             super.onRestore(data, appVersionCode, newState);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 63bef54..cc1b697 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -295,7 +295,11 @@
         if (mWifiHandler == null) return false;
 
         synchronized (mWifiHandler) {
+            // caller may not have WAKE_LOCK permission - it's not required here
+            long ident = Binder.clearCallingIdentity();
             sWakeLock.acquire();
+            Binder.restoreCallingIdentity(ident);
+
             mLastEnableUid = Binder.getCallingUid();
             // set a flag if the user is enabling Wifi while in airplane mode
             mAirplaneModeOverwridden = (enable && isAirplaneModeOn() && isAirplaneToggleable());
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 60496d6..bbf2a24 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1384,12 +1384,18 @@
                     (mLowerWallpaperTarget == null && foundW.mAppToken != null)
                     ? foundW.mAppToken.animLayerAdjustment : 0;
             
+            final int maxLayer = mPolicy.getMaxWallpaperLayer()
+                    * TYPE_LAYER_MULTIPLIER
+                    + TYPE_LAYER_OFFSET;
+            
             // Now w is the window we are supposed to be behind...  but we
             // need to be sure to also be behind any of its attached windows,
-            // AND any starting window associated with it.
+            // AND any starting window associated with it, AND below the
+            // maximum layer the policy allows for wallpapers.
             while (foundI > 0) {
                 WindowState wb = (WindowState)localmWindows.get(foundI-1);
-                if (wb.mAttachedWindow != foundW &&
+                if (wb.mBaseLayer < maxLayer &&
+                        wb.mAttachedWindow != foundW &&
                         (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
                                 wb.mToken != foundW.mToken)) {
                     // This window is not related to the previous one in any
@@ -2266,6 +2272,12 @@
                             // Currently in a hide animation... turn this into
                             // an exit.
                             win.mExiting = true;
+                        } else if (win == mWallpaperTarget) {
+                            // If the wallpaper is currently behind this
+                            // window, we need to change both of them inside
+                            // of a transaction to avoid artifacts.
+                            win.mExiting = true;
+                            win.mAnimating = true;
                         } else {
                             if (mInputMethodWindow == win) {
                                 mInputMethodWindow = null;
@@ -3158,6 +3170,10 @@
                     return;
                 }
                 if (ent.array.getBoolean(
+                        com.android.internal.R.styleable.Window_windowIsFloating, false)) {
+                    return;
+                }
+                if (ent.array.getBoolean(
                         com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
                     return;
                 }
@@ -7056,7 +7072,7 @@
                         + " attHidden=" + mAttachedHidden
                         + " tok.hiddenRequested="
                         + (mAppToken != null ? mAppToken.hiddenRequested : false)
-                        + " tok.idden="
+                        + " tok.hidden="
                         + (mAppToken != null ? mAppToken.hidden : false)
                         + " animating=" + mAnimating
                         + " tok animating="
@@ -7085,10 +7101,20 @@
                 if (mAttrs.type != TYPE_APPLICATION_STARTING
                         && mAppToken != null) {
                     mAppToken.firstWindowDrawn = true;
-                    if (mAnimation == null && mAppToken.startingData != null) {
-                        if (DEBUG_STARTING_WINDOW) Log.v(TAG, "Finish starting "
-                                + mToken
+                    
+                    if (mAppToken.startingData != null) {
+                        if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Log.v(TAG,
+                                "Finish starting " + mToken
                                 + ": first real window is shown, no animation");
+                        // If this initial window is animating, stop it -- we
+                        // will do an animation to reveal it from behind the
+                        // starting window, so there is no need for it to also
+                        // be doing its own stuff.
+                        if (mAnimation != null) {
+                            mAnimation = null;
+                            // Make sure we clean up the animation.
+                            mAnimating = true;
+                        }
                         mFinishedStarting.add(mAppToken);
                         mH.sendEmptyMessage(H.FINISHED_STARTING);
                     }
@@ -7293,15 +7319,16 @@
                 final Matrix tmpMatrix = mTmpMatrix;
 
                 // Compute the desired transformation.
-                tmpMatrix.setTranslate(frame.left, frame.top);
+                tmpMatrix.setTranslate(0, 0);
                 if (selfTransformation) {
-                    tmpMatrix.preConcat(mTransformation.getMatrix());
+                    tmpMatrix.postConcat(mTransformation.getMatrix());
                 }
+                tmpMatrix.postTranslate(frame.left, frame.top);
                 if (attachedTransformation != null) {
-                    tmpMatrix.preConcat(attachedTransformation.getMatrix());
+                    tmpMatrix.postConcat(attachedTransformation.getMatrix());
                 }
                 if (appTransformation != null) {
-                    tmpMatrix.preConcat(appTransformation.getMatrix());
+                    tmpMatrix.postConcat(appTransformation.getMatrix());
                 }
 
                 // "convert" it into SurfaceFlinger's format
@@ -8918,11 +8945,14 @@
                                 wallpaperMayChange = true;
                             }
                         }
+                        boolean wasAnimating = w.mAnimating;
                         if (w.stepAnimationLocked(currentTime, dw, dh)) {
                             animating = true;
                             //w.dump("  ");
                         }
-
+                        if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
+                            wallpaperMayChange = true;
+                        }
                         mPolicy.animatingWindowLw(w, attrs);
                     }
 
@@ -9259,6 +9289,7 @@
             boolean covered = false;
             boolean syswin = false;
             boolean backgroundFillerShown = false;
+            boolean forceHiding = false;
 
             final int N = mWindows.size();
             
@@ -9391,7 +9422,10 @@
                         }
                     }
 
-                    if (w.mAttachedHidden) {
+                    if ((forceHiding
+                            && attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
+                            && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER)
+                            || w.mAttachedHidden) {
                         if (!w.mLastHidden) {
                             //dump();
                             w.mLastHidden = true;
@@ -9505,6 +9539,9 @@
                     }
 
                     if (displayed) {
+                        if (attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
+                            forceHiding = true;
+                        }
                         if (!covered) {
                             if (attrs.width == LayoutParams.FILL_PARENT
                                     && attrs.height == LayoutParams.FILL_PARENT) {
@@ -9587,7 +9624,7 @@
                         }
                         backgroundFillerShown = true;
                         mBackgroundFillerShown = true;
-                    } else if (canBeSeen && !obscured &&
+                    } else if (canBeSeen && !obscured && !forceHiding &&
                             (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
                         if (localLOGV) Log.v(TAG, "Win " + w
                                 + ": blurring=" + blurring
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 66ef557..d4f7207e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -33,7 +33,6 @@
 import android.app.ApplicationErrorReport;
 import android.app.Dialog;
 import android.app.IActivityController;
-import android.app.IActivityManager;
 import android.app.IActivityWatcher;
 import android.app.IApplicationThread;
 import android.app.IInstrumentationWatcher;
@@ -53,6 +52,7 @@
 import android.content.IntentFilter;
 import android.content.IIntentReceiver;
 import android.content.IIntentSender;
+import android.content.IntentSender;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ConfigurationInfo;
@@ -1572,6 +1572,7 @@
                 }
             }
             
+            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
             synchronized(bstats) {
                 synchronized(mPidsSelfLocked) {
@@ -1585,11 +1586,13 @@
                                 if (pr != null) {
                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
+                                    ps.addSpeedStepTimes(cpuSpeedTimes);
                                 } else {
                                     BatteryStatsImpl.Uid.Proc ps =
                                             bstats.getProcessStatsLocked(st.name, st.pid);
                                     if (ps != null) {
                                         ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
+                                        ps.addSpeedStepTimes(cpuSpeedTimes);
                                     }
                                 }
                             }
@@ -3613,8 +3616,8 @@
         }
     }
 
-    public int startActivityPendingIntent(IApplicationThread caller,
-            PendingIntent intent, Intent fillInIntent, String resolvedType,
+    public int startActivityIntentSender(IApplicationThread caller,
+            IntentSender intent, Intent fillInIntent, String resolvedType,
             IBinder resultTo, String resultWho, int requestCode,
             int flagsMask, int flagsValues) {
         // Refuse possible leaked file descriptors
@@ -3628,8 +3631,15 @@
         }
         
         PendingIntentRecord pir = (PendingIntentRecord)sender;
-        if (pir.key.type != IActivityManager.INTENT_SENDER_ACTIVITY) {
-            return START_NOT_ACTIVITY;
+        
+        synchronized (this) {
+            // If this is coming from the currently resumed activity, it is
+            // effectively saying that app switches are allowed at this point.
+            if (mResumedActivity != null
+                    && mResumedActivity.info.applicationInfo.uid ==
+                            Binder.getCallingUid()) {
+                mAppSwitchesAllowedTime = 0;
+            }
         }
         
         return pir.sendInner(0, fillInIntent, resolvedType,
@@ -4921,23 +4931,14 @@
         Binder.restoreCallingIdentity(origId);
     }
     
-    public void getProcessMemoryInfo(int pid, Debug.MemoryInfo mi)
+    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
             throws RemoteException {
-        ProcessRecord proc;
-        synchronized (mPidsSelfLocked) {
-            proc = mPidsSelfLocked.get(pid);
+        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
+        for (int i=pids.length-1; i>=0; i--) {
+            infos[i] = new Debug.MemoryInfo();
+            Debug.getMemoryInfo(pids[i], infos[i]);
         }
-        
-        if (proc == null) {
-            throw new RemoteException();
-        }
-        
-        IApplicationThread thread = proc.thread;
-        if (thread == null) {
-            throw new RemoteException();
-        }
-        
-        thread.getMemoryInfo(mi);
+        return infos;
     }
 
     public void killApplicationProcess(String processName, int uid) {
@@ -8433,6 +8434,13 @@
     }
 
     private ComponentName getErrorReportReceiver(ProcessRecord app) {
+        // check if error reporting is enabled in Gservices
+        int enabled = Settings.Gservices.getInt(mContext.getContentResolver(),
+                Settings.Gservices.SEND_ACTION_APP_ERROR, 0);
+        if (enabled == 0) {
+            return null;
+        }
+
         IPackageManager pm = ActivityThread.getPackageManager();
 
         try {
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index ed0d534..61537f5 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -28,6 +28,7 @@
 
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.PowerProfile;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -49,6 +50,7 @@
     public void publish(Context context) {
         mContext = context;
         ServiceManager.addService("batteryinfo", asBinder());
+        mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
     }
     
     public void shutdown() {
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index d994362..a753d05 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -198,6 +198,7 @@
                 } else {
                     resolvedType = key.requestResolvedType;
                 }
+                flagsMask &= ~Intent.IMMUTABLE_FLAGS;
                 flagsValues &= flagsMask;
                 finalIntent.setFlags((finalIntent.getFlags()&~flagsMask) | flagsValues);
                 
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 4368464..046bfea 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -111,6 +111,11 @@
         return c == PAUSE || c == WAIT;
     }
 
+    /** Returns true if ch is not dialable or alpha char */
+    private static boolean isSeparator(char ch) {
+        return !isDialable(ch) && !(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'));
+    }
+
     /** Extracts the phone number from an Intent.
      *
      * @param intent the intent to get the number of
@@ -129,6 +134,8 @@
             return uri.getSchemeSpecificPart();
         }
 
+        // TODO: We don't check for SecurityException here (requires
+        // READ_PHONE_STATE permission).
         if (scheme.equals("voicemail")) {
             return TelephonyManager.getDefault().getVoiceMailNumber();
         }
@@ -291,18 +298,36 @@
     }
 
     /**
+     * Compare phone numbers a and b, return true if they're identical enough for caller ID purposes.
+     */
+    public static boolean compare(String a, String b) {
+        // We've used loose comparation at least Eclair, which may change in the future.
+        return compare(a, b, false);
+    }
+
+    /**
+     * @hide only for testing.
+     */
+    public static boolean compare(String a, String b, boolean useStrictComparation) {
+        return (useStrictComparation ? compareStrictly(a, b) : compareLoosely(a, b));
+    }
+
+    /**
      * Compare phone numbers a and b, return true if they're identical
      * enough for caller ID purposes.
      *
      * - Compares from right to left
-     * - requires MIN_MATCH (5) characters to match
+     * - requires MIN_MATCH (7) characters to match
      * - handles common trunk prefixes and international prefixes
      *   (basically, everything except the Russian trunk prefix)
      *
-     * Tolerates nulls
+     * Note that this method does not return false even when the two phone numbers
+     * are not exactly same; rather; we can call this method "similar()", not "equals()".
+     *
+     * @hide
      */
     public static boolean
-    compare(String a, String b) {
+    compareLoosely(String a, String b) {
         int ia, ib;
         int matched;
 
@@ -389,6 +414,160 @@
     }
 
     /**
+     * @hide
+     */
+    public static boolean
+    compareStrictly(String a, String b) {
+        return compareStrictly(a, b, true);
+    }
+
+    /**
+     * @hide
+     */
+    public static boolean
+    compareStrictly(String a, String b, boolean acceptInvalidCCCPrefix) {
+        if (a == null || b == null) {
+            return a == b;
+        } else if (a.length() == 0 && b.length() == 0) {
+            return false;
+        }
+
+        int forwardIndexA = 0;
+        int forwardIndexB = 0;
+
+        CountryCallingCodeAndNewIndex cccA =
+            tryGetCountryCallingCodeAndNewIndex(a, acceptInvalidCCCPrefix);
+        CountryCallingCodeAndNewIndex cccB =
+            tryGetCountryCallingCodeAndNewIndex(b, acceptInvalidCCCPrefix);
+        boolean bothHasCountryCallingCode = false;
+        boolean okToIgnorePrefix = true;
+        boolean trunkPrefixIsOmittedA = false;
+        boolean trunkPrefixIsOmittedB = false;
+        if (cccA != null && cccB != null) {
+            if (cccA.countryCallingCode != cccB.countryCallingCode) {
+                // Different Country Calling Code. Must be different phone number.
+                return false;
+            }
+            // When both have ccc, do not ignore trunk prefix. Without this,
+            // "+81123123" becomes same as "+810123123" (+81 == Japan)
+            okToIgnorePrefix = false;
+            bothHasCountryCallingCode = true;
+            forwardIndexA = cccA.newIndex;
+            forwardIndexB = cccB.newIndex;
+        } else if (cccA == null && cccB == null) {
+            // When both do not have ccc, do not ignore trunk prefix. Without this,
+            // "123123" becomes same as "0123123"
+            okToIgnorePrefix = false;
+        } else {
+            if (cccA != null) {
+                forwardIndexA = cccA.newIndex;
+            } else {
+                int tmp = tryGetTrunkPrefixOmittedIndex(b, 0);
+                if (tmp >= 0) {
+                    forwardIndexA = tmp;
+                    trunkPrefixIsOmittedA = true;
+                }
+            }
+            if (cccB != null) {
+                forwardIndexB = cccB.newIndex;
+            } else {
+                int tmp = tryGetTrunkPrefixOmittedIndex(b, 0);
+                if (tmp >= 0) {
+                    forwardIndexB = tmp;
+                    trunkPrefixIsOmittedB = true;
+                }
+            }
+        }
+
+        int backwardIndexA = a.length() - 1;
+        int backwardIndexB = b.length() - 1;
+        while (backwardIndexA >= forwardIndexA && backwardIndexB >= forwardIndexB) {
+            boolean skip_compare = false;
+            final char chA = a.charAt(backwardIndexA);
+            final char chB = b.charAt(backwardIndexB);
+            if (isSeparator(chA)) {
+                backwardIndexA--;
+                skip_compare = true;
+            }
+            if (isSeparator(chB)) {
+                backwardIndexB--;
+                skip_compare = true;
+            }
+
+            if (!skip_compare) {
+                if (chA != chB) {
+                    return false;
+                }
+                backwardIndexA--;
+                backwardIndexB--;
+            }
+        }
+
+        if (okToIgnorePrefix) {
+            if ((trunkPrefixIsOmittedA && forwardIndexA <= backwardIndexA) ||
+                !checkPrefixIsIgnorable(a, forwardIndexA, backwardIndexA)) {
+                if (acceptInvalidCCCPrefix) {
+                    // Maybe the code handling the special case for Thailand makes the
+                    // result garbled, so disable the code and try again.
+                    // e.g. "16610001234" must equal to "6610001234", but with
+                    //      Thailand-case handling code, they become equal to each other.
+                    //
+                    // Note: we select simplicity rather than adding some complicated
+                    //       logic here for performance(like "checking whether remaining
+                    //       numbers are just 66 or not"), assuming inputs are small
+                    //       enough.
+                    return compare(a, b, false);
+                } else {
+                    return false;
+                }
+            }
+            if ((trunkPrefixIsOmittedB && forwardIndexB <= backwardIndexB) ||
+                !checkPrefixIsIgnorable(b, forwardIndexA, backwardIndexB)) {
+                if (acceptInvalidCCCPrefix) {
+                    return compare(a, b, false);
+                } else {
+                    return false;
+                }
+            }
+        } else {
+            // In the US, 1-650-555-1234 must be equal to 650-555-1234,
+            // while 090-1234-1234 must not be equalt to 90-1234-1234 in Japan.
+            // This request exists just in US (with 1 trunk (NDD) prefix).
+            // In addition, "011 11 7005554141" must not equal to "+17005554141",
+            // while "011 1 7005554141" must equal to "+17005554141"
+            //
+            // In this comparison, we ignore the prefix '1' just once, when
+            // - at least either does not have CCC, or
+            // - the remaining non-separator number is 1
+            boolean maybeNamp = !bothHasCountryCallingCode;
+            while (backwardIndexA >= forwardIndexA) {
+                final char chA = a.charAt(backwardIndexA);
+                if (isDialable(chA)) {
+                    if (maybeNamp && tryGetISODigit(chA) == 1) {
+                        maybeNamp = false;
+                    } else {
+                        return false;
+                    }
+                }
+                backwardIndexA--;
+            }
+            while (backwardIndexB >= forwardIndexB) {
+                final char chB = b.charAt(backwardIndexB);
+                if (isDialable(chB)) {
+                    if (maybeNamp && tryGetISODigit(chB) == 1) {
+                        maybeNamp = false;
+                    } else {
+                        return false;
+                    }
+                }
+                backwardIndexB--;
+            }
+        }
+
+        return true;
+    }
+
+    /**
      * Returns the rightmost MIN_MATCH (5) characters in the network portion
      * in *reversed* order
      *
@@ -473,54 +652,6 @@
     }
 
     /**
-     * Phone numbers are stored in "lookup" form in the database
-     * as reversed strings to allow for caller ID lookup
-     *
-     * This method takes a phone number and makes a valid SQL "LIKE"
-     * string that will match the lookup form
-     *
-     */
-    /** all of a up to len must be an international prefix or
-     *  separators/non-dialing digits
-     */
-    private static boolean
-    matchIntlPrefix(String a, int len) {
-        /* '([^0-9*#+pwn]\+[^0-9*#+pwn] | [^0-9*#+pwn]0(0|11)[^0-9*#+pwn] )$' */
-        /*        0       1                           2 3 45               */
-
-        int state = 0;
-        for (int i = 0 ; i < len ; i++) {
-            char c = a.charAt(i);
-
-            switch (state) {
-                case 0:
-                    if      (c == '+') state = 1;
-                    else if (c == '0') state = 2;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 2:
-                    if      (c == '0') state = 3;
-                    else if (c == '1') state = 4;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 4:
-                    if      (c == '1') state = 5;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                default:
-                    if (isNonSeparator(c)) return false;
-                break;
-
-            }
-        }
-
-        return state == 1 || state == 3 || state == 5;
-    }
-
-    /**
      *  3GPP TS 24.008 10.5.4.7
      *  Called Party BCD Number
      *
@@ -833,76 +964,6 @@
         return result;
     }
 
-    /** all of 'a' up to len must match non-US trunk prefix ('0') */
-    private static boolean
-    matchTrunkPrefix(String a, int len) {
-        boolean found;
-
-        found = false;
-
-        for (int i = 0 ; i < len ; i++) {
-            char c = a.charAt(i);
-
-            if (c == '0' && !found) {
-                found = true;
-            } else if (isNonSeparator(c)) {
-                return false;
-            }
-        }
-
-        return found;
-    }
-
-    /** all of 'a' up to len must be a (+|00|011)country code)
-     *  We're fast and loose with the country code. Any \d{1,3} matches */
-    private static boolean
-    matchIntlPrefixAndCC(String a, int len) {
-        /*  [^0-9*#+pwn]*(\+|0(0|11)\d\d?\d? [^0-9*#+pwn] $ */
-        /*      0          1 2 3 45  6 7  8                 */
-
-        int state = 0;
-        for (int i = 0 ; i < len ; i++ ) {
-            char c = a.charAt(i);
-
-            switch (state) {
-                case 0:
-                    if      (c == '+') state = 1;
-                    else if (c == '0') state = 2;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 2:
-                    if      (c == '0') state = 3;
-                    else if (c == '1') state = 4;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 4:
-                    if      (c == '1') state = 5;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 1:
-                case 3:
-                case 5:
-                    if      (isISODigit(c)) state = 6;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                case 6:
-                case 7:
-                    if      (isISODigit(c)) state++;
-                    else if (isNonSeparator(c)) return false;
-                break;
-
-                default:
-                    if (isNonSeparator(c)) return false;
-            }
-        }
-
-        return state == 6 || state == 7 || state == 8;
-    }
-
     //================ Number formatting =========================
 
     /** The current locale is unknown, look for a country code or don't format */
@@ -1141,10 +1202,24 @@
         JapanesePhoneNumberFormatter.format(text);
     }
 
-    // Three and four digit phone numbers for either special services
-    // or from the network (eg carrier-originated SMS messages) should
-    // not match
-    static final int MIN_MATCH = 5;
+    // Three and four digit phone numbers for either special services,
+    // or 3-6 digit addresses from the network (eg carrier-originated SMS messages) should
+    // not match.
+    //
+    // This constant used to be 5, but SMS short codes has increased in length and
+    // can be easily 6 digits now days. Most countries have SMS short code length between
+    // 3 to 6 digits. The exceptions are
+    //
+    // Australia: Short codes are six or eight digits in length, starting with the prefix "19"
+    //            followed by an additional four or six digits and two.
+    // Czech Republic: Codes are seven digits in length for MO and five (not billed) or
+    //            eight (billed) for MT direction
+    //
+    // see http://en.wikipedia.org/wiki/Short_code#Regional_differences for reference
+    //
+    // However, in order to loose match 650-555-1212 and 555-1212, we need to set the min match
+    // to 7.
+    static final int MIN_MATCH = 7;
 
     /**
      * isEmergencyNumber: checks a given number against the list of
@@ -1179,6 +1254,35 @@
     }
 
     /**
+     * isVoiceMailNumber: checks a given number against the voicemail
+     *   number provided by the RIL and SIM card. The caller must have
+     *   the READ_PHONE_STATE credential.
+     *
+     * @param number the number to look up.
+     * @return true if the number is in the list of voicemail. False
+     * otherwise, including if the caller does not have the permission
+     * to read the VM number.
+     * @hide TODO: pending API Council approval
+     */
+    public static boolean isVoiceMailNumber(String number) {
+        String vmNumber;
+
+        try {
+            vmNumber = TelephonyManager.getDefault().getVoiceMailNumber();
+        } catch (SecurityException ex) {
+            return false;
+        }
+
+        // Strip the separators from the number before comparing it
+        // to the list.
+        number = extractNetworkPortion(number);
+
+        // compare tolerates null so we need to make sure that we
+        // don't return true when both are null.
+        return !TextUtils.isEmpty(number) && compare(number, vmNumber);
+    }
+
+    /**
      * Translates any alphabetic letters (i.e. [A-Za-z]) in the
      * specified phone number into the equivalent numeric digits,
      * according to the phone keypad letter mapping described in
@@ -1522,4 +1626,317 @@
         }
         return retStr;
     }
+
+    //===== Begining of utility methods used in compareLoosely() =====
+
+    /**
+     * Phone numbers are stored in "lookup" form in the database
+     * as reversed strings to allow for caller ID lookup
+     *
+     * This method takes a phone number and makes a valid SQL "LIKE"
+     * string that will match the lookup form
+     *
+     */
+    /** all of a up to len must be an international prefix or
+     *  separators/non-dialing digits
+     */
+    private static boolean
+    matchIntlPrefix(String a, int len) {
+        /* '([^0-9*#+pwn]\+[^0-9*#+pwn] | [^0-9*#+pwn]0(0|11)[^0-9*#+pwn] )$' */
+        /*        0       1                           2 3 45               */
+
+        int state = 0;
+        for (int i = 0 ; i < len ; i++) {
+            char c = a.charAt(i);
+
+            switch (state) {
+                case 0:
+                    if      (c == '+') state = 1;
+                    else if (c == '0') state = 2;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 2:
+                    if      (c == '0') state = 3;
+                    else if (c == '1') state = 4;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 4:
+                    if      (c == '1') state = 5;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                default:
+                    if (isNonSeparator(c)) return false;
+                break;
+
+            }
+        }
+
+        return state == 1 || state == 3 || state == 5;
+    }
+
+    /** all of 'a' up to len must be a (+|00|011)country code)
+     *  We're fast and loose with the country code. Any \d{1,3} matches */
+    private static boolean
+    matchIntlPrefixAndCC(String a, int len) {
+        /*  [^0-9*#+pwn]*(\+|0(0|11)\d\d?\d? [^0-9*#+pwn] $ */
+        /*      0          1 2 3 45  6 7  8                 */
+
+        int state = 0;
+        for (int i = 0 ; i < len ; i++ ) {
+            char c = a.charAt(i);
+
+            switch (state) {
+                case 0:
+                    if      (c == '+') state = 1;
+                    else if (c == '0') state = 2;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 2:
+                    if      (c == '0') state = 3;
+                    else if (c == '1') state = 4;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 4:
+                    if      (c == '1') state = 5;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 1:
+                case 3:
+                case 5:
+                    if      (isISODigit(c)) state = 6;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                case 6:
+                case 7:
+                    if      (isISODigit(c)) state++;
+                    else if (isNonSeparator(c)) return false;
+                break;
+
+                default:
+                    if (isNonSeparator(c)) return false;
+            }
+        }
+
+        return state == 6 || state == 7 || state == 8;
+    }
+
+    /** all of 'a' up to len must match non-US trunk prefix ('0') */
+    private static boolean
+    matchTrunkPrefix(String a, int len) {
+        boolean found;
+
+        found = false;
+
+        for (int i = 0 ; i < len ; i++) {
+            char c = a.charAt(i);
+
+            if (c == '0' && !found) {
+                found = true;
+            } else if (isNonSeparator(c)) {
+                return false;
+            }
+        }
+
+        return found;
+    }
+
+    //===== End of utility methods used only in compareLoosely() =====
+
+    //===== Beggining of utility methods used only in compareStrictly() ====
+
+    /*
+     * If true, the number is country calling code.
+     */
+    private static final boolean COUNTLY_CALLING_CALL[] = {
+        true, true, false, false, false, false, false, true, false, false,
+        false, false, false, false, false, false, false, false, false, false,
+        true, false, false, false, false, false, false, true, true, false,
+        true, true, true, true, true, false, true, false, false, true,
+        true, false, false, true, true, true, true, true, true, true,
+        false, true, true, true, true, true, true, true, true, false,
+        true, true, true, true, true, true, true, false, false, false,
+        false, false, false, false, false, false, false, false, false, false,
+        false, true, true, true, true, false, true, false, false, true,
+        true, true, true, true, true, true, false, false, true, false,
+    };
+    private static final int CCC_LENGTH = COUNTLY_CALLING_CALL.length;
+
+    /**
+     * @return true when input is valid Country Calling Code.
+     */
+    private static boolean isCountryCallingCode(int countryCallingCodeCandidate) {
+        return countryCallingCodeCandidate > 0 && countryCallingCodeCandidate < CCC_LENGTH &&
+                COUNTLY_CALLING_CALL[countryCallingCodeCandidate];
+    }
+
+    /**
+     * Returns interger corresponding to the input if input "ch" is
+     * ISO-LATIN characters 0-9.
+     * Returns -1 otherwise
+     */
+    private static int tryGetISODigit(char ch) {
+        if ('0' <= ch && ch <= '9') {
+            return ch - '0';
+        } else {
+            return -1;
+        }
+    }
+
+    private static class CountryCallingCodeAndNewIndex {
+        public final int countryCallingCode;
+        public final int newIndex;
+        public CountryCallingCodeAndNewIndex(int countryCode, int newIndex) {
+            this.countryCallingCode = countryCode;
+            this.newIndex = newIndex;
+        }
+    }
+
+    /*
+     * Note that this function does not strictly care the country calling code with
+     * 3 length (like Morocco: +212), assuming it is enough to use the first two
+     * digit to compare two phone numbers.
+     */
+    private static CountryCallingCodeAndNewIndex tryGetCountryCallingCodeAndNewIndex(
+        String str, boolean acceptThailandCase) {
+        // Rough regexp:
+        //  ^[^0-9*#+]*((\+|0(0|11)\d\d?|166) [^0-9*#+] $
+        //         0        1 2 3 45  6 7  89
+        //
+        // In all the states, this function ignores separator characters.
+        // "166" is the special case for the call from Thailand to the US. Uguu!
+        int state = 0;
+        int ccc = 0;
+        final int length = str.length();
+        for (int i = 0 ; i < length ; i++ ) {
+            char ch = str.charAt(i);
+            switch (state) {
+                case 0:
+                    if      (ch == '+') state = 1;
+                    else if (ch == '0') state = 2;
+                    else if (ch == '1') {
+                        if (acceptThailandCase) {
+                            state = 8;
+                        } else {
+                            return null;
+                        }
+                    } else if (isDialable(ch)) {
+                        return null;
+                    }
+                break;
+
+                case 2:
+                    if      (ch == '0') state = 3;
+                    else if (ch == '1') state = 4;
+                    else if (isDialable(ch)) {
+                        return null;
+                    }
+                break;
+
+                case 4:
+                    if      (ch == '1') state = 5;
+                    else if (isDialable(ch)) {
+                        return null;
+                    }
+                break;
+
+                case 1:
+                case 3:
+                case 5:
+                case 6:
+                case 7:
+                    {
+                        int ret = tryGetISODigit(ch);
+                        if (ret > 0) {
+                            ccc = ccc * 10 + ret;
+                            if (ccc >= 100 || isCountryCallingCode(ccc)) {
+                                return new CountryCallingCodeAndNewIndex(ccc, i + 1);
+                            }
+                            if (state == 1 || state == 3 || state == 5) {
+                                state = 6;
+                            } else {
+                                state++;
+                            }
+                        } else if (isDialable(ch)) {
+                            return null;
+                        }
+                    }
+                    break;
+                case 8:
+                    if (ch == '6') state = 9;
+                    else if (isDialable(ch)) {
+                        return null;
+                    }
+                    break;
+                case 9:
+                    if (ch == '6') {
+                        return new CountryCallingCodeAndNewIndex(66, i + 1);
+                    } else {
+                        return null;
+                    }
+                default:
+                    return null;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Currently this function simply ignore the first digit assuming it is
+     * trunk prefix. Actually trunk prefix is different in each country.
+     *
+     * e.g.
+     * "+79161234567" equals "89161234567" (Russian trunk digit is 8)
+     * "+33123456789" equals "0123456789" (French trunk digit is 0)
+     *
+     */
+    private static int tryGetTrunkPrefixOmittedIndex(String str, int currentIndex) {
+        int length = str.length();
+        for (int i = currentIndex ; i < length ; i++) {
+            final char ch = str.charAt(i);
+            if (tryGetISODigit(ch) >= 0) {
+                return i + 1;
+            } else if (isDialable(ch)) {
+                return -1;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Return true if the prefix of "str" is "ignorable". Here, "ignorable" means
+     * that "str" has only one digit and separater characters. The one digit is
+     * assumed to be trunk prefix.
+     */
+    private static boolean checkPrefixIsIgnorable(final String str,
+            int forwardIndex, int backwardIndex) {
+        boolean trunk_prefix_was_read = false;
+        while (backwardIndex >= forwardIndex) {
+            if (tryGetISODigit(str.charAt(backwardIndex)) >= 0) {
+                if (trunk_prefix_was_read) {
+                    // More than one digit appeared, meaning that "a" and "b"
+                    // is different.
+                    return false;
+                } else {
+                    // Ignore just one digit, assuming it is trunk prefix.
+                    trunk_prefix_was_read = true;
+                }
+            } else if (isDialable(str.charAt(backwardIndex))) {
+                // Trunk prefix is a digit, not "*", "#"...
+                return false;
+            }
+            backwardIndex--;
+        }
+
+        return true;
+    }
+
+    //==== End of utility methods used only in compareStrictly() =====
 }
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index b8778f8..676fba7 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -20,8 +20,7 @@
 import android.telephony.CellLocation;
 
 /**
- * Represents the cell location on a GSM phone.
- * @hide
+ * Represents the cell location on a CDMA phone.
  */
 public class CdmaCellLocation extends CellLocation {
     private int mBaseStationId = -1;
@@ -31,7 +30,8 @@
     private int mNetworkId = -1;
 
     /**
-     * Empty constructor.  Initializes the LAC and CID to -1.
+     * Empty constructor.
+     * Initializes the BID, SID, NID and base station latitude and longitude to -1.
      */
     public CdmaCellLocation() {
         this.mBaseStationId = -1;
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 3edca66..52f25f6 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -64,6 +64,7 @@
     protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
     protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
     protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
+    protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
 
     protected Registrant mSMSRegistrant;
     protected Registrant mNITZTimeRegistrant;
@@ -569,6 +570,15 @@
         mT53AudCntrlInfoRegistrants.remove(h);
     }
 
+    public void registerForRingbackTone(Handler h, int what, Object obj) {
+        Registrant r = new Registrant (h, what, obj);
+        mRingbackToneRegistrants.add(r);
+    }
+
+    public void unregisterForRingbackTone(Handler h) {
+        mRingbackToneRegistrants.remove(h);
+    }
+
     //***** Protected Methods
     /**
      * Store new RadioState and send notification based on the changes
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index c8490e9..01b1746 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -101,13 +101,12 @@
     public boolean isCachedPhotoCurrent;
 
     private boolean mIsEmergency;
-
-    // Don't keep checking VM if it's going to throw an exception for this proc.
-    private static boolean sSkipVmCheck = false;
+    private boolean mIsVoiceMail;
 
     public CallerInfo() {
         // TODO: Move all the basic initialization here?
         mIsEmergency = false;
+        mIsVoiceMail = false;
     }
 
     /**
@@ -220,32 +219,15 @@
     public static CallerInfo getCallerInfo(Context context, String number) {
         if (TextUtils.isEmpty(number)) {
             return null;
-        } else {
-            // Change the callerInfo number ONLY if it is an emergency number
-            // or if it is the voicemail number.  If it is either, take a
-            // shortcut and skip the query.
-            if (PhoneNumberUtils.isEmergencyNumber(number)) {
-                return new CallerInfo().markAsEmergency(context);
-            } else {
-                try {
-                    if (!sSkipVmCheck && PhoneNumberUtils.compare(number,
-                                TelephonyManager.getDefault().getVoiceMailNumber())) {
-                        CallerInfo ci = new CallerInfo();
+        }
 
-                        // Note we're setting the phone number here (refer to javadoc
-                        // comments at the top of CallerInfo class).
-                        ci.phoneNumber = TelephonyManager.getDefault().getVoiceMailAlphaTag();
-                        // TODO: FIND ANOTHER ICON
-                        //info.photoResource = android.R.drawable.badge_voicemail;
-                        return ci;
-                    }
-                } catch (SecurityException ex) {
-                    // Don't crash if this process doesn't have permission to
-                    // retrieve VM number.  It's still allowed to look up caller info.
-                    // But don't try it again.
-                    sSkipVmCheck = true;
-                }
-            }
+        // Change the callerInfo number ONLY if it is an emergency number
+        // or if it is the voicemail number.  If it is either, take a
+        // shortcut and skip the query.
+        if (PhoneNumberUtils.isEmergencyNumber(number)) {
+            return new CallerInfo().markAsEmergency(context);
+        } else if (PhoneNumberUtils.isVoiceMailNumber(number)) {
+            return new CallerInfo().markAsVoiceMail();
         }
 
         Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
@@ -304,6 +286,13 @@
     }
 
     /**
+     * @return true if the caller info is a voicemail number.
+     */
+    public boolean isVoiceMailNumber() {
+        return mIsVoiceMail;
+    }
+
+    /**
      * Mark this CallerInfo as an emergency call.
      * @param context To lookup the localized 'Emergency Number' string.
      * @return this instance.
@@ -323,6 +312,37 @@
         return this;
     }
 
+
+    /**
+     * Mark this CallerInfo as a voicemail call. The voicemail label
+     * is obtained from the telephony manager. Caller must hold the
+     * READ_PHONE_STATE permission otherwise the phoneNumber will be
+     * set to null.
+     * @return this instance.
+     */
+    // TODO: As in the emergency number handling, we end up writing a
+    // string in the phone number field.
+    /* package */ CallerInfo markAsVoiceMail() {
+        mIsVoiceMail = true;
+
+        try {
+            String voiceMailLabel = TelephonyManager.getDefault().getVoiceMailAlphaTag();
+
+            phoneNumber = voiceMailLabel;
+        } catch (SecurityException se) {
+            // Should never happen: if this process does not have
+            // permission to retrieve VM tag, it should not have
+            // permission to retrieve VM number and would not call
+            // this method.
+            // Leave phoneNumber untouched.
+            Log.e(TAG, "Cannot access VoiceMail.", se);
+        }
+        // TODO: There is no voicemail picture?
+        // FIXME: FIND ANOTHER ICON
+        // photoResource = android.R.drawable.badge_voicemail;
+        return this;
+    }
+
     private static String normalize(String s) {
         if (s == null || s.length() > 0) {
             return s;
@@ -330,4 +350,31 @@
             return null;
         }
     }
+
+    /**
+     * @return a string debug representation of this instance.
+     */
+    public String toString() {
+        return new StringBuilder(384)
+                .append("\nname: " + name)
+                .append("\nphoneNumber: " + phoneNumber)
+                .append("\ncnapName: " + cnapName)
+                .append("\nnumberPresentation: " + numberPresentation)
+                .append("\nnamePresentation: " + namePresentation)
+                .append("\ncontactExits: " + contactExists)
+                .append("\nphoneLabel: " + phoneLabel)
+                .append("\nnumberType: " + numberType)
+                .append("\nnumberLabel: " + numberLabel)
+                .append("\nphotoResource: " + photoResource)
+                .append("\nperson_id: " + person_id)
+                .append("\nneedUpdate: " + needUpdate)
+                .append("\ncontactRefUri: " + contactRefUri)
+                .append("\ncontactRingtoneUri: " + contactRefUri)
+                .append("\nshouldSendToVoicemail: " + shouldSendToVoicemail)
+                .append("\ncachedPhoto: " + cachedPhoto)
+                .append("\nisCachedPhotoCurrent: " + isCachedPhotoCurrent)
+                .append("\nemergency: " + mIsEmergency)
+                .append("\nvoicemail " + mIsVoiceMail)
+                .toString();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index 4227a84..802e79b 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -47,9 +47,6 @@
 
     private CallerInfoAsyncQueryHandler mHandler;
 
-    // Don't keep checking VM if it's going to throw an exception for this proc.
-    private static boolean sSkipVmCheck = false;
-
     /**
      * Interface for a CallerInfoAsyncQueryHandler result return.
      */
@@ -227,18 +224,7 @@
                     // comments at the top of CallerInfo class).
                     mCallerInfo = new CallerInfo().markAsEmergency(mQueryContext);
                 } else if (cw.event == EVENT_VOICEMAIL_NUMBER) {
-                    mCallerInfo = new CallerInfo();
-                    try {
-                        // Note we're setting the phone number here (refer to javadoc
-                        // comments at the top of CallerInfo class).
-                        mCallerInfo.phoneNumber =
-                                TelephonyManager.getDefault().getVoiceMailAlphaTag();
-                    } catch (SecurityException ex) {
-                        // Should never happen: if this process does not have
-                        // permission to retrieve VM tag, it should not have
-                        // permission to retrieve VM number and would not generate
-                        // an EVENT_VOICEMAIL_NUMBER.  But if it happens, don't crash.
-                    }
+                    mCallerInfo = new CallerInfo().markAsVoiceMail();
                 } else {
                     mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor);
                     // Use the number entered by the user for display.
@@ -258,7 +244,7 @@
             //notify the listener that the query is complete.
             if (cw.listener != null) {
                 if (DBG) log("notifying listener: " + cw.listener.getClass().toString() +
-                        " for token: " + token);
+                             " for token: " + token + mCallerInfo);
                 cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
             }
         }
@@ -315,23 +301,10 @@
         // check to see if these are recognized numbers, and use shortcuts if we can.
         if (PhoneNumberUtils.isEmergencyNumber(number)) {
             cw.event = EVENT_EMERGENCY_NUMBER;
+        } else if (PhoneNumberUtils.isVoiceMailNumber(number)) {
+            cw.event = EVENT_VOICEMAIL_NUMBER;
         } else {
-            String vmNumber = null;
-            if (!sSkipVmCheck){
-                try {
-                    vmNumber = TelephonyManager.getDefault().getVoiceMailNumber();
-                } catch (SecurityException ex) {
-                    // Don't crash if this process doesn't have permission to
-                    // retrieve VM number.  It's still allowed to look up caller info.
-                    // But don't try it again.
-                    sSkipVmCheck = true;
-                }
-            }
-            if (PhoneNumberUtils.compare(number, vmNumber)) {
-                cw.event = EVENT_VOICEMAIL_NUMBER;
-            } else {
-                cw.event = EVENT_NEW_QUERY;
-            }
+            cw.event = EVENT_NEW_QUERY;
         }
 
         c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 63bdc2c..9d83556 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -525,6 +525,17 @@
      void registerForCdmaOtaProvision(Handler h,int what, Object obj);
      void unregisterForCdmaOtaProvision(Handler h);
 
+     /**
+      * Registers the handler when out-band ringback tone is needed.<p>
+      *
+      *  Messages received from this:
+      *  Message.obj will be an AsyncResult
+      *  AsyncResult.userObj = obj
+      *  AsyncResult.result = boolean. <p>
+      */
+     void registerForRingbackTone(Handler h, int what, Object obj);
+     void unregisterForRingbackTone(Handler h);
+
     /**
      * Supply the ICC PIN to the ICC card
      *
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
index e6fd0a0..a48900a 100644
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ b/telephony/java/com/android/internal/telephony/Connection.java
@@ -15,6 +15,7 @@
  */
 
 package com.android.internal.telephony;
+import android.util.Log;
 
 /**
  * {@hide}
@@ -27,6 +28,7 @@
     public static int PRESENTATION_UNKNOWN = 3;    // no specified or unknown by network
     public static int PRESENTATION_PAYPHONE = 4;   // show pay phone info
 
+    private static String LOG_TAG = "TelephonyConnection";
 
     public enum DisconnectCause {
         NOT_DISCONNECTED,               /* has not yet disconnected */
@@ -269,4 +271,25 @@
      */
     public abstract int getNumberPresentation();
 
+    /**
+     * Build a human representation of a connection instance, suitable for debugging.
+     * Don't log personal stuff unless in debug mode.
+     * @return a string representing the internal state of this connection.
+     */
+    public String toString() {
+        StringBuilder str = new StringBuilder(128);
+
+        if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
+            str.append("addr: " + getAddress())
+                    .append(" pres.: " + getNumberPresentation())
+                    .append(" dial: " + getOrigDialString())
+                    .append(" postdial: " + getRemainingPostDialString())
+                    .append(" cnap name: " + getCnapName())
+                    .append("(" + getCnapNamePresentation() + ")");
+        }
+        str.append(" incoming: " + isIncoming())
+                .append(" state: " + getState())
+                .append(" post dial state: " + getPostDialState());
+        return str.toString();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 8d2785a..5581a24 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -127,7 +127,7 @@
 
     /** Retry configuration for secondary networks: 4 tries in 20 sec */
     protected static final String SECONDARY_DATA_RETRY_CONFIG =
-            "max_retries=3; 5000, 5000, 5000";
+            "max_retries=3, 5000, 5000, 5000";
 
     /** Slow poll when attempting connection recovery. */
     protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index f32837f..fffd128 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -379,6 +379,23 @@
 
     void unregisterForIncomingRing(Handler h);
 
+    /**
+     * Notifies when out-band ringback tone is needed.<p>
+     *
+     *  Messages received from this:
+     *  Message.obj will be an AsyncResult
+     *  AsyncResult.userObj = obj
+     *  AsyncResult.result = boolean, true to start play ringback tone
+     *                       and false to stop. <p>
+     */
+    void registerForRingbackTone(Handler h, int what, Object obj);
+
+    /**
+     * Unregisters for ringback tone notification.
+     */
+
+    void unregisterForRingbackTone(Handler h);
+
 
     /**
      * Notifies when a voice connection has disconnected, either due to local
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index e340f85..1c62a82 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -482,6 +482,16 @@
         mServiceStateRegistrants.remove(h);
     }
 
+    // Inherited documentation suffices.
+    public void registerForRingbackTone(Handler h, int what, Object obj) {
+        mCM.registerForRingbackTone(h,what,obj);
+    }
+
+    // Inherited documentation suffices.
+    public void unregisterForRingbackTone(Handler h) {
+        mCM.unregisterForRingbackTone(h);
+    }
+
     /**
      * Subclasses of Phone probably want to replace this with a
      * version scoped to their packages
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 711a48c..c4f663a 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -331,6 +331,14 @@
         mActivePhone.unregisterForEcmTimerReset(h);
     }
 
+    public void registerForRingbackTone(Handler h, int what, Object obj) {
+        mActivePhone.registerForRingbackTone(h,what,obj);
+    }
+
+    public void unregisterForRingbackTone(Handler h) {
+        mActivePhone.unregisterForRingbackTone(h);
+    }
+
     public boolean getIccRecordsLoaded() {
         return mActivePhone.getIccRecordsLoaded();
     }
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index cd6340e..d1b446b 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2313,6 +2313,7 @@
             case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
             case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
             case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
+            case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
 
             default:
                 throw new RuntimeException("Unrecognized unsol response: " + response);
@@ -2597,6 +2598,14 @@
                     mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
                 }
                 break;
+
+            case RIL_UNSOL_RINGBACK_TONE:
+                if (RILJ_LOGD) unsljLogvRet(response, ret);
+                if (mRingbackToneRegistrants != null) {
+                    boolean playtone = (((int[])ret)[0] == 1);
+                    mRingbackToneRegistrants.notifyRegistrants(
+                                        new AsyncResult (null, playtone, null));
+                }
         }
     }
 
@@ -3209,6 +3218,7 @@
             case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
             case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
             case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
+            case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG";
             default: return "<unknown reponse>";
         }
     }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 90a82f9..3e9d8ad 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -258,4 +258,5 @@
     int RIL_UNSOL_CDMA_OTA_PROVISION_STATUS = 1026;
     int RIL_UNSOL_CDMA_INFO_REC = 1027;
     int RIL_UNSOL_OEM_HOOK_RAW = 1028;
+    int RIL_UNSOL_RINGBACK_TONE = 1029;
 }
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 3f0213b..3c2f2ed 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -383,7 +383,7 @@
          * 2. [x@y][ ]/[body]
          */
          String[] parts = messageBody.split("( /)|( )", 2);
-         if (parts.length < 1) return;
+         if (parts.length < 2) return;
          emailFrom = parts[0];
          emailBody = parts[1];
          isEmail = true;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index 5bf1a0f..9fe2038 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -437,7 +437,7 @@
                     new AsyncResult(null, null, null));
         }
         if (Phone.DEBUG_PHONE) {
-            log("update phone state, old= , new= , " + oldState + state);
+            log("update phone state, old=" + oldState + " new="+ state);
         }
         if (state != oldState) {
             phone.notifyPhoneStateChanged();
@@ -522,37 +522,44 @@
                     }
                 } else {
                     if (Phone.DEBUG_PHONE) {
-                        log("pending Mo= , dc= " + pendingMO + dc);
+                        log("pendingMo=" + pendingMO + ", dc=" + dc);
                     }
                     // find if the MT call is a new ring or unknown connection
                     newRinging = checkMtFindNewRinging(dc,i);
                     if (newRinging == null) {
                         unknownConnectionAppeared = true;
                     }
+                    checkAndEnableDataCallAfterEmergencyCallDropped();
                 }
                 hasNonHangupStateChanged = true;
             } else if (conn != null && dc == null) {
+                // This case means the RIL has no more active call anymore and
+                // we need to clean up the foregroundCall and ringingCall.
+                // Loop through foreground call connections as
+                // it contains the known logical connections.
                 int count = foregroundCall.connections.size();
-                if (count == 0) {
-                    // Handle an unanswered MO/MT call, there is no
-                    // foregroundCall connections at this time.
-                    droppedDuringPoll.add(conn);
-                } else {
-                    // Loop through foreground call connections as
-                    // it contains the known logical connections.
-                    for (int n = 0; n < count; n++) {
-                        CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
-                        droppedDuringPoll.add(cn);
-                    }
+                for (int n = 0; n < count; n++) {
+                    if (Phone.DEBUG_PHONE) log("adding fgCall cn " + n + " to droppedDuringPoll");
+                    CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
+                    droppedDuringPoll.add(cn);
+                }
+                count = ringingCall.connections.size();
+                // Loop through ringing call connections as
+                // it may contain the known logical connections.
+                for (int n = 0; n < count; n++) {
+                    if (Phone.DEBUG_PHONE) log("adding rgCall cn " + n + " to droppedDuringPoll");
+                    CdmaConnection cn = (CdmaConnection)ringingCall.connections.get(n);
+                    droppedDuringPoll.add(cn);
                 }
                 foregroundCall.setGeneric(false);
+                ringingCall.setGeneric(false);
 
                 // Re-start Ecm timer when the connected emergency call ends
                 if (mIsEcmTimerCanceled) {
                     handleEcmTimer(phone.RESTART_ECM_TIMER);
-                } else {
-                    mIsInEmergencyCall = false;
                 }
+                // If emergency call is not going through while dialing
+                checkAndEnableDataCallAfterEmergencyCallDropped();
 
                 // Dropped connections are removed from the CallTracker
                 // list but kept in the Call list
@@ -568,6 +575,7 @@
                         if (newRinging == null) {
                             unknownConnectionAppeared = true;
                         }
+                        checkAndEnableDataCallAfterEmergencyCallDropped();
                     } else {
                         // Call info stored in conn is not consistent with the call info from dc.
                         // We should follow the rule of MT calls taking precedence over MO calls
@@ -1030,10 +1038,30 @@
      */
     private void disableDataCallInEmergencyCall(String dialString) {
         if (PhoneNumberUtils.isEmergencyNumber(dialString)) {
+            if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall");
             phone.disableDataConnectivity();
             mIsInEmergencyCall = true;
         }
     }
+
+    /**
+     * Check and enable data call after an emergency call is dropped if it's
+     * not in ECM
+     */
+    private void checkAndEnableDataCallAfterEmergencyCallDropped() {
+        if (mIsInEmergencyCall) {
+            String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
+            if (Phone.DEBUG_PHONE) {
+                log("checkAndEnableDataCallAfterEmergencyCallDropped,inEcm=" + inEcm);
+            }
+            if (inEcm.compareTo("false") == 0) {
+                // Re-initiate data connection
+                phone.mDataConnection.setDataEnabled(true);
+            }
+            mIsInEmergencyCall = false;
+        }
+    }
+
     /**
      * Check the MT call to see if it's a new ring or
      * a unknown connection.
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 0c94e6a..bc04e02 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -221,10 +221,6 @@
         return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
     }
 
-    public String
-    toString() {
-        return (isIncoming ? "incoming" : "outgoing");
-    }
 
     public String getOrigDialString(){
         return dialString;
@@ -492,6 +488,8 @@
 
         newParent = parentFromDCState(dc.state);
 
+        if (Phone.DEBUG_PHONE) log("parent= " +parent +", newParent= " + newParent);
+
         if (!equalsHandlesNulls(address, dc.number)) {
             if (Phone.DEBUG_PHONE) log("update: phone # changed!");
             address = dc.number;
@@ -509,7 +507,7 @@
             cnapName = dc.name;
         }
 
-        log("--dssds----"+cnapName);
+        if (Phone.DEBUG_PHONE) log("--dssds----"+cnapName);
         cnapNamePresentation = dc.namePresentation;
         numberPresentation = dc.numberPresentation;
 
@@ -529,9 +527,7 @@
         /** Some state-transition events */
 
         if (Phone.DEBUG_PHONE) log(
-                "update: parent=" + parent +
-                ", hasNewParent=" + (newParent != parent) +
-                ", wasConnectingInOrOut=" + wasConnectingInOrOut +
+                "Update, wasConnectingInOrOut=" + wasConnectingInOrOut +
                 ", wasHolding=" + wasHolding +
                 ", isConnectingInOrOut=" + isConnectingInOrOut() +
                 ", changed=" + changed);
@@ -860,10 +856,13 @@
         // Append the PW char
         ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT;
 
-        // if there is a PAUSE in at the beginning of PW character sequences, and this
-        // PW character sequences has more than 2 PAUSE and WAIT Characters,skip PAUSE,
-        // append WAIT.
-        if (isPause(c) && (nextNonPwCharIndex > (currPwIndex + 2))) {
+        // If the nextNonPwCharIndex is greater than currPwIndex + 1,
+        // it means the PW sequence contains not only P characters.
+        // Since for the sequence that only contains P character,
+        // the P character is handled one by one, the nextNonPwCharIndex
+        // equals to currPwIndex + 1.
+        // In this case, skip P, append W.
+        if (nextNonPwCharIndex > (currPwIndex + 1)) {
             ret = PhoneNumberUtils.WAIT;
         }
         return ret;
@@ -882,6 +881,11 @@
      *    and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT.
      */
     public static String formatDialString(String phoneNumber) {
+        /**
+         * TODO(cleanup): This function should move to PhoneNumberUtils, and
+         * tests should be added.
+         */
+
         if (phoneNumber == null) {
             return null;
         }
@@ -901,9 +905,9 @@
                         char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex);
                         ret.append(pC);
                         // If PW char sequence has more than 2 PW characters,
-                        // skip to the last character since the sequence already be
+                        // skip to the last PW character since the sequence already be
                         // converted to WAIT character
-                        if (nextIndex > (currIndex + 2)) {
+                        if (nextIndex > (currIndex + 1)) {
                             currIndex = nextIndex - 1;
                         }
                     } else if (nextIndex == length) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 386dc3d46..7baf770 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -48,6 +48,7 @@
 
 import java.io.ByteArrayOutputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.lang.Boolean;
 
@@ -57,6 +58,9 @@
 
     private CDMAPhone mCdmaPhone;
 
+    private byte[] mLastDispatchedSmsFingerprint;
+    private byte[] mLastAcknowledgedSmsFingerprint;
+
     CdmaSMSDispatcher(CDMAPhone phone) {
         super(phone);
         mCdmaPhone = phone;
@@ -101,11 +105,17 @@
 
         String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
         if (inEcm.equals("true")) {
-            return Intents.RESULT_SMS_GENERIC_ERROR;
+            return Activity.RESULT_OK;
         }
 
-        // Decode BD stream and set sms variables.
+        // See if we have a network duplicate SMS.
         SmsMessage sms = (SmsMessage) smsb;
+        mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint();
+        if (mLastAcknowledgedSmsFingerprint != null &&
+                Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) {
+            return Intents.RESULT_SMS_HANDLED;
+        }
+        // Decode BD stream and set sms variables.
         sms.parseSms();
         int teleService = sms.getTeleService();
         boolean handled = false;
@@ -433,7 +443,13 @@
         }
 
         if (mCm != null) {
-            mCm.acknowledgeLastIncomingCdmaSms(success, resultToCause(result), response);
+            int causeCode = resultToCause(result);
+            mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response);
+
+            if (causeCode == 0) {
+                mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint;
+            }
+            mLastDispatchedSmsFingerprint = null;
         }
     }
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 266d127..3e491d1 100755
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -794,5 +794,20 @@
         return mBearerData.numberOfMessages;
     }
 
+    /**
+     * Returns a byte array that can be use to uniquely identify a received SMS message.
+     * C.S0015-B  4.3.1.6 Unique Message Identification.
+     *
+     * @return byte array uniquely identifying the message.
+     * @hide
+     */
+    /* package */ byte[] getIncomingSmsFingerprint() {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
 
+        output.write(mEnvelope.teleService);
+        output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length);
+        output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length);
+
+        return output.toByteArray();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
index 2091fb6..445be39 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
@@ -180,11 +180,6 @@
         return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
     }
 
-    public String
-    toString() {
-        return (isIncoming ? "incoming" : "outgoing");
-    }
-
     public String getAddress() {
         return address;
     }
diff --git a/telephony/tests/TelephonyTest/AndroidManifest.xml b/telephony/tests/TelephonyTest/AndroidManifest.xml
index c0cc0d5..b2a481b 100644
--- a/telephony/tests/TelephonyTest/AndroidManifest.xml
+++ b/telephony/tests/TelephonyTest/AndroidManifest.xml
@@ -28,8 +28,9 @@
             </intent-filter>
         </activity>
     </application>
-     <instrumentation android:name=".TelephonyUnitTestRunner"
-         android:targetPackage="com.android.telephonytest"
-         android:label="Telephony unit tests InstrumentationRunner">
-     </instrumentation>
+    <instrumentation android:name=".TelephonyUnitTestRunner"
+        android:targetPackage="com.android.telephonytest"
+        android:label="Telephony unit tests InstrumentationRunner">
+    </instrumentation>
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 </manifest>
diff --git a/telephony/tests/TelephonyTest/src/com/android/telephonytest/TelephonyUnitTestRunner.java b/telephony/tests/TelephonyTest/src/com/android/telephonytest/TelephonyUnitTestRunner.java
index 5da940d..9e1af31 100644
--- a/telephony/tests/TelephonyTest/src/com/android/telephonytest/TelephonyUnitTestRunner.java
+++ b/telephony/tests/TelephonyTest/src/com/android/telephonytest/TelephonyUnitTestRunner.java
@@ -37,6 +37,7 @@
     public TestSuite getAllTests() {
         TestSuite suite = new InstrumentationTestSuite(this);
         suite.addTestSuite(com.android.telephonytest.unit.CallerInfoUnitTest.class);
+        suite.addTestSuite(com.android.telephonytest.unit.PhoneNumberUtilsUnitTest.class);
         return suite;
     }
 
diff --git a/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/CallerInfoUnitTest.java b/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/CallerInfoUnitTest.java
index 4cd0266..0f24f15 100644
--- a/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/CallerInfoUnitTest.java
+++ b/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/CallerInfoUnitTest.java
@@ -107,6 +107,16 @@
         assertIsValidEmergencyCallerInfo();
     }
 
+    // TODO: Add more tests:
+    /**
+     * Check if the voice mail number cannot be retrieved that the
+     * original phone number is preserved.
+     */
+    /**
+     * Check the markAs* methods work.
+     */
+
+
     //
     // Helpers
     //
diff --git a/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/PhoneNumberUtilsUnitTest.java b/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/PhoneNumberUtilsUnitTest.java
new file mode 100644
index 0000000..2d3c548
--- /dev/null
+++ b/telephony/tests/TelephonyTest/src/com/android/telephonytest/unit/PhoneNumberUtilsUnitTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 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.telephonytest.unit;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+
+/*
+ * Check the PhoneNumberUtils utility class works as expected.
+ *
+ */
+
+public class PhoneNumberUtilsUnitTest extends AndroidTestCase {
+    private String mVoiceMailNumber;
+    private static final String TAG = "PhoneNumberUtilsUnitTest";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // FIXME: Why are we getting a security exception here? The
+        // permission is declared in the manifest....
+        // mVoiceMailNumber = TelephonyManager.getDefault().getVoiceMailNumber();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Basic checks for the VoiceMail number.
+     * Assumes READ_PHONE_STATE permission and we don't have it.
+     */
+    // TODO: Figure out why we don't have the permission declared in the manifest.
+    @SmallTest
+    public void testWithNumberNotEqualToVoiceMail() throws Exception {
+        assertFalse(PhoneNumberUtils.isVoiceMailNumber("911"));
+        assertFalse(PhoneNumberUtils.isVoiceMailNumber("tel:911"));
+        assertFalse(PhoneNumberUtils.isVoiceMailNumber("+18001234567"));
+        assertFalse(PhoneNumberUtils.isVoiceMailNumber(""));
+        assertFalse(PhoneNumberUtils.isVoiceMailNumber(null));
+        // FIXME:
+        // assertTrue(PhoneNumberUtils.isVoiceMailNumber(mVoiceMailNumber));
+    }
+
+}
diff --git a/test-runner/android/test/mock/MockContext.java b/test-runner/android/test/mock/MockContext.java
index 9fb1e61..57b22f8 100644
--- a/test-runner/android/test/mock/MockContext.java
+++ b/test-runner/android/test/mock/MockContext.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.BroadcastReceiver;
+import android.content.IntentSender;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.content.pm.ApplicationInfo;
@@ -228,6 +229,13 @@
     }
 
     @Override
+    public void startIntentSender(IntentSender intent,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            throws IntentSender.SendIntentException {
+        throw new UnsupportedOperationException();
+    }
+    
+    @Override
     public void sendBroadcast(Intent intent) {
         throw new UnsupportedOperationException();
     }
@@ -256,6 +264,13 @@
     }
 
     @Override
+    public void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+           Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public void removeStickyBroadcast(Intent intent) {
         throw new UnsupportedOperationException();
     }
diff --git a/tests/AndroidTests/Android.mk b/tests/AndroidTests/Android.mk
index f5e49d7..ced796a 100644
--- a/tests/AndroidTests/Android.mk
+++ b/tests/AndroidTests/Android.mk
@@ -8,7 +8,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := googlelogin-client
 
 # Resource unit tests use a private locale
-LOCAL_AAPT_FLAGS = -c xx_YY -c cs
+LOCAL_AAPT_FLAGS = -c xx_YY -c cs -c 160dpi -c 32dpi -c 240dpi
 
 LOCAL_SRC_FILES := \
 	$(call all-subdir-java-files) \
diff --git a/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java b/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java
index 0991e8c..853f10a 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java
@@ -204,16 +204,18 @@
         assertEquals("+" + PHONE_NUMBER, number);
         c.close();
     }
-
-
-    private void phoneNumberCompare(String phone1, String phone2, boolean equal)
-        throws Exception {
+    
+    private void phoneNumberCompare(String phone1, String phone2, boolean equal, 
+            boolean useStrictComparation) {
         String[] temporalPhoneNumbers = new String[2];
         temporalPhoneNumbers[0] = phone1;
         temporalPhoneNumbers[1] = phone2;
 
         Cursor cursor = mDatabase.rawQuery(
-                "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END",
+                String.format(
+                        "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?, %d) " +
+                        "THEN 'equal' ELSE 'not equal' END",
+                        (useStrictComparation ? 1 : 0)),
                 temporalPhoneNumbers);
         try {
             assertNotNull(cursor);
@@ -233,11 +235,23 @@
     }
 
     private void assertPhoneNumberEqual(String phone1, String phone2) throws Exception {
-        phoneNumberCompare(phone1, phone2, true);
+        assertPhoneNumberEqual(phone1, phone2, true);
+        assertPhoneNumberEqual(phone1, phone2, false);
+    }
+    
+    private void assertPhoneNumberEqual(String phone1, String phone2, boolean useStrict)
+            throws Exception {
+        phoneNumberCompare(phone1, phone2, true, useStrict);
     }
 
     private void assertPhoneNumberNotEqual(String phone1, String phone2) throws Exception {
-        phoneNumberCompare(phone1, phone2, false);
+        assertPhoneNumberNotEqual(phone1, phone2, true);
+        assertPhoneNumberNotEqual(phone1, phone2, false);
+    }
+    
+    private void assertPhoneNumberNotEqual(String phone1, String phone2, boolean useStrict)
+            throws Exception {
+        phoneNumberCompare(phone1, phone2, false, useStrict);
     }
 
     /**
@@ -252,7 +266,8 @@
         assertPhoneNumberNotEqual("123123", "923123");
         assertPhoneNumberNotEqual("123123", "123129");
         assertPhoneNumberNotEqual("123123", "1231234");
-        assertPhoneNumberNotEqual("123123", "0123123");
+        assertPhoneNumberEqual("123123", "0123123", false);
+        assertPhoneNumberNotEqual("123123", "0123123", true);
         assertPhoneNumberEqual("650-253-0000", "6502530000");
         assertPhoneNumberEqual("650-253-0000", "650 253 0000");
         assertPhoneNumberEqual("650 253 0000", "6502530000");
@@ -291,11 +306,13 @@
         assertPhoneNumberEqual("+593-2-1234-123", "21234123");
 
         // Two continuous 0 at the beginning of the phone string should not be
-        // treated as trunk prefix.
-        assertPhoneNumberNotEqual("008001231234", "8001231234");
+        // treated as trunk prefix in the strict comparation.
+        assertPhoneNumberEqual("008001231234", "8001231234", false);
+        assertPhoneNumberNotEqual("008001231234", "8001231234", true);
 
-        // Confirm that the bug found before does not re-appear.
-        assertPhoneNumberNotEqual("080-1234-5678", "+819012345678");
+        // Confirm that the bug found before does not re-appear in the strict compalation
+        assertPhoneNumberEqual("080-1234-5678", "+819012345678", false);
+        assertPhoneNumberNotEqual("080-1234-5678", "+819012345678", true);
     }
 
     @MediumTest
diff --git a/tests/AndroidTests/src/com/android/unit_tests/os/HandlerThreadTest.java b/tests/AndroidTests/src/com/android/unit_tests/os/HandlerThreadTest.java
index c62f94f..f2025c6 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/os/HandlerThreadTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/os/HandlerThreadTest.java
@@ -36,8 +36,11 @@
     public void testHandlerThread() throws Exception {
         HandlerThread th1 =  new HandlerThread("HandlerThreadTest") {
             protected void onLooperPrepared() {
-                mDidSetup = true;
-                mLooperTid = Process.myTid();
+                synchronized (HandlerThreadTest.this) {
+                    mDidSetup = true;
+                    mLooperTid = Process.myTid();
+                    HandlerThreadTest.this.notify();
+                }
             }
         };
         
@@ -49,14 +52,23 @@
         assertTrue(th1.isAlive());
         assertNotNull(th1.getLooper());
        
-        /* 
-         * Since getLooper() will block until the HandlerThread is setup, we are guaranteed
-         * that mDidSetup and mLooperTid will have been initalized. If they have not, then 
-         * this test should fail
-         */
+        // The call to getLooper() internally blocks until the looper is
+        // available, but will call onLooperPrepared() after that.  So we
+        // need to block here to wait for our onLooperPrepared() to complete
+        // and fill in the values we expect.
+        synchronized (this) {
+            while (!mDidSetup) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+        
+        // Make sure that the process was set.
+        assertNotSame(-1, mLooperTid);
         // Make sure that the onLooperPrepared() was called on a different thread.
         assertNotSame(Process.myTid(), mLooperTid);
-        assertTrue(mDidSetup);
         
         final Handler h1 = new Handler(th1.getLooper()) {
             public void handleMessage(Message msg) {
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
index 8fea967..395e572 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -96,7 +96,9 @@
         // Android layout tests are stored in "layout_tests". The following two
         // tests expect "LayoutTests" in their output.
         "storage/domstorage/localstorage/iframe-events.html",
-        "storage/domstorage/sessionstorage/iframe-events.html"
+        "storage/domstorage/sessionstorage/iframe-events.html",
+        // below tests (failed or crashes) are filtered out temporarily due to prioritizing
+        "editing/selection/move-left-right.html",
     };
     
     static void fillIgnoreResultSet() {
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
index cc2f1f5..85e0422 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
@@ -1,5 +1,23 @@
+/*
+ * Copyright (C) 2009 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.dumprendertree;
 
+import com.android.dumprendertree.forwarder.ForwardService;
+
 import android.util.Log;
 
 import java.io.BufferedOutputStream;
@@ -12,6 +30,12 @@
 public class FsUtils {
 
     private static final String LOGTAG = "FsUtils";
+    static final String HTTP_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/";
+    static final String HTTPS_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/ssl/";
+    static final String HTTP_LOCAL_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/local/";
+    static final String HTTP_MEDIA_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/media/";
+    static final String HTTP_WML_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/wml/";
+
     private FsUtils() {
         //no creation of instances
     }
@@ -77,4 +101,24 @@
         return status;
     }
 
+    public static String getTestUrl(String path) {
+        String url = null;
+        if (!path.startsWith(HTTP_TESTS_PREFIX)) {
+            url = "file://" + path;
+        } else {
+            ForwardService.getForwardService().startForwardService();
+            if (path.startsWith(HTTPS_TESTS_PREFIX)) {
+                // still cut the URL after "http/tests/"
+                url = "https://127.0.0.1:8443/" + path.substring(HTTP_TESTS_PREFIX.length());
+            } else if (!path.startsWith(HTTP_LOCAL_TESTS_PREFIX)
+                    && !path.startsWith(HTTP_MEDIA_TESTS_PREFIX)
+                    && !path.startsWith(HTTP_WML_TESTS_PREFIX)) {
+                url = "http://127.0.0.1:8000/" + path.substring(HTTP_TESTS_PREFIX.length());
+            } else {
+                url = "file://" + path;
+            }
+        }
+        return url;
+    }
+
 }
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
index e4c8716..235e10e 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
@@ -19,6 +19,7 @@
 import com.android.dumprendertree.TestShellActivity.DumpDataType;
 import com.android.dumprendertree.forwarder.AdbUtils;
 import com.android.dumprendertree.forwarder.ForwardServer;
+import com.android.dumprendertree.forwarder.ForwardService;
 
 import android.app.Instrumentation;
 import android.content.Intent;
@@ -143,17 +144,6 @@
     static final String LAYOUT_RESULTS_CRASHED_RESULT_FILE = "results/layout_tests_crashed.txt";
     static final String LAYOUT_TESTS_RUNNER = "run_layout_tests.py";
 
-    static final String HTTP_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/";
-    static final String HTTPS_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/ssl/";
-    static final String HTTP_LOCAL_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/local/";
-    static final String HTTP_MEDIA_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/media/";
-    static final String HTTP_WML_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/wml/";
-
-
-    static final String DEFAULT_TEST_HOST = "android-browser-test.mtv.corp.google.com";
-    static final String FORWARD_HOST_CONF = "/sdcard/drt_forward_host.txt";
-    private ForwardServer fs8000, fs8080, fs8443;
-
     private MyTestRecorder mResultRecorder;
     private Vector<String> mTestList;
     private boolean mRebaselineResults;
@@ -162,45 +152,6 @@
 
     public LayoutTestsAutoTest() {
       super("com.android.dumprendertree", TestShellActivity.class);
-
-      int addr = getForwardHostAddr();
-      if(addr != -1) {
-          fs8000 = new ForwardServer(8000, addr, 8000);
-          fs8080 = new ForwardServer(8080, addr, 8080);
-          fs8443 = new ForwardServer(8443, addr, 8443);
-      }
-    }
-
-    private int getForwardHostAddr() {
-        int addr = -1;
-        String host = null;
-        File forwardHostConf = new File(FORWARD_HOST_CONF);
-        if (forwardHostConf.isFile()) {
-            BufferedReader hostReader = null;
-            try {
-                hostReader = new BufferedReader(new FileReader(forwardHostConf));
-                host = hostReader.readLine();
-                Log.v(LOGTAG, "read forward host from file: " + host);
-            } catch (IOException ioe) {
-                Log.v(LOGTAG, "cannot read forward host from file", ioe);
-            } finally {
-                if (hostReader != null) {
-                    try {
-                        hostReader.close();
-                    } catch (IOException ioe) {
-                        // burn!!!
-                    }
-                }
-            }
-        }
-        if (host == null || host.length() == 0)
-            host = DEFAULT_TEST_HOST;
-        try {
-            addr = AdbUtils.resolve(host);
-        } catch (IOException ioe) {
-            Log.e(LOGTAG, "failed to resolve server address", ioe);
-        }
-        return addr;
     }
 
     // This function writes the result of the layout test to
@@ -366,7 +317,7 @@
         Intent intent = new Intent(Intent.ACTION_VIEW);
         intent.setClass(activity, TestShellActivity.class);
         intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        intent.putExtra(TestShellActivity.TEST_URL, getTestUrl(test));
+        intent.putExtra(TestShellActivity.TEST_URL, FsUtils.getTestUrl(test));
         intent.putExtra(TestShellActivity.RESULT_FILE, resultFile);
         intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout);
         activity.startActivity(intent);
@@ -450,49 +401,10 @@
         }
 
         FsUtils.updateTestStatus(TEST_STATUS_FILE, "#DONE");
-        if(fs8000 != null)
-            fs8000.stop();
-        if(fs8080 != null)
-            fs8080.stop();
-        if(fs8443 != null)
-            fs8443.stop();
-
+        ForwardService.getForwardService().stopForwardService();
         activity.finish();
     }
 
-    private void startForwardServerIfNeeded() {
-        try {
-            if(fs8000 != null)
-                fs8000.start();
-            if(fs8080 != null)
-                fs8080.start();
-            if(fs8443 != null)
-                fs8443.start();
-        } catch (IOException ioe) {
-            Log.w(LOGTAG, "failed to start forwarder. http tests will fail.", ioe);
-        }
-    }
-
-    private String getTestUrl(String path) {
-        String url = null;
-        if (!path.startsWith(HTTP_TESTS_PREFIX)) {
-            url = "file://" + path;
-        } else {
-            startForwardServerIfNeeded();
-            if (path.startsWith(HTTPS_TESTS_PREFIX)) {
-                // still cut the URL after "http/tests/"
-                url = "https://127.0.0.1:8443/" + path.substring(HTTP_TESTS_PREFIX.length());
-            } else if (!path.startsWith(HTTP_LOCAL_TESTS_PREFIX)
-                    && !path.startsWith(HTTP_MEDIA_TESTS_PREFIX)
-                    && !path.startsWith(HTTP_WML_TESTS_PREFIX)) {
-                url = "http://127.0.0.1:8000/" + path.substring(HTTP_TESTS_PREFIX.length());
-            } else {
-                url = "file://" + path;
-            }
-        }
-        return url;
-    }
-
     private String getTestPath() {
         LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();
 
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
index 71d9758..50b7c3f 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2009 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.dumprendertree;
 
 import android.app.Activity;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
index 995c129..fbce78a 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2009 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.dumprendertree;
 
 import android.app.Activity;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index 663df83..3fef61c 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.dumprendertree;
 
+import com.android.dumprendertree.forwarder.ForwardService;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.Context;
@@ -184,6 +186,7 @@
         } catch (IOException ioe) {
             Log.w(LOGTAG, "Failed to close test list file.", ioe);
         }
+        ForwardService.getForwardService().stopForwardService();
         finished();
     }
 
@@ -215,10 +218,9 @@
             builder.create().show();
             return;
         }
-        url = "file://" + url;
         Intent intent = new Intent(Intent.ACTION_VIEW);
         intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        intent.putExtra(TestShellActivity.TEST_URL, url);
+        intent.putExtra(TestShellActivity.TEST_URL, FsUtils.getTestUrl(url));
         intent.putExtra(TIMEOUT_IN_MILLIS, 10000);
         executeIntent(intent);
     }
@@ -289,13 +291,20 @@
     }
 
     public void finished() {
-        if (mUiAutoTestPath != null) {
-            //don't really finish here
-            moveToNextTest();
-        } else {
-            if (mCallback != null) {
-                mCallback.finished();
+        if (mTestPageLoaded) {
+            if (mUiAutoTestPath != null) {
+                //don't really finish here
+                moveToNextTest();
+            } else {
+                if (mCallback != null) {
+                    mCallback.finished();
+                }
             }
+        } else {
+            // The test is complete but the page has not completed loading. We
+            // can't continue to the next test until both the test is finished
+            // and the page has stopped loading.
+            mReadyForNextTest = true;
         }
     }
 
@@ -443,12 +452,14 @@
         @Override
         public void onPageFinished(WebView view, String url) {
             Log.v(LOGTAG, "onPageFinished, url=" + url);
+            mTestPageLoaded = true;
             super.onPageFinished(view, url);
         }
 
         @Override
         public void onPageStarted(WebView view, String url, Bitmap favicon) {
             Log.v(LOGTAG, "onPageStarted, url=" + url);
+            mTestPageLoaded = false;
             super.onPageStarted(view, url, favicon);
         }
 
@@ -478,6 +489,17 @@
         @Override
         public void onProgressChanged(WebView view, int newProgress) {
             if (newProgress == 100) {
+
+                if (mReadyForNextTest) {
+                    // In this case, the test has completed (i.e. called
+                    // layoutTestController.notifyDone) before the page finished loading. This
+                    // usually happens if the test is not invoked by an onload handler, rather
+                    // directly in a script tag. Now that the page has finished loading, it is
+                    // safe for DRT to go to the next test.
+                    finished();
+                    return;
+                }
+
                 if (!mTimedOut && !mWaitUntilDone && !mRequestedWebKitData) {
                     String url = mWebView.getUrl();
                     Log.v(LOGTAG, "Finished: "+ url);
@@ -653,6 +675,8 @@
         mDumpDatabaseCallbacks = false;
         mCanOpenWindows = false;
         mEventSender.resetMouse();
+        mTestPageLoaded = false;
+        mReadyForNextTest = false;
     }
 
     private void setupWebViewForLayoutTests(WebView webview, CallbackProxy callbackProxy) {
@@ -709,6 +733,9 @@
     private StringBuffer mConsoleMessages;
     private boolean mCanOpenWindows;
 
+    private boolean mTestPageLoaded = false;
+    private boolean mReadyForNextTest = false;
+
     static final String TIMEOUT_STR = "**Test timeout";
 
     static final int MSG_TIMEOUT = 0;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/AdbUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/AdbUtils.java
index 9a3e9c2..c2ecf3a 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/AdbUtils.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/AdbUtils.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2009 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.dumprendertree.forwarder;
 
 import android.util.Log;
@@ -44,7 +60,6 @@
         DataInputStream dis = new DataInputStream(localSocket.getInputStream());
         OutputStream os = localSocket.getOutputStream();
         int count_read = 0;
-        byte[] buf = new byte[128];
 
         if (localSocket == null || dis == null || os == null)
             return -1;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardServer.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardServer.java
index 74e018e..14f8fbe 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardServer.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardServer.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2009 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.dumprendertree.forwarder;
 
 import android.util.Log;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
new file mode 100644
index 0000000..8b7de6e
--- /dev/null
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2009 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.dumprendertree.forwarder;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import android.util.Log;
+
+public class ForwardService {
+
+    private ForwardServer fs8000, fs8080, fs8443;
+
+    private static ForwardService inst;
+
+    private static final String LOGTAG = "ForwardService";
+
+    private static final String DEFAULT_TEST_HOST = "android-browser-test.mtv.corp.google.com";
+
+    private static final String FORWARD_HOST_CONF = "/sdcard/drt_forward_host.txt";
+
+    private ForwardService() {
+        int addr = getForwardHostAddr();
+        if (addr != -1) {
+            fs8000 = new ForwardServer(8000, addr, 8000);
+            fs8080 = new ForwardServer(8080, addr, 8080);
+            fs8443 = new ForwardServer(8443, addr, 8443);
+        }
+    }
+
+    public static ForwardService getForwardService() {
+        if (inst == null) {
+            inst = new ForwardService();
+        }
+        return inst;
+    }
+
+    public void startForwardService() {
+        try {
+            if (fs8000 != null)
+                fs8000.start();
+            if (fs8080 != null)
+                fs8080.start();
+            if (fs8443 != null)
+                fs8443.start();
+        } catch (IOException ioe) {
+            Log.w(LOGTAG, "failed to start forwarder. http tests will fail.", ioe);
+            return;
+        }
+    }
+
+    public void stopForwardService() {
+        if (fs8000 != null) {
+            fs8000.stop();
+            fs8000 = null;
+        }
+        if (fs8080 != null) {
+            fs8080.stop();
+            fs8080 = null;
+        }
+        if (fs8443 != null) {
+            fs8443.stop();
+            fs8443 = null;
+        }
+        Log.v(LOGTAG, "forwarders stopped.");
+    }
+
+    private static int getForwardHostAddr() {
+        int addr = -1;
+        String host = null;
+        File forwardHostConf = new File(FORWARD_HOST_CONF);
+        if (forwardHostConf.isFile()) {
+            BufferedReader hostReader = null;
+            try {
+                hostReader = new BufferedReader(new FileReader(forwardHostConf));
+                host = hostReader.readLine();
+                Log.v(LOGTAG, "read forward host from file: " + host);
+            } catch (IOException ioe) {
+                Log.v(LOGTAG, "cannot read forward host from file", ioe);
+            } finally {
+                if (hostReader != null) {
+                    try {
+                        hostReader.close();
+                    } catch (IOException ioe) {
+                        // burn!!!
+                    }
+                }
+            }
+        }
+        if (host == null || host.length() == 0)
+            host = DEFAULT_TEST_HOST;
+        try {
+            addr = AdbUtils.resolve(host);
+        } catch (IOException ioe) {
+            Log.e(LOGTAG, "failed to resolve server address", ioe);
+        }
+        return addr;
+    }
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/Forwarder.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/Forwarder.java
index e1e04a7..a1f3cdf 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/Forwarder.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/Forwarder.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2009 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.dumprendertree.forwarder;
 
 import android.util.Log;
diff --git a/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java b/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java
index dc959f5..aea124b 100644
--- a/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java
+++ b/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java
@@ -29,7 +29,6 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.Set;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -145,7 +144,7 @@
                 public Cursor query(Uri uri, String[] projection, String selection,
                         String[] selectionArgs, String sortOrder) {
                     // Return cursor over specific set of values
-                    return getCursor(sTestValues1);
+                    return getCursor(sTestValues1, 1);
                 }
             }, null, 0);
         } catch (OperationApplicationException e) {
@@ -153,11 +152,62 @@
         }
     }
 
+    public void testAssertNoValues() {
+        // Build an operation to assert values match provider
+        ContentProviderOperation op1 = ContentProviderOperation.newAssertQuery(sTestUri1)
+                .withExpectedCount(1).build();
+
+        try {
+            // Assert that values match from cursor
+            ContentProviderResult result = op1.apply(new TestContentProvider() {
+                public Cursor query(Uri uri, String[] projection, String selection,
+                        String[] selectionArgs, String sortOrder) {
+                    // Return cursor over specific set of values
+                    return getCursor(sTestValues1, 1);
+                }
+            }, null, 0);
+        } catch (OperationApplicationException e) {
+            fail("newAssert() failed");
+        }
+
+        ContentProviderOperation op2 = ContentProviderOperation.newAssertQuery(sTestUri1)
+                .withExpectedCount(0).build();
+
+        try {
+            // Assert that values match from cursor
+            ContentProviderResult result = op2.apply(new TestContentProvider() {
+                public Cursor query(Uri uri, String[] projection, String selection,
+                        String[] selectionArgs, String sortOrder) {
+                    // Return cursor over specific set of values
+                    return getCursor(sTestValues1, 0);
+                }
+            }, null, 0);
+        } catch (OperationApplicationException e) {
+            fail("newAssert() failed");
+        }
+
+        ContentProviderOperation op3 = ContentProviderOperation.newAssertQuery(sTestUri1)
+                .withExpectedCount(2).build();
+
+        try {
+            // Assert that values match from cursor
+            ContentProviderResult result = op3.apply(new TestContentProvider() {
+                public Cursor query(Uri uri, String[] projection, String selection,
+                        String[] selectionArgs, String sortOrder) {
+                    // Return cursor over specific set of values
+                    return getCursor(sTestValues1, 5);
+                }
+            }, null, 0);
+            fail("we expect the exception to be thrown");
+        } catch (OperationApplicationException e) {
+        }
+    }
+
     /**
      * Build a {@link Cursor} with a single row that contains all values
      * provided through the given {@link ContentValues}.
      */
-    private Cursor getCursor(ContentValues contentValues) {
+    private Cursor getCursor(ContentValues contentValues, int numRows) {
         final Set<Entry<String, Object>> valueSet = contentValues.valueSet();
         final String[] keys = new String[valueSet.size()];
         final Object[] values = new Object[valueSet.size()];
@@ -170,7 +220,9 @@
         }
 
         final MatrixCursor cursor = new MatrixCursor(keys);
-        cursor.addRow(values);
+        for (i = 0; i < numRows; i++) {
+            cursor.addRow(values);
+        }
         return cursor;
     }
 
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index f2cdf75..4742341 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -712,7 +712,8 @@
                                 LARGE_SCREEN_ATTR, NULL, 1);
                     } else if (tag == "uses-feature") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (error == "") {
+
+                        if (name != "" && error == "") {
                             int req = getIntegerAttribute(tree,
                                     REQUIRED_ATTR, NULL, 1);
                             if (name == "android.hardware.camera") {
@@ -729,7 +730,7 @@
                         }
                     } else if (tag == "uses-permission") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (error == "") {
+                        if (name != "" && error == "") {
                             if (name == "android.permission.CAMERA") {
                                 hasCameraPermission = true;
                             }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
index f48c8db..1e9f573 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.IntentSender;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.content.pm.ApplicationInfo;
@@ -1098,6 +1099,13 @@
     }
 
     @Override
+    public void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+           Bundle initialExtras) {
+        // TODO Auto-generated method stub
+    }
+    
+    @Override
     public void setTheme(int arg0) {
         // TODO Auto-generated method stub
 
@@ -1124,6 +1132,13 @@
     }
 
     @Override
+    public void startIntentSender(IntentSender intent,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            throws IntentSender.SendIntentException {
+        // TODO Auto-generated method stub
+    }
+    
+    @Override
     public boolean startInstrumentation(ComponentName arg0, String arg1,
             Bundle arg2) {
         // TODO Auto-generated method stub
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 9a11404..e3d8bf4 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -1350,7 +1350,7 @@
      */
     private synchronized void requestPolledInfo(WifiInfo info, boolean polling)
     {
-        int newRssi = WifiNative.getRssiCommand();
+        int newRssi = (polling ? WifiNative.getRssiApproxCommand() : WifiNative.getRssiCommand());
         if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
             /* some implementations avoid negative values by adding 256
              * so we need to adjust for that here.