Merge "fix functor flag parsing, tweak process delay"
diff --git a/Android.mk b/Android.mk
index f65f9e4..d27dbab 100644
--- a/Android.mk
+++ b/Android.mk
@@ -110,6 +110,7 @@
 	core/java/android/content/pm/IPackageStatsObserver.aidl \
 	core/java/android/database/IContentObserver.aidl \
 	core/java/android/hardware/ISerialManager.aidl \
+	core/java/android/hardware/input/IInputManager.aidl \
 	core/java/android/hardware/usb/IUsbManager.aidl \
 	core/java/android/net/IConnectivityManager.aidl \
 	core/java/android/net/INetworkManagementEventObserver.aidl \
@@ -171,6 +172,7 @@
 	core/java/com/android/internal/view/IInputMethodClient.aidl \
 	core/java/com/android/internal/view/IInputMethodManager.aidl \
 	core/java/com/android/internal/view/IInputMethodSession.aidl \
+	core/java/com/android/internal/widget/ILockSettings.aidl \
 	core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \
 	core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \
 	keystore/java/android/security/IKeyChainAliasCallback.aidl \
diff --git a/api/current.txt b/api/current.txt
index 9186952..e6a01a8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -80,7 +80,7 @@
     field public static final java.lang.String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
     field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
     field public static final java.lang.String READ_HISTORY_BOOKMARKS = "com.android.browser.permission.READ_HISTORY_BOOKMARKS";
-    field public static final java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
+    field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
     field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
     field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
     field public static final java.lang.String READ_PROFILE = "android.permission.READ_PROFILE";
@@ -570,6 +570,7 @@
     field public static final int itemIconDisabledAlpha = 16843057; // 0x1010131
     field public static final int itemPadding = 16843565; // 0x101032d
     field public static final int itemTextAppearance = 16843052; // 0x101012c
+    field public static final int kcm = 16843696; // 0x10103b0
     field public static final int keepScreenOn = 16843286; // 0x1010216
     field public static final int key = 16843240; // 0x10101e8
     field public static final int keyBackground = 16843315; // 0x1010233
@@ -727,6 +728,7 @@
     field public static final int panelColorForeground = 16842848; // 0x1010060
     field public static final int panelFullBackground = 16842847; // 0x101005f
     field public static final int panelTextAppearance = 16842850; // 0x1010062
+    field public static final int parentActivityName = 16843697; // 0x10103b1
     field public static final deprecated int password = 16843100; // 0x101015c
     field public static final int path = 16842794; // 0x101002a
     field public static final int pathPattern = 16842796; // 0x101002c
@@ -932,6 +934,7 @@
     field public static final int summaryOff = 16843248; // 0x10101f0
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsRtl = 16843688; // 0x10103a8
+    field public static final int supportsSentenceSpellCheck = 16843698; // 0x10103b2
     field public static final int supportsUploading = 16843419; // 0x101029b
     field public static final int switchMinWidth = 16843632; // 0x1010370
     field public static final int switchPadding = 16843633; // 0x1010371
@@ -2578,6 +2581,7 @@
     method public java.lang.String getLocalClassName();
     method public android.view.MenuInflater getMenuInflater();
     method public final android.app.Activity getParent();
+    method public android.content.Intent getParentActivityIntent();
     method public android.content.SharedPreferences getPreferences(int);
     method public int getRequestedOrientation();
     method public int getTaskId();
@@ -2594,6 +2598,8 @@
     method public boolean isTaskRoot();
     method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public boolean moveTaskToBack(boolean);
+    method public boolean navigateUpTo(android.content.Intent);
+    method public boolean navigateUpToFromChild(android.app.Activity, android.content.Intent);
     method public void onActionModeFinished(android.view.ActionMode);
     method public void onActionModeStarted(android.view.ActionMode);
     method protected void onActivityResult(int, int, android.content.Intent);
@@ -2610,6 +2616,7 @@
     method public java.lang.CharSequence onCreateDescription();
     method protected deprecated android.app.Dialog onCreateDialog(int);
     method protected deprecated android.app.Dialog onCreateDialog(int, android.os.Bundle);
+    method public void onCreateNavigateUpTaskStack(android.app.TaskStackBuilder);
     method public boolean onCreateOptionsMenu(android.view.Menu);
     method public boolean onCreatePanelMenu(int, android.view.Menu);
     method public android.view.View onCreatePanelView(int);
@@ -2627,6 +2634,8 @@
     method public void onLowMemory();
     method public boolean onMenuItemSelected(int, android.view.MenuItem);
     method public boolean onMenuOpened(int, android.view.Menu);
+    method public boolean onNavigateUp();
+    method public boolean onNavigateUpFromChild(android.app.Activity);
     method protected void onNewIntent(android.content.Intent);
     method public boolean onOptionsItemSelected(android.view.MenuItem);
     method public void onOptionsMenuClosed(android.view.Menu);
@@ -2636,6 +2645,7 @@
     method protected void onPostResume();
     method protected deprecated void onPrepareDialog(int, android.app.Dialog);
     method protected deprecated void onPrepareDialog(int, android.app.Dialog, android.os.Bundle);
+    method public void onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder);
     method public boolean onPrepareOptionsMenu(android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
     method protected void onRestart();
@@ -2686,6 +2696,7 @@
     method public void setTitleColor(int);
     method public void setVisible(boolean);
     method public final void setVolumeControlStream(int);
+    method public boolean shouldUpRecreateTask(android.content.Intent);
     method public final deprecated void showDialog(int);
     method public final deprecated boolean showDialog(int, android.os.Bundle);
     method public android.view.ActionMode startActionMode(android.view.ActionMode.Callback);
@@ -3932,6 +3943,18 @@
     method public void setDefaultTab(int);
   }
 
+  public class TaskStackBuilder implements java.lang.Iterable {
+    method public android.app.TaskStackBuilder addNextIntent(android.content.Intent);
+    method public android.app.TaskStackBuilder addParentStack(android.app.Activity);
+    method public android.app.TaskStackBuilder addParentStack(java.lang.Class<?>);
+    method public static android.app.TaskStackBuilder from(android.content.Context);
+    method public android.content.Intent getIntent(int);
+    method public int getIntentCount();
+    method public android.app.PendingIntent getPendingIntent(int, int);
+    method public java.util.Iterator<android.content.Intent> iterator();
+    method public void startActivities();
+  }
+
   public class TimePickerDialog extends android.app.AlertDialog implements android.content.DialogInterface.OnClickListener android.widget.TimePicker.OnTimeChangedListener {
     ctor public TimePickerDialog(android.content.Context, android.app.TimePickerDialog.OnTimeSetListener, int, int, boolean);
     ctor public TimePickerDialog(android.content.Context, int, android.app.TimePickerDialog.OnTimeSetListener, int, int, boolean);
@@ -5211,6 +5234,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
+    field public static final java.lang.String INPUT_SERVICE = "input";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";
     field public static final java.lang.String LOCATION_SERVICE = "location";
@@ -6102,6 +6126,7 @@
     field public int configChanges;
     field public int flags;
     field public int launchMode;
+    field public java.lang.String parentActivityName;
     field public java.lang.String permission;
     field public int screenOrientation;
     field public int softInputMode;
@@ -9795,6 +9820,15 @@
 
 }
 
+package android.hardware.input {
+
+  public final class InputManager {
+    field public static final java.lang.String ACTION_QUERY_KEYBOARD_LAYOUTS = "android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS";
+    field public static final java.lang.String META_DATA_KEYBOARD_LAYOUTS = "android.hardware.input.metadata.KEYBOARD_LAYOUTS";
+  }
+
+}
+
 package android.hardware.usb {
 
   public class UsbAccessory implements android.os.Parcelable {
@@ -22225,6 +22259,7 @@
 
   public final class InputDevice implements android.os.Parcelable {
     method public int describeContents();
+    method public java.lang.String getDescriptor();
     method public static android.view.InputDevice getDevice(int);
     method public static int[] getDeviceIds();
     method public int getId();
@@ -24148,15 +24183,18 @@
   }
 
   public final class ViewTreeObserver {
+    method public void addOnDrawListener(android.view.ViewTreeObserver.OnDrawListener);
     method public void addOnGlobalFocusChangeListener(android.view.ViewTreeObserver.OnGlobalFocusChangeListener);
     method public void addOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener);
     method public void addOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener);
     method public void addOnScrollChangedListener(android.view.ViewTreeObserver.OnScrollChangedListener);
     method public void addOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener);
+    method public final void dispatchOnDraw();
     method public final void dispatchOnGlobalLayout();
     method public final boolean dispatchOnPreDraw();
     method public boolean isAlive();
     method public deprecated void removeGlobalOnLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener);
+    method public void removeOnDrawListener(android.view.ViewTreeObserver.OnDrawListener);
     method public void removeOnGlobalFocusChangeListener(android.view.ViewTreeObserver.OnGlobalFocusChangeListener);
     method public void removeOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener);
     method public void removeOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener);
@@ -24164,6 +24202,10 @@
     method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener);
   }
 
+  public static abstract interface ViewTreeObserver.OnDrawListener {
+    method public abstract void onDraw();
+  }
+
   public static abstract interface ViewTreeObserver.OnGlobalFocusChangeListener {
     method public abstract void onGlobalFocusChanged(android.view.View, android.view.View);
   }
@@ -25239,11 +25281,13 @@
     method public android.view.textservice.SpellCheckerInfo getSpellChecker();
     method public void getSuggestions(android.view.textservice.TextInfo, int);
     method public void getSuggestions(android.view.textservice.TextInfo[], int, boolean);
+    method public boolean isSentenceSpellCheckSupported();
     method public boolean isSessionDisconnected();
     field public static final java.lang.String SERVICE_META_DATA = "android.view.textservice.scs";
   }
 
   public static abstract interface SpellCheckerSession.SpellCheckerSessionListener {
+    method public abstract void onGetSentenceSuggestions(android.view.textservice.SentenceSuggestionsInfo[]);
     method public abstract void onGetSuggestions(android.view.textservice.SuggestionsInfo[]);
   }
 
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index 2391b72..b39c335 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -13,3 +13,29 @@
 LOCAL_MODULE:= app_process
 
 include $(BUILD_EXECUTABLE)
+
+
+# Build a variant of app_process binary linked with ASan runtime.
+# ARM-only at the moment.
+ifeq ($(TARGET_ARCH),arm)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	app_main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+	libandroid_runtime
+
+LOCAL_MODULE := app_process__asan
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)/asan
+LOCAL_MODULE_STEM := app_process
+LOCAL_ADDRESS_SANITIZER := true
+
+include $(BUILD_EXECUTABLE)
+
+endif # ifeq($(TARGET_ARCH),arm)
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index c4c3b8a..3037881 100755
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -16,11 +16,12 @@
 
 package com.android.commands.input;
 
+import android.hardware.input.InputManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.util.Log;
-import android.view.IWindowManager;
+import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -33,8 +34,6 @@
 public class Input {
     private static final String TAG = "Input";
 
-    private IWindowManager mWindowManager;
-
     /**
      * Command-line entry point.
      *
@@ -44,13 +43,6 @@
         (new Input()).run(args);
     }
 
-    private IWindowManager getWindowManager() {
-        if (mWindowManager == null) {
-            mWindowManager = (IWindowManager.Stub.asInterface(ServiceManager.getService("window")));
-        }
-        return mWindowManager;
-    }
-
     private void run(String[] args) {
         if (args.length < 1) {
             showUsage();
@@ -127,8 +119,10 @@
 
     private void sendKeyEvent(int keyCode) {
         long now = SystemClock.uptimeMillis();
-        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0));
-        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0));
+        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
+                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
+        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0, 0,
+                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
     }
 
     private void sendTap(float x, float y) {
@@ -150,23 +144,14 @@
     }
 
     private void injectKeyEvent(KeyEvent event) {
-        try {
-            Log.i(TAG, "InjectKeyEvent: " + event);
-            getWindowManager().injectKeyEvent(event, true);
-        } catch (RemoteException ex) {
-            Log.i(TAG, "RemoteException", ex);
-        }
+        Log.i(TAG, "InjectKeyEvent: " + event);
+        InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
     }
 
     private void injectPointerEvent(MotionEvent event) {
-        try {
-            Log.i("Input", "InjectPointerEvent: " + event);
-            getWindowManager().injectPointerEvent(event, true);
-        } catch (RemoteException ex) {
-            Log.i(TAG, "RemoteException", ex);
-        } finally {
-            event.recycle();
-        }
+        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        Log.i("Input", "InjectPointerEvent: " + event);
+        InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
     }
 
     private static final float lerp(float a, float b, float alpha) {
@@ -174,7 +159,7 @@
     }
 
     private void showUsage() {
-        System.err.println("usage: input [text|keyevent]");
+        System.err.println("usage: input ...");
         System.err.println("       input text <string>");
         System.err.println("       input keyevent <key code>");
         System.err.println("       input tap <x> <y>");
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b277efb..3e123ba 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -29,6 +29,8 @@
 import android.content.IntentSender;
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -65,13 +67,13 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.WindowManagerImpl;
 import android.view.View.OnCreateContextMenuListener;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewManager;
 import android.view.Window;
 import android.view.WindowManager;
+import android.view.WindowManagerImpl;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.AdapterView;
 
@@ -704,6 +706,7 @@
     /*package*/ boolean mVisibleFromServer = false;
     /*package*/ boolean mVisibleFromClient = true;
     /*package*/ ActionBarImpl mActionBar = null;
+    private boolean mEnableDefaultActionBarUp;
 
     private CharSequence mTitle;
     private int mTitleColor = 0;
@@ -865,6 +868,13 @@
         if (mLastNonConfigurationInstances != null) {
             mAllLoaderManagers = mLastNonConfigurationInstances.loaders;
         }
+        if (mActivityInfo.parentActivityName != null) {
+            if (mActionBar == null) {
+                mEnableDefaultActionBarUp = true;
+            } else {
+                mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
+            }
+        }
         if (savedInstanceState != null) {
             Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
             mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
@@ -1829,6 +1839,7 @@
         }
         
         mActionBar = new ActionBarImpl(this);
+        mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
     }
     
     /**
@@ -2630,7 +2641,7 @@
      * facilities.
      * 
      * <p>Derived classes should call through to the base class for it to
-     * perform the default menu handling.
+     * perform the default menu handling.</p>
      * 
      * @param item The menu item that was selected.
      * 
@@ -2643,10 +2654,105 @@
         if (mParent != null) {
             return mParent.onOptionsItemSelected(item);
         }
+        if (item.getItemId() == android.R.id.home && mActionBar != null &&
+                (mActionBar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+            if (mParent == null) {
+                onNavigateUp();
+            } else {
+                mParent.onNavigateUpFromChild(this);
+            }
+            return true;
+        }
         return false;
     }
 
     /**
+     * This method is called whenever the user chooses to navigate Up within your application's
+     * activity hierarchy from the action bar.
+     *
+     * <p>If the attribute {@link android.R.attr#parentActivityName parentActivityName}
+     * was specified in the manifest for this activity or an activity-alias to it,
+     * default Up navigation will be handled automatically. If any activity
+     * along the parent chain requires extra Intent arguments, the Activity subclass
+     * should override the method {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)}
+     * to supply those arguments.</p>
+     *
+     * <p>See <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
+     * from the developer guide and <a href="{@docRoot}design/patterns/navigation.html">Navigation</a>
+     * from the design guide for more information about navigating within your app.</p>
+     *
+     * <p>See the {@link TaskStackBuilder} class and the Activity methods
+     * {@link #getParentActivityIntent()}, {@link #shouldUpRecreateTask(Intent)}, and
+     * {@link #navigateUpTo(Intent)} for help implementing custom Up navigation.
+     * The AppNavigation sample application in the Android SDK is also available for reference.</p>
+     *
+     * @return true if Up navigation completed successfully and this Activity was finished,
+     *         false otherwise.
+     */
+    public boolean onNavigateUp() {
+        // Automatically handle hierarchical Up navigation if the proper
+        // metadata is available.
+        Intent upIntent = getParentActivityIntent();
+        if (upIntent != null) {
+            if (shouldUpRecreateTask(upIntent)) {
+                TaskStackBuilder b = TaskStackBuilder.from(this);
+                onCreateNavigateUpTaskStack(b);
+                onPrepareNavigateUpTaskStack(b);
+                b.startActivities();
+                finish();
+            } else {
+                navigateUpTo(upIntent);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * This is called when a child activity of this one attempts to navigate up.
+     * The default implementation simply calls onNavigateUp() on this activity (the parent).
+     *
+     * @param child The activity making the call.
+     */
+    public boolean onNavigateUpFromChild(Activity child) {
+        return onNavigateUp();
+    }
+
+    /**
+     * Define the synthetic task stack that will be generated during Up navigation from
+     * a different task.
+     *
+     * <p>The default implementation of this method adds the parent chain of this activity
+     * as specified in the manifest to the supplied {@link TaskStackBuilder}. Applications
+     * may choose to override this method to construct the desired task stack in a different
+     * way.</p>
+     *
+     * <p>Applications that wish to supply extra Intent parameters to the parent stack defined
+     * by the manifest should override {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)}.</p>
+     *
+     * @param builder An empty TaskStackBuilder - the application should add intents representing
+     *                the desired task stack
+     */
+    public void onCreateNavigateUpTaskStack(TaskStackBuilder builder) {
+        builder.addParentStack(this);
+    }
+
+    /**
+     * Prepare the synthetic task stack that will be generated during Up navigation
+     * from a different task.
+     *
+     * <p>This method receives the {@link TaskStackBuilder} with the constructed series of
+     * Intents as generated by {@link #onCreateNavigateUpTaskStack(TaskStackBuilder)}.
+     * If any extra data should be added to these intents before launching the new task,
+     * the application should override this method and add that data here.</p>
+     *
+     * @param builder A TaskStackBuilder that has been populated with Intents by
+     *                onCreateNavigateUpTaskStack.
+     */
+    public void onPrepareNavigateUpTaskStack(TaskStackBuilder builder) {
+    }
+
+    /**
      * This hook is called whenever the options menu is being closed (either by the user canceling
      * the menu with the back/menu button, or when an item is selected).
      *  
@@ -4658,6 +4764,114 @@
     public void onActionModeFinished(ActionMode mode) {
     }
 
+    /**
+     * Returns true if the app should recreate the task when navigating 'up' from this activity
+     * by using targetIntent.
+     *
+     * <p>If this method returns false the app can trivially call
+     * {@link #navigateUpTo(Intent)} using the same parameters to correctly perform
+     * up navigation. If this method returns false, the app should synthesize a new task stack
+     * by using {@link TaskStackBuilder} or another similar mechanism to perform up navigation.</p>
+     *
+     * @param targetIntent An intent representing the target destination for up navigation
+     * @return true if navigating up should recreate a new task stack, false if the same task
+     *         should be used for the destination
+     */
+    public boolean shouldUpRecreateTask(Intent targetIntent) {
+        try {
+            PackageManager pm = getPackageManager();
+            ComponentName cn = targetIntent.getComponent();
+            if (cn == null) {
+                cn = targetIntent.resolveActivity(pm);
+            }
+            ActivityInfo info = pm.getActivityInfo(cn, 0);
+            if (info.taskAffinity == null) {
+                return false;
+            }
+            return !ActivityManagerNative.getDefault()
+                    .targetTaskAffinityMatchesActivity(mToken, info.taskAffinity);
+        } catch (RemoteException e) {
+            return false;
+        } catch (NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Navigate from this activity to the activity specified by upIntent, finishing this activity
+     * in the process. If the activity indicated by upIntent already exists in the task's history,
+     * this activity and all others before the indicated activity in the history stack will be
+     * finished. If the indicated activity does not appear in the history stack, this is equivalent
+     * to simply calling finish() on this activity.
+     *
+     * <p>This method should be used when performing up navigation from within the same task
+     * as the destination. If up navigation should cross tasks in some cases, see
+     * {@link #shouldUpRecreateTask(Intent)}.</p>
+     *
+     * @param upIntent An intent representing the target destination for up navigation
+     *
+     * @return true if up navigation successfully reached the activity indicated by upIntent and
+     *         upIntent was delivered to it. false if an instance of the indicated activity could
+     *         not be found and this activity was simply finished normally.
+     */
+    public boolean navigateUpTo(Intent upIntent) {
+        if (mParent == null) {
+            ComponentName destInfo = upIntent.getComponent();
+            if (destInfo == null) {
+                destInfo = upIntent.resolveActivity(getPackageManager());
+                if (destInfo == null) {
+                    return false;
+                }
+                upIntent = new Intent(upIntent);
+                upIntent.setComponent(destInfo);
+            }
+            int resultCode;
+            Intent resultData;
+            synchronized (this) {
+                resultCode = mResultCode;
+                resultData = mResultData;
+            }
+            if (resultData != null) {
+                resultData.setAllowFds(false);
+            }
+            try {
+                return ActivityManagerNative.getDefault().navigateUpTo(mToken, upIntent,
+                        resultCode, resultData);
+            } catch (RemoteException e) {
+                return false;
+            }
+        } else {
+            return mParent.navigateUpToFromChild(this, upIntent);
+        }
+    }
+
+    /**
+     * This is called when a child activity of this one calls its
+     * {@link #navigateUpTo} method.  The default implementation simply calls
+     * navigateUpTo(upIntent) on this activity (the parent).
+     *
+     * @param child The activity making the call.
+     * @param upIntent An intent representing the target destination for up navigation
+     *
+     * @return true if up navigation successfully reached the activity indicated by upIntent and
+     *         upIntent was delivered to it. false if an instance of the indicated activity could
+     *         not be found and this activity was simply finished normally.
+     */
+    public boolean navigateUpToFromChild(Activity child, Intent upIntent) {
+        return navigateUpTo(upIntent);
+    }
+
+    /**
+     * Obtain an {@link Intent} that will launch an explicit target activity specified by
+     * this activity's logical parent. The logical parent is named in the application's manifest
+     * by the {@link android.R.attr#parentActivityName parentActivityName} attribute.
+     *
+     * @return a new Intent targeting the defined parent of this activity
+     */
+    public Intent getParentActivityIntent() {
+        return new Intent().setClassName(this, mActivityInfo.parentActivityName);
+    }
+
     // ------------------ Internal API ------------------
     
     final void setParent(Activity parent) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 531a695..11b4c3a 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1774,5 +1774,4 @@
             return false;
         }
     }
-
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 5917cbf..000abc5 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -17,10 +17,10 @@
 package android.app;
 
 import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
 import android.content.Intent;
 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;
@@ -32,11 +32,11 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Debug;
-import android.os.Parcelable;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
 import android.os.IBinder;
 import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
 import android.text.TextUtils;
@@ -1605,6 +1605,31 @@
             return true;
         }
 
+        case TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            String destAffinity = data.readString();
+            boolean res = targetTaskAffinityMatchesActivity(token, destAffinity);
+            reply.writeNoException();
+            reply.writeInt(res ? 1 : 0);
+            return true;
+        }
+
+        case NAVIGATE_UP_TO_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            Intent target = Intent.CREATOR.createFromParcel(data);
+            int resultCode = data.readInt();
+            Intent resultData = null;
+            if (data.readInt() != 0) {
+                resultData = Intent.CREATOR.createFromParcel(data);
+            }
+            boolean res = navigateUpTo(token, target, resultCode, resultData);
+            reply.writeNoException();
+            reply.writeInt(res ? 1 : 0);
+            return true;
+        }
+
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -3662,5 +3687,42 @@
         reply.recycle();
     }
 
+    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        data.writeString(destAffinity);
+        mRemote.transact(TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean result = reply.readInt() != 0;
+        data.recycle();
+        reply.recycle();
+        return result;
+    }
+
+    public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        target.writeToParcel(data, 0);
+        data.writeInt(resultCode);
+        if (resultData != null) {
+            data.writeInt(1);
+            resultData.writeToParcel(data, 0);
+        } else {
+            data.writeInt(0);
+        }
+        mRemote.transact(NAVIGATE_UP_TO_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean result = reply.readInt() != 0;
+        data.recycle();
+        reply.recycle();
+        return result;
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 5ffceb3..c5d7b91 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -45,6 +45,8 @@
 import android.hardware.ISerialManager;
 import android.hardware.SensorManager;
 import android.hardware.SerialManager;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
 import android.hardware.usb.IUsbManager;
 import android.hardware.usb.UsbManager;
 import android.location.CountryDetector;
@@ -323,6 +325,11 @@
                     return createDropBoxManager();
                 }});
 
+        registerService(INPUT_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
+                    return new InputManager(ctx);
+                }});
+
         registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                     return InputMethodManager.getInstance(ctx);
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index ad8d41f..dd58397 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -1097,6 +1097,18 @@
         }
     }
 
+    /** {@hide} */
+    public static boolean isActiveNetworkExpensive(Context context) {
+        // TODO: connect to NetworkPolicyManager
+        return false;
+    }
+
+    /** {@hide} */
+    public static long getActiveNetworkWarningBytes(Context context) {
+        // TODO: connect to NetworkPolicyManager
+        return -1;
+    }
+
     /**
      * Adds a file to the downloads database system, so it could appear in Downloads App
      * (and thus become eligible for management by the Downloads App).
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 2b1eb43..0f287c1 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -341,6 +341,12 @@
 
     public void dismissKeyguardOnNextActivity() throws RemoteException;
 
+    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)
+            throws RemoteException;
+
+    public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
+            throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -578,4 +584,6 @@
     int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
     int KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+143;
     int GET_CURRENT_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+144;
+    int TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+145;
+    int NAVIGATE_UP_TO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+146;
 }
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index e4f7950..f955713 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -23,6 +23,7 @@
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
+import android.hardware.input.InputManager;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.IBinder;
@@ -35,6 +36,7 @@
 import android.util.AndroidRuntimeException;
 import android.util.Log;
 import android.view.IWindowManager;
+import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -859,11 +861,30 @@
      */
     public void sendKeySync(KeyEvent event) {
         validateNotAppThread();
-        try {
-            (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
-                .injectKeyEvent(event, true);
-        } catch (RemoteException e) {
+
+        long downTime = event.getDownTime();
+        long eventTime = event.getEventTime();
+        int action = event.getAction();
+        int code = event.getKeyCode();
+        int repeatCount = event.getRepeatCount();
+        int metaState = event.getMetaState();
+        int deviceId = event.getDeviceId();
+        int scancode = event.getScanCode();
+        int source = event.getSource();
+        int flags = event.getFlags();
+        if (source == InputDevice.SOURCE_UNKNOWN) {
+            source = InputDevice.SOURCE_KEYBOARD;
         }
+        if (eventTime == 0) {
+            eventTime = SystemClock.uptimeMillis();
+        }
+        if (downTime == 0) {
+            downTime = eventTime;
+        }
+        KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
+                deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
+        InputManager.injectInputEvent(newEvent,
+                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
     }
     
     /**
@@ -902,11 +923,10 @@
      */
     public void sendPointerSync(MotionEvent event) {
         validateNotAppThread();
-        try {
-            (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
-                .injectPointerEvent(event, true);
-        } catch (RemoteException e) {
+        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
+            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
         }
+        InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
     }
 
     /**
@@ -922,11 +942,10 @@
      */
     public void sendTrackballEventSync(MotionEvent event) {
         validateNotAppThread();
-        try {
-            (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
-                .injectTrackballEvent(event, true);
-        } catch (RemoteException e) {
+        if ((event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
+            event.setSource(InputDevice.SOURCE_TRACKBALL);
         }
+        InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
     }
 
     /**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 096af93..04c64a0 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -26,6 +26,7 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.IntProperty;
 import android.util.Log;
@@ -808,6 +809,7 @@
     @Deprecated
     public void setLatestEventInfo(Context context,
             CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
+        // TODO: rewrite this to use Builder
         RemoteViews contentView = new RemoteViews(context.getPackageName(),
                 R.layout.notification_template_base);
         if (this.icon != 0) {
@@ -820,6 +822,7 @@
             contentView.setTextViewText(R.id.text, contentText);
         }
         if (this.when != 0) {
+            contentView.setViewVisibility(R.id.time, View.VISIBLE);
             contentView.setLong(R.id.time, "setTime", when);
         }
 
@@ -942,6 +945,7 @@
         private ArrayList<Action> mActions = new ArrayList<Action>(3);
         private boolean mCanHasIntruder;
         private boolean mIntruderActionsShowText;
+        private boolean mUseChronometer;
 
         /**
          * Constructs a new Builder with the defaults:
@@ -983,6 +987,18 @@
         }
 
         /**
+         * @hide
+         * 
+         * Show the {@link Notification#when} field as a countdown (or count-up) timer instead of a timestamp.  
+         *
+         * @see Notification#when
+         */
+        public Builder setUsesChronometer(boolean b) {
+            mUseChronometer = b;
+            return this;
+        }
+
+        /**
          * Set the small icon resource, which will be used to represent the notification in the
          * status bar.
          *
@@ -1434,7 +1450,15 @@
                 }
             }
             if (mWhen != 0) {
-                contentView.setLong(R.id.time, "setTime", mWhen);
+                if (mUseChronometer) {
+                    contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
+                    contentView.setLong(R.id.chronometer, "setBase",
+                            mWhen + (SystemClock.elapsedRealtime() - System.currentTimeMillis()));
+                    contentView.setBoolean(R.id.chronometer, "setStarted", true);
+                } else {
+                    contentView.setViewVisibility(R.id.time, View.VISIBLE);
+                    contentView.setLong(R.id.time, "setTime", mWhen);
+                }
             }
             contentView.setViewVisibility(R.id.line3, hasLine3 ? View.VISIBLE : View.GONE);
             return contentView;
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
new file mode 100644
index 0000000..7fd4747
--- /dev/null
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2012 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.app;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * Utility class for constructing synthetic back stacks for cross-task navigation
+ * on Android 3.0 and newer.
+ *
+ * <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for
+ * app navigation using the back key changed. The back key's behavior is local
+ * to the current task and does not capture navigation across different tasks.
+ * Navigating across tasks and easily reaching the previous task is accomplished
+ * through the "recents" UI, accessible through the software-provided Recents key
+ * on the navigation or system bar. On devices with the older hardware button configuration
+ * the recents UI can be accessed with a long press on the Home key.</p>
+ *
+ * <p>When crossing from one task stack to another post-Android 3.0,
+ * the application should synthesize a back stack/history for the new task so that
+ * the user may navigate out of the new task and back to the Launcher by repeated
+ * presses of the back key. Back key presses should not navigate across task stacks.</p>
+ *
+ * <p>TaskStackBuilder provides a way to obey the correct conventions
+ * around cross-task navigation.</p>
+ *
+ * <div class="special reference">
+ * <h3>About Navigation</h3>
+ * For more detailed information about tasks, the back stack, and navigation design guidelines,
+ * please read
+ * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
+ * from the developer guide and <a href="{@docRoot}design/patterns/navigation.html">Navigation</a>
+ * from the design guide.
+ * </div>
+ */
+public class TaskStackBuilder implements Iterable<Intent> {
+    private static final String TAG = "TaskStackBuilder";
+
+    private final ArrayList<Intent> mIntents = new ArrayList<Intent>();
+    private final Context mSourceContext;
+
+    private TaskStackBuilder(Context a) {
+        mSourceContext = a;
+    }
+
+    /**
+     * Return a new TaskStackBuilder for launching a fresh task stack consisting
+     * of a series of activities.
+     *
+     * @param context The context that will launch the new task stack or generate a PendingIntent
+     * @return A new TaskStackBuilder
+     */
+    public static TaskStackBuilder from(Context context) {
+        return new TaskStackBuilder(context);
+    }
+
+    /**
+     * Add a new Intent to the task stack. The most recently added Intent will invoke
+     * the Activity at the top of the final task stack.
+     *
+     * @param nextIntent Intent for the next Activity in the synthesized task stack
+     * @return This TaskStackBuilder for method chaining
+     */
+    public TaskStackBuilder addNextIntent(Intent nextIntent) {
+        mIntents.add(nextIntent);
+        return this;
+    }
+
+    /**
+     * Add the activity parent chain as specified by the
+     * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
+     * (or activity-alias) element in the application's manifest to the task stack builder.
+     *
+     * @param sourceActivity All parents of this activity will be added
+     * @return This TaskStackBuilder for method chaining
+     */
+    public TaskStackBuilder addParentStack(Activity sourceActivity) {
+        final int insertAt = mIntents.size();
+        Intent parent = sourceActivity.getParentActivityIntent();
+        PackageManager pm = sourceActivity.getPackageManager();
+        while (parent != null) {
+            mIntents.add(insertAt, parent);
+            try {
+                ActivityInfo info = pm.getActivityInfo(parent.getComponent(), 0);
+                String parentActivity = info.parentActivityName;
+                if (parentActivity != null) {
+                    parent = new Intent().setComponent(
+                            new ComponentName(mSourceContext, parentActivity));
+                } else {
+                    parent = null;
+                }
+            } catch (NameNotFoundException e) {
+                Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
+                throw new IllegalArgumentException(e);
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Add the activity parent chain as specified by the
+     * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
+     * (or activity-alias) element in the application's manifest to the task stack builder.
+     *
+     * @param sourceActivityClass All parents of this activity will be added
+     * @return This TaskStackBuilder for method chaining
+     */
+    public TaskStackBuilder addParentStack(Class<?> sourceActivityClass) {
+        final int insertAt = mIntents.size();
+        PackageManager pm = mSourceContext.getPackageManager();
+        try {
+            ActivityInfo info = pm.getActivityInfo(
+                    new ComponentName(mSourceContext, sourceActivityClass), 0);
+            String parentActivity = info.parentActivityName;
+            Intent parent = new Intent().setComponent(
+                    new ComponentName(mSourceContext, parentActivity));
+            while (parent != null) {
+                mIntents.add(insertAt, parent);
+                info = pm.getActivityInfo(parent.getComponent(), 0);
+                parentActivity = info.parentActivityName;
+                if (parentActivity != null) {
+                    parent = new Intent().setComponent(
+                            new ComponentName(mSourceContext, parentActivity));
+                } else {
+                    parent = null;
+                }
+            }
+        } catch (NameNotFoundException e) {
+            Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
+            throw new IllegalArgumentException(e);
+        }
+        return this;
+    }
+
+    /**
+     * @return the number of intents added so far.
+     */
+    public int getIntentCount() {
+        return mIntents.size();
+    }
+
+    /**
+     * Get the intent at the specified index.
+     * Useful if you need to modify the flags or extras of an intent that was previously added,
+     * for example with {@link #addParentStack(Activity)}.
+     *
+     * @param index Index from 0-getIntentCount()
+     * @return the intent at position index
+     */
+    public Intent getIntent(int index) {
+        return mIntents.get(index);
+    }
+
+    public Iterator<Intent> iterator() {
+        return mIntents.iterator();
+    }
+
+    /**
+     * Start the task stack constructed by this builder.
+     */
+    public void startActivities() {
+        if (mIntents.isEmpty()) {
+            throw new IllegalStateException(
+                    "No intents added to TaskStackBuilder; cannot startActivities");
+        }
+
+        Intent[] intents = mIntents.toArray(new Intent[mIntents.size()]);
+        intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+                Intent.FLAG_ACTIVITY_CLEAR_TASK |
+                Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+        mSourceContext.startActivities(intents);
+    }
+
+    /**
+     * Obtain a {@link PendingIntent} for launching the task constructed by this builder so far.
+     *
+     * @param requestCode Private request code for the sender
+     * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT},
+     *              {@link PendingIntent#FLAG_NO_CREATE}, {@link PendingIntent#FLAG_CANCEL_CURRENT},
+     *              {@link PendingIntent#FLAG_UPDATE_CURRENT}, or any of the flags supported by
+     *              {@link Intent#fillIn(Intent, int)} to control which unspecified parts of the
+     *              intent that can be supplied when the actual send happens.
+     * @return The obtained PendingIntent
+     */
+    public PendingIntent getPendingIntent(int requestCode, int flags) {
+        if (mIntents.isEmpty()) {
+            throw new IllegalStateException(
+                    "No intents added to TaskStackBuilder; cannot getPendingIntent");
+        }
+
+        Intent[] intents = mIntents.toArray(new Intent[mIntents.size()]);
+        intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+                Intent.FLAG_ACTIVITY_CLEAR_TASK |
+                Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+        return PendingIntent.getActivities(mSourceContext, requestCode, intents, flags);
+    }
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 98ed117..36638f9 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1919,6 +1919,15 @@
     public static final String SERIAL_SERVICE = "serial";
 
     /**
+     * Use with {@link #getSystemService} to retrieve a
+     * {@link android.hardware.input.InputManager} for interacting with input devices.
+     *
+     * @see #getSystemService
+     * @see android.hardware.input.InputManager
+     */
+    public static final String INPUT_SERVICE = "input";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2a9f1af..736dd24 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2034,6 +2034,38 @@
             "android.intent.action.HDMI_AUDIO_PLUG";
 
     /**
+     * Broadcast Action: A USB audio device was plugged in or unplugged.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>card</em> - ALSA card number (integer) </li>
+     *   <li><em>device</em> - ALSA device number (integer) </li>
+     * </ul>
+     * </ul>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_USB_AUDIO_DEVICE_PLUG =
+            "android.intent.action.USB_AUDIO_DEVICE_PLUG";
+
+    /**
+     * Broadcast Action: A USB audio accessory was plugged in or unplugged.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>card</em> - ALSA card number (integer) </li>
+     *   <li><em>device</em> - ALSA device number (integer) </li>
+     * </ul>
+     * </ul>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_USB_AUDIO_ACCESSORY_PLUG =
+            "android.intent.action.USB_AUDIO_ACCESSORY_PLUG";
+
+    /**
      * <p>Broadcast Action: The user has switched on advanced settings in the settings app:</p>
      * <ul>
      *   <li><em>state</em> - A boolean value indicating whether the settings is on or off.</li>
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 0e6694de..6b16e74 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -450,6 +450,11 @@
      */
     public static final int UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = 1;
 
+    /**
+     * If defined, the activity named here is the logical parent of this activity.
+     */
+    public String parentActivityName;
+
     public ActivityInfo() {
     }
 
@@ -465,6 +470,7 @@
         configChanges = orig.configChanges;
         softInputMode = orig.softInputMode;
         uiOptions = orig.uiOptions;
+        parentActivityName = orig.parentActivityName;
     }
     
     /**
@@ -524,6 +530,7 @@
         dest.writeInt(configChanges);
         dest.writeInt(softInputMode);
         dest.writeInt(uiOptions);
+        dest.writeString(parentActivityName);
     }
 
     public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -548,5 +555,6 @@
         configChanges = source.readInt();
         softInputMode = source.readInt();
         uiOptions = source.readInt();
+        parentActivityName = source.readString();
     }
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a79b86a..7ff9bfa 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -94,10 +94,12 @@
     public static class SplitPermissionInfo {
         public final String rootPerm;
         public final String[] newPerms;
+        public final int targetSdk;
 
-        public SplitPermissionInfo(String rootPerm, String[] newPerms) {
+        public SplitPermissionInfo(String rootPerm, String[] newPerms, int targetSdk) {
             this.rootPerm = rootPerm;
             this.newPerms = newPerms;
+            this.targetSdk = targetSdk;
         }
     }
 
@@ -126,7 +128,14 @@
     public static final PackageParser.SplitPermissionInfo SPLIT_PERMISSIONS[] =
         new PackageParser.SplitPermissionInfo[] {
             new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
-                    new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE })
+                    new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE },
+                    android.os.Build.VERSION_CODES.CUR_DEVELOPMENT+1),
+            new PackageParser.SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS,
+                    new String[] { android.Manifest.permission.READ_CALL_LOG },
+                    android.os.Build.VERSION_CODES.JELLY_BEAN),
+            new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS,
+                    new String[] { android.Manifest.permission.WRITE_CALL_LOG },
+                    android.os.Build.VERSION_CODES.JELLY_BEAN)
     };
 
     private String mArchiveSourcePath;
@@ -1293,7 +1302,8 @@
         for (int is=0; is<NS; is++) {
             final PackageParser.SplitPermissionInfo spi
                     = PackageParser.SPLIT_PERMISSIONS[is];
-            if (!pkg.requestedPermissions.contains(spi.rootPerm)) {
+            if (pkg.applicationInfo.targetSdkVersion >= spi.targetSdk
+                    || !pkg.requestedPermissions.contains(spi.rootPerm)) {
                 break;
             }
             for (int in=0; in<spi.newPerms.length; in++) {
@@ -2030,6 +2040,19 @@
                 com.android.internal.R.styleable.AndroidManifestActivity_uiOptions,
                 a.info.applicationInfo.uiOptions);
 
+        String parentName = sa.getNonConfigurationString(
+                com.android.internal.R.styleable.AndroidManifestActivity_parentActivityName, 0);
+        if (parentName != null) {
+            String parentClassName = buildClassName(a.info.packageName, parentName, outError);
+            if (outError[0] == null) {
+                a.info.parentActivityName = parentClassName;
+            } else {
+                Log.e(TAG, "Activity " + a.info.name + " specified invalid parentActivityName " +
+                        parentName);
+                outError[0] = null;
+            }
+        }
+
         String str;
         str = sa.getNonConfigurationString(
                 com.android.internal.R.styleable.AndroidManifestActivity_permission, 0);
@@ -2274,6 +2297,7 @@
         info.theme = target.info.theme;
         info.softInputMode = target.info.softInputMode;
         info.uiOptions = target.info.uiOptions;
+        info.parentActivityName = target.info.parentActivityName;
         
         Activity a = new Activity(mParseActivityAliasArgs, info);
         if (outError[0] != null) {
@@ -2295,6 +2319,20 @@
             a.info.permission = str.length() > 0 ? str.toString().intern() : null;
         }
 
+        String parentName = sa.getNonConfigurationString(
+                com.android.internal.R.styleable.AndroidManifestActivityAlias_parentActivityName,
+                0);
+        if (parentName != null) {
+            String parentClassName = buildClassName(a.info.packageName, parentName, outError);
+            if (outError[0] == null) {
+                a.info.parentActivityName = parentClassName;
+            } else {
+                Log.e(TAG, "Activity alias " + a.info.name +
+                        " specified invalid parentActivityName " + parentName);
+                outError[0] = null;
+            }
+        }
+
         sa.recycle();
 
         if (outError[0] != null) {
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
new file mode 100644
index 0000000..c2abce5
--- /dev/null
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 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.hardware.input;
+
+import android.view.InputDevice;
+import android.view.InputEvent;
+
+/** @hide */
+interface IInputManager {
+    // Gets input device information.
+    InputDevice getInputDevice(int deviceId);
+    int[] getInputDeviceIds();
+
+    // Reports whether the hardware supports the given keys; returns true if successful
+    boolean hasKeys(int deviceId, int sourceMask, in int[] keyCodes, out boolean[] keyExists);
+
+    // Temporarily changes the pointer speed.
+    void tryPointerSpeed(int speed);
+
+    // Injects an input event into the system.  To inject into windows owned by other
+    // applications, the caller must have the INJECT_EVENTS permission.
+    boolean injectInputEvent(in InputEvent ev, int mode);
+}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
new file mode 100755
index 0000000..ba64035f
--- /dev/null
+++ b/core/java/android/hardware/input/InputManager.java
@@ -0,0 +1,654 @@
+/*
+ * Copyright (C) 2012 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.hardware.input;
+
+import com.android.internal.util.XmlUtils;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.util.Log;
+import android.view.Display;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.KeyCharacterMap;
+import android.view.WindowManagerPolicy;
+import android.view.KeyCharacterMap.UnavailableException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Provides information about input devices and available key layouts.
+ * <p>
+ * Get an instance of this class by calling
+ * {@link android.content.Context#getSystemService(java.lang.String)
+ * Context.getSystemService()} with the argument
+ * {@link android.content.Context#INPUT_SERVICE}.
+ * </p>
+ */
+public final class InputManager {
+    private static final String TAG = "InputManager";
+
+    private static final IInputManager sIm;
+
+    private final Context mContext;
+
+    // Used to simulate a persistent data store.
+    // TODO: Replace with the real thing.
+    private static final HashMap<String, String> mFakeRegistry = new HashMap<String, String>();
+
+    /**
+     * Broadcast Action: Query available keyboard layouts.
+     * <p>
+     * The input manager service locates available keyboard layouts
+     * by querying broadcast receivers that are registered for this action.
+     * An application can offer additional keyboard layouts to the user
+     * by declaring a suitable broadcast receiver in its manifest.
+     * </p><p>
+     * Here is an example broadcast receiver declaration that an application
+     * might include in its AndroidManifest.xml to advertise keyboard layouts.
+     * The meta-data specifies a resource that contains a description of each keyboard
+     * layout that is provided by the application.
+     * <pre><code>
+     * &lt;receiver android:name=".InputDeviceReceiver">
+     *     &lt;intent-filter>
+     *         &lt;action android:name="android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS" />
+     *     &lt;/intent-filter>
+     *     &lt;meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS"
+     *             android:resource="@xml/keyboard_layouts" />
+     * &lt;/receiver>
+     * </code></pre>
+     * </p><p>
+     * In the above example, the <code>@xml/keyboard_layouts</code> resource refers to
+     * an XML resource whose root element is <code>&lt;keyboard-layouts></code> that
+     * contains zero or more <code>&lt;keyboard-layout></code> elements.
+     * Each <code>&lt;keyboard-layout></code> element specifies the name, label, and location
+     * of a key character map for a particular keyboard layout.
+     * <pre></code>
+     * &lt;?xml version="1.0" encoding="utf-8"?>
+     * &lt;keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android">
+     *     &lt;keyboard-layout android:name="keyboard_layout_english_us"
+     *             android:label="@string/keyboard_layout_english_us_label"
+     *             android:kcm="@raw/keyboard_layout_english_us" />
+     * &lt;/keyboard-layouts>
+     * </p><p>
+     * The <code>android:name</code> attribute specifies an identifier by which
+     * the keyboard layout will be known in the package.
+     * The <code>android:label</code> attributes specifies a human-readable descriptive
+     * label to describe the keyboard layout in the user interface, such as "English (US)".
+     * The <code>android:kcm</code> attribute refers to a
+     * <a href="http://source.android.com/tech/input/key-character-map-files.html">
+     * key character map</a> resource that defines the keyboard layout.
+     * </p>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_QUERY_KEYBOARD_LAYOUTS =
+            "android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS";
+
+    /**
+     * Metadata Key: Keyboard layout metadata associated with
+     * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS}.
+     * <p>
+     * Specifies the resource id of a XML resource that describes the keyboard
+     * layouts that are provided by the application.
+     * </p>
+     */
+    public static final String META_DATA_KEYBOARD_LAYOUTS =
+            "android.hardware.input.metadata.KEYBOARD_LAYOUTS";
+
+    /**
+     * Pointer Speed: The minimum (slowest) pointer speed (-7).
+     * @hide
+     */
+    public static final int MIN_POINTER_SPEED = -7;
+
+    /**
+     * Pointer Speed: The maximum (fastest) pointer speed (7).
+     * @hide
+     */
+    public static final int MAX_POINTER_SPEED = 7;
+
+    /**
+     * Pointer Speed: The default pointer speed (0).
+     * @hide
+     */
+    public static final int DEFAULT_POINTER_SPEED = 0;
+
+    /**
+     * Input Event Injection Synchronization Mode: None.
+     * Never blocks.  Injection is asynchronous and is assumed always to be successful.
+     * @hide
+     */
+    public static final int INJECT_INPUT_EVENT_MODE_ASYNC = 0; // see InputDispatcher.h
+
+    /**
+     * Input Event Injection Synchronization Mode: Wait for result.
+     * Waits for previous events to be dispatched so that the input dispatcher can
+     * determine whether input event injection will be permitted based on the current
+     * input focus.  Does not wait for the input event to finish being handled
+     * by the application.
+     * @hide
+     */
+    public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT = 1;  // see InputDispatcher.h
+
+    /**
+     * Input Event Injection Synchronization Mode: Wait for finish.
+     * Waits for the event to be delivered to the application and handled.
+     * @hide
+     */
+    public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2;  // see InputDispatcher.h
+
+    static {
+        IBinder b = ServiceManager.getService(Context.INPUT_SERVICE);
+        sIm = IInputManager.Stub.asInterface(b);
+    }
+
+    /** @hide */
+    public InputManager(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Gets information about all supported keyboard layouts.
+     * <p>
+     * The input manager consults the built-in keyboard layouts as well
+     * as all keyboard layouts advertised by applications using a
+     * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver.
+     * </p>
+     *
+     * @return A list of all supported keyboard layouts.
+     * @hide
+     */
+    public List<KeyboardLayout> getKeyboardLayouts() {
+        ArrayList<KeyboardLayout> list = new ArrayList<KeyboardLayout>();
+
+        final PackageManager pm = mContext.getPackageManager();
+        Intent intent = new Intent(ACTION_QUERY_KEYBOARD_LAYOUTS);
+        for (ResolveInfo resolveInfo : pm.queryBroadcastReceivers(intent,
+                PackageManager.GET_META_DATA)) {
+            loadKeyboardLayouts(pm, resolveInfo.activityInfo, list, null);
+        }
+        return list;
+    }
+
+    /**
+     * Gets the keyboard layout with the specified descriptor.
+     *
+     * @param keyboardLayoutDescriptor The keyboard layout descriptor, as returned by
+     * {@link KeyboardLayout#getDescriptor()}.
+     * @return The keyboard layout, or null if it could not be loaded.
+     *
+     * @hide
+     */
+    public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) {
+        if (keyboardLayoutDescriptor == null) {
+            throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
+        }
+
+        KeyboardLayoutDescriptor d = parseKeyboardLayoutDescriptor(keyboardLayoutDescriptor);
+        if (d == null) {
+            return null;
+        }
+
+        final PackageManager pm = mContext.getPackageManager();
+        try {
+            ActivityInfo receiver = pm.getReceiverInfo(
+                    new ComponentName(d.packageName, d.receiverName),
+                    PackageManager.GET_META_DATA);
+            return loadKeyboardLayouts(pm, receiver, null, d.keyboardLayoutName);
+        } catch (NameNotFoundException ex) {
+            Log.w(TAG, "Could not load keyboard layout '" + d.keyboardLayoutName
+                    + "' from receiver " + d.packageName + "/" + d.receiverName, ex);
+            return null;
+        }
+    }
+
+    /**
+     * Gets the keyboard layout descriptor for the specified input device.
+     *
+     * @param inputDeviceDescriptor The input device descriptor.
+     * @return The keyboard layout descriptor, or null if unknown or if the default
+     * keyboard layout will be used.
+     *
+     * @hide
+     */
+    public String getInputDeviceKeyboardLayoutDescriptor(String inputDeviceDescriptor) {
+        if (inputDeviceDescriptor == null) {
+            throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
+        }
+
+        return mFakeRegistry.get(inputDeviceDescriptor);
+    }
+
+    /**
+     * Sets the keyboard layout descriptor for the specified input device.
+     * <p>
+     * This method may have the side-effect of causing the input device in question
+     * to be reconfigured.
+     * </p>
+     *
+     * @param inputDeviceDescriptor The input device descriptor.
+     * @param keyboardLayoutDescriptor The keyboard layout descriptor, or null to remove
+     * the mapping so that the default keyboard layout will be used for the input device.
+     *
+     * @hide
+     */
+    public void setInputDeviceKeyboardLayoutDescriptor(String inputDeviceDescriptor,
+            String keyboardLayoutDescriptor) {
+        if (inputDeviceDescriptor == null) {
+            throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
+        }
+
+        mFakeRegistry.put(inputDeviceDescriptor, keyboardLayoutDescriptor);
+    }
+
+    private KeyboardLayout loadKeyboardLayouts(
+            PackageManager pm, ActivityInfo receiver,
+            List<KeyboardLayout> list, String keyboardName) {
+        Bundle metaData = receiver.metaData;
+        if (metaData == null) {
+            return null;
+        }
+
+        int configResId = metaData.getInt(META_DATA_KEYBOARD_LAYOUTS);
+        if (configResId == 0) {
+            Log.w(TAG, "Missing meta-data '" + META_DATA_KEYBOARD_LAYOUTS + "' on receiver "
+                    + receiver.packageName + "/" + receiver.name);
+            return null;
+        }
+
+        try {
+            Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+            XmlResourceParser parser = resources.getXml(configResId);
+            try {
+                XmlUtils.beginDocument(parser, "keyboard-layouts");
+
+                for (;;) {
+                    XmlUtils.nextElement(parser);
+                    String element = parser.getName();
+                    if (element == null) {
+                        break;
+                    }
+                    if (element.equals("keyboard-layout")) {
+                        TypedArray a = resources.obtainAttributes(
+                                parser, com.android.internal.R.styleable.KeyboardLayout);
+                        try {
+                            String name = a.getString(
+                                    com.android.internal.R.styleable.KeyboardLayout_name);
+                            String label = a.getString(
+                                    com.android.internal.R.styleable.KeyboardLayout_label);
+                            int kcmResId = a.getResourceId(
+                                     com.android.internal.R.styleable.KeyboardLayout_kcm, 0);
+                            if (name == null || label == null || kcmResId == 0) {
+                                Log.w(TAG, "Missing required 'name', 'label' or 'kcm' "
+                                        + "attributes in keyboard layout "
+                                        + "resource from receiver "
+                                        + receiver.packageName + "/" + receiver.name);
+                            } else {
+                                String descriptor = makeKeyboardLayoutDescriptor(
+                                        receiver.packageName, receiver.name, name);
+                                KeyboardLayout c = new KeyboardLayout(
+                                        descriptor, label, kcmResId);
+                                if (keyboardName != null && name.equals(keyboardName)) {
+                                    return c;
+                                }
+                                if (list != null) {
+                                    list.add(c);
+                                }
+                            }
+                        } finally {
+                            a.recycle();
+                        }
+                    } else {
+                        Log.w(TAG, "Skipping unrecognized element '" + element
+                                + "' in keyboard layout resource from receiver "
+                                + receiver.packageName + "/" + receiver.name);
+                    }
+                }
+            } finally {
+                parser.close();
+            }
+        } catch (Exception ex) {
+            Log.w(TAG, "Could not load keyboard layout resource from receiver "
+                    + receiver.packageName + "/" + receiver.name, ex);
+            return null;
+        }
+        if (keyboardName != null) {
+            Log.w(TAG, "Could not load keyboard layout '" + keyboardName
+                    + "' from receiver " + receiver.packageName + "/" + receiver.name
+                    + " because it was not declared in the keyboard layout resource.");
+        }
+        return null;
+    }
+
+    /**
+     * Gets the mouse pointer speed.
+     * <p>
+     * Only returns the permanent mouse pointer speed.  Ignores any temporary pointer
+     * speed set by {@link #tryPointerSpeed}.
+     * </p>
+     *
+     * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and
+     * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}.
+     *
+     * @hide
+     */
+    public int getPointerSpeed() {
+        int speed = DEFAULT_POINTER_SPEED;
+        try {
+            speed = Settings.System.getInt(mContext.getContentResolver(),
+                    Settings.System.POINTER_SPEED);
+        } catch (SettingNotFoundException snfe) {
+        }
+        return speed;
+    }
+
+    /**
+     * Sets the mouse pointer speed.
+     * <p>
+     * Requires {@link android.Manifest.permissions.WRITE_SETTINGS}.
+     * </p>
+     *
+     * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and
+     * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}.
+     *
+     * @hide
+     */
+    public void setPointerSpeed(int speed) {
+        if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) {
+            throw new IllegalArgumentException("speed out of range");
+        }
+
+        Settings.System.putInt(mContext.getContentResolver(),
+                Settings.System.POINTER_SPEED, speed);
+    }
+
+    /**
+     * Changes the mouse pointer speed temporarily, but does not save the setting.
+     * <p>
+     * Requires {@link android.Manifest.permission.SET_POINTER_SPEED}.
+     * </p>
+     *
+     * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and
+     * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}.
+     *
+     * @hide
+     */
+    public void tryPointerSpeed(int speed) {
+        if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) {
+            throw new IllegalArgumentException("speed out of range");
+        }
+
+        try {
+            sIm.tryPointerSpeed(speed);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not set temporary pointer speed.", ex);
+        }
+    }
+
+    /**
+     * Gets information about the input device with the specified id.
+     * @param id The device id.
+     * @return The input device or null if not found.
+     *
+     * @hide
+     */
+    public static InputDevice getInputDevice(int id) {
+        try {
+            return sIm.getInputDevice(id);
+        } catch (RemoteException ex) {
+            throw new RuntimeException("Could not get input device information.", ex);
+        }
+    }
+
+    /**
+     * Gets the ids of all input devices in the system.
+     * @return The input device ids.
+     *
+     * @hide
+     */
+    public static int[] getInputDeviceIds() {
+        try {
+            return sIm.getInputDeviceIds();
+        } catch (RemoteException ex) {
+            throw new RuntimeException("Could not get input device ids.", ex);
+        }
+    }
+
+    /**
+     * Queries the framework about whether any physical keys exist on the
+     * any keyboard attached to the device that are capable of producing the given
+     * array of key codes.
+     *
+     * @param keyCodes The array of key codes to query.
+     * @return A new array of the same size as the key codes array whose elements
+     * are set to true if at least one attached keyboard supports the corresponding key code
+     * at the same index in the key codes array.
+     *
+     * @hide
+     */
+    public static boolean[] deviceHasKeys(int[] keyCodes) {
+        boolean[] ret = new boolean[keyCodes.length];
+        try {
+            sIm.hasKeys(-1, InputDevice.SOURCE_ANY, keyCodes, ret);
+        } catch (RemoteException e) {
+            // no fallback; just return the empty array
+        }
+        return ret;
+    }
+
+    /**
+     * Injects an input event into the event system on behalf of an application.
+     * The synchronization mode determines whether the method blocks while waiting for
+     * input injection to proceed.
+     * <p>
+     * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into
+     * windows that are owned by other applications.
+     * </p><p>
+     * Make sure you correctly set the event time and input source of the event
+     * before calling this method.
+     * </p>
+     *
+     * @param event The event to inject.
+     * @param mode The synchronization mode.  One of:
+     * {@link #INJECT_INPUT_EVENT_MODE_ASYNC},
+     * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT}, or
+     * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH}.
+     * @return True if input event injection succeeded.
+     *
+     * @hide
+     */
+    public static boolean injectInputEvent(InputEvent event, int mode) {
+        if (event == null) {
+            throw new IllegalArgumentException("event must not be null");
+        }
+        if (mode != INJECT_INPUT_EVENT_MODE_ASYNC
+                && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
+                && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
+            throw new IllegalArgumentException("mode is invalid");
+        }
+
+        try {
+            return sIm.injectInputEvent(event, mode);
+        } catch (RemoteException ex) {
+            return false;
+        }
+    }
+
+    private static String makeKeyboardLayoutDescriptor(String packageName,
+            String receiverName, String keyboardName) {
+        return packageName + "/" + receiverName + "/" + keyboardName;
+    }
+
+    private static KeyboardLayoutDescriptor parseKeyboardLayoutDescriptor(String descriptor) {
+        int pos = descriptor.indexOf('/');
+        if (pos < 0 || pos + 1 == descriptor.length()) {
+            return null;
+        }
+        int pos2 = descriptor.indexOf('/', pos + 1);
+        if (pos2 < pos + 2 || pos2 + 1 == descriptor.length()) {
+            return null;
+        }
+
+        KeyboardLayoutDescriptor result = new KeyboardLayoutDescriptor();
+        result.packageName = descriptor.substring(0, pos);
+        result.receiverName = descriptor.substring(pos + 1, pos2);
+        result.keyboardLayoutName = descriptor.substring(pos2 + 1);
+        return result;
+    }
+
+    /**
+     * Describes a keyboard layout.
+     *
+     * @hide
+     */
+    public static final class KeyboardLayout implements Parcelable,
+            Comparable<KeyboardLayout> {
+        private final String mDescriptor;
+        private final String mLabel;
+        private final int mKeyCharacterMapResId;
+
+        private KeyCharacterMap mKeyCharacterMap;
+
+        public static final Parcelable.Creator<KeyboardLayout> CREATOR =
+                new Parcelable.Creator<KeyboardLayout>() {
+            public KeyboardLayout createFromParcel(Parcel source) {
+                return new KeyboardLayout(source);
+            }
+            public KeyboardLayout[] newArray(int size) {
+                return new KeyboardLayout[size];
+            }
+        };
+
+        private KeyboardLayout(String descriptor,
+                String label, int keyCharacterMapResId) {
+            mDescriptor = descriptor;
+            mLabel = label;
+            mKeyCharacterMapResId = keyCharacterMapResId;
+        }
+
+        private KeyboardLayout(Parcel source) {
+            mDescriptor = source.readString();
+            mLabel = source.readString();
+            mKeyCharacterMapResId = source.readInt();
+        }
+
+        /**
+         * Gets the keyboard layout descriptor, which can be used to retrieve
+         * the keyboard layout again later using
+         * {@link InputManager#getKeyboardLayout(String)}.
+         *
+         * @return The keyboard layout descriptor.
+         */
+        public String getDescriptor() {
+            return mDescriptor;
+        }
+
+        /**
+         * Gets the keyboard layout descriptive label to show in the user interface.
+         * @return The keyboard layout descriptive label.
+         */
+        public String getLabel() {
+            return mLabel;
+        }
+
+        /**
+         * Loads the key character map associated with the keyboard layout.
+         *
+         * @param pm The package manager.
+         * @return The key character map, or null if it could not be loaded for any reason.
+         */
+        public KeyCharacterMap loadKeyCharacterMap(PackageManager pm) {
+            if (pm == null) {
+                throw new IllegalArgumentException("pm must not be null");
+            }
+
+            if (mKeyCharacterMap == null) {
+                KeyboardLayoutDescriptor d = parseKeyboardLayoutDescriptor(mDescriptor);
+                if (d == null) {
+                    Log.e(TAG, "Could not load key character map '" + mDescriptor
+                            + "' because the descriptor could not be parsed.");
+                    return null;
+                }
+
+                CharSequence cs = pm.getText(d.packageName, mKeyCharacterMapResId, null);
+                if (cs == null) {
+                    Log.e(TAG, "Could not load key character map '" + mDescriptor
+                            + "' because its associated resource could not be loaded.");
+                    return null;
+                }
+
+                try {
+                    mKeyCharacterMap = KeyCharacterMap.load(cs);
+                } catch (UnavailableException ex) {
+                    Log.e(TAG, "Could not load key character map '" + mDescriptor
+                            + "' due to an error while parsing.", ex);
+                    return null;
+                }
+            }
+            return mKeyCharacterMap;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(mDescriptor);
+            dest.writeString(mLabel);
+            dest.writeInt(mKeyCharacterMapResId);
+        }
+
+        @Override
+        public int compareTo(KeyboardLayout another) {
+            return mLabel.compareToIgnoreCase(another.mLabel);
+        }
+
+        @Override
+        public String toString() {
+            return mLabel;
+        }
+    }
+
+    private static final class KeyboardLayoutDescriptor {
+        public String packageName;
+        public String receiverName;
+        public String keyboardLayoutName;
+    }
+}
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 93f93c7..c40504a7 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -66,6 +66,8 @@
      * PTP function is enabled
      * <li> {@link #USB_FUNCTION_PTP} boolean extra indicating whether the
      * accessory function is enabled
+     * <li> {@link #USB_FUNCTION_AUDIO_SOURCE} boolean extra indicating whether the
+     * audio source function is enabled
      * </ul>
      *
      * {@hide}
@@ -178,6 +180,14 @@
     public static final String USB_FUNCTION_PTP = "ptp";
 
     /**
+     * Name of the audio source USB function.
+     * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+     *
+     * {@hide}
+     */
+    public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
+
+    /**
      * Name of the Accessory USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 2eef8f4..de16985 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -20,6 +20,7 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
 import android.os.Binder;
 import android.os.Build.VERSION_CODES;
 import android.os.RemoteException;
@@ -610,6 +611,11 @@
         mService = checkNotNull(service, "missing IConnectivityManager");
     }
 
+    /** {@hide} */
+    public static ConnectivityManager from(Context context) {
+        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
     /**
      * {@hide}
      */
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index ee12989..4ac5e76 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -16,9 +16,13 @@
 
 package android.net;
 
+import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.ConnectivityManager.getNetworkTypeName;
 import static android.net.ConnectivityManager.isNetworkTypeMobile;
 
 import android.content.Context;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.os.Build;
 import android.telephony.TelephonyManager;
 
@@ -42,18 +46,21 @@
     final int mType;
     final int mSubType;
     final String mSubscriberId;
+    final String mNetworkId;
     final boolean mRoaming;
 
-    public NetworkIdentity(int type, int subType, String subscriberId, boolean roaming) {
-        this.mType = type;
-        this.mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType;
-        this.mSubscriberId = subscriberId;
-        this.mRoaming = roaming;
+    public NetworkIdentity(
+            int type, int subType, String subscriberId, String networkId, boolean roaming) {
+        mType = type;
+        mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType;
+        mSubscriberId = subscriberId;
+        mNetworkId = networkId;
+        mRoaming = roaming;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(mType, mSubType, mSubscriberId, mRoaming);
+        return Objects.hashCode(mType, mSubType, mSubscriberId, mNetworkId, mRoaming);
     }
 
     @Override
@@ -61,27 +68,34 @@
         if (obj instanceof NetworkIdentity) {
             final NetworkIdentity ident = (NetworkIdentity) obj;
             return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming
-                    && Objects.equal(mSubscriberId, ident.mSubscriberId);
+                    && Objects.equal(mSubscriberId, ident.mSubscriberId)
+                    && Objects.equal(mNetworkId, ident.mNetworkId);
         }
         return false;
     }
 
     @Override
     public String toString() {
-        final String typeName = ConnectivityManager.getNetworkTypeName(mType);
-        final String subTypeName;
+        final StringBuilder builder = new StringBuilder("[");
+        builder.append("type=").append(getNetworkTypeName(mType));
+        builder.append(", subType=");
         if (COMBINE_SUBTYPE_ENABLED) {
-            subTypeName = "COMBINED";
+            builder.append("COMBINED");
         } else if (ConnectivityManager.isNetworkTypeMobile(mType)) {
-            subTypeName = TelephonyManager.getNetworkTypeName(mSubType);
+            builder.append(TelephonyManager.getNetworkTypeName(mSubType));
         } else {
-            subTypeName = Integer.toString(mSubType);
+            builder.append(mSubType);
         }
-
-        final String scrubSubscriberId = scrubSubscriberId(mSubscriberId);
-        final String roaming = mRoaming ? ", ROAMING" : "";
-        return "[type=" + typeName + ", subType=" + subTypeName + ", subscriberId="
-                + scrubSubscriberId + roaming + "]";
+        if (mSubscriberId != null) {
+            builder.append(", subscriberId=").append(scrubSubscriberId(mSubscriberId));
+        }
+        if (mNetworkId != null) {
+            builder.append(", networkId=").append(mNetworkId);
+        }
+        if (mRoaming) {
+            builder.append(", ROAMING");
+        }
+        return builder.append("]").toString();
     }
 
     public int getType() {
@@ -96,6 +110,10 @@
         return mSubscriberId;
     }
 
+    public String getNetworkId() {
+        return mNetworkId;
+    }
+
     public boolean getRoaming() {
         return mRoaming;
     }
@@ -106,8 +124,11 @@
     public static String scrubSubscriberId(String subscriberId) {
         if ("eng".equals(Build.TYPE)) {
             return subscriberId;
+        } else if (subscriberId != null) {
+            // TODO: parse this as MCC+MNC instead of hard-coding
+            return subscriberId.substring(0, Math.min(6, subscriberId.length())) + "...";
         } else {
-            return subscriberId != null ? "valid" : "null";
+            return "null";
         }
     }
 
@@ -122,8 +143,10 @@
         // TODO: consider moving subscriberId over to LinkCapabilities, so it
         // comes from an authoritative source.
 
-        final String subscriberId;
-        final boolean roaming;
+        String subscriberId = null;
+        String networkId = null;
+        boolean roaming = false;
+
         if (isNetworkTypeMobile(type)) {
             final TelephonyManager telephony = (TelephonyManager) context.getSystemService(
                     Context.TELEPHONY_SERVICE);
@@ -133,10 +156,13 @@
             } else {
                 subscriberId = telephony.getSubscriberId();
             }
-        } else {
-            subscriberId = null;
-            roaming = false;
+
+        } else if (type == TYPE_WIFI) {
+            final WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+            final WifiInfo info = wifi.getConnectionInfo();
+            networkId = info != null ? info.getSSID() : null;
         }
-        return new NetworkIdentity(type, subType, subscriberId, roaming);
+
+        return new NetworkIdentity(type, subType, subscriberId, networkId, roaming);
     }
 }
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index c1f58a3..441db7a 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -30,6 +30,7 @@
  * @hide
  */
 public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
+    public static final int CYCLE_NONE = -1;
     public static final long WARNING_DISABLED = -1;
     public static final long LIMIT_DISABLED = -1;
     public static final long SNOOZE_NEVER = -1;
@@ -123,6 +124,13 @@
         lastLimitSnooze = SNOOZE_NEVER;
     }
 
+    /**
+     * Test if this policy has a cycle defined, after which usage should reset.
+     */
+    public boolean hasCycle() {
+        return cycleDay != CYCLE_NONE;
+    }
+
     @Override
     public int compareTo(NetworkPolicy another) {
         if (another == null || another.limitBytes == LIMIT_DISABLED) {
@@ -159,10 +167,17 @@
 
     @Override
     public String toString() {
-        return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", cycleTimezone="
-                + cycleTimezone + ", warningBytes=" + warningBytes + ", limitBytes=" + limitBytes
-                + ", lastWarningSnooze=" + lastWarningSnooze + ", lastLimitSnooze="
-                + lastLimitSnooze + ", metered=" + metered + ", inferred=" + inferred;
+        final StringBuilder builder = new StringBuilder("NetworkPolicy");
+        builder.append("[").append(template).append("]:");
+        builder.append(" cycleDay=").append(cycleDay);
+        builder.append(", cycleTimezone=").append(cycleTimezone);
+        builder.append(", warningBytes=").append(warningBytes);
+        builder.append(", limitBytes=").append(limitBytes);
+        builder.append(", lastWarningSnooze=").append(lastWarningSnooze);
+        builder.append(", lastLimitSnooze=").append(lastLimitSnooze);
+        builder.append(", metered=").append(metered);
+        builder.append(", inferred=").append(inferred);
+        return builder.toString();
     }
 
     public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index c09c676..2b36131 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import static android.content.pm.PackageManager.GET_SIGNATURES;
+import static android.net.NetworkPolicy.CYCLE_NONE;
 import static android.text.format.Time.MONTH_DAY;
 
 import android.content.Context;
@@ -66,27 +67,10 @@
         mService = service;
     }
 
-    public static NetworkPolicyManager getSystemService(Context context) {
+    public static NetworkPolicyManager from(Context context) {
         return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
     }
 
-    /** {@hide} */
-    public void setNetworkPolicies(NetworkPolicy[] policies) {
-        try {
-            mService.setNetworkPolicies(policies);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /** {@hide} */
-    public NetworkPolicy[] getNetworkPolicies() {
-        try {
-            return mService.getNetworkPolicies();
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
     /**
      * Set policy flags for specific application.
      *
@@ -122,6 +106,36 @@
         }
     }
 
+    public void setNetworkPolicies(NetworkPolicy[] policies) {
+        try {
+            mService.setNetworkPolicies(policies);
+        } catch (RemoteException e) {
+        }
+    }
+
+    public NetworkPolicy[] getNetworkPolicies() {
+        try {
+            return mService.getNetworkPolicies();
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    public void setRestrictBackground(boolean restrictBackground) {
+        try {
+            mService.setRestrictBackground(restrictBackground);
+        } catch (RemoteException e) {
+        }
+    }
+
+    public boolean getRestrictBackground() {
+        try {
+            return mService.getRestrictBackground();
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
     /**
      * Compute the last cycle boundary for the given {@link NetworkPolicy}. For
      * example, if cycle day is 20th, and today is June 15th, it will return May
@@ -131,6 +145,10 @@
      * @hide
      */
     public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
+        if (policy.cycleDay == CYCLE_NONE) {
+            throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
+        }
+
         final Time now = new Time(policy.cycleTimezone);
         now.set(currentTime);
 
@@ -157,6 +175,10 @@
 
     /** {@hide} */
     public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
+        if (policy.cycleDay == CYCLE_NONE) {
+            throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
+        }
+
         final Time now = new Time(policy.cycleTimezone);
         now.set(currentTime);
 
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index e1fbdcc..50432a1 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -43,15 +43,10 @@
  */
 public class NetworkTemplate implements Parcelable {
 
-    /** {@hide} */
     public static final int MATCH_MOBILE_ALL = 1;
-    /** {@hide} */
     public static final int MATCH_MOBILE_3G_LOWER = 2;
-    /** {@hide} */
     public static final int MATCH_MOBILE_4G = 3;
-    /** {@hide} */
     public static final int MATCH_WIFI = 4;
-    /** {@hide} */
     public static final int MATCH_ETHERNET = 5;
 
     /**
@@ -65,37 +60,50 @@
     }
 
     /**
-     * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
-     * networks together. Only uses statistics for requested IMSI.
+     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
+     * the given IMSI.
      */
     public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
-        return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId);
+        return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId, null);
     }
 
     /**
-     * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
-     * networks together that roughly meet a "3G" definition, or lower. Only
-     * uses statistics for requested IMSI.
+     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
+     * the given IMSI that roughly meet a "3G" definition, or lower.
      */
+    @Deprecated
     public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
-        return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId);
+        return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId, null);
     }
 
     /**
-     * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
-     * networks together that meet a "4G" definition. Only uses statistics for
-     * requested IMSI.
+     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
+     * the given IMSI that roughly meet a "4G" definition.
      */
+    @Deprecated
     public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
-        return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId);
+        return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId, null);
     }
 
     /**
-     * Template to combine all {@link ConnectivityManager#TYPE_WIFI} style
-     * networks together.
+     * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks,
+     * regardless of SSID.
      */
+    public static NetworkTemplate buildTemplateWifiWildcard() {
+        return new NetworkTemplate(MATCH_WIFI, null, null);
+    }
+
+    @Deprecated
     public static NetworkTemplate buildTemplateWifi() {
-        return new NetworkTemplate(MATCH_WIFI, null);
+        return buildTemplateWifiWildcard();
+    }
+
+    /**
+     * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
+     * given SSID.
+     */
+    public static NetworkTemplate buildTemplateWifi(String networkId) {
+        return new NetworkTemplate(MATCH_WIFI, null, networkId);
     }
 
     /**
@@ -103,44 +111,53 @@
      * networks together.
      */
     public static NetworkTemplate buildTemplateEthernet() {
-        return new NetworkTemplate(MATCH_ETHERNET, null);
+        return new NetworkTemplate(MATCH_ETHERNET, null, null);
     }
 
     private final int mMatchRule;
     private final String mSubscriberId;
+    private final String mNetworkId;
 
-    /** {@hide} */
-    public NetworkTemplate(int matchRule, String subscriberId) {
-        this.mMatchRule = matchRule;
-        this.mSubscriberId = subscriberId;
+    public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
+        mMatchRule = matchRule;
+        mSubscriberId = subscriberId;
+        mNetworkId = networkId;
     }
 
     private NetworkTemplate(Parcel in) {
         mMatchRule = in.readInt();
         mSubscriberId = in.readString();
+        mNetworkId = in.readString();
     }
 
-    /** {@inheritDoc} */
+    @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mMatchRule);
         dest.writeString(mSubscriberId);
+        dest.writeString(mNetworkId);
     }
 
-    /** {@inheritDoc} */
+    @Override
     public int describeContents() {
         return 0;
     }
 
     @Override
     public String toString() {
-        final String scrubSubscriberId = scrubSubscriberId(mSubscriberId);
-        return "NetworkTemplate: matchRule=" + getMatchRuleName(mMatchRule) + ", subscriberId="
-                + scrubSubscriberId;
+        final StringBuilder builder = new StringBuilder("NetworkTemplate: ");
+        builder.append("matchRule=").append(getMatchRuleName(mMatchRule));
+        if (mSubscriberId != null) {
+            builder.append(", subscriberId=").append(scrubSubscriberId(mSubscriberId));
+        }
+        if (mNetworkId != null) {
+            builder.append(", networkId=").append(mNetworkId);
+        }
+        return builder.toString();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(mMatchRule, mSubscriberId);
+        return Objects.hashCode(mMatchRule, mSubscriberId, mNetworkId);
     }
 
     @Override
@@ -148,21 +165,24 @@
         if (obj instanceof NetworkTemplate) {
             final NetworkTemplate other = (NetworkTemplate) obj;
             return mMatchRule == other.mMatchRule
-                    && Objects.equal(mSubscriberId, other.mSubscriberId);
+                    && Objects.equal(mSubscriberId, other.mSubscriberId)
+                    && Objects.equal(mNetworkId, other.mNetworkId);
         }
         return false;
     }
 
-    /** {@hide} */
     public int getMatchRule() {
         return mMatchRule;
     }
 
-    /** {@hide} */
     public String getSubscriberId() {
         return mSubscriberId;
     }
 
+    public String getNetworkId() {
+        return mNetworkId;
+    }
+
     /**
      * Test if given {@link NetworkIdentity} matches this template.
      */
@@ -237,8 +257,13 @@
     private boolean matchesWifi(NetworkIdentity ident) {
         switch (ident.mType) {
             case TYPE_WIFI:
+                if (mNetworkId == null) {
+                    return true;
+                } else {
+                    return Objects.equal(mNetworkId, ident.mNetworkId);
+                }
             case TYPE_WIFI_P2P:
-                return true;
+                return mNetworkId == null;
             default:
                 return false;
         }
@@ -279,10 +304,12 @@
     }
 
     public static final Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
+        @Override
         public NetworkTemplate createFromParcel(Parcel in) {
             return new NetworkTemplate(in);
         }
 
+        @Override
         public NetworkTemplate[] newArray(int size) {
             return new NetworkTemplate[size];
         }
diff --git a/core/java/android/nfc/INdefPushCallback.aidl b/core/java/android/nfc/INdefPushCallback.aidl
index e60a5b0..4e79822 100644
--- a/core/java/android/nfc/INdefPushCallback.aidl
+++ b/core/java/android/nfc/INdefPushCallback.aidl
@@ -17,6 +17,7 @@
 package android.nfc;
 
 import android.nfc.NdefMessage;
+import android.net.Uri;
 
 /**
  * @hide
@@ -24,5 +25,7 @@
 interface INdefPushCallback
 {
     NdefMessage createMessage();
+    Uri getUri();
+    String getMimeType();
     void onNdefPushComplete();
 }
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 2c73056..f80dae4 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.Application;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.util.Log;
@@ -107,10 +108,16 @@
         NdefMessage ndefMessage = null;  // static NDEF message
         NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
         NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
+        Uri uri = null;
+        String mimeType = null;
         public NfcActivityState(Activity activity) {
             if (activity.getWindow().isDestroyed()) {
                 throw new IllegalStateException("activity is already destroyed");
             }
+            // Check if activity is resumed right now, as we will not
+            // immediately get a callback for that.
+            resumed = activity.isResumed();
+
             this.activity = activity;
             registerApplication(activity.getApplication());
         }
@@ -121,12 +128,14 @@
             ndefMessage = null;
             ndefMessageCallback = null;
             onNdefPushCompleteCallback = null;
+            uri = null;
+            mimeType = null;
         }
         @Override
         public String toString() {
             StringBuilder s = new StringBuilder("[").append(" ");
             s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
-            s.append(onNdefPushCompleteCallback).append("]");
+            s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
             return s.toString();
         }
     }
@@ -175,6 +184,19 @@
         mDefaultEvent = new NfcEvent(mAdapter);
     }
 
+    public void setNdefPushContentUri(Activity activity, String mimeType, Uri uri) {
+        boolean isResumed;
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = getActivityState(activity);
+            state.uri = uri;
+            state.mimeType = mimeType;
+            isResumed = state.resumed;
+        }
+        if (isResumed) {
+            requestNfcServiceCallback(true);
+        }
+    }
+
     public void setNdefPushMessage(Activity activity, NdefMessage message) {
         boolean isResumed;
         synchronized (NfcActivityManager.this) {
@@ -249,6 +271,26 @@
 
     /** Callback from NFC service, usually on binder thread */
     @Override
+    public Uri getUri() {
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = findResumedActivityState();
+            if (state == null) return null;
+
+            return state.uri;
+        }
+    }
+    /** Callback from NFC service, usually on binder thread */
+    @Override
+    public String getMimeType() {
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = findResumedActivityState();
+            if (state == null) return null;
+
+            return state.mimeType;
+        }
+    }
+    /** Callback from NFC service, usually on binder thread */
+    @Override
     public void onNdefPushComplete() {
         NfcAdapter.OnNdefPushCompleteCallback callback;
         synchronized (NfcActivityManager.this) {
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index d78e06c..917751c 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -28,6 +28,7 @@
 import android.content.IntentFilter;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.net.Uri;
 import android.nfc.tech.MifareClassic;
 import android.nfc.tech.Ndef;
 import android.nfc.tech.NfcA;
@@ -555,6 +556,18 @@
         }
     }
 
+    //TODO: Consider a callback alternative
+    //TOOD: See if we get rid of mimeType
+    //TODO: make sure NFC service has permission for URI
+    //TODO: javadoc
+    /** @hide */
+    public void setBeamPushUri(String mimeType, Uri uri, Activity activity) {
+        if (activity == null) {
+            throw new NullPointerException("activity cannot be null");
+        }
+        mNfcActivityManager.setNdefPushContentUri(activity, mimeType, uri);
+    }
+
     /**
      * Set a static {@link NdefMessage} to send using Android Beam (TM).
      *
diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java
index 9d1e6a1..8c92288 100644
--- a/core/java/android/nfc/tech/MifareClassic.java
+++ b/core/java/android/nfc/tech/MifareClassic.java
@@ -150,6 +150,7 @@
         mIsEmulated = false;
 
         switch (a.getSak()) {
+        case 0x01:
         case 0x08:
             mType = TYPE_CLASSIC;
             mSize = SIZE_1K;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 830a85f..371e2a1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -36,14 +36,19 @@
 import android.net.wifi.WifiManager;
 import android.os.BatteryManager;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemProperties;
+import android.os.UserId;
 import android.speech.tts.TextToSpeech;
 import android.text.TextUtils;
 import android.util.AndroidException;
 import android.util.Log;
 import android.view.WindowOrientationListener;
 
+import com.android.internal.widget.ILockSettings;
+
 import java.net.URISyntaxException;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -2253,6 +2258,16 @@
         // Populated lazily, guarded by class object:
         private static NameValueCache sNameValueCache = null;
 
+        private static ILockSettings sLockSettings = null;
+
+        private static final HashSet<String> MOVED_TO_LOCK_SETTINGS;
+        static {
+            MOVED_TO_LOCK_SETTINGS = new HashSet<String>(3);
+            MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_ENABLED);
+            MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_VISIBLE);
+            MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED);
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -2264,6 +2279,19 @@
                 sNameValueCache = new NameValueCache(SYS_PROP_SETTING_VERSION, CONTENT_URI,
                                                      CALL_METHOD_GET_SECURE);
             }
+
+            if (sLockSettings == null) {
+                sLockSettings = ILockSettings.Stub.asInterface(
+                        (IBinder) ServiceManager.getService("lock_settings"));
+            }
+            if (sLockSettings != null && MOVED_TO_LOCK_SETTINGS.contains(name)) {
+                try {
+                    return sLockSettings.getString(name, "0", UserId.getCallingUserId());
+                } catch (RemoteException re) {
+                    // Fall through
+                }
+            }
+
             return sNameValueCache.getString(resolver, name);
         }
 
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index f7a7eb8..bb4b282 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -50,6 +50,8 @@
     public SpannableStringBuilder(CharSequence text, int start, int end) {
         int srclen = end - start;
 
+        if (srclen < 0) throw new StringIndexOutOfBoundsException();
+
         int len = ArrayUtils.idealCharArraySize(srclen + 1);
         mText = new char[len];
         mGapStart = srclen;
@@ -153,7 +155,7 @@
         if (where == mGapStart)
             return;
 
-        boolean atend = (where == length());
+        boolean atEnd = (where == length());
 
         if (where < mGapStart) {
             int overlap = mGapStart - where;
@@ -179,7 +181,7 @@
             else if (start == where) {
                 int flag = (mSpanFlags[i] & START_MASK) >> START_SHIFT;
 
-                if (flag == POINT || (atend && flag == PARAGRAPH))
+                if (flag == POINT || (atEnd && flag == PARAGRAPH))
                     start += mGapLength;
             }
 
@@ -190,7 +192,7 @@
             else if (end == where) {
                 int flag = (mSpanFlags[i] & END_MASK);
 
-                if (flag == POINT || (atend && flag == PARAGRAPH))
+                if (flag == POINT || (atEnd && flag == PARAGRAPH))
                     end += mGapLength;
             }
 
@@ -397,7 +399,7 @@
 
     // Documentation from interface
     public SpannableStringBuilder replace(final int start, final int end,
-                        CharSequence tb, int tbstart, int tbend) {
+            CharSequence tb, int tbstart, int tbend) {
         int filtercount = mFilters.length;
         for (int i = 0; i < filtercount; i++) {
             CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end);
@@ -419,53 +421,26 @@
         TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class);
         sendBeforeTextChanged(textWatchers, start, origLen, newLen);
 
-        if (origLen == 0 || newLen == 0) {
-            change(start, end, tb, tbstart, tbend);
-        } else {
-            int selstart = Selection.getSelectionStart(this);
-            int selend = Selection.getSelectionEnd(this);
+        // Try to keep the cursor / selection at the same relative position during
+        // a text replacement. If replaced or replacement text length is zero, this
+        // is already taken care of.
+        boolean adjustSelection = origLen != 0 && newLen != 0;
+        int selstart = 0;
+        int selend = 0;
+        if (adjustSelection) {
+            selstart = Selection.getSelectionStart(this);
+            selend = Selection.getSelectionEnd(this);
+        }
 
-            // XXX just make the span fixups in change() do the right thing
-            // instead of this madness!
+        checkRange("replace", start, end);
 
-            checkRange("replace", start, end);
-            moveGapTo(end);
+        change(start, end, tb, tbstart, tbend);
 
-            if (mGapLength < 2)
-                resizeFor(length() + 1);
-
-            for (int i = mSpanCount - 1; i >= 0; i--) {
-                if (mSpanStarts[i] == mGapStart)
-                    mSpanStarts[i]++;
-
-                if (mSpanEnds[i] == mGapStart)
-                    mSpanEnds[i]++;
-            }
-
-            mText[mGapStart] = ' ';
-            mGapStart++;
-            mGapLength--;
-
-            if (mGapLength < 1) {
-                new Exception("mGapLength < 1").printStackTrace();
-            }
-
-            change(start + 1, start + 1, tb, tbstart, tbend);
-            change(start, start + 1, "", 0, 0);
-            change(start + newLen, start + newLen + origLen, "", 0, 0);
-
-            /*
-             * Special case to keep the cursor in the same position
-             * if it was somewhere in the middle of the replaced region.
-             * If it was at the start or the end or crossing the whole
-             * replacement, it should already be where it belongs.
-             * TODO: Is there some more general mechanism that could
-             * accomplish this?
-             */
+        if (adjustSelection) {
             if (selstart > start && selstart < end) {
                 long off = selstart - start;
 
-                off = off * newLen / (end - start);
+                off = off * newLen / origLen;
                 selstart = (int) off + start;
 
                 setSpan(false, Selection.SELECTION_START, selstart, selstart,
@@ -474,7 +449,7 @@
             if (selend > start && selend < end) {
                 long off = selend - start;
 
-                off = off * newLen / (end - start);
+                off = off * newLen / origLen;
                 selend = (int) off + start;
 
                 setSpan(false, Selection.SELECTION_END, selend, selend, Spanned.SPAN_POINT_POINT);
diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java
index cbb908b..16a13cf 100644
--- a/core/java/android/view/GLES20TextureLayer.java
+++ b/core/java/android/view/GLES20TextureLayer.java
@@ -42,6 +42,12 @@
         }        
     }
 
+    GLES20TextureLayer(SurfaceTexture surface, boolean isOpaque) {
+        this(isOpaque);
+        mSurface = surface;
+        mSurface.attachToGLContext(mTexture);
+    }
+
     @Override
     boolean isValid() {
         return mLayer != 0 && mTexture != 0;
@@ -72,6 +78,14 @@
         return mSurface;
     }
 
+    void setSurfaceTexture(SurfaceTexture surfaceTexture) {
+        if (mSurface != null) {
+            mSurface.release();
+        }
+        mSurface = surfaceTexture;
+        mSurface.attachToGLContext(mTexture);
+    }
+
     @Override
     void update(int width, int height, boolean isOpaque) {
         super.update(width, height, isOpaque);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index a1e7e7d..b0399fd 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -391,9 +391,9 @@
      * @param isOpaque Whether the layer should be opaque or not
      * 
      * @return A hardware layer
-     */    
+     */
     abstract HardwareLayer createHardwareLayer(boolean isOpaque);
-    
+
     /**
      * Creates a new hardware layer.
      * 
@@ -417,6 +417,15 @@
     abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer);
 
     /**
+     * Sets the {@link android.graphics.SurfaceTexture} that will be used to
+     * render into the specified hardware layer.
+     *
+     * @param layer The layer to render into using a {@link android.graphics.SurfaceTexture}
+     * @param surfaceTexture The {@link android.graphics.SurfaceTexture} to use for the layer
+     */
+    abstract void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture);
+
+    /**
      * Initializes the hardware renderer for the specified surface and setup the
      * renderer for drawing, if needed. This is invoked when the ViewAncestor has
      * potentially lost the hardware renderer. The hardware renderer should be
@@ -1345,6 +1354,11 @@
         }
 
         @Override
+        void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture) {
+            ((GLES20TextureLayer) layer).setSurfaceTexture(surfaceTexture);
+        }
+
+        @Override
         void destroyLayers(View view) {
             if (view != null && isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) {
                 destroyHardwareLayer(view);
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 14cd48f..8fe8e40 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -62,18 +62,9 @@
     void setForcedDisplaySize(int longDimen, int shortDimen);
     void clearForcedDisplaySize();
 
-    // Is device configured with a hideable status bar or a tablet system bar?
-    boolean canStatusBarHide();
+    // Is the device configured to have a full system bar for larger screens?
+    boolean hasSystemNavBar();
 
-    // These can only be called when injecting events to your own window,
-    // or by holding the INJECT_EVENTS permission.  These methods may block
-    // until pending input events are finished being dispatched even when 'sync' is false.
-    // Avoid calling these methods on your UI thread or use the 'NoWait' version instead.
-    boolean injectKeyEvent(in KeyEvent ev, boolean sync);
-    boolean injectPointerEvent(in MotionEvent ev, boolean sync);
-    boolean injectTrackballEvent(in MotionEvent ev, boolean sync);
-    boolean injectInputEventNoWait(in InputEvent ev);
-    
     // These can only be called when holding the MANAGE_APP_TOKENS permission.
     void pauseKeyDispatching(IBinder token);
     void resumeKeyDispatching(IBinder token);
@@ -128,26 +119,6 @@
     void setAnimationScale(int which, float scale);
     void setAnimationScales(in float[] scales);
     
-    // These require the READ_INPUT_STATE permission.
-    int getSwitchState(int sw);
-    int getSwitchStateForDevice(int devid, int sw);
-    int getScancodeState(int sw);
-    int getScancodeStateForDevice(int devid, int sw);
-    int getTrackballScancodeState(int sw);
-    int getDPadScancodeState(int sw);
-    int getKeycodeState(int sw);
-    int getKeycodeStateForDevice(int devid, int sw);
-    int getTrackballKeycodeState(int sw);
-    int getDPadKeycodeState(int sw);
-    InputChannel monitorInput(String inputChannelName);
-
-    // Report whether the hardware supports the given keys; returns true if successful
-    boolean hasKeys(in int[] keycodes, inout boolean[] keyExists);
-    
-    // Get input device information.
-    InputDevice getInputDevice(int deviceId);
-    int[] getInputDeviceIds();
-    
     // For testing
     void setInTouchMode(boolean showFocus);
 
@@ -171,8 +142,10 @@
      * @param alwaysSendConfiguration Flag to force a new configuration to
      * be evaluated.  This can be used when there are other parameters in
      * configuration that are changing.
+     * @param forceRelayout If true, the window manager will always do a relayout
+     * of its windows even if the rotation hasn't changed.
      */
-    void updateRotation(boolean alwaysSendConfiguration);
+    void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout);
 
     /**
      * Retrieve the current screen orientation, constants as per
@@ -218,11 +191,6 @@
     void statusBarVisibilityChanged(int visibility);
 
     /**
-     * Called by the settings application to temporarily set the pointer speed.
-     */
-    void setPointerSpeed(int speed);
-
-    /**
      * Block until the given window has been drawn to the screen.
      */
     void waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 8115b36..93a0185 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -16,9 +16,9 @@
 
 package android.view;
 
+import android.hardware.input.InputManager;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.RemoteException;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -26,7 +26,7 @@
 /**
  * Describes the capabilities of a particular input device.
  * <p>
- * Each input device may support multiple classes of input.  For example, a multifunction
+ * Each input device may support multiple classes of input.  For example, a multi-function
  * keyboard may compose the capabilities of a standard keyboard together with a track pad mouse
  * or other pointing device.
  * </p><p>
@@ -118,7 +118,11 @@
     
     /**
      * The input source is a keyboard.
-     * 
+     *
+     * This source indicates pretty much anything that has buttons.  Use
+     * {@link #getKeyboardType()} to determine whether the keyboard has alphabetic keys
+     * and can be used to enter text.
+     *
      * @see #SOURCE_CLASS_BUTTON
      */
     public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON;
@@ -297,13 +301,7 @@
      * @return The input device or null if not found.
      */
     public static InputDevice getDevice(int id) {
-        IWindowManager wm = Display.getWindowManager();
-        try {
-            return wm.getInputDevice(id);
-        } catch (RemoteException ex) {
-            throw new RuntimeException(
-                    "Could not get input device information from Window Manager.", ex);
-        }
+        return InputManager.getInputDevice(id);
     }
     
     /**
@@ -311,23 +309,39 @@
      * @return The input device ids.
      */
     public static int[] getDeviceIds() {
-        IWindowManager wm = Display.getWindowManager();
-        try {
-            return wm.getInputDeviceIds();
-        } catch (RemoteException ex) {
-            throw new RuntimeException(
-                    "Could not get input device ids from Window Manager.", ex);
-        }
+        return InputManager.getInputDeviceIds();
     }
-    
+
     /**
      * Gets the input device id.
+     * <p>
+     * Each input device receives a unique id when it is first configured
+     * by the system.  The input device id may change when the system is restarted or if the
+     * input device is disconnected, reconnected or reconfigured at any time.
+     * If you require a stable identifier for a device that persists across
+     * boots and reconfigurations, use {@link #getDescriptor()}.
+     * </p>
+     *
      * @return The input device id.
      */
     public int getId() {
         return mId;
     }
-    
+
+    /**
+     * Gets the input device descriptor, which is a stable identifier for an input device.
+     * <p>
+     * An input device descriptor uniquely identifies an input device.  Its value
+     * is intended to be persistent across system restarts, and should not change even
+     * if the input device is disconnected, reconnected or reconfigured at any time.
+     * </p>
+     *
+     * @return The input device descriptor.
+     */
+    public String getDescriptor() {
+        return "PLACEHOLDER"; // TODO: implement for real
+    }
+
     /**
      * Gets the name of this input device.
      * @return The input device name.
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 575af3b..b03f086 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -19,7 +19,7 @@
 import android.text.method.MetaKeyKeyListener;
 import android.util.AndroidRuntimeException;
 import android.util.SparseIntArray;
-import android.os.RemoteException;
+import android.hardware.input.InputManager;
 import android.util.SparseArray;
 
 import java.lang.Character;
@@ -196,6 +196,14 @@
     }
 
     /**
+     * TODO implement this
+     * @hide
+     */
+    public static KeyCharacterMap load(CharSequence contents) {
+        return null;
+    }
+
+    /**
      * Gets the Unicode character generated by the specified key and meta
      * key state combination.
      * <p>
@@ -456,7 +464,8 @@
 
     /**
      * Gets the keyboard type.
-     * Returns {@link #NUMERIC}, {@link #PREDICTIVE}, {@link #ALPHA} or {@link #FULL}.
+     * Returns {@link #NUMERIC}, {@link #PREDICTIVE}, {@link #ALPHA}, {@link #FULL}
+     * or {@link #SPECIAL_FUNCTION}.
      * <p>
      * Different keyboard types have different semantics.  Refer to the documentation
      * associated with the keyboard type constants for details.
@@ -518,10 +527,7 @@
      * @return True if at least one attached keyboard supports the specified key code.
      */
     public static boolean deviceHasKey(int keyCode) {
-        int[] codeArray = new int[1];
-        codeArray[0] = keyCode;
-        boolean[] ret = deviceHasKeys(codeArray);
-        return ret[0];
+        return InputManager.deviceHasKeys(new int[] { keyCode })[0];
     }
 
     /**
@@ -535,14 +541,7 @@
      * at the same index in the key codes array.
      */
     public static boolean[] deviceHasKeys(int[] keyCodes) {
-        boolean[] ret = new boolean[keyCodes.length];
-        IWindowManager wm = Display.getWindowManager();
-        try {
-            wm.hasKeys(keyCodes, ret);
-        } catch (RemoteException e) {
-            // no fallback; just return the empty array
-        }
-        return ret;
+        return InputManager.deviceHasKeys(keyCodes);
     }
 
     /**
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 83999a1..3cd8b71 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -115,6 +115,7 @@
 
     private final Object[] mLock = new Object[0];
     private boolean mUpdateLayer;
+    private boolean mUpdateSurface;
 
     private SurfaceTexture.OnFrameAvailableListener mUpdateListener;
 
@@ -208,6 +209,8 @@
 
     private void destroySurface() {
         if (mLayer != null) {
+            mSurface.detachFromGLContext();
+
             boolean shouldRelease = true;
             if (mListener != null) {
                 shouldRelease = mListener.onSurfaceTextureDestroyed(mSurface);
@@ -322,9 +325,13 @@
             }
 
             mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(mOpaque);
-            mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
+            if (!mUpdateSurface) {
+                // We already have a SurfaceTexture to use, and we will pass it
+                // to mLayer below.
+                mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
+            }
             nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
-            nCreateNativeWindow(mSurface);            
+            nCreateNativeWindow(mSurface);
 
             mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() {
                 @Override
@@ -344,6 +351,15 @@
             }
         }
 
+        if (mUpdateSurface) {
+            // Someone has requested that we use a specific SurfaceTexture, so
+            // tell mLayer about it and set the SurfaceTexture to use the
+            // current view size.
+            mUpdateSurface = false;
+            mAttachInfo.mHardwareRenderer.setSurfaceTexture(mLayer, mSurface);
+            nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
+        }
+
         applyUpdate();
         applyTransformMatrix();
 
@@ -371,7 +387,7 @@
         mUpdateLayer = true;
         invalidate();
     }
-    
+
     private void applyUpdate() {
         if (mLayer == null) {
             return;
@@ -636,6 +652,32 @@
     }
 
     /**
+     * Set the {@link SurfaceTexture} for this view to use. If a {@link
+     * SurfaceTexture} is already being used by this view, it is immediately
+     * released and not be usable any more.  The {@link
+     * SurfaceTextureListener#onSurfaceTextureDestroyed} callback is <b>not</b>
+     * called.
+     *
+     * The {@link SurfaceTexture} object must be detached from all OpenGL ES
+     * contexts prior to calling this method.
+     *
+     * @param surfaceTexture The {@link SurfaceTexture} that the view should use.
+     * @see SurfaceTexture#detachFromGLContext()
+     * @hide
+     */
+    public void setSurfaceTexture(SurfaceTexture surfaceTexture) {
+        if (surfaceTexture == null) {
+            throw new NullPointerException("surfaceTexture must not be null");
+        }
+        if (mSurface != null) {
+            mSurface.release();
+        }
+        mSurface = surfaceTexture;
+        mUpdateSurface = true;
+        invalidateParentIfNeeded();
+    }
+
+    /**
      * Returns the {@link SurfaceTextureListener} currently associated with this
      * texture view.
      * 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4b35c72..d62e32f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4032,8 +4032,9 @@
      * <p>
      * <strong>Note:</strong> When a View clears focus the framework is trying
      * to give focus to the first focusable View from the top. Hence, if this
-     * View is the first from the top that can take focus, then its focus will
-     * not be cleared nor will the focus change callback be invoked.
+     * View is the first from the top that can take focus, then all callbacks
+     * related to clearing focus will be invoked after wich the framework will
+     * give focus to this view.
      * </p>
      */
     public void clearFocus() {
@@ -4050,25 +4051,15 @@
 
             onFocusChanged(false, 0, null);
             refreshDrawableState();
+
+            ensureInputFocusOnFirstFocusable();
         }
     }
 
-    /**
-     * Called to clear the focus of a view that is about to be removed.
-     * Doesn't call clearChildFocus, which prevents this view from taking
-     * focus again before it has been removed from the parent
-     */
-    void clearFocusForRemoval() {
-        if ((mPrivateFlags & FOCUSED) != 0) {
-            mPrivateFlags &= ~FOCUSED;
-
-            onFocusChanged(false, 0, null);
-            refreshDrawableState();
-
-            // The view cleared focus and invoked the callbacks, so  now is the
-            // time to give focus to the the first focusable from the top to
-            // ensure that the gain focus is announced after clear focus.
-            getRootView().requestFocus(FOCUS_FORWARD);
+    void ensureInputFocusOnFirstFocusable() {
+        View root = getRootView();
+        if (root != null) {
+            root.requestFocus(FOCUS_FORWARD);
         }
     }
 
@@ -14423,9 +14414,48 @@
     }
 
     /**
-     * Request that the visibility of the status bar be changed.
-     * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
-     * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
+     * Request that the visibility of the status bar or other screen/window
+     * decorations be changed.
+     *
+     * <p>This method is used to put the over device UI into temporary modes
+     * where the user's attention is focused more on the application content,
+     * by dimming or hiding surrounding system affordances.  This is typically
+     * used in conjunction with {@link Window#FEATURE_ACTION_BAR_OVERLAY
+     * Window.FEATURE_ACTION_BAR_OVERLAY}, allowing the applications content
+     * to be placed behind the action bar (and with these flags other system
+     * affordances) so that smooth transitions between hiding and showing them
+     * can be done.
+     *
+     * <p>Two representative examples of the use of system UI visibility is
+     * implementing a content browsing application (like a magazine reader)
+     * and a video playing application.
+     *
+     * <p>The first code shows a typical implementation of a View in a content
+     * browsing application.  In this implementation, the application goes
+     * into a content-oriented mode by hiding the status bar and action bar,
+     * and putting the navigation elements into lights out mode.  The user can
+     * then interact with content while in this mode.  Such an application should
+     * provide an easy way for the user to toggle out of the mode (such as to
+     * check information in the status bar or access notifications).  In the
+     * implementation here, this is done simply by tapping on the content.
+     *
+     * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/ContentBrowserActivity.java
+     *      content}
+     *
+     * <p>This second code sample shows a typical implementation of a View
+     * in a video playing application.  In this situation, while the video is
+     * playing the application would like to go into a complete full-screen mode,
+     * to use as much of the display as possible for the video.  When in this state
+     * the user can not interact with the application; the system intercepts
+     * touching on the screen to pop the UI out of full screen mode.
+     *
+     * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/VideoPlayerActivity.java
+     *      content}
+     *
+     * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
+     * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
+     * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
+     * and {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
      */
     public void setSystemUiVisibility(int visibility) {
         if (visibility != mSystemUiVisibility) {
@@ -14437,9 +14467,11 @@
     }
 
     /**
-     * Returns the status bar visibility that this view has requested.
-     * @return  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
-     * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
+     * Returns the last {@link #setSystemUiVisibility(int) that this view has requested.
+     * @return  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
+     * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
+     * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
+     * and {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
      */
     public int getSystemUiVisibility() {
         return mSystemUiVisibility;
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index b9924c7..9d06145 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -315,7 +315,7 @@
         if (!sHasPermanentMenuKeySet) {
             IWindowManager wm = Display.getWindowManager();
             try {
-                sHasPermanentMenuKey = wm.canStatusBarHide() && !wm.hasNavigationBar();
+                sHasPermanentMenuKey = !wm.hasSystemNavBar() && !wm.hasNavigationBar();
                 sHasPermanentMenuKeySet = true;
             } catch (RemoteException ex) {
                 sHasPermanentMenuKey = false;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index ae5debe..121b544 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3375,7 +3375,7 @@
 
         boolean clearChildFocus = false;
         if (view == mFocused) {
-            view.clearFocusForRemoval();
+            view.unFocus();
             clearChildFocus = true;
         }
 
@@ -3398,6 +3398,7 @@
 
         if (clearChildFocus) {
             clearChildFocus(view);
+            ensureInputFocusOnFirstFocusable();
         }
     }
 
@@ -3450,7 +3451,7 @@
             }
 
             if (view == focused) {
-                view.clearFocusForRemoval();
+                view.unFocus();
                 clearChildFocus = view;
             }
 
@@ -3474,6 +3475,7 @@
 
         if (clearChildFocus != null) {
             clearChildFocus(clearChildFocus);
+            ensureInputFocusOnFirstFocusable();
         }
     }
 
@@ -3519,7 +3521,7 @@
             }
 
             if (view == focused) {
-                view.clearFocusForRemoval();
+                view.unFocus();
                 clearChildFocus = view;
             }
 
@@ -3542,6 +3544,7 @@
 
         if (clearChildFocus != null) {
             clearChildFocus(clearChildFocus);
+            ensureInputFocusOnFirstFocusable();
         }
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index d72f3b7..899fb32 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2039,9 +2039,10 @@
 
         scrollToRectOrFocus(null, false);
 
-        if (mAttachInfo.mViewScrollChanged) {
-            mAttachInfo.mViewScrollChanged = false;
-            mAttachInfo.mTreeObserver.dispatchOnScrollChanged();
+        final AttachInfo attachInfo = mAttachInfo;
+        if (attachInfo.mViewScrollChanged) {
+            attachInfo.mViewScrollChanged = false;
+            attachInfo.mTreeObserver.dispatchOnScrollChanged();
         }
 
         int yoff;
@@ -2056,8 +2057,8 @@
             fullRedrawNeeded = true;
         }
 
-        final float appScale = mAttachInfo.mApplicationScale;
-        final boolean scalingRequired = mAttachInfo.mScalingRequired;
+        final float appScale = attachInfo.mApplicationScale;
+        final boolean scalingRequired = attachInfo.mScalingRequired;
 
         int resizeAlpha = 0;
         if (mResizeBuffer != null) {
@@ -2086,7 +2087,7 @@
         }
 
         if (fullRedrawNeeded) {
-            mAttachInfo.mIgnoreDirtyState = true;
+            attachInfo.mIgnoreDirtyState = true;
             dirty.set(0, 0, (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
         }
 
@@ -2099,8 +2100,10 @@
                     appScale + ", width=" + mWidth + ", height=" + mHeight);
         }
 
+        attachInfo.mTreeObserver.dispatchOnDraw();
+
         if (!dirty.isEmpty() || mIsAnimating) {
-            if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
+            if (attachInfo.mHardwareRenderer != null && attachInfo.mHardwareRenderer.isEnabled()) {
                 // Draw with hardware renderer.
                 mIsAnimating = false;
                 mHardwareYOffset = yoff;
@@ -2111,147 +2114,12 @@
                 mPreviousDirty.set(dirty);
                 dirty.setEmpty();
 
-                if (mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this,
+                if (attachInfo.mHardwareRenderer.draw(mView, attachInfo, this,
                         animating ? null : mCurrentDirty)) {
                     mPreviousDirty.set(0, 0, mWidth, mHeight);
                 }
-            } else {
-                // Draw with software renderer.
-                Canvas canvas;
-                try {
-                    int left = dirty.left;
-                    int top = dirty.top;
-                    int right = dirty.right;
-                    int bottom = dirty.bottom;
-
-                    final long lockCanvasStartTime;
-                    if (ViewDebug.DEBUG_LATENCY) {
-                        lockCanvasStartTime = System.nanoTime();
-                    }
-
-                    canvas = mSurface.lockCanvas(dirty);
-
-                    if (ViewDebug.DEBUG_LATENCY) {
-                        long now = System.nanoTime();
-                        Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- lockCanvas() took "
-                                + ((now - lockCanvasStartTime) * 0.000001f) + "ms");
-                    }
-
-                    if (left != dirty.left || top != dirty.top || right != dirty.right ||
-                            bottom != dirty.bottom) {
-                        mAttachInfo.mIgnoreDirtyState = true;
-                    }
-
-                    // TODO: Do this in native
-                    canvas.setDensity(mDensity);
-                } catch (Surface.OutOfResourcesException e) {
-                    Log.e(TAG, "OutOfResourcesException locking surface", e);
-                    try {
-                        if (!sWindowSession.outOfMemory(mWindow)) {
-                            Slog.w(TAG, "No processes killed for memory; killing self");
-                            Process.killProcess(Process.myPid());
-                        }
-                    } catch (RemoteException ex) {
-                    }
-                    mLayoutRequested = true;    // ask wm for a new surface next time.
-                    return;
-                } catch (IllegalArgumentException e) {
-                    Log.e(TAG, "IllegalArgumentException locking surface", e);
-                    // Don't assume this is due to out of memory, it could be
-                    // something else, and if it is something else then we could
-                    // kill stuff (or ourself) for no reason.
-                    mLayoutRequested = true;    // ask wm for a new surface next time.
-                    return;
-                }
-
-                try {
-                    if (DEBUG_ORIENTATION || DEBUG_DRAW) {
-                        Log.v(TAG, "Surface " + surface + " drawing to bitmap w="
-                                + canvas.getWidth() + ", h=" + canvas.getHeight());
-                        //canvas.drawARGB(255, 255, 0, 0);
-                    }
-
-                    long startTime = 0L;
-                    if (ViewDebug.DEBUG_PROFILE_DRAWING) {
-                        startTime = SystemClock.elapsedRealtime();
-                    }
-
-                    // If this bitmap's format includes an alpha channel, we
-                    // need to clear it before drawing so that the child will
-                    // properly re-composite its drawing on a transparent
-                    // background. This automatically respects the clip/dirty region
-                    // or
-                    // If we are applying an offset, we need to clear the area
-                    // where the offset doesn't appear to avoid having garbage
-                    // left in the blank areas.
-                    if (!canvas.isOpaque() || yoff != 0) {
-                        canvas.drawColor(0, PorterDuff.Mode.CLEAR);
-                    }
-
-                    dirty.setEmpty();
-                    mIsAnimating = false;
-                    mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
-                    mView.mPrivateFlags |= View.DRAWN;
-
-                    if (DEBUG_DRAW) {
-                        Context cxt = mView.getContext();
-                        Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
-                                ", metrics=" + cxt.getResources().getDisplayMetrics() +
-                                ", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
-                    }
-                    try {
-                        canvas.translate(0, -yoff);
-                        if (mTranslator != null) {
-                            mTranslator.translateCanvas(canvas);
-                        }
-                        canvas.setScreenDensity(scalingRequired
-                                ? DisplayMetrics.DENSITY_DEVICE : 0);
-                        mAttachInfo.mSetIgnoreDirtyState = false;
-
-                        final long drawStartTime;
-                        if (ViewDebug.DEBUG_LATENCY) {
-                            drawStartTime = System.nanoTime();
-                        }
-
-                        mView.draw(canvas);
-
-                        if (ViewDebug.DEBUG_LATENCY) {
-                            long now = System.nanoTime();
-                            Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- draw() took "
-                                    + ((now - drawStartTime) * 0.000001f) + "ms");
-                        }
-                    } finally {
-                        if (!mAttachInfo.mSetIgnoreDirtyState) {
-                            // Only clear the flag if it was not set during the mView.draw() call
-                            mAttachInfo.mIgnoreDirtyState = false;
-                        }
-                    }
-
-                    if (false && ViewDebug.consistencyCheckEnabled) {
-                        mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
-                    }
-
-                    if (ViewDebug.DEBUG_PROFILE_DRAWING) {
-                        EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
-                    }
-                } finally {
-                    final long unlockCanvasAndPostStartTime;
-                    if (ViewDebug.DEBUG_LATENCY) {
-                        unlockCanvasAndPostStartTime = System.nanoTime();
-                    }
-
-                    surface.unlockCanvasAndPost(canvas);
-
-                    if (ViewDebug.DEBUG_LATENCY) {
-                        long now = System.nanoTime();
-                        Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- unlockCanvasAndPost() took "
-                                + ((now - unlockCanvasAndPostStartTime) * 0.000001f) + "ms");
-                    }
-
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "Surface " + surface + " unlockCanvasAndPost");
-                    }
-                }
+            } else if (!drawSoftware(surface, attachInfo, yoff, scalingRequired, dirty)) {
+                return;
             }
         }
 
@@ -2261,6 +2129,151 @@
         }
     }
 
+    /**
+     * @return true if drawing was succesfull, false if an error occurred
+     */
+    private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int yoff,
+            boolean scalingRequired, Rect dirty) {
+
+        // Draw with software renderer.
+        Canvas canvas;
+        try {
+            int left = dirty.left;
+            int top = dirty.top;
+            int right = dirty.right;
+            int bottom = dirty.bottom;
+
+            final long lockCanvasStartTime;
+            if (ViewDebug.DEBUG_LATENCY) {
+                lockCanvasStartTime = System.nanoTime();
+            }
+
+            canvas = mSurface.lockCanvas(dirty);
+
+            if (ViewDebug.DEBUG_LATENCY) {
+                long now = System.nanoTime();
+                Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- lockCanvas() took "
+                        + ((now - lockCanvasStartTime) * 0.000001f) + "ms");
+            }
+
+            if (left != dirty.left || top != dirty.top || right != dirty.right ||
+                    bottom != dirty.bottom) {
+                attachInfo.mIgnoreDirtyState = true;
+            }
+
+            // TODO: Do this in native
+            canvas.setDensity(mDensity);
+        } catch (Surface.OutOfResourcesException e) {
+            Log.e(TAG, "OutOfResourcesException locking surface", e);
+            try {
+                if (!sWindowSession.outOfMemory(mWindow)) {
+                    Slog.w(TAG, "No processes killed for memory; killing self");
+                    Process.killProcess(Process.myPid());
+                }
+            } catch (RemoteException ex) {
+            }
+            mLayoutRequested = true;    // ask wm for a new surface next time.
+            return false;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "IllegalArgumentException locking surface", e);
+            // Don't assume this is due to out of memory, it could be
+            // something else, and if it is something else then we could
+            // kill stuff (or ourself) for no reason.
+            mLayoutRequested = true;    // ask wm for a new surface next time.
+            return false;
+        }
+
+        try {
+            if (DEBUG_ORIENTATION || DEBUG_DRAW) {
+                Log.v(TAG, "Surface " + surface + " drawing to bitmap w="
+                        + canvas.getWidth() + ", h=" + canvas.getHeight());
+                //canvas.drawARGB(255, 255, 0, 0);
+            }
+
+            long startTime = 0L;
+            if (ViewDebug.DEBUG_PROFILE_DRAWING) {
+                startTime = SystemClock.elapsedRealtime();
+            }
+
+            // If this bitmap's format includes an alpha channel, we
+            // need to clear it before drawing so that the child will
+            // properly re-composite its drawing on a transparent
+            // background. This automatically respects the clip/dirty region
+            // or
+            // If we are applying an offset, we need to clear the area
+            // where the offset doesn't appear to avoid having garbage
+            // left in the blank areas.
+            if (!canvas.isOpaque() || yoff != 0) {
+                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+            }
+
+            dirty.setEmpty();
+            mIsAnimating = false;
+            attachInfo.mDrawingTime = SystemClock.uptimeMillis();
+            mView.mPrivateFlags |= View.DRAWN;
+
+            if (DEBUG_DRAW) {
+                Context cxt = mView.getContext();
+                Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
+                        ", metrics=" + cxt.getResources().getDisplayMetrics() +
+                        ", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
+            }
+            try {
+                canvas.translate(0, -yoff);
+                if (mTranslator != null) {
+                    mTranslator.translateCanvas(canvas);
+                }
+                canvas.setScreenDensity(scalingRequired
+                        ? DisplayMetrics.DENSITY_DEVICE : 0);
+                attachInfo.mSetIgnoreDirtyState = false;
+
+                final long drawStartTime;
+                if (ViewDebug.DEBUG_LATENCY) {
+                    drawStartTime = System.nanoTime();
+                }
+
+                mView.draw(canvas);
+
+                if (ViewDebug.DEBUG_LATENCY) {
+                    long now = System.nanoTime();
+                    Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- draw() took "
+                            + ((now - drawStartTime) * 0.000001f) + "ms");
+                }
+            } finally {
+                if (!attachInfo.mSetIgnoreDirtyState) {
+                    // Only clear the flag if it was not set during the mView.draw() call
+                    attachInfo.mIgnoreDirtyState = false;
+                }
+            }
+
+            if (false && ViewDebug.consistencyCheckEnabled) {
+                mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
+            }
+
+            if (ViewDebug.DEBUG_PROFILE_DRAWING) {
+                EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
+            }
+        } finally {
+            final long unlockCanvasAndPostStartTime;
+            if (ViewDebug.DEBUG_LATENCY) {
+                unlockCanvasAndPostStartTime = System.nanoTime();
+            }
+
+            surface.unlockCanvasAndPost(canvas);
+
+            if (ViewDebug.DEBUG_LATENCY) {
+                long now = System.nanoTime();
+                Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- unlockCanvasAndPost() took "
+                        + ((now - unlockCanvasAndPostStartTime) * 0.000001f) + "ms");
+            }
+
+            if (LOCAL_LOGV) {
+                Log.v(TAG, "Surface " + surface + " unlockCanvasAndPost");
+            }
+        }
+        return true;
+    }
+
     void invalidateDisplayLists() {
         final ArrayList<DisplayList> displayLists = mDisplayLists;
         final int count = displayLists.size();
@@ -3830,30 +3843,33 @@
         if (LOCAL_LOGV) Log.v(TAG, "DIE in " + this + " of " + mSurface);
         synchronized (this) {
             if (mAdded) {
-                mAdded = false;
                 dispatchDetachedFromWindow();
             }
 
             if (mAdded && !mFirst) {
                 destroyHardwareRenderer();
 
-                int viewVisibility = mView.getVisibility();
-                boolean viewVisibilityChanged = mViewVisibility != viewVisibility;
-                if (mWindowAttributesChanged || viewVisibilityChanged) {
-                    // If layout params have been changed, first give them
-                    // to the window manager to make sure it has the correct
-                    // animation info.
-                    try {
-                        if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
-                                & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
-                            sWindowSession.finishDrawing(mWindow);
+                if (mView != null) {
+                    int viewVisibility = mView.getVisibility();
+                    boolean viewVisibilityChanged = mViewVisibility != viewVisibility;
+                    if (mWindowAttributesChanged || viewVisibilityChanged) {
+                        // If layout params have been changed, first give them
+                        // to the window manager to make sure it has the correct
+                        // animation info.
+                        try {
+                            if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
+                                    & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
+                                sWindowSession.finishDrawing(mWindow);
+                            }
+                        } catch (RemoteException e) {
                         }
-                    } catch (RemoteException e) {
                     }
+    
+                    mSurface.release();
                 }
-
-                mSurface.release();
             }
+
+            mAdded = false;
         }
     }
 
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 7fd3389..1c5d436 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -38,6 +38,7 @@
     private CopyOnWriteArrayList<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
     private CopyOnWriteArrayList<OnScrollChangedListener> mOnScrollChangedListeners;
     private ArrayList<OnPreDrawListener> mOnPreDrawListeners;
+    private ArrayList<OnDrawListener> mOnDrawListeners;
 
     private boolean mAlive = true;
 
@@ -90,6 +91,27 @@
     }
 
     /**
+     * Interface definition for a callback to be invoked when the view tree is about to be drawn.
+     */
+    public interface OnDrawListener {
+        /**
+         * <p>Callback method to be invoked when the view tree is about to be drawn. At this point,
+         * views cannot be modified in any way.</p>
+         * 
+         * <p>Unlike with {@link OnPreDrawListener}, this method cannot be used to cancel the
+         * current drawing pass.</p>
+         * 
+         * <p>An {@link OnDrawListener} listener <strong>cannot be added or removed</strong>
+         * from this method.</p>
+         *
+         * @see android.view.View#onMeasure
+         * @see android.view.View#onLayout
+         * @see android.view.View#onDraw
+         */
+        public void onDraw();
+    }
+
+    /**
      * Interface definition for a callback to be invoked when the touch mode changes.
      */
     public interface OnTouchModeChangeListener {
@@ -171,11 +193,7 @@
         public void setTouchableInsets(int val) {
             mTouchableInsets = val;
         }
-        
-        public int getTouchableInsets() {
-            return mTouchableInsets;
-        }
-        
+
         int mTouchableInsets;
         
         void reset() {
@@ -184,29 +202,28 @@
             touchableRegion.setEmpty();
             mTouchableInsets = TOUCHABLE_INSETS_FRAME;
         }
-        
+
+        @Override
+        public int hashCode() {
+            int result = contentInsets != null ? contentInsets.hashCode() : 0;
+            result = 31 * result + (visibleInsets != null ? visibleInsets.hashCode() : 0);
+            result = 31 * result + (touchableRegion != null ? touchableRegion.hashCode() : 0);
+            result = 31 * result + mTouchableInsets;
+            return result;
+        }
+
         @Override
         public boolean equals(Object o) {
-            try {
-                if (o == null) {
-                    return false;
-                }
-                InternalInsetsInfo other = (InternalInsetsInfo)o;
-                if (mTouchableInsets != other.mTouchableInsets) {
-                    return false;
-                }
-                if (!contentInsets.equals(other.contentInsets)) {
-                    return false;
-                }
-                if (!visibleInsets.equals(other.visibleInsets)) {
-                    return false;
-                }
-                return touchableRegion.equals(other.touchableRegion);
-            } catch (ClassCastException e) {
-                return false;
-            }
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            InternalInsetsInfo other = (InternalInsetsInfo)o;
+            return mTouchableInsets == other.mTouchableInsets &&
+                    contentInsets.equals(other.contentInsets) &&
+                    visibleInsets.equals(other.visibleInsets) &&
+                    touchableRegion.equals(other.touchableRegion);
         }
-        
+
         void set(InternalInsetsInfo other) {
             contentInsets.set(other.contentInsets);
             visibleInsets.set(other.visibleInsets);
@@ -420,6 +437,44 @@
     }
 
     /**
+     * <p>Register a callback to be invoked when the view tree is about to be drawn.</p>
+     * <p><strong>Note:</strong> this method <strong>cannot</strong> be invoked from
+     * {@link android.view.ViewTreeObserver.OnDrawListener#onDraw()}.</p>
+     *
+     * @param listener The callback to add
+     *
+     * @throws IllegalStateException If {@link #isAlive()} returns false
+     */
+    public void addOnDrawListener(OnDrawListener listener) {
+        checkIsAlive();
+
+        if (mOnDrawListeners == null) {
+            mOnDrawListeners = new ArrayList<OnDrawListener>();
+        }
+
+        mOnDrawListeners.add(listener);
+    }
+
+    /**
+     * <p>Remove a previously installed pre-draw callback.</p>
+     * <p><strong>Note:</strong> this method <strong>cannot</strong> be invoked from
+     * {@link android.view.ViewTreeObserver.OnDrawListener#onDraw()}.</p>
+     *
+     * @param victim The callback to remove
+     *
+     * @throws IllegalStateException If {@link #isAlive()} returns false
+     *
+     * @see #addOnDrawListener(OnDrawListener)
+     */
+    public void removeOnDrawListener(OnDrawListener victim) {
+        checkIsAlive();
+        if (mOnDrawListeners == null) {
+            return;
+        }
+        mOnDrawListeners.remove(victim);
+    }
+
+    /**
      * Register a callback to be invoked when a view has been scrolled.
      *
      * @param listener The callback to add
@@ -601,6 +656,7 @@
      *
      * @return True if the current draw should be canceled and resceduled, false otherwise.
      */
+    @SuppressWarnings("unchecked")
     public final boolean dispatchOnPreDraw() {
         // NOTE: we *must* clone the listener list to perform the dispatching.
         // The clone is a safe guard against listeners that
@@ -619,6 +675,19 @@
     }
 
     /**
+     * Notifies registered listeners that the drawing pass is about to start.
+     */
+    public final void dispatchOnDraw() {
+        if (mOnDrawListeners != null) {
+            final ArrayList<OnDrawListener> listeners = mOnDrawListeners;
+            int numListeners = listeners.size();
+            for (int i = 0; i < numListeners; ++i) {
+                listeners.get(i).onDraw();
+            }
+        }
+    }
+
+    /**
      * Notifies registered listeners that the touch mode has changed.
      *
      * @param inTouchMode True if the touch mode is now enabled, false otherwise.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 75267bb..491cd67 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -326,6 +326,11 @@
          * Returns true if {@link #hideLw} was last called for the window.
          */
         public boolean showLw(boolean doAnimation);
+
+        /**
+         * Check whether the process hosting this window is currently alive.
+         */
+        public boolean isAlive();
     }
 
     /**
@@ -344,6 +349,10 @@
      * between it and the policy.
      */
     public interface WindowManagerFuncs {
+        public static final int LID_ABSENT = -1;
+        public static final int LID_CLOSED = 0;
+        public static final int LID_OPEN = 1;
+
         /**
          * Ask the window manager to re-evaluate the system UI flags.
          */
@@ -357,6 +366,16 @@
                 InputEventReceiver.Factory inputEventReceiverFactory,
                 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
                 boolean hasFocus, boolean touchFullscreen);
+
+        /**
+         * Returns a code that describes the current state of the lid switch.
+         */
+        public int getLidState();
+
+        /**
+         * Creates an input channel that will receive all input from the input dispatcher.
+         */
+        public InputChannel monitorInput(String name);
     }
 
     /**
@@ -447,7 +466,7 @@
      * Called by window manager once it has the initial, default native
      * display dimensions.
      */
-    public void setInitialDisplaySize(int width, int height);
+    public void setInitialDisplaySize(Display display, int width, int height);
 
     /**
      * Check permissions when adding a window.
@@ -514,10 +533,10 @@
     public int getMaxWallpaperLayer();
     
     /**
-     * Return true if the policy allows the status bar to hide.  Otherwise,
-     * it is a tablet-style system bar.
+     * Return true if the policy desires a full unified system nav bar.  Otherwise,
+     * it is a phone-style status bar with optional nav bar.
      */
-    public boolean canStatusBarHide();
+    public boolean hasSystemNavBar();
 
     /**
      * Return the display width available after excluding any screen
@@ -938,10 +957,10 @@
     public void setRotationLw(int rotation);
 
     /**
-     * Called when the system is mostly done booting to determine whether
+     * Called when the system is mostly done booting to set whether
      * the system should go into safe mode.
      */
-    public boolean detectSafeMode();
+    public void setSafeMode(boolean safeMode);
     
     /**
      * Called when the system is mostly done booting.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 17dbde8..067be39 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -405,7 +405,9 @@
                             }
                             // Check focus again in case that "onWindowFocus" is called before
                             // handling this message.
-                            checkFocus(mHasBeenInactive);
+                            if (mServedView != null && mServedView.hasWindowFocus()) {
+                                checkFocus(mHasBeenInactive);
+                            }
                         }
                     }
                     return;
@@ -1202,7 +1204,9 @@
             }
             if (DEBUG) Log.v(TAG, "checkFocus: view=" + mServedView
                     + " next=" + mNextServedView
-                    + " forceNewFocus=" + forceNewFocus);
+                    + " forceNewFocus=" + forceNewFocus
+                    + " package="
+                    + (mServedView != null ? mServedView.getContext().getPackageName() : "<none>"));
 
             if (mNextServedView == null) {
                 finishInputLocked();
diff --git a/core/java/android/view/textservice/SpellCheckerInfo.java b/core/java/android/view/textservice/SpellCheckerInfo.java
index 137743a..d05c1af 100644
--- a/core/java/android/view/textservice/SpellCheckerInfo.java
+++ b/core/java/android/view/textservice/SpellCheckerInfo.java
@@ -45,6 +45,7 @@
     private final ResolveInfo mService;
     private final String mId;
     private final int mLabel;
+    private final boolean mSupportsSentenceSpellCheck;
 
     /**
      * The spell checker setting activity's name, used by the system settings to
@@ -97,6 +98,9 @@
             label = sa.getResourceId(com.android.internal.R.styleable.SpellChecker_label, 0);
             settingsActivityComponent = sa.getString(
                     com.android.internal.R.styleable.SpellChecker_settingsActivity);
+            mSupportsSentenceSpellCheck = sa.getBoolean(
+                    com.android.internal.R.styleable.SpellChecker_supportsSentenceSpellCheck,
+                    false);
             sa.recycle();
 
             final int depth = parser.getDepth();
@@ -138,6 +142,7 @@
      */
     public SpellCheckerInfo(Parcel source) {
         mLabel = source.readInt();
+        mSupportsSentenceSpellCheck = source.readInt() != 0;
         mId = source.readString();
         mSettingsActivityName = source.readString();
         mService = ResolveInfo.CREATOR.createFromParcel(source);
@@ -152,6 +157,12 @@
         return mId;
     }
 
+    /**
+     * @hide
+     */
+    public boolean isSentenceSpellCheckSupported() {
+        return mSupportsSentenceSpellCheck;
+    }
 
     /**
      * Return the component of the service that implements.
@@ -177,6 +188,7 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mLabel);
+        dest.writeInt(mSupportsSentenceSpellCheck ? 1 : 0);
         dest.writeString(mId);
         dest.writeString(mSettingsActivityName);
         mService.writeToParcel(dest, flags);
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 35940ba..9dc05e4 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -436,15 +436,15 @@
      */
     public interface SpellCheckerSessionListener {
         /**
-         * Callback for {@link SpellCheckerSession#getSuggestions(TextInfo[], int, boolean)}
+         * Callback for {@link SpellCheckerSession#getSuggestions(TextInfo, int)}
+         * and {@link SpellCheckerSession#getSuggestions(TextInfo[], int, boolean)}
          * @param results an array of {@link SuggestionsInfo}s.
          * These results are suggestions for {@link TextInfo}s queried by
-         * {@link SpellCheckerSession#getSuggestions(TextInfo[], int, boolean)}.
+         * {@link SpellCheckerSession#getSuggestions(TextInfo, int)} or
+         * {@link SpellCheckerSession#getSuggestions(TextInfo[], int, boolean)}
          */
         public void onGetSuggestions(SuggestionsInfo[] results);
-        // TODO: Remove @hide as soon as the sample spell checker client gets fixed.
         /**
-         * @hide
          * Callback for {@link SpellCheckerSession#getSentenceSuggestions(TextInfo[], int)}
          * @param results an array of {@link SentenceSuggestionsInfo}s.
          * These results are suggestions for {@link TextInfo}s
@@ -494,7 +494,7 @@
     }
 
     /**
-     * @hide
+     * @return true if the spell checker supports sentence level spell checking APIs
      */
     public boolean isSentenceSpellCheckSupported() {
         return mSubtype.containsExtraValueKey(SUPPORT_SENTENCE_SPELL_CHECK);
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index 94b46fc..aa3d8d3 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -33,7 +33,7 @@
  */
 public class WebSettingsClassic extends WebSettings {
     // TODO: Keep this up to date
-    private static final String PREVIOUS_VERSION = "4.0.3";
+    private static final String PREVIOUS_VERSION = "4.0.4";
 
     // WebView associated with this WebSettings.
     private WebViewClassic mWebView;
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index 0370049..9c9eb4b 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -25,6 +25,7 @@
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Slog;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.RemoteViews.RemoteView;
@@ -247,6 +248,7 @@
             }
         }
         setText(text);
+        Slog.v("Chronometer", "updateText: sec=" + seconds + " mFormat=" + mFormat + " text=" + text);
     }
 
     private void updateRunning() {
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 3115eff..f1dffa1 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -85,6 +85,8 @@
     private TabImpl mSelectedTab;
     private int mSavedTabPosition = INVALID_POSITION;
     
+    private boolean mDisplayHomeAsUpSet;
+
     ActionModeImpl mActionMode;
     ActionMode mDeferredDestroyActionMode;
     ActionMode.Callback mDeferredModeDestroyCallback;
@@ -375,11 +377,17 @@
     }
 
     public void setDisplayOptions(int options) {
+        if ((options & DISPLAY_HOME_AS_UP) != 0) {
+            mDisplayHomeAsUpSet = true;
+        }
         mActionView.setDisplayOptions(options);
     }
 
     public void setDisplayOptions(int options, int mask) {
         final int current = mActionView.getDisplayOptions(); 
+        if ((mask & DISPLAY_HOME_AS_UP) != 0) {
+            mDisplayHomeAsUpSet = true;
+        }
         mActionView.setDisplayOptions((options & mask) | (current & ~mask));
     }
 
@@ -1072,4 +1080,10 @@
     public void setLogo(Drawable logo) {
         mActionView.setLogo(logo);
     }
+
+    public void setDefaultDisplayHomeAsUpEnabled(boolean enable) {
+        if (!mDisplayHomeAsUpSet) {
+            setDisplayHomeAsUpEnabled(enable);
+        }
+    }
 }
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index ccd2763..d59585f 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.net;
 
-import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
@@ -101,7 +101,7 @@
             while (reader.hasMoreData()) {
                 entry.iface = reader.nextString();
                 entry.uid = UID_ALL;
-                entry.set = SET_DEFAULT;
+                entry.set = SET_ALL;
                 entry.tag = TAG_NONE;
 
                 final boolean active = reader.nextInt() != 0;
@@ -165,7 +165,7 @@
 
             entry.iface = iface;
             entry.uid = UID_ALL;
-            entry.set = SET_DEFAULT;
+            entry.set = SET_ALL;
             entry.tag = TAG_NONE;
             entry.rxBytes = readSingleLongFromFile(new File(ifacePath, "rx_bytes"));
             entry.rxPackets = readSingleLongFromFile(new File(ifacePath, "rx_packets"));
@@ -193,7 +193,7 @@
                 try {
                     entry.iface = values.get(0);
                     entry.uid = UID_ALL;
-                    entry.set = SET_DEFAULT;
+                    entry.set = SET_ALL;
                     entry.tag = TAG_NONE;
                     entry.rxBytes = Long.parseLong(values.get(1));
                     entry.rxPackets = Long.parseLong(values.get(2));
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 8521481..d1652df 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -18,14 +18,11 @@
 
 import com.android.internal.app.ActionBarImpl;
 
-import android.animation.LayoutTransition;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
-import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
 
 /**
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
new file mode 100644
index 0000000..c72c770
--- /dev/null
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 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.internal.widget;
+
+/** {@hide} */
+interface ILockSettings {
+    void setBoolean(in String key, in boolean value, in int userId);
+    void setLong(in String key, in long value, in int userId);
+    void setString(in String key, in String value, in int userId);
+    boolean getBoolean(in String key, in boolean defaultValue, in int userId);
+    long getLong(in String key, in long defaultValue, in int userId);
+    String getString(in String key, in String defaultValue, in int userId);
+    void setLockPattern(in byte[] hash, int userId);
+    boolean checkPattern(in byte[] hash, int userId);
+    void setLockPassword(in byte[] hash, int userId);
+    boolean checkPassword(in byte[] hash, int userId);
+    boolean havePattern(int userId);
+    boolean havePassword(int userId);
+    void removeUser(int userId);
+}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 93f90f6..4d308dd 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -21,15 +21,20 @@
 import com.google.android.collect.Lists;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.os.Binder;
 import android.os.FileObserver;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.UserId;
 import android.os.storage.IMountService;
 import android.provider.Settings;
 import android.security.KeyStore;
@@ -59,10 +64,6 @@
 
     private static final String TAG = "LockPatternUtils";
 
-    private static final String SYSTEM_DIRECTORY = "/system/";
-    private static final String LOCK_PATTERN_FILE = "gesture.key";
-    private static final String LOCK_PASSWORD_FILE = "password.key";
-
     /**
      * The maximum number of incorrect attempts before the user is prevented
      * from trying again for {@link #FAILED_ATTEMPT_TIMEOUT_MS}.
@@ -111,14 +112,14 @@
      */
     public static final int FLAG_BIOMETRIC_WEAK_LIVELINESS = 0x1;
 
-    private final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
-    private final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
-    private final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
+    protected final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
+    protected final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
+    protected final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
     public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
     public static final String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate";
-    private final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
-    private final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
-    private final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
+    protected final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
+    protected final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
+    protected final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
     public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK
             = "lockscreen.biometric_weak_fallback";
     public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY
@@ -126,35 +127,13 @@
     public final static String LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
             = "lockscreen.power_button_instantly_locks";
 
-    private final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
+    protected final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
 
     private final Context mContext;
     private final ContentResolver mContentResolver;
     private DevicePolicyManager mDevicePolicyManager;
-    private static String sLockPatternFilename;
-    private static String sLockPasswordFilename;
-
-    private static final AtomicBoolean sHaveNonZeroPatternFile = new AtomicBoolean(false);
-    private static final AtomicBoolean sHaveNonZeroPasswordFile = new AtomicBoolean(false);
-
-    private static FileObserver sPasswordObserver;
-
-    private static class PasswordFileObserver extends FileObserver {
-        public PasswordFileObserver(String path, int mask) {
-            super(path, mask);
-        }
-
-        @Override
-        public void onEvent(int event, String path) {
-            if (LOCK_PATTERN_FILE.equals(path)) {
-                Log.d(TAG, "lock pattern file changed");
-                sHaveNonZeroPatternFile.set(new File(sLockPatternFilename).length() > 0);
-            } else if (LOCK_PASSWORD_FILE.equals(path)) {
-                Log.d(TAG, "lock password file changed");
-                sHaveNonZeroPasswordFile.set(new File(sLockPasswordFilename).length() > 0);
-            }
-        }
-    }
+    private ILockSettings mLockSettingsService;
+    private int mCurrentUserId = 0;
 
     public DevicePolicyManager getDevicePolicyManager() {
         if (mDevicePolicyManager == null) {
@@ -167,34 +146,27 @@
         }
         return mDevicePolicyManager;
     }
+
     /**
      * @param contentResolver Used to look up and save settings.
      */
     public LockPatternUtils(Context context) {
         mContext = context;
         mContentResolver = context.getContentResolver();
+    }
 
-        // Initialize the location of gesture & PIN lock files
-        if (sLockPatternFilename == null) {
-            String dataSystemDirectory =
-                    android.os.Environment.getDataDirectory().getAbsolutePath() +
-                    SYSTEM_DIRECTORY;
-            sLockPatternFilename =  dataSystemDirectory + LOCK_PATTERN_FILE;
-            sLockPasswordFilename = dataSystemDirectory + LOCK_PASSWORD_FILE;
-            sHaveNonZeroPatternFile.set(new File(sLockPatternFilename).length() > 0);
-            sHaveNonZeroPasswordFile.set(new File(sLockPasswordFilename).length() > 0);
-            int fileObserverMask = FileObserver.CLOSE_WRITE | FileObserver.DELETE |
-                    FileObserver.MOVED_TO | FileObserver.CREATE;
-            sPasswordObserver = new PasswordFileObserver(dataSystemDirectory, fileObserverMask);
-            sPasswordObserver.startWatching();
+    private ILockSettings getLockSettings() {
+        if (mLockSettingsService == null) {
+            mLockSettingsService = ILockSettings.Stub.asInterface(
+                (IBinder) ServiceManager.getService("lock_settings"));
         }
+        return mLockSettingsService;
     }
 
     public int getRequestedMinimumPasswordLength() {
         return getDevicePolicyManager().getPasswordMinimumLength(null);
     }
 
-
     /**
      * Gets the device policy password mode. If the mode is non-specific, returns
      * MODE_PATTERN which allows the user to choose anything.
@@ -243,6 +215,33 @@
         getDevicePolicyManager().reportSuccessfulPasswordAttempt();
     }
 
+    public void setCurrentUser(int userId) {
+        if (Process.myUid() == Process.SYSTEM_UID) {
+            mCurrentUserId = userId;
+        } else {
+            throw new SecurityException("Only the system process can set the current user");
+        }
+    }
+
+    public void removeUser(int userId) {
+        if (Process.myUid() == Process.SYSTEM_UID) {
+            try {
+                getLockSettings().removeUser(userId);
+            } catch (RemoteException re) {
+                Log.e(TAG, "Couldn't remove lock settings for user " + userId);
+            }
+        }
+    }
+
+    private int getCurrentOrCallingUserId() {
+        int callingUid = Binder.getCallingUid();
+        if (callingUid == android.os.Process.SYSTEM_UID) {
+            return mCurrentUserId;
+        } else {
+            return UserId.getUserId(callingUid);
+        }
+    }
+
     /**
      * Check to see if a pattern matches the saved pattern.  If no pattern exists,
      * always returns true.
@@ -250,20 +249,10 @@
      * @return Whether the pattern matches the stored one.
      */
     public boolean checkPattern(List<LockPatternView.Cell> pattern) {
+        int userId = getCurrentOrCallingUserId();
         try {
-            // Read all the bytes from the file
-            RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename, "r");
-            final byte[] stored = new byte[(int) raf.length()];
-            int got = raf.read(stored, 0, stored.length);
-            raf.close();
-            if (got <= 0) {
-                return true;
-            }
-            // Compare the hash from the file with the entered pattern's hash
-            return Arrays.equals(stored, LockPatternUtils.patternToHash(pattern));
-        } catch (FileNotFoundException fnfe) {
-            return true;
-        } catch (IOException ioe) {
+            return getLockSettings().checkPattern(patternToHash(pattern), userId);
+        } catch (RemoteException re) {
             return true;
         }
     }
@@ -275,20 +264,10 @@
      * @return Whether the password matches the stored one.
      */
     public boolean checkPassword(String password) {
+        int userId = getCurrentOrCallingUserId();
         try {
-            // Read all the bytes from the file
-            RandomAccessFile raf = new RandomAccessFile(sLockPasswordFilename, "r");
-            final byte[] stored = new byte[(int) raf.length()];
-            int got = raf.read(stored, 0, stored.length);
-            raf.close();
-            if (got <= 0) {
-                return true;
-            }
-            // Compare the hash from the file with the entered password's hash
-            return Arrays.equals(stored, passwordToHash(password));
-        } catch (FileNotFoundException fnfe) {
-            return true;
-        } catch (IOException ioe) {
+            return getLockSettings().checkPassword(passwordToHash(password), userId);
+        } catch (RemoteException re) {
             return true;
         }
     }
@@ -325,7 +304,11 @@
      * @return Whether a saved pattern exists.
      */
     public boolean savedPatternExists() {
-        return sHaveNonZeroPatternFile.get();
+        try {
+            return getLockSettings().havePattern(getCurrentOrCallingUserId());
+        } catch (RemoteException re) {
+            return false;
+        }
     }
 
     /**
@@ -333,7 +316,11 @@
      * @return Whether a saved pattern exists.
      */
     public boolean savedPasswordExists() {
-        return sHaveNonZeroPasswordFile.get();
+        try {
+            return getLockSettings().havePassword(getCurrentOrCallingUserId());
+        } catch (RemoteException re) {
+            return false;
+        }
     }
 
     /**
@@ -471,15 +458,7 @@
         // Compute the hash
         final byte[] hash = LockPatternUtils.patternToHash(pattern);
         try {
-            // Write the hash to file
-            RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename, "rw");
-            // Truncate the file if pattern is null, to clear the lock
-            if (pattern == null) {
-                raf.setLength(0);
-            } else {
-                raf.write(hash, 0, hash.length);
-            }
-            raf.close();
+            getLockSettings().setLockPattern(hash, getCurrentOrCallingUserId());
             DevicePolicyManager dpm = getDevicePolicyManager();
             KeyStore keyStore = KeyStore.getInstance();
             if (pattern != null) {
@@ -505,13 +484,8 @@
                 dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0,
                         0, 0, 0, 0, 0);
             }
-        } catch (FileNotFoundException fnfe) {
-            // Cant do much, unless we want to fail over to using the settings
-            // provider
-            Log.e(TAG, "Unable to save lock pattern to " + sLockPatternFilename);
-        } catch (IOException ioe) {
-            // Cant do much
-            Log.e(TAG, "Unable to save lock pattern to " + sLockPatternFilename);
+        } catch (RemoteException re) {
+            Log.e(TAG, "Couldn't save lock pattern " + re);
         }
     }
 
@@ -586,15 +560,7 @@
         // Compute the hash
         final byte[] hash = passwordToHash(password);
         try {
-            // Write the hash to file
-            RandomAccessFile raf = new RandomAccessFile(sLockPasswordFilename, "rw");
-            // Truncate the file if pattern is null, to clear the lock
-            if (password == null) {
-                raf.setLength(0);
-            } else {
-                raf.write(hash, 0, hash.length);
-            }
-            raf.close();
+            getLockSettings().setLockPassword(hash, getCurrentOrCallingUserId());
             DevicePolicyManager dpm = getDevicePolicyManager();
             KeyStore keyStore = KeyStore.getInstance();
             if (password != null) {
@@ -676,12 +642,9 @@
                 dpm.setActivePasswordState(
                         DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0);
             }
-        } catch (FileNotFoundException fnfe) {
-            // Cant do much, unless we want to fail over to using the settings provider
-            Log.e(TAG, "Unable to save lock pattern to " + sLockPasswordFilename);
-        } catch (IOException ioe) {
+        } catch (RemoteException re) {
             // Cant do much
-            Log.e(TAG, "Unable to save lock pattern to " + sLockPasswordFilename);
+            Log.e(TAG, "Unable to save lock password " + re);
         }
     }
 
@@ -1013,30 +976,57 @@
     }
 
     private boolean getBoolean(String secureSettingKey, boolean defaultValue) {
-        return 1 ==
-                android.provider.Settings.Secure.getInt(mContentResolver, secureSettingKey,
-                        defaultValue ? 1 : 0);
+        try {
+            return getLockSettings().getBoolean(secureSettingKey, defaultValue,
+                    getCurrentOrCallingUserId());
+        } catch (RemoteException re) {
+            return defaultValue;
+        }
     }
 
     private void setBoolean(String secureSettingKey, boolean enabled) {
-        android.provider.Settings.Secure.putInt(mContentResolver, secureSettingKey,
-                                                enabled ? 1 : 0);
+        try {
+            getLockSettings().setBoolean(secureSettingKey, enabled, getCurrentOrCallingUserId());
+        } catch (RemoteException re) {
+            // What can we do?
+            Log.e(TAG, "Couldn't write boolean " + secureSettingKey + re);
+        }
     }
 
-    private long getLong(String secureSettingKey, long def) {
-        return android.provider.Settings.Secure.getLong(mContentResolver, secureSettingKey, def);
+    private long getLong(String secureSettingKey, long defaultValue) {
+        try {
+            return getLockSettings().getLong(secureSettingKey, defaultValue,
+                    getCurrentOrCallingUserId());
+        } catch (RemoteException re) {
+            return defaultValue;
+        }
     }
 
     private void setLong(String secureSettingKey, long value) {
-        android.provider.Settings.Secure.putLong(mContentResolver, secureSettingKey, value);
+        try {
+            getLockSettings().setLong(secureSettingKey, value, getCurrentOrCallingUserId());
+        } catch (RemoteException re) {
+            // What can we do?
+            Log.e(TAG, "Couldn't write long " + secureSettingKey + re);
+        }
     }
 
     private String getString(String secureSettingKey) {
-        return android.provider.Settings.Secure.getString(mContentResolver, secureSettingKey);
+        try {
+            return getLockSettings().getString(secureSettingKey, null,
+                    getCurrentOrCallingUserId());
+        } catch (RemoteException re) {
+            return null;
+        }
     }
 
     private void setString(String secureSettingKey, String value) {
-        android.provider.Settings.Secure.putString(mContentResolver, secureSettingKey, value);
+        try {
+            getLockSettings().setString(secureSettingKey, value, getCurrentOrCallingUserId());
+        } catch (RemoteException re) {
+            // What can we do?
+            Log.e(TAG, "Couldn't write string " + secureSettingKey + re);
+        }
     }
 
     public boolean isSecure() {
diff --git a/core/java/com/android/internal/widget/LockSettingsService.java b/core/java/com/android/internal/widget/LockSettingsService.java
new file mode 100644
index 0000000..24c7161
--- /dev/null
+++ b/core/java/com/android/internal/widget/LockSettingsService.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2012 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.internal.widget;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.UserId;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Arrays;
+
+/**
+ * Keeps the lock pattern/password data and related settings for each user.
+ * Used by LockPatternUtils. Needs to be a service because Settings app also needs
+ * to be able to save lockscreen information for secondary users.
+ * @hide
+ */
+public class LockSettingsService extends ILockSettings.Stub {
+
+    private final DatabaseHelper mOpenHelper;
+    private static final String TAG = "LockSettingsService";
+
+    private static final String TABLE = "locksettings";
+    private static final String COLUMN_KEY = "name";
+    private static final String COLUMN_USERID = "user";
+    private static final String COLUMN_VALUE = "value";
+
+    private static final String[] COLUMNS_FOR_QUERY = {
+        COLUMN_VALUE
+    };
+
+    private static final String SYSTEM_DIRECTORY = "/system/";
+    private static final String LOCK_PATTERN_FILE = "gesture.key";
+    private static final String LOCK_PASSWORD_FILE = "password.key";
+
+    private final Context mContext;
+
+    public LockSettingsService(Context context) {
+        mContext = context;
+        // Open the database
+        mOpenHelper = new DatabaseHelper(mContext);
+    }
+
+    public void systemReady() {
+        migrateOldData();
+    }
+
+    private void migrateOldData() {
+        try {
+            if (getString("migrated", null, 0) != null) {
+                // Already migrated
+                return;
+            }
+
+            final ContentResolver cr = mContext.getContentResolver();
+            for (String validSetting : VALID_SETTINGS) {
+                String value = Settings.Secure.getString(cr, validSetting);
+                if (value != null) {
+                    setString(validSetting, value, 0);
+                }
+            }
+            // No need to move the password / pattern files. They're already in the right place.
+            setString("migrated", "true", 0);
+            Slog.i(TAG, "Migrated lock settings to new location");
+        } catch (RemoteException re) {
+            Slog.e(TAG, "Unable to migrate old data");
+        }
+    }
+
+    private static final void checkWritePermission(int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (UserId.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("uid=" + callingUid
+                    + " not authorized to write lock settings");
+        }
+    }
+
+    private static final void checkPasswordReadPermission(int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (UserId.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("uid=" + callingUid
+                    + " not authorized to read lock password");
+        }
+    }
+
+    private static final void checkReadPermission(int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (UserId.getAppId(callingUid) != android.os.Process.SYSTEM_UID
+                && UserId.getUserId(callingUid) != userId) {
+            throw new SecurityException("uid=" + callingUid
+                    + " not authorized to read settings of user " + userId);
+        }
+    }
+
+    @Override
+    public void setBoolean(String key, boolean value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+
+        writeToDb(key, value ? "1" : "0", userId);
+    }
+
+    @Override
+    public void setLong(String key, long value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+
+        writeToDb(key, Long.toString(value), userId);
+    }
+
+    @Override
+    public void setString(String key, String value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+
+        writeToDb(key, value, userId);
+    }
+
+    @Override
+    public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
+        //checkReadPermission(userId);
+
+        String value = readFromDb(key, null, userId);
+        return TextUtils.isEmpty(value) ?
+                defaultValue : (value.equals("1") || value.equals("true"));
+    }
+
+    @Override
+    public long getLong(String key, long defaultValue, int userId) throws RemoteException {
+        //checkReadPermission(userId);
+
+        String value = readFromDb(key, null, userId);
+        return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
+    }
+
+    @Override
+    public String getString(String key, String defaultValue, int userId) throws RemoteException {
+        //checkReadPermission(userId);
+
+        return readFromDb(key, defaultValue, userId);
+    }
+
+    private String getLockPatternFilename(int userId) {
+        String dataSystemDirectory =
+                android.os.Environment.getDataDirectory().getAbsolutePath() +
+                SYSTEM_DIRECTORY;
+        if (userId == 0) {
+            // Leave it in the same place for user 0
+            return dataSystemDirectory + LOCK_PATTERN_FILE;
+        } else {
+            return  dataSystemDirectory + "users/" + userId + "/" + LOCK_PATTERN_FILE;
+        }
+    }
+
+    private String getLockPasswordFilename(int userId) {
+        String dataSystemDirectory =
+                android.os.Environment.getDataDirectory().getAbsolutePath() +
+                SYSTEM_DIRECTORY;
+        if (userId == 0) {
+            // Leave it in the same place for user 0
+            return dataSystemDirectory + LOCK_PASSWORD_FILE;
+        } else {
+            return  dataSystemDirectory + "users/" + userId + "/" + LOCK_PASSWORD_FILE;
+        }
+    }
+
+    @Override
+    public boolean havePassword(int userId) throws RemoteException {
+        // Do we need a permissions check here?
+
+        return new File(getLockPasswordFilename(userId)).length() > 0;
+    }
+
+    @Override
+    public boolean havePattern(int userId) throws RemoteException {
+        // Do we need a permissions check here?
+
+        return new File(getLockPatternFilename(userId)).length() > 0;
+    }
+
+    @Override
+    public void setLockPattern(byte[] hash, int userId) throws RemoteException {
+        checkWritePermission(userId);
+
+        writeFile(getLockPatternFilename(userId), hash);
+    }
+
+    @Override
+    public boolean checkPattern(byte[] hash, int userId) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        try {
+            // Read all the bytes from the file
+            RandomAccessFile raf = new RandomAccessFile(getLockPatternFilename(userId), "r");
+            final byte[] stored = new byte[(int) raf.length()];
+            int got = raf.read(stored, 0, stored.length);
+            raf.close();
+            if (got <= 0) {
+                return true;
+            }
+            // Compare the hash from the file with the entered pattern's hash
+            return Arrays.equals(stored, hash);
+        } catch (FileNotFoundException fnfe) {
+            Slog.e(TAG, "Cannot read file " + fnfe);
+            return true;
+        } catch (IOException ioe) {
+            Slog.e(TAG, "Cannot read file " + ioe);
+            return true;
+        }
+    }
+
+    @Override
+    public void setLockPassword(byte[] hash, int userId) throws RemoteException {
+        checkWritePermission(userId);
+
+        writeFile(getLockPasswordFilename(userId), hash);
+    }
+
+    @Override
+    public boolean checkPassword(byte[] hash, int userId) throws RemoteException {
+        checkPasswordReadPermission(userId);
+
+        try {
+            // Read all the bytes from the file
+            RandomAccessFile raf = new RandomAccessFile(getLockPasswordFilename(userId), "r");
+            final byte[] stored = new byte[(int) raf.length()];
+            int got = raf.read(stored, 0, stored.length);
+            raf.close();
+            if (got <= 0) {
+                return true;
+            }
+            // Compare the hash from the file with the entered password's hash
+            return Arrays.equals(stored, hash);
+        } catch (FileNotFoundException fnfe) {
+            Slog.e(TAG, "Cannot read file " + fnfe);
+            return true;
+        } catch (IOException ioe) {
+            Slog.e(TAG, "Cannot read file " + ioe);
+            return true;
+        }
+    }
+
+    @Override
+    public void removeUser(int userId) {
+        checkWritePermission(userId);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        try {
+            File file = new File(getLockPasswordFilename(userId));
+            if (file.exists()) {
+                file.delete();
+            }
+            file = new File(getLockPatternFilename(userId));
+            if (file.exists()) {
+                file.delete();
+            }
+
+            db.beginTransaction();
+            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    private void writeFile(String name, byte[] hash) {
+        try {
+            // Write the hash to file
+            RandomAccessFile raf = new RandomAccessFile(name, "rw");
+            // Truncate the file if pattern is null, to clear the lock
+            if (hash == null || hash.length == 0) {
+                raf.setLength(0);
+            } else {
+                raf.write(hash, 0, hash.length);
+            }
+            raf.close();
+        } catch (IOException ioe) {
+            Slog.e(TAG, "Error writing to file " + ioe);
+        }
+    }
+
+    private void writeToDb(String key, String value, int userId) {
+        ContentValues cv = new ContentValues();
+        cv.put(COLUMN_KEY, key);
+        cv.put(COLUMN_USERID, userId);
+        cv.put(COLUMN_VALUE, value);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
+                    new String[] {key, Integer.toString(userId)});
+            db.insert(TABLE, null, cv);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    private String readFromDb(String key, String defaultValue, int userId) {
+        Cursor cursor;
+        String result = defaultValue;
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
+                COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
+                new String[] { Integer.toString(userId), key },
+                null, null, null)) != null) {
+            if (cursor.moveToFirst()) {
+                result = cursor.getString(0);
+            }
+            cursor.close();
+        }
+        return result;
+    }
+
+    class DatabaseHelper extends SQLiteOpenHelper {
+        private static final String TAG = "LockSettingsDB";
+        private static final String DATABASE_NAME = "locksettings.db";
+
+        private static final int DATABASE_VERSION = 1;
+
+        public DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+            setWriteAheadLoggingEnabled(true);
+        }
+
+        private void createTable(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE + " (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    COLUMN_KEY + " TEXT," +
+                    COLUMN_USERID + " INTEGER," +
+                    COLUMN_VALUE + " TEXT" +
+                    ");");
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            createTable(db);
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
+            // Nothing yet
+        }
+    }
+
+    private static final String[] VALID_SETTINGS = new String[] {
+        LockPatternUtils.LOCKOUT_PERMANENT_KEY,
+        LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
+        LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
+        LockPatternUtils.PASSWORD_TYPE_KEY,
+        LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+        LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
+        LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
+        LockPatternUtils.LOCKSCREEN_OPTIONS,
+        LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
+        LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
+        LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
+        LockPatternUtils.PASSWORD_HISTORY_KEY,
+        Secure.LOCK_PATTERN_ENABLED,
+        Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
+        Secure.LOCK_PATTERN_VISIBLE,
+        Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
+        };
+}
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 3d350ed..244b166 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -218,6 +218,18 @@
     return surfaceTexture->updateTexImage();
 }
 
+static jint SurfaceTexture_detachFromGLContext(JNIEnv* env, jobject thiz)
+{
+    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+    return surfaceTexture->detachFromContext();
+}
+
+static jint SurfaceTexture_attachToGLContext(JNIEnv* env, jobject thiz, jint tex)
+{
+    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+    return surfaceTexture->attachToContext((GLuint)tex);
+}
+
 static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
         jfloatArray jmtx)
 {
@@ -242,14 +254,16 @@
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gSurfaceTextureMethods[] = {
-    {"nativeClassInit",          "()V",   (void*)SurfaceTexture_classInit },
-    {"nativeInit",               "(ILjava/lang/Object;Z)V", (void*)SurfaceTexture_init },
-    {"nativeFinalize",           "()V",   (void*)SurfaceTexture_finalize },
+    {"nativeClassInit",            "()V",   (void*)SurfaceTexture_classInit },
+    {"nativeInit",                 "(ILjava/lang/Object;Z)V", (void*)SurfaceTexture_init },
+    {"nativeFinalize",             "()V",   (void*)SurfaceTexture_finalize },
     {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
-    {"nativeUpdateTexImage",     "()I",   (void*)SurfaceTexture_updateTexImage },
-    {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
-    {"nativeGetTimestamp",       "()J",   (void*)SurfaceTexture_getTimestamp },
-    {"nativeRelease",            "()V",   (void*)SurfaceTexture_release },
+    {"nativeUpdateTexImage",       "()I",   (void*)SurfaceTexture_updateTexImage },
+    {"nativeDetachFromGLContext",  "()I",   (void*)SurfaceTexture_detachFromGLContext },
+    {"nativeAttachToGLContext",    "(I)I",   (void*)SurfaceTexture_attachToGLContext },
+    {"nativeGetTransformMatrix",   "([F)V", (void*)SurfaceTexture_getTransformMatrix },
+    {"nativeGetTimestamp",         "()J",   (void*)SurfaceTexture_getTimestamp },
+    {"nativeRelease",              "()V",   (void*)SurfaceTexture_release },
 };
 
 int register_android_graphics_SurfaceTexture(JNIEnv* env)
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5ae12b6..00faa41 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1200,7 +1200,8 @@
         android:protectionLevel="signature|system" />
 
     <!-- Allows an application to retrieve the current state of keys and
-         switches.  This is only for use by the system.-->
+         switches.  This is only for use by the system.
+         @deprecated The API that used this permission has been removed. -->
     <permission android:name="android.permission.READ_INPUT_STATE"
         android:label="@string/permlab_readInputState"
         android:description="@string/permdesc_readInputState"
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_bottom_enter.xml
similarity index 77%
copy from packages/SystemUI/res/anim/status_bar_enter.xml
copy to core/res/res/anim/dock_bottom_enter.xml
index f1c1301..7a2e94b 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_bottom_enter.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, 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. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the bottom of the screen is entering. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_quad">
-	<translate android:fromYDelta="-75%" android:toYDelta="0"
+    <translate android:fromYDelta="75%" android:toYDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
         android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_bottom_exit.xml
similarity index 78%
copy from packages/SystemUI/res/anim/status_bar_exit.xml
copy to core/res/res/anim/dock_bottom_exit.xml
index 46462e2..c2fd15c 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_bottom_exit.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, 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. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the bottom of the screen is exiting. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_quad">
-	<translate android:fromYDelta="0" android:toYDelta="-75%"
+    <translate android:fromYDelta="0" android:toYDelta="75%"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_left_enter.xml
similarity index 77%
copy from packages/SystemUI/res/anim/status_bar_enter.xml
copy to core/res/res/anim/dock_left_enter.xml
index f1c1301..b057f67 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_left_enter.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, 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. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the left of the screen is entering. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_quad">
-	<translate android:fromYDelta="-75%" android:toYDelta="0"
+    <translate android:fromXDelta="-75%" android:toXDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
         android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_left_exit.xml
similarity index 78%
copy from packages/SystemUI/res/anim/status_bar_exit.xml
copy to core/res/res/anim/dock_left_exit.xml
index 46462e2..576b1aa 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_left_exit.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, 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. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the right of the screen is exiting. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_quad">
-	<translate android:fromYDelta="0" android:toYDelta="-75%"
+    <translate android:fromXDelta="0" android:toXDelta="-75%"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_right_enter.xml
similarity index 77%
copy from packages/SystemUI/res/anim/status_bar_enter.xml
copy to core/res/res/anim/dock_right_enter.xml
index f1c1301..e1bd190 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_right_enter.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, 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. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the right of the screen is entering. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_quad">
-	<translate android:fromYDelta="-75%" android:toYDelta="0"
+    <translate android:fromXDelta="75%" android:toXDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
         android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_right_exit.xml
similarity index 78%
copy from packages/SystemUI/res/anim/status_bar_exit.xml
copy to core/res/res/anim/dock_right_exit.xml
index 46462e2..6d778fa 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_right_exit.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2012, 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. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the right of the screen is exiting. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_quad">
-	<translate android:fromYDelta="0" android:toYDelta="-75%"
+    <translate android:fromXDelta="0" android:toXDelta="75%"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_top_enter.xml
similarity index 77%
rename from packages/SystemUI/res/anim/status_bar_enter.xml
rename to core/res/res/anim/dock_top_enter.xml
index f1c1301..f2e4cae 100644
--- a/packages/SystemUI/res/anim/status_bar_enter.xml
+++ b/core/res/res/anim/dock_top_enter.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_enter.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2007, 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. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the top of the screen is entering. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/decelerate_quad">
-	<translate android:fromYDelta="-75%" android:toYDelta="0"
+    <translate android:fromYDelta="-75%" android:toYDelta="0"
         android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
         android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_top_exit.xml
similarity index 78%
rename from packages/SystemUI/res/anim/status_bar_exit.xml
rename to core/res/res/anim/dock_top_exit.xml
index 46462e2..7373695 100644
--- a/packages/SystemUI/res/anim/status_bar_exit.xml
+++ b/core/res/res/anim/dock_top_exit.xml
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/anim/options_panel_exit.xml
-**
-** Copyright 2007, The Android Open Source Project
+/* Copyright 2007, 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. 
@@ -18,10 +16,11 @@
 */
 -->
 
+<!-- Animation for when a dock window at the top of the screen is exiting. -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:interpolator/accelerate_quad">
-	<translate android:fromYDelta="0" android:toYDelta="-75%"
+    <translate android:fromYDelta="0" android:toYDelta="-75%"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
-	<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
         android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" />
 </set>
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png
new file mode 100644
index 0000000..0d2e2ef
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png
new file mode 100644
index 0000000..66d14ae
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png
new file mode 100644
index 0000000..73c6be6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png
new file mode 100644
index 0000000..73c6be6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png
new file mode 100644
index 0000000..c625a36
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png
new file mode 100644
index 0000000..c625a36
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/core/res/res/drawable/ic_lockscreen_search.xml b/core/res/res/drawable/ic_lockscreen_search.xml
new file mode 100644
index 0000000..b103922
--- /dev/null
+++ b/core/res/res/drawable/ic_lockscreen_search.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:state_enabled="true"
+        android:state_active="false"
+        android:state_focused="false"
+        android:drawable="@drawable/ic_lockscreen_search_normal" />
+
+    <item
+        android:state_enabled="true"
+        android:state_active="true"
+        android:state_focused="false"
+        android:drawable="@drawable/ic_lockscreen_search_activated" />
+
+</selector>
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index 9a2e024..35b8665 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -173,13 +173,13 @@
     <RelativeLayout
         android:id="@+id/faceLockAreaView"
         android:visibility="invisible"
-        android:layout_row="4"
+        android:layout_row="3"
         android:layout_column="0"
-        android:layout_rowSpan="1"
+        android:layout_rowSpan="2"
         android:layout_columnSpan="1"
         android:layout_gravity="fill"
-        android:layout_marginTop="8dip"
-        android:layout_marginBottom="8dip"
+        android:layout_marginTop="4dip"
+        android:layout_marginBottom="4dip"
         android:layout_width="0dip"
         android:layout_height="0dip"
         android:background="@drawable/intro_bg">
diff --git a/core/res/res/layout/notification_template_base.xml b/core/res/res/layout/notification_template_base.xml
index 93843fd..b9710d6 100644
--- a/core/res/res/layout/notification_template_base.xml
+++ b/core/res/res/layout/notification_template_base.xml
@@ -53,15 +53,21 @@
                 android:fadingEdge="horizontal"
                 android:layout_weight="1"
                 />
-            <DateTimeView android:id="@+id/time"
-                android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+            <ViewStub android:id="@+id/time"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
                 android:layout_weight="0"
-                android:singleLine="true"
-                android:gravity="center"
-                android:paddingLeft="8dp"
+                android:visibility="gone"
+                android:layout="@layout/notification_template_part_time"
+                />
+            <ViewStub android:id="@+id/chronometer"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:visibility="gone"
+                android:layout="@layout/notification_template_part_chronometer"
                 />
         </LinearLayout>
         <TextView android:id="@+id/text2"
diff --git a/core/res/res/layout/notification_template_part_chronometer.xml b/core/res/res/layout/notification_template_part_chronometer.xml
new file mode 100644
index 0000000..382b0e4
--- /dev/null
+++ b/core/res/res/layout/notification_template_part_chronometer.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<Chronometer android:id="@+id/chronometer" xmlns:android="http://schemas.android.com/apk/res/android"
+    android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:layout_weight="0"
+    android:singleLine="true"
+    android:gravity="center"
+    android:paddingLeft="8dp"
+    />
diff --git a/core/res/res/layout/notification_template_part_time.xml b/core/res/res/layout/notification_template_part_time.xml
new file mode 100644
index 0000000..410fcaf
--- /dev/null
+++ b/core/res/res/layout/notification_template_part_time.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<DateTimeView android:id="@+id/time" xmlns:android="http://schemas.android.com/apk/res/android"
+    android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Time"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:layout_weight="0"
+    android:singleLine="true"
+    android:gravity="center"
+    android:paddingLeft="8dp"
+    />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 203c335..d6073e3 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Voer \'n PUK van 8 syfers of langer in."</string>
     <string name="needPuk" msgid="919668385956251611">"Jou SIM-kaart is PUK-gesluit. Voer die PUK-kode in om dit te ontsluit."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Sleutel PUK2 in om SIM-kaart oop te sluit."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Inkomender beller-ID"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Uitgaande beller-ID"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Oproepaanstuur"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Stel tyd"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Stel datum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Stel"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Verstek"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUUT: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Geen toestemmings benodig nie"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Voeg \'n rekening by"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Watter rekening wil jy gebruik?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Voeg rekening by"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Verhoging"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Verminder"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> raak en hou."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Skuif op om by te tel en af om af te trek."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Tel \'n minuut by"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Trek \'n minuut af"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Tel \'n uur by."</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Trek \'n uur af"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Stel NM."</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Stel VM."</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Tel \'n maand by"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Trek \'n maand af"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Tel \'n dag by"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Trek \'n dag af."</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Tel \'n jaar by"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Trek \'n jaar af"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"gekontroleer"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"nie gekontroleer nie"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"gekies"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Deel met"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Deel met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Skyfievatsel. Raak en hou."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Op na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Af vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Regs vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Ontsluit"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ab937c5..2b98607 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"8 ወይም ከዛ በላይ የሆኑ ቁጥሮችንPUK ተይብ።"</string>
     <string name="needPuk" msgid="919668385956251611">"SIM ካርድዎ PUK-የተቆለፈ ነው።የPUK ኮዱን በመተየብ ይክፈቱት።"</string>
     <string name="needPuk2" msgid="4526033371987193070">" SIM ለመክፈት PUK2 ተይብ።"</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"የገቢ ደዋይID"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"የወጪ ጥሪID"</string>
     <string name="CfMmi" msgid="5123218989141573515">"ጥሪ ማስተላለፍ"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"ጊዜ አዘጋጅ"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"ውሂብ አዘጋጅ"</string>
     <string name="date_time_set" msgid="5777075614321087758">"አዘጋጅ"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"ነባሪ"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"አዲስ፦ "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"ምንም ፍቃዶች አይጠየቁም"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"መለያ አክል"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"የትኛውን መለያ መጠቀም ትፈልጋለህ?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"መለያ አክል"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"ጨምር"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"ቀንስ"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ንካ እና ያዝ።"</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"ለመጨመር ወደላይ ለመቀነስ ወደታች አንሸራት"</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"ደቂቃዎች ጨምር"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"ደቂቃ ቀንስ"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"ሰዓት ጨምር።"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"ሰዓት ቀንስ"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM አዘጋጅ"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM አዘጋጅ"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"ወር ጨምር"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"ወር ቀንስ"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"ቀን ጨምር"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"ቀን ቀንስ"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"አመት ጨምር"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"አመት ቀንስ"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"ታይቷል"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"አልተፈተሸም"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"የተመረጠ"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"ተጋራ ከ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ከ <xliff:g id="APPLICATION_NAME">%s</xliff:g> ጋር ተጋራ"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ባለስላይድ መያዣ፡፡ ዳስ&amp;ያዝ፡፡"</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደላይ።"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደታች።"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደግራ።"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደቀኝ።"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"ክፈት"</string>
     <string name="description_target_camera" msgid="969071997552486814">"ካሜራ"</string>
     <string name="description_target_silent" msgid="893551287746522182">"ፀጥታ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index aca8f47..9c3ef5e 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"اكتب رمز PUK مكونًا من 8 أرقام أو أكثر."</string>
     <string name="needPuk" msgid="919668385956251611">"بطاقة SIM مؤمّنة بكود PUK. اكتب كود PUK لإلغاء تأمينها."</string>
     <string name="needPuk2" msgid="4526033371987193070">"اكتب PUK2 لإلغاء تأمين بطاقة SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"معرف المتصل الوارد"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"معرف المتصل الصادر"</string>
     <string name="CfMmi" msgid="5123218989141573515">"إعادة توجيه الاتصال"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"تعيين الوقت"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"تعيين التاريخ"</string>
     <string name="date_time_set" msgid="5777075614321087758">"تعيين"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"افتراضي"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"جديد: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"لا أذونات مطلوبة"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"إضافة حساب"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"ما الحساب الذي تريد استخدامه؟"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"إضافة حساب"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"زيادة"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"تناقص"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> المس مع الاستمرار."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"مرر لأعلى للزيادة ولأسفل للإنقاص."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"زيادة دقيقة"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"إنقاص دقيقة"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"زيادة ساعة"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"إنقاص ساعة"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"تعيين المساء"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"تعيين الصباح"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"زيادة شهر"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"إنقاص شهر"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"زيادة يوم"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"إنقاص يوم"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"زيادة عام"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"إنقاص عام"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"تم التحديد"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"لم يتم التحديد"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"محدد"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"مشاركة مع"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"مشاركة مع <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"مقبض التمرير. المس مع الاستمرار."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"أعلى إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"أسفل إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"يسارًا إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"يمينًا إلى <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"إلغاء تأمين"</string>
     <string name="description_target_camera" msgid="969071997552486814">"الكاميرا"</string>
     <string name="description_target_silent" msgid="893551287746522182">"صامت"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 4d304f1..dcb8f05 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Увядзіце PUK з 8 лічбаў ці больш."</string>
     <string name="needPuk" msgid="919668385956251611">"Ваша SIM-карта заблакавана PUK-кодам. Увядзіце PUK, каб разблакаваць карту."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Увядзіце PUK2 для разблакавання SIM-карты."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Ідэнтыфікатар АВН"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Ідэнтыфікатар АВН"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Пераадрасацыя выкліку"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Усталяваць час"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Усталяваць дату"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Задаць"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Па змаўчанні"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВАЕ: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Дазволу не патрабуецца"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Дадаць уліковы запіс"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Які ўліковы запіс вы жадаеце выкарыстоўваць?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Дадаць уліковы запіс"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Інкрэмент"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Дэкрэмент"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Націсніце і ўтрымлівайце <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Перасуньце палец уверх, каб павялiчыць адрэзак, або ўніз, каб паменшыць."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"На хвiлiну больш"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"На хвiлiну менш"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"На гадзiну больш"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"На гадзiну менш"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Усталяваць час пасля паўдня"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Усталяваць час да паўдня"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"На месяц больш"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"На месяц менш"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"На дзень больш"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"На дзень менш."</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"На год больш"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"На год менш"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"пастаўлены"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"не пастаўлены"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"абрана"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Апублікаваць з дапамогай"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Адправiць з дапамогай прыкладання <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Ручка для перасоўвання. Націсніце і ўтрымлівайце."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Уверх да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Уніз да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Улева да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Управа да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Разблакаваць"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Ціхі рэжым"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b057cef..cee54b4 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Въведете PUK код с поне осем цифри."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM картата ви е заключена с PUK. Въведете PUK кода, за да я отключите."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Въведете PUK2, за да отблокирате SIM картата."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Идентификация на вх. обаждания"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Идентификация на изходящите повиквания"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Пренасочване на повиквания"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Задаване на часа"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Задаване на дата"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Задаване"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"По подразбиране"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВО: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Не се изискват разрешения"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Добавяне на профил"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Кой профил искате да използвате?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Добавяне на профил"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличаване"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Намаляване"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Докоснете <xliff:g id="VALUE">%s</xliff:g> път/и и задръжте."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Плъзнете нагоре за увеличаване и надолу за намаляване."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Увеличаване на минутите"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Намаляване на минутите"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Увеличаване на часа"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Намаляване на часа"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Задаване на PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Задаване на AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Увеличаване на месеца"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Намаляване на месеца"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Увеличаване на деня"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Намаляване на деня"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Увеличаване на годината"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Намаляване на годината"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"отметнато"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"не е отметнато"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"избрано"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Споделяне със"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Споделяне със: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Плъзгаща се дръжка. Докоснете и задръжте."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Надолу за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Надясно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Отключване"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Тих режим"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 61c3cf0..e360af1 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Introdueix un PUK compost com a mínim de 8 nombres."</string>
     <string name="needPuk" msgid="919668385956251611">"La targeta SIM està bloquejada pel PUK. Escriviu el codi PUK per desbloquejar-la."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Escriviu el PUK2 per desbloquejar la targeta SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Identificació de trucada entrant"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Identificació de trucada de sortida"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Desviació de trucades"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Estableix l\'hora"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Establiment de data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Defineix"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Predeterminat"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOU: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"No cal cap permís"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Addició d\'un compte"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Quin compte vols utilitzar?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Afegeix un compte"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementa"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminueix"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Mantén premut <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Fes lliscar el dit cap amunt per incrementar i cap avall per disminuir."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Incrementa els minuts"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Disminueix els minuts"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Incrementa les hores"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Disminueix les hores"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Estableix com a p. m."</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Estableix com a a. m."</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Incrementa el mes"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Disminueix el mes"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Incrementa els dies"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Disminueix els dies"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Incrementa l\'any"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Disminueix l\'any"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"marcat"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"no marcat"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"seleccionat"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Comparteix amb"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Comparteix amb <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Llisca el dit. Mantén premut."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Cap avall per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Cap a la dreta per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Desbloqueja"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Càmera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Silenci"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index ec640f7..ea206b0 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Zadejte osmimístný nebo delší kód PUK."</string>
     <string name="needPuk" msgid="919668385956251611">"Karta SIM je blokována pomocí kódu PUK. Odblokujete ji zadáním kódu PUK."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Chcete-li odblokovat kartu SIM, zadejte kód PUK2."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Příchozí identifikace volajícího"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Odchozí identifikace volajícího"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Přesměrování hovorů"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastavení času"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavení data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Nastavit"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Výchozí"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVÉ: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nejsou vyžadována žádná oprávnění"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Přidat účet"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Který účet chcete použít?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Přidat účet"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšení"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Snížení"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> dotkněte se a podržte."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Chcete-li přičítat, přejeďte prstem nahoru, chcete-li odečítat, přejeďte prstem dolů."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Přičíst minutu"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Odečíst minutu"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Přičíst hodinu"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Odečíst hodinu"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nastavit odp."</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastavit dop."</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Přičíst měsíc"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Odečíst měsíc"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Přičíst den"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Odečíst den"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Přičíst rok"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Odečíst rok"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"zaškrtnuto"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"nezaškrtnuto"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"Vybráno"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Sdílet s"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Sdílet s aplikací <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvník. Dotkněte se a podržte."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – nahoru."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – dolů."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – vlevo."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> – vpravo."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Odemknout"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index d72364b..94c2999 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Angiv en PUK-kode på 8 eller flere cifre."</string>
     <string name="needPuk" msgid="919668385956251611">"Dit SIM-kort er låst med PUK-koden. Indtast PUK-koden for at låse den op."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Indtast PUK2-koden for at låse op for SIM-kortet."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI-nummer"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Indgående opkalds-id"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Udgående opkalds-id"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Viderestilling af opkald"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Angiv tidspunkt"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Angiv dato"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Angiv"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NYHED! "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Der kræves ingen tilladelser"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Tilføj en konto"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Hvilken konto vil du bruge?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Tilføj konto"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Optælling"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Nedtælling"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Tryk <xliff:g id="VALUE">%s</xliff:g> gange, og hold inde."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Glid op for at tilføje, og glid ned for at fjerne."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Tilføj minut"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Fjern minut"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Tilføj time"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Fjern time"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Indstil PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Indstil AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Tilføj måned"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Fjern måned"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Tilføj dag"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Fjern dag"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Tilføj år"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Fjern år"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"markeret"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"ikke markeret"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"udvalgt"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Glidende håndtag. Tryk og hold nede."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Ned for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Til højre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Lås op"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Lydløs"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index defd850..82a60d2 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Geben Sie eine mindestens achtstellige PUK ein."</string>
     <string name="needPuk" msgid="919668385956251611">"Ihre SIM-Karte ist mit einem PUK gesperrt. Geben Sie zum Entsperren den PUK-Code ein."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Geben Sie zum Entsperren der SIM-Karte den PUK2 ein."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Anrufer-ID für eingehenden Anruf"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Anrufer-ID für ausgehenden Anruf"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Rufweiterleitung"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Uhrzeit festlegen"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum festlegen"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Speichern"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"Neu: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Keine Berechtigungen erforderlich"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Konto hinzufügen"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Welches Konto möchten Sie verwenden?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Konto hinzufügen"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Erhöhen"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Verringern"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> berühren und gedrückt halten"</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Zum Vorstellen nach oben und zum Zurückstellen nach unten ziehen"</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minute vorstellen"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minute zurückstellen"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Stunde vorstellen"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Stunde zurückstellen"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Zeit festlegen"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Zeit festlegen"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Monat vorstellen"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Monat zurückstellen"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Tag vorstellen"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Tag zurückstellen"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Jahr vorstellen"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Jahr zurückstellen"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"Aktiviert"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"Nicht aktiviert"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"Ausgewählt"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Teilen mit"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Mit <xliff:g id="APPLICATION_NAME">%s</xliff:g> teilen"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Schieberegler: Berühren und halten"</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach unten"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Für <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach rechts"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Entsperren"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Lautlos"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 71547ce..b9710e5 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Πληκτρολογήστε έναν κωδικό PUK με 8 αριθμούς ή περισσότερους."</string>
     <string name="needPuk" msgid="919668385956251611">"Η κάρτα SIM έχει κλειδωθεί με κωδικό PUK. Πληκτρολογήστε τον κωδικό PUK για να την ξεκλειδώσετε."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Πληκτρολογήστε τον κωδικό PUK2 για την κατάργηση αποκλεισμού της κάρτας SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Εισερχόμενη αναγνώριση κλήσης"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Εξερχόμενη αναγνώριση κλήσης"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Προώθηση κλήσεων"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Ρύθμιση ώρας"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Ορισμός ημερομηνίας"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Ορισμός"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Προεπιλεγμένο"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ΝΕΟ: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Δεν απαιτούνται άδειες"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Προσθήκη λογαριασμού"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Ποιον λογαριασμό θέλετε να χρησιμοποιήσετε;"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Προσθήκη λογαριασμού"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Αύξηση"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Μείωση"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Πατήστε παρατεταμένα το <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Πραγματοποιήστε κύλιση προς τα πάνω για αύξηση και προς τα κάτω για μείωση."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Αύξηση λεπτού"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Μείωση λεπτού"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Αύξηση ώρας"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Μείωση ώρας"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Ορισμός ΜΜ"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Ορισμός ΠΜ"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Επόμενος μήνας"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Προηγούμενος μήνας"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Επόμενη ημέρα"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Προηγούμενη μέρα"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Αύξηση έτους"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Προηγούμενο έτος"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"ελέγχθηκε"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"δεν επιλέχθηκε"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"επιλεγμένο"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Κοινή χρήση με"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Κοινή χρήση με <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Στοιχείο χειρισμού με δυνατότητα ολίσθησης. Αγγίξτε και πατήστε παρατεταμένα."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Κύλιση πάνω <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Κύλιση κάτω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Κύλιση αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Κύλιση δεξιά <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Ξεκλείδωμα"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Φωτογραφική μηχανή"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Αθόρυβο"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index b070e02..c41f2be 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Type a PUK that is 8 numbers or longer."</string>
     <string name="needPuk" msgid="919668385956251611">"Your SIM card is PUK-locked. Type the PUK code to unlock it."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Type PUK2 to unblock SIM card."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Incoming Caller ID"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Outgoing Caller ID"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Call forwarding"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Set time"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Set date"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Set"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NEW: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"No permission required"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Add an account"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Which account do you want to use?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Add account"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Increment"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> touch and hold."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Slide up to increment and down to decrease."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Increment minute"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Decrement minute"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Increment hour"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Decrement hour"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Set p.m."</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Set a.m."</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Increment month"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Decrement month"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Increment day"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Decrement day"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Increment year"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Decrement year"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"ticked"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"not ticked"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"selected"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Share with"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Share with <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Sliding handle. Touch &amp; hold."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Right for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Unlock"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Silent"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 8de6b8c0..19e8e25 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Ingresa un código PUK de ocho números o más."</string>
     <string name="needPuk" msgid="919668385956251611">"Tu tarjeta SIM está bloqueada con PUK. Escribe el código PUK para desbloquearla."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Escribir PUK2 para desbloquear la tarjeta SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Identificador de llamadas entrantes"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Identificador de llamadas salientes"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Desvío de llamadas"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Configurar hora"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Configurar fecha"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUEVO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"No se requieren permisos"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Agregar una cuenta"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"¿Qué cuenta quieres usar?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Agregar una cuenta"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decremento"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Mantén presionado <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Deslízate hacia arriba para aumentar y hacia abajo para disminuir."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minutos"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Disminuir minutos"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumentar horas"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Disminuir horas"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Establecer p.m."</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Establecer a.m."</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumentar mes"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Disminuir mes"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumentar día"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Disminuir día"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumentar año"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Disminuir año"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"marcado"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"no marcado"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"seleccionado"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartir con"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartir con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Mantén presionado el controlador deslizante."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index b76053f..c732ab9 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Escribe un código PUK de ocho caracteres o más."</string>
     <string name="needPuk" msgid="919668385956251611">"La tarjeta SIM está bloqueada con el código PUK. Introduce el código PUK para desbloquearla."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Introduce el código PUK2 para desbloquear la tarjeta SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID de emisor de llamada entrante"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID de emisor de llamada saliente"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Desvío de llamada"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Establecer hora"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Establecer fecha"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUEVO:"</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"No es necesario ningún permiso"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Añadir una cuenta"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"¿Qué cuenta quieres usar?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Añadir cuenta"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminuir"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Mantén pulsado <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Desliza el dedo hacia arriba para aumentar y hacia abajo para disminuir."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minuto"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Disminuir minuto"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumentar hora"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Disminuir hora"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Establecer p.m."</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Establecer a.m."</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumentar mes"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Disminuir mes"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumentar día"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Disminuir día"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumentar año"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Disminuir año"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"seleccionado"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"no seleccionado"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"seleccionado"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartir con"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartir con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Mantén pulsado el icono de desbloqueo y deslízalo."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Silencio"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 38c9251..890dd7b 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Sisestage 8- või enamanumbriline PUK-kood."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM-kaart on PUK-lukustatud. Avamiseks sisestage PUK-kood."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Sisestage SIM-kaardi blokeeringu tühistamiseks PUK2-kood."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Sissetuleva kõne helistaja ID"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Väljuva kõne helistaja ID"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Kõnede suunamine"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Kellaaja määramine"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Kuupäeva määramine"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Määra"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Vaikimisi"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"UUS: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Lube pole vaja"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Konto lisamine"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Millist kontot soovite kasutada?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Lisa konto"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Suurenda"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Vähenda"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> puudutage ja hoidke."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Suurendamiseks lohistage üles, vähendamiseks alla."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minutite arvu suurendamine"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minutite arvu vähendamine"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Tundide arvu suurendamine"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Tundide arvu vähendamine"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM-i seadmine"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM-i seadmine"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Järgmine kuu"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Eelmine kuu"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Järgmine päev"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Eelmine päev"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aastaarvu suurendamine"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Aastaarvu vähendamine"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"märgitud"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"pole märgitud"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"valitud"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Jaga:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Jaga rakendusega <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Libistamispide. Puudutage ja hoidke all."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Üles – <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Alla – <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Vasakule – <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Paremale – <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Luku avamine"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kaamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Hääletu"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 5a50a8f..ce26f1e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"یک PUK با 8 رقم یا بیشتر تایپ کنید."</string>
     <string name="needPuk" msgid="919668385956251611">"سیم کارت شما با PUK قفل شده است. کد PUK را برای بازگشایی آن بنویسید."</string>
     <string name="needPuk2" msgid="4526033371987193070">"PUK2 را برای بازگشایی قفل سیم کارت بنویسید."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"شناسه تماس گیرنده ورودی"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"شناسه تماس گیرنده خروجی"</string>
     <string name="CfMmi" msgid="5123218989141573515">"هدایت تماس"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"تنظیم زمان"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"تاریخ تنظیم"</string>
     <string name="date_time_set" msgid="5777075614321087758">"تنظیم"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"پیش فرض"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"جدید: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"مجوزی لازم نیست"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"افزودن یک حساب"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"کدام حساب را می‎خواهید استفاده کنید؟"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"افزودن حساب"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"افزایش"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"کاهش"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> لمس کرده و نگه دارید."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"برای افزایش به بالا و برای کاهش به پایین بلغزانید."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">" افزایش دقیقه"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"کاهش دقیقه"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"افزایش ساعت"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"کاهش ساعت"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"تنظیم ب.ظ"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"تنظیم ق.ظ"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"ماه افزایشی"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"کاهش ماه"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"افزایش روز"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"کاهش روز"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"افزایش سال"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"کاهش سال"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"علامت زده"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"بدون علامت"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"انتخاب شد"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"اشتراک‌گذاری با"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"اشتراک‌گذاری با <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"اهرم کنترل حرکت. لمس کرده و نگهدارید."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"پایین برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"راست برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"بازکردن قفل"</string>
     <string name="description_target_camera" msgid="969071997552486814">"دوربین"</string>
     <string name="description_target_silent" msgid="893551287746522182">"ساکت"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 6d849dd..54e1a1b 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Kirjoita vähintään 8 numeron pituinen PUK-koodi."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM-korttisi on PUK-lukittu. Poista lukitus antamalla PUK-koodi."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Pura SIM-kortin esto antamalla PUK2-koodi."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI-koodi"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Soittajan tunnus"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Soittajan tunnus"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Soitonsiirto"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Aseta aika"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Aseta päivämäärä"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Aseta"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Oletus"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"UUTTA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Lupia ei tarvita"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Lisää tili"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Mitä tiliä haluat käyttää?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Lisää tili"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Lisää"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Vähennä"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> kosketa pitkään."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Kasvata tai pienennä arvoa liu\'uttamalla ylös tai alas."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Kasvata minuuttia"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Pienennä minuuttia"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Kasvata tuntia"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Pienennä tuntia"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Aseta ip"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Aseta ap"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Kasvata kuukautta"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Vähennä kuukautta"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Kasvata päivää"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Pienennä päivää"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Kasvata vuotta"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Pienennä vuotta"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"valittu"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"ei valittu"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"valittu"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Jaa seuraavien kanssa:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Jaa sovelluksessa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Liukuva valitsin. Kosketa pitkään."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Ylös: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Alas: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Vasemmalle: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Oikealle: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Poista lukitus"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Äänetön"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 548d66b..d4a6f5b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Saisissez un code PUK comportant au moins huit chiffres."</string>
     <string name="needPuk" msgid="919668385956251611">"Votre carte SIM est verrouillée par clé PUK. Saisissez la clé PUK pour la déverrouiller."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Saisissez la clé PUK2 pour débloquer la carte SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"Code IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"Code MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Numéro de l\'appelant (entrant)"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Numéro de l\'appelant (sortant)"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Transfert d\'appel"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Définir l\'heure"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Définir la date"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Définir"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Par défaut"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOUVEAU"</font>" :"</string>
     <string name="no_permissions" msgid="7283357728219338112">"Aucune autorisation requise"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Ajouter un compte"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Quel compte souhaitez-vous utiliser ?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Ajouter un compte"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Augmenter"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuer"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> appuyez de manière prolongée."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Faire glisser vers le haut pour augmenter et vers le bas pour diminuer"</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minute suivante"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minute précédente"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Heure suivante"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Heure précédente"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Définir la valeur PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Définir la valeur AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Mois suivant"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Mois précédent"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Jour suivant"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Jour précédent"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Année suivante"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Année précédente"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"coché"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"non coché"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"sélectionné"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partager avec"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Partager avec <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Poignée coulissante. Appuyez de manière prolongée."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Vers le bas pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Vers la droite pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Déverrouiller"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Appareil photo"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Mode silencieux"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index be85378..d84915e 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"ऐसा PUK लिखें जो 8 अंकों या अधिक का हो."</string>
     <string name="needPuk" msgid="919668385956251611">"आपका सिम कार्ड PUK लॉक किया गया है. इसे अनलॉक करने के लिए PUK कोड लिखें."</string>
     <string name="needPuk2" msgid="4526033371987193070">"सिम कार्ड अनब्‍लॉक करने के लिए PUK2 लिखें."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"इनकमिंग कॉलर ID"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"आउटगोइंग कॉलर ID"</string>
     <string name="CfMmi" msgid="5123218989141573515">"कॉल अग्रेषण"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"समय सेट करें"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"दिनांक सेट करें"</string>
     <string name="date_time_set" msgid="5777075614321087758">"सेट करें"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"डिफ़ॉल्ट"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"नया: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"किसी अनुमति की आवश्‍यकता नहीं है"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"कोई खाता जोड़ें"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"आप कौन-सा खाता उपयोग करना चाहते हैं?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"खाता जोड़ें"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"वृद्धि"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"कमी"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> को स्‍पर्श करके रखें."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"बढ़ते क्रम के लिए ऊपर और घटते क्रम के लिए नीचे की ओर स्‍लाइड करें."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"बढ़ते क्रम में मिनट"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"घटते क्रम में मिनट"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"बढ़ते क्रम में घंटा"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"घटते क्रम में घंटा"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"सायं सेट करें"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"प्रात: सेट करें"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"बढ़ते क्रम में माह"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"घटते क्रम में माह"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"बढ़ते क्रम में दिन"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"घटते क्रम में दिन"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"बढ़ते क्रम में वर्ष"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"घटते क्रम में वर्ष"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"चेक किया गया"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"चेक नहीं किया गया"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"चयनित"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"इसके साथ साझा करें:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> के साथ साझा करें"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"स्लाइडिंग हैंडल. स्पर्श करके रखें."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए नीचे."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए दाएं."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"अनलॉक करें"</string>
     <string name="description_target_camera" msgid="969071997552486814">"कैमरा"</string>
     <string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index a30a5e0..b0ebc8a 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Upišite PUK koji se sastoji od barem 8 brojeva."</string>
     <string name="needPuk" msgid="919668385956251611">"Vaša je SIM kartica zaključana PUK-om. Unesite PUK kôd da biste je otključali."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Unesite PUK2 da biste odblokirali SIM karticu."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID dolaznog pozivatelja"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID izlaznog pozivatelja"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Preusmjeravanje poziva"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Postavljanje vremena"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Postavi datum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Postavi"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Zadano"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nije potrebno dopuštenje"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Dodajte račun"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Koji račun želite upotrijebiti?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Dodaj račun"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Povećaj"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Smanji"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> pritisnite i držite."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Klizite prema gore za pomak unaprijed, a prema dolje za pomak unatrag."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Pomak unaprijed za jednu minutu"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Pomak unatrag za jednu minutu"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Pomak unaprijed za jedan sat"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Pomak unatrag za jedan sat"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Postavi PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Postavi AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Pomak unaprijed za jedan mjesec"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Pomak unatrag za jedan mjesec"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Pomak unaprijed za jedan dan"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Pomak unatrag za jedan dan"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Pomak unaprijed za jednu godinu"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Pomak unatrag za jednu godinu"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"označeno"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"nije označeno"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"odabran"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Dijeljenje sa"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dijeli s aplikacijom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Klizna ručka. Dodirnite i držite."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Dolje za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Otključaj"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Bešumno"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f6fd651..5e3464d 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"8 számjegyű vagy hosszabb PUK kódot írjon be."</string>
     <string name="needPuk" msgid="919668385956251611">"A SIM-kártya le van zárva a PUK-kóddal. A feloldáshoz adja meg a PUK-kódot."</string>
     <string name="needPuk2" msgid="4526033371987193070">"A SIM-kártya feloldásához adja meg a PUK2-kódot."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Beérkező hívóazonosító"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Kimenő hívóazonosító"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Hívásátirányítás"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Idő beállítása"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Dátum beállítása"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Beállítás"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Alapértelmezett"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ÚJ: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nincs szükség engedélyre"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Fiók hozzáadása"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Melyik fiókot szeretné használni?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Fiók hozzáadása"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Növelés"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Csökkentés"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> érintse meg és tartsa lenyomva."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Csúsztassa fel a növeléshez és le a csökkentéshez."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Percek növelése"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Percek csökkentése"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Órák növelése"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Órák csökkentése"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Állítsa du. értékre"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Állítsa de. értékre"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Hónapok növelése"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Hónapok csökkentése"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Napok növelése"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Napok csökkentése"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Évek növelése"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Évek csökkentése"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"bejelölve"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"nincs bejelölve"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"bejelölve"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Megosztás a következővel:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ossza meg a következő alkalmazással: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Csúsztatható fogantyú. Érintse meg és tartsa."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Fel: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Le: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Balra: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Jobbra: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Feloldás"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Némítás"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 4a142083..4fb25c1 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Ketik PUK yang terdiri dari 8 angka atau lebih."</string>
     <string name="needPuk" msgid="919668385956251611">"Kartu SIM Anda dikunci PUK. Ketikkan kode PUK untuk membukanya."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Ketikkan PUK2 untuk membuka kartu SIM"</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Nomor Penelepon Masuk"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Nomor Penelepon Keluar"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Penerusan panggilan"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Setel waktu"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Setel tanggal"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Setel"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BARU: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Tidak perlu izin"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Tambahkan akun"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Akun mana yang ingin Anda gunakan?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Tambahkan akun"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Penambahan"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Pengurangan"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh dan tahan."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Geser ke atas untuk menambah dan ke bawah untuk mengurangi."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Menit penambahan"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Menit pengurangan"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Jam penambahan"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Jam pengurangan"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Menyetel PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Setel AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Bulan penambahan"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Bulan pengurangan"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Hari penambahan"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Hari pengurangan"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Tahun penambahan"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Tahun pengurangan"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"dicentang"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"tidak diperiksa"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"dipilih"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Berbagi dengan"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Berbagi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Gagang geser. Sentuh &amp; tahan."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Membuka gembok"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index c682a85..7f399be 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Digita un PUK formato da almeno 8 numeri."</string>
     <string name="needPuk" msgid="919668385956251611">"La SIM è bloccata tramite PUK. Digita il codice PUK per sbloccarla."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Digita il PUK2 per sbloccare la SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID chiamante in entrata"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID chiamante in uscita"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Deviazione chiamate"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Imposta ora"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Imposta data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Imposta"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Predefinito"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUOVA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nessuna autorizzazione richiesta"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Aggiungi un account"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Quale account vuoi usare?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Aggiungi account"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Aumenta"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuisci"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Tocca e tieni premuto il numero <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Scorri verso l\'alto per aumentare il valore e verso il basso per diminuirlo."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumenta minuto"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Diminuisci minuto"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumenta ora"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Diminuisci ora"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Imposta PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Imposta AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumenta mese"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Diminuisci mese"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumenta giorno"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Diminuisci giorno"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumenta anno"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Diminuisci anno"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"selezionata"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"non selezionato"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"selezionato"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Condividi con"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Condividi con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Maniglia scorrevole. Tocca e tieni premuto."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Giù per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"A destra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Sblocca"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Fotocamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Silenzioso"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 9ebc58d..b03207d 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"הקלד PUK באורך 8 מספרים או יותר."</string>
     <string name="needPuk" msgid="919668385956251611">"כרטיס ה-SIM נעול באמצעות PUK. הקלד את קוד PUK כדי לבטל את נעילתו."</string>
     <string name="needPuk2" msgid="4526033371987193070">"הקלד PUK2 כדי לבטל את חסימת כרטיס ה-SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"זיהוי מתקשר של שיחה נכנסת"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"זיהוי מתקשר בשיחה יוצאת"</string>
     <string name="CfMmi" msgid="5123218989141573515">"העברת שיחות"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"הגדרת שעה"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"הגדר תאריך"</string>
     <string name="date_time_set" msgid="5777075614321087758">"הגדר"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"ברירת מחדל"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"חדש: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"לא דרושים אישורים"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"הוסף חשבון"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"באיזה חשבון ברצונך להשתמש?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"הוסף חשבון"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"הגדל"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"הפחת"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> גע והחזק."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"הסט מעלה כדי להוסיף ומטה כדי להפחית."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"הוסף דקה"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"הפחת דקה"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"הוסף שעה"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"הפחת שעה"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"הגדר PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"הגדר AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"הוסף חודש"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"הפחת חודש"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"הוסף יום"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"הפחת יום."</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"הוסף שנה"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"הפחת שנה"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"מסומן"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"לא מסומן"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"נבחר"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"שתף עם"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"שתף עם <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ידית להחלקה. גע והחזק."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"\'למעלה\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"\'למטה\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"\'שמאל\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"\'ימין\' עבור <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"בטל נעילה"</string>
     <string name="description_target_camera" msgid="969071997552486814">"מצלמה"</string>
     <string name="description_target_silent" msgid="893551287746522182">"שקט"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 9f70bb3..526535f 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"PUKは8桁以上で入力してください。"</string>
     <string name="needPuk" msgid="919668385956251611">"SIMカードはPUKでロックされています。ロックを解除するにはPUKコードを入力してください。"</string>
     <string name="needPuk2" msgid="4526033371987193070">"SIMカードのロック解除のためPUK2を入力します。"</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"着信時の発信者番号"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"発信者番号"</string>
     <string name="CfMmi" msgid="5123218989141573515">"着信転送"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"時刻設定"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"日付設定"</string>
     <string name="date_time_set" msgid="5777075614321087758">"設定"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"端末既定"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NEW: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"権限の許可は必要ありません"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"アカウントを追加"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"どのアカウントを使用しますか?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"アカウントを追加"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"増やす"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"減らす"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>回タップして押し続けます。"</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"上にスライドで大きく、下にスライドで小さくなります。"</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"1分進める"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"1分戻す"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"1時間進める"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"1時間戻す"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"午後に設定"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"午前に設定"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"1か月進める"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"1か月戻す"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"1日進める"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"1日戻す"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"1年進める"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"1年戻す"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"ON"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"OFF"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"ON"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"共有"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>と共有"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"スライダーハンドルです。押し続けます。"</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"上は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"下は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"左は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"右は<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>です。"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"ロックを解除"</string>
     <string name="description_target_camera" msgid="969071997552486814">"カメラ"</string>
     <string name="description_target_silent" msgid="893551287746522182">"マナーモード"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 0057a5b..b38b988 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"8자리 이상의 숫자 PUK를 입력합니다."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM 카드의 PUK가 잠겨 있습니다. 잠금해제하려면 PUK 코드를 입력하세요."</string>
     <string name="needPuk2" msgid="4526033371987193070">"SIM 카드 잠금을 해제하려면 PUK2를 입력하세요."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"발신자 번호"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"내 발신 번호"</string>
     <string name="CfMmi" msgid="5123218989141573515">"착신전환"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"시간 설정"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"날짜 설정"</string>
     <string name="date_time_set" msgid="5777075614321087758">"설정"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"기본값"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"신규: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"권한 필요 없음"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"계정 추가"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"사용할 계정을 선택하세요."</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"계정 추가"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"올리기"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"줄이기"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> 길게 터치하세요."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"올리려면 위로 슬라이드하고 줄이려면 아래로 슬라이드합니다."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"\'분\'을 올립니다."</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"\'분\'을 줄입니다."</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"\'시\'를 올립니다."</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"\'시\'를 줄입니다."</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM 설정"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM 설정"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"\'월\'을 올립니다."</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"\'월\'을 줄입니다."</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"\'날짜\'를 올립니다."</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"\'날짜\'를 줄입니다."</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"\'연도\'를 올립니다."</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"\'연도\'를 줄입니다."</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"확인"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"선택 안함"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"선택됨"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"공유 대상:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>와(과) 공유"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"슬라이딩 핸들을 길게 터치하세요."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 아래로 슬라이드"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 오른쪽으로 슬라이드"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"잠금 해제"</string>
     <string name="description_target_camera" msgid="969071997552486814">"카메라"</string>
     <string name="description_target_silent" msgid="893551287746522182">"무음"</string>
diff --git a/core/res/res/values-land/arrays.xml b/core/res/res/values-land/arrays.xml
index 68e5cfd..537d27c 100644
--- a/core/res/res/values-land/arrays.xml
+++ b/core/res/res/values-land/arrays.xml
@@ -23,49 +23,49 @@
     <array name="lockscreen_targets_when_silent">
         <item>@null</item>"
         <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
+        <item>@drawable/ic_lockscreen_search</item>
         <item>@drawable/ic_lockscreen_soundon</item>
     </array>
 
     <array name="lockscreen_target_descriptions_when_silent">
         <item>@null</item>
         <item>@string/description_target_unlock</item>
-        <item>@null</item>
+        <item>@string/description_target_search</item>
         <item>@string/description_target_soundon</item>
     </array>
 
     <array name="lockscreen_direction_descriptions">
         <item>@null</item>
         <item>@string/description_direction_up</item>
-        <item>@null</item>
+        <item>@string/description_direction_left</item>
         <item>@string/description_direction_down</item>
     </array>
 
     <array name="lockscreen_targets_when_soundon">
         <item>@null</item>
         <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
+        <item>@drawable/ic_lockscreen_search</item>
         <item>@drawable/ic_lockscreen_silent</item>
     </array>
 
     <array name="lockscreen_target_descriptions_when_soundon">
         <item>@null</item>
         <item>@string/description_target_unlock</item>
-        <item>@null</item>
+        <item>@string/description_target_search</item>
         <item>@string/description_target_silent</item>
     </array>
 
     <array name="lockscreen_targets_with_camera">
         <item>@null</item>
         <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
+        <item>@drawable/ic_lockscreen_search</item>
         <item>@drawable/ic_lockscreen_camera</item>
     </array>
 
     <array name="lockscreen_target_descriptions_with_camera">
         <item>@null</item>
         <item>@string/description_target_unlock</item>
-        <item>@null</item>
+        <item>@string/description_target_search</item>
         <item>@string/description_target_camera</item>
     </array>
 
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 8aeb170..4d67940 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Įveskite 8 skaitmenų ar ilgesnį PUK kodą."</string>
     <string name="needPuk" msgid="919668385956251611">"Jūsų SIM kortelė yra užrakinta PUK kodu. Jei norite ją atrakinti, įveskite PUK kodą."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Įveskite PUK2 kodą, kad panaikintumėte SIM kortelės blokavimą."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Įeinančio skambintojo ID"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Išeinančio skambintojo ID"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Skambučio peradresavimas"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Nustatyti laiką"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nustatyti datą"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Nustatyti"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Numatytasis"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NAUJAS: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nereikia leidimų"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Pridėti paskyrą"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Kurią paskyrą norite naudoti?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Pridėti paskyrą"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Padidinti"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Sumažinti"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Palieskite <xliff:g id="VALUE">%s</xliff:g> ir laikykite."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Slinkite aukštyn, kad būtų parodytas padidėjimas, ir žemyn, kad būtų parodytas sumažėjimas."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Padidėjimo minutė"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Sumažėjimo minutė"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Padidėjimo valanda"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Sumažėjimo valanda"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nustatyti po pusiaudienio"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nustatyti prieš pusiaudienį"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Padidėjimo mėnuo"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Sumažėjimo mėnuo"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Padidėjimo diena"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Sumažėjimo diena"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Padidėjimo metai"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Sumažėjimo metai"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"pažymėtas"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"nepatikrinta"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"pasirinkta"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Bendrinti su"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Bendrinti su „<xliff:g id="APPLICATION_NAME">%s</xliff:g>“"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Slydimo valdymas. Palieskite ir laikykite."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Aukštyn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Žemyn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Kairėn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Dešinėn į <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Atrakinti"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Vaizdo kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Begarsis"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index f434e09..12a0e58 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Ierakstiet PUK kodu, kas sastāv no 8 vai vairāk cipariem."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM karte ir bloķēta ar PUK kodu. Ierakstiet PUK kodu, lai to atbloķētu."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Ierakstiet PUK2 kodu, lai atbloķētu SIM karti."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Ienākošā zvana zvanītāja ID"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Izejošā zvana zvanītāja ID"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Zvanu pāradresācija"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Laika iestatīšana"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Datuma iestatīšana"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Iestatīt"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Noklusējums"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"JAUNA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Atļaujas nav nepieciešamas."</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Pievienot kontu"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Kuru kontu vēlaties izmantot?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Pievienot kontu"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Palielināt"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Samazināt"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>: pieskarieties un turiet nospiestu."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Bīdiet uz augšu, lai palielinātu vērtību, un uz leju, lai to samazinātu."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Palielināt minūtes vērtību"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Samazināt minūtes vērtību"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Palielināt stundas vērtību"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Samazināt stundas vērtību"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Iestatīt pēcpusdienas laiku"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Iestatīt priekšpusdienas laiku"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Palielināt mēneša vērtību"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Samazināt mēneša vērtību"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Palielināt datuma vērtību"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Samazināt datuma vērtību"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Palielināt gada vērtību"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Samazināt gada vērtību"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"atzīmēta"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"nav atzīmēta"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"atlasīta"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kopīgot ar:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kopīgot ar lietojumprogrammu <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Bīdāms turis. Pieskarieties tam un turiet to nospiestu."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Bīdiet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Bīdiet uz leju, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Bīdiet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Bīdiet pa labi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Atbloķēt"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Klusums"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index a2dd90c..f725896 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Taipkan PUK yang mempunyai 8 nombor atau lebih panjang."</string>
     <string name="needPuk" msgid="919668385956251611">"Kad SIM anda dikunci PUK. Taipkan kod PUK untuk membuka kuncinya."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Taipkan PUK2 untuk menyahsekat kad SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID Pemanggil Masuk"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID Pemanggil Keluar"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Pemajuan panggilan"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Tetapkan masa"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Tetapkan tarikh"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Tetapkan"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Lalai"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BAHARU: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Tiada kebenaran diperlukan"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Tambah akaun"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Akaun mana yang mahu anda gunakan?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Tambah akaun"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Kenaikan"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Penyusutan"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh terus."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Luncurkan ke atas untuk kenaikan dan ke bawah untuk penyusutan."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minit kenaikan"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minit penyusutan"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Jam kenaikan"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Jam penyusutan"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Tetapkan PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Tetapkan AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Bulan kenaikan"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Bulan penyusutan"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Hari kenaikan"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Hari penyusutan"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Tahun kenaikan"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Tahun penyusutan"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"ditandakan"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"tidak ditandakan"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"dipilih"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kongsi dengan"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kongsi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Pemegang gelongsor. Sentuh &amp; tahan."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Buka kunci"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index b3ea39ff..8bc9dab 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Skriv inn en PUK-kode på åtte tall eller mer."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM-kortet ditt er PUK-låst. Skriv inn PUK-koden for å låse det opp."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Skriv inn PUK2 for å låse opp SIM-kortet."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Inngående nummervisning"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Utgående nummervisning"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Viderekobling"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Stille klokken"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Angi dato"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Lagre"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NYTT: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Trenger ingen rettigheter"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Legg til en konto"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Hvilken konto vil du bruke?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Legg til konto"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Øke"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Senke"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> – trykk og hold inne."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Skyv opp for å øke og ned for å redusere."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Endre minutter (fremover)"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Endre minutter (bakover)"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Endre timer (fremover)"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Endre time (bakover)"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Angi p.m."</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Angi a.m."</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Endre måned (fremover)"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Endre måned (bakover)"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Endre dag (fremover)"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Endre dag (bakover)"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Endre år (fremover)"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Endre år (bakover)"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"valgt"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"ikke valgt"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"valgt"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Glidebryter. Trykk og hold inne."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Opp for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Ned for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Venstre for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Høyre for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Lås opp"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Stille"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 5698f03..61f08e0 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Typ een PUK-code die 8 cijfers of langer is."</string>
     <string name="needPuk" msgid="919668385956251611">"Uw SIM-kaart is vergrendeld met de PUK-code. Typ de PUK-code om te ontgrendelen."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Voer de PUK2-code in om de SIM-kaart te ontgrendelen."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Inkomende beller-id"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Uitgaande beller-id"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Oproep doorschakelen"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Tijd instellen"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum instellen"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Instellen"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Standaard"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NIEUW: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Geen machtigingen vereist"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Een account toevoegen"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Welk account wilt u gebruiken?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Account toevoegen"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Hoger"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Lager"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> blijven aanraken."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Schuif omhoog om te verhogen en omlaag om te verlagen."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minuten verhogen"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minuten verlagen"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Uren verhogen"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Uren verlagen"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM instellen"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM instellen"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Maand verhogen"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Maand verlagen"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Dag verhogen"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Dag verlagen"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Jaar verhogen"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Jaar verlagen"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"aangevinkt"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"niet aangevinkt"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"geselecteerd"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delen met"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delen met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Schuifgreep. Tikken en blijven aanraken."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Omlaag voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Rechts voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Ontgrendelen"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index da2f78d..77f8adc 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Wpisz kod PUK składający się z co najmniej 8 cyfr."</string>
     <string name="needPuk" msgid="919668385956251611">"Karta SIM jest zablokowana kodem PUK. Wprowadź kod PUK, aby odblokować kartę."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Wprowadź kod PUK2, aby odblokować kartę SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Identyfikator rozmówcy przy połączeniach przychodzących"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Identyfikator rozmówcy przy połączeniach wychodzących"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Przekazywanie połączeń"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Ustaw godzinę"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Ustaw datę"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Ustaw"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Domyślne"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOWE: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nie są wymagane żadne uprawnienia"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Dodaj konto"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Którego konta chcesz użyć?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Dodaj konto"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Zwiększ"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmniejsz"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> dotknij i przytrzymaj."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Przesuń w górę, aby zwiększyć wartość, lub w dół, aby ją zmniejszyć."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Następna minuta"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Poprzednia minuta"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Następna godzina"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Poprzednia godzina"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Ustaw PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Ustaw AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Następny miesiąc"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Poprzedni miesiąc"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Następny dzień"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Poprzedni dzień"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Następny rok"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Poprzedni rok"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"zaznaczono"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"nie zaznaczono"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"wybrano"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Udostępnij przez"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Udostępnij przez <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Uchwyt przesuwny. Dotknij i przytrzymaj."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w górę"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w dół"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w lewo"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>: w prawo"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Odblokuj"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Aparat"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Wyciszenie"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index ec43491..2a3e2b9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Introduza um PUK que tenha 8 ou mais algarismos."</string>
     <string name="needPuk" msgid="919668385956251611">"O seu cartão SIM está bloqueado com PUK. Introduza o código PUK para desbloqueá-lo."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Introduza o PUK2 para desbloquear o cartão SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID do Autor da Chamada"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID do autor da chamada efetuada"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Encaminhamento de chamadas"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Definir hora"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Predefinido"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Não são necessárias permissões"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Adicionar uma conta"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Que conta pretende utilizar?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuir"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Toque sem soltar em <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Deslize lentamente para cima para aumentar e para baixo para diminuir."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minuto"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Diminuir minuto"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumentar hora"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Diminuir hora"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Definir PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Definir AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumentar mês"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Diminuir mês"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumentar dia"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Diminuir dia"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumentar ano"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Diminuir ano"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"marcado"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"desmarcado"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"selecionado"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partilhar com:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Barra deslizante. Toque &amp; não solte."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Para a direita para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Câmara"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 53e2a96..88b7a57 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Digite um PUK com oito números ou mais."</string>
     <string name="needPuk" msgid="919668385956251611">"O seu cartão SIM está bloqueado por um PUK. Digite o código PUK para desbloqueá-lo."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Digite o PUK2 para desbloquear o cartão SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID do chamador de entrada"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID do chamador de saída"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Encaminhamento de chamada"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Definir hora"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Padrão"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nenhuma permissão necessária"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Adicionar uma conta"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Qual conta você deseja usar?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Redução"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> toque e mantenha pressionado."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Deslize para cima para aumentar e para baixo para diminuir."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minuto"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Diminuir minuto"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Aumentar hora"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Diminuir hora"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Configurar valor PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Configurar valor AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Aumentar mês"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Diminuir mês"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Aumentar dia"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Reduzir dia"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Aumentar ano"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Diminuir ano"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"verificado"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"não selecionado"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"selecionado"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartilhar com"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Recurso deslizante. Toque e segure."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Deslize para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Deslize para a direita para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Câmera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 5f0561b..75c5c7e 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1509,6 +1509,8 @@
     <!-- no translation found for date_picker_dialog_title (5879450659453782278) -->
     <skip />
     <string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
     <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
     <skip />
@@ -1746,37 +1748,37 @@
     <skip />
     <!-- no translation found for add_account_button_label (3611982894853435874) -->
     <skip />
-    <!-- no translation found for number_picker_increment_button (4830170763103463443) -->
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
     <skip />
-    <!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
     <skip />
     <!-- no translation found for number_picker_increment_scroll_mode (3073101067441638428) -->
     <skip />
-    <!-- no translation found for number_picker_increment_scroll_action (4628981789985093179) -->
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
     <skip />
-    <!-- no translation found for time_picker_increment_minute_button (2843066823236250329) -->
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
     <skip />
-    <!-- no translation found for time_picker_decrement_minute_button (4357907223628449595) -->
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
     <skip />
-    <!-- no translation found for time_picker_increment_hour_button (2484204991937119057) -->
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
     <skip />
-    <!-- no translation found for time_picker_decrement_hour_button (4659353501775842780) -->
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
     <skip />
     <!-- no translation found for time_picker_increment_set_pm_button (4147590696151230863) -->
     <skip />
     <!-- no translation found for time_picker_decrement_set_am_button (8302140353539486752) -->
     <skip />
-    <!-- no translation found for date_picker_increment_month_button (6324978841467899081) -->
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
     <skip />
-    <!-- no translation found for date_picker_decrement_month_button (7304349355000398077) -->
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
     <skip />
-    <!-- no translation found for date_picker_increment_day_button (4397040141921413183) -->
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
     <skip />
-    <!-- no translation found for date_picker_decrement_day_button (2427816793443629131) -->
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
     <skip />
-    <!-- no translation found for date_picker_increment_year_button (3058553394722295105) -->
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
     <skip />
-    <!-- no translation found for date_picker_decrement_year_button (5193062846559743823) -->
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
     <skip />
     <!-- no translation found for checkbox_checked (7222044992652711167) -->
     <skip />
@@ -1816,13 +1818,13 @@
     <skip />
     <!-- no translation found for content_description_sliding_handle (415975056159262248) -->
     <skip />
-    <!-- no translation found for description_direction_up (1983114130441878529) -->
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
     <skip />
-    <!-- no translation found for description_direction_down (4294993639091088240) -->
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
     <skip />
-    <!-- no translation found for description_direction_left (6814008463839915747) -->
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
     <skip />
-    <!-- no translation found for description_direction_right (4296057241963012862) -->
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
     <skip />
     <!-- no translation found for description_target_unlock (2228524900439801453) -->
     <skip />
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 11199b0..5409290 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Introduceţi un cod PUK care să aibă 8 cifre sau mai mult."</string>
     <string name="needPuk" msgid="919668385956251611">"Cardul SIM este blocat cu codul PUK. Introduceţi codul PUK pentru a-l debloca."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Introduceţi codul PUK2 pentru a debloca cardul SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID apelant de primire"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID apelant"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Redirecţionarea apelurilor"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Setaţi ora"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Setaţi data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Setaţi"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Prestabilit"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOU: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nu se solicită nicio permisiune"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Adăugaţi un cont"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Ce cont doriţi să utilizaţi?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Adăugaţi un cont"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementaţi"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrementaţi"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Atingeţi şi ţineţi apăsat <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Glisaţi în sus pentru incrementare şi în jos pentru decrementare."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Incrementaţi valoarea pentru minut"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Decrementaţi valoarea pentru minut"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Incrementaţi valoarea pentru oră"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Decrementaţi valoarea pentru oră"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Setaţi valoarea PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Setaţi valoarea AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Incrementaţi valoarea pentru lună"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Decrementaţi valoarea pentru lună"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Incrementaţi valoarea pentru zi"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Decrementaţi valoarea pentru zi"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Incrementaţi valoarea pentru an"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Decrementaţi valoarea pentru an"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"bifată"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"nebifată"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"selectat"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Permiteţi accesul pentru"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Permiteţi accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Mâner glisant. Atingeţi şi ţineţi apăsat."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"În sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"În jos pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"La stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"La dreapta pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Deblocaţi"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Cameră foto"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Silenţios"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d4adfb4..9d8e4a6 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Введите PUK-код из 8 или более цифр."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM-карта заблокирована с помощью кода PUK. Для разблокировки введите код PUK."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Для разблокировки SIM-карты введите PUK2."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Идентификация вызывающего абонента"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Идентификация звонящего абонента"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Переадресация вызова"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Настройка времени"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Настройка даты"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Установить"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"По умолчанию"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВОЕ: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Не требуется разрешений"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Добавить аккаунт"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Выберите аккаунт"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Добавить аккаунт"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличить"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Уменьшить"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Нажмите и удерживайте <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Проведите вверх, чтобы увеличить значение, и вниз, чтобы уменьшить его."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"На минуту вперед"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"На минуту назад"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"На час вперед"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"На час назад"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Установить время после полудня"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Установить время до полудня"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"На месяц вперед"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"На месяц назад"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"На день вперед"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"На день назад"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"На год вперед"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"На год назад"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"установлено"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"не установлено"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"выбрано"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Открыть доступ:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Открыть доступ приложению \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\""</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Перетаскиваемый значок блокировки. Нажмите и удерживайте."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Проведите вниз, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Проведите вправо, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Разблокировать"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Без звука"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index bad739f9..ca80f6b 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Zadajte kód PUK, ktorý má 8 alebo viac čísel."</string>
     <string name="needPuk" msgid="919668385956251611">"Karta SIM je uzamknutá pomocou kódu PUK. Odomknite ju zadaním kódu PUK."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Ak chcete odblokovať kartu SIM, zadajte kód PUK2."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Prichádzajúca identifikácia volajúceho"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Odchádzajúca identifikácia volajúceho"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Presmerovanie hovorov"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastaviť čas"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastaviť dátum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Nastaviť"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Predvolené"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVINKA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nevyžadujú sa žiadne oprávnenia."</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Pridať účet"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Ktorý účet chcete použiť?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Pridať účet"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšenie"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Zníženie"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Dotknite sa a podržte <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Ak chcete pripočítať, potiahnite prst nahor. Ak chcete odpočítať, potiahnite prst nadol."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Pripočítať minútu"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Odpočítať minútu"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Pripočítať hodinu"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Odpočítať hodinu"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nastaviť čas popoludní"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastaviť čas dopoludnia"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Pripočítať mesiac"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Odpočítať mesiac"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Pripočítať deň"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Odpočítať deň"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Pripočítať rok"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Odpočítať rok"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"začiarknuté"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"nezačiarknuté"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"vybratý"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Zdieľať s"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Zdieľať s aplikáciou <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvné tlačidlo. Dotknite sa a podržte."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Nahor na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Nadol na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Doľava na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Doprava na <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Odomknúť"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 767305c..e664d9c 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Vnesite 8- ali več mestni PUK."</string>
     <string name="needPuk" msgid="919668385956251611">"Kartica SIM je zaklenjena s kodo PUK. Če jo želite odkleniti, vnesite kodo PUK."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Če želite odstraniti blokiranje kartice SIM, vnesite PUK2."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID dohodnega klicatelja"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID odhodnega klicatelja"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Preusmerjanje klicev"</string>
@@ -430,7 +428,7 @@
     <string name="permlab_readPhoneState" msgid="2326172951448691631">"branje stanja in identitete telefona"</string>
     <string name="permdesc_readPhoneState" msgid="5127767618743602782">"Programu omogoča dostop do funkcij telefona v napravi. Program lahko s tem dovoljenjem določi telefonsko številko in serijsko številko tega telefona, določi lahko tudi, ali je klic aktiven, številko, s katero je klic povezan, in podobno."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"preprečitev prehoda tabličnega računalnika v stanje pripravljenosti"</string>
-    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"preprečevanje prehod v stanje pripravljenosti telefona"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"preprečevanje prehoda v stanje pripravljenosti telefona"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Omogoča, da program prepreči prehod tabličnega računalnika v stanje pripravljenosti."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Programu omogoča, da v telefonu prepreči prehod v stanje pripravljenosti."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"vklop ali izklop tabličnega računalnika"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastavi uro"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavi datum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Nastavi"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Privzeto"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Ni zahtevanih dovoljenj"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Dodajanje računa"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Kateri račun želite uporabiti?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Dodaj račun"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Povečaj"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmanjšaj"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Dotaknite se vrednosti <xliff:g id="VALUE">%s</xliff:g> in jo pridržite."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Povlecite gor za povečanje in dol za zmanjšanje."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Povečaj minute"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Zmanjšaj minute"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Povečaj uro"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Zmanjšaj uro"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nastavi PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastavi AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Naslednji mesec"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Prejšnji mesec"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Naslednji dan"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Prejšnji dan"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Naslednje leto"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Prejšnje leto"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"potrjeno"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"ni odkljukano"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"izbrano"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delite z"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delite s programom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Drsna ročica. Dotaknite se in pridržite."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Gor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Dol za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Odkleni"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Tiho"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index d03abd7..4a3839b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Унесите PUK који се састоји од 8 цифара или више."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM картица је закључана PUK кодом. Унесите PUK кôд да бисте је откључали."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Унесите PUK2 да бисте деблокирали SIM картицу."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Долазни ИД позиваоца"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Одлазни ИД позиваоца"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Преусмеравање позива"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Подешавање времена"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Подешавање датума"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Подеси"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Подразумевано"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВО: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Није потребна ниједна дозвола"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Додај налог"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Који налог желите да користите?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Додај налог"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Повећање"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Смањење"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> додирните и задржите."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Превуците нагоре за повећање, а надоле за смањење."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Повећај минуте"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Смањи минуте"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Повећај сате"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Смањи сате"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Подеси по подне"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Подеси пре подне"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Повећај месеце"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Смањи месеце"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Повећај дане"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Смањи дане"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Повећај године"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Смањи године"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"изабрано"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"није потврђено"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"изабрано"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Дели са"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Дели са апликацијом <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Клизна ручица. Додирните и задржите."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Надоле за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Удесно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Откључај"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Нечујно"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index ddaa30a..7ba32ce 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Ange en PUK-kod med minst 8 siffror."</string>
     <string name="needPuk" msgid="919668385956251611">"Ditt SIM-kort är PUK-låst. Ange PUK-koden om du vill låsa upp det."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Ange PUK2-koden för att häva spärren av SIM-kortet."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI-kod"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Nummerpresentatör för inkommande samtal"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Nummerpresentatör för utgående samtal"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Vidarebefordra samtal"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Ange tid"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Ange datum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Ställ in"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Standardinställning"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NY: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Inga behörigheter krävs"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Lägg till ett konto"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Vilket konto vill du använda?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Lägg till konto"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Öka"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Minska"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> tryck länge."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Skjut uppåt för att öka och nedåt för att minska."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Öka minuter"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minska minuter"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Öka timmar"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Minska timmar"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Ange em"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Ange fm"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Öka månad"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Minska månad"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Öka dagar"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Minska dag"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Öka år"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Minska år"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"markerat"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"inte markerat"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"markerade"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Dela med"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dela med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Skärmlåsfunktion. Tryck och dra."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Upp för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Ned för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Höger för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Lås upp"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Tyst"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 0424964..1744095 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Andika PUK ambayo ina urefu wa nambari 8 au zaidi."</string>
     <string name="needPuk" msgid="919668385956251611">"Kadi yako ya SIM imefungwa na PUK. Anika msimbo wa PUK ili kuifungua."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Chapisha PUK2 ili kufungua SIM kadi."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Kitambulisho cha Mpigaji wa Simu Inayoingia"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID ya Mpigaji simu Inayotoka nje"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Kusambaza simu"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Weka muda"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Weka tarehe"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Weka"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Chaguo-msingi"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">" MPYA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Hakuna vibali vinavyohitajika"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Ongeza akaunti"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Je, ni akaunti gani unataka kutumia?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Ongeza akaunti"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Ongezeko"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Punguza"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> gusa na ushikilie."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Nyiririsha juu kuongeza na chini kupunguza."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Dakika ya nyongeza"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Dakika pungufu"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Saa ya nyongeza"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Saa pungufu."</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Seti PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Seti AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Mwezi wa nyongeza"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Mwezi pungufu"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Siku ya nyongeza"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Siku pungufu"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Mwaka wa nyongeza"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Mwaka pungufu"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"imeangaliwa"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"haijakaguliwa"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"Iliyochaguliwa"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Gawa na"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Gawa na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Utambo unaosonga. Gusa &amp; shika"</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Juu ajili ya<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Chini kwa ajili ya<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Kulia kwa ajili ya <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Fungua"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Kimya"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 7197f90..32281b5 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"พิมพ์รหัส PUK ซึ่งต้องเป็นตัวเลขอย่างน้อย 8 หลัก"</string>
     <string name="needPuk" msgid="919668385956251611">"ซิมการ์ดของคุณถูกล็อกด้วย PUK พิมพ์รหัส PUK เพื่อปลดล็อก"</string>
     <string name="needPuk2" msgid="4526033371987193070">"พิมพ์ PUK2 เพื่อยกเลิกการปิดกั้นซิมการ์ด"</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"หมายเลขผู้โทรเข้า"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"หมายเลขผู้โทรออก"</string>
     <string name="CfMmi" msgid="5123218989141573515">"การโอนสาย"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"ตั้งเวลา"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"ตั้งวันที่"</string>
     <string name="date_time_set" msgid="5777075614321087758">"ตั้งค่า"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"เริ่มต้น"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ใหม่: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"ไม่ต้องการการอนุญาต"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"เพิ่มบัญชี"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"คุณต้องการใช้บัญชีใด"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"เพิ่มบัญชี"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"การเพิ่ม"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"การลด"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"แตะ <xliff:g id="VALUE">%s</xliff:g> ค้างไว้"</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"เลื่อนขึ้นเพื่อเพิ่มและเลื่อนลงเพื่อลด"</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"เพิ่มนาที"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"ลดนาที"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"เพิ่มชั่วโมง"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"ลดชั่วโมง"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"ตั้งค่า PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"ตั้งค่า AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"เพิ่มเดือน"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"ลดเดือน"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"เพิ่มวัน"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"ลดวัน"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"เพิ่มปี"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"ลดปี"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"เลือกไว้"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"ไม่ได้ตรวจสอบ"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"เลือกแล้ว"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"แบ่งปันกับ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"แบ่งปันด้วย <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ที่จับสำหรับเลื่อน แตะค้างไว้"</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"เลื่อนลงเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"เลื่อนไปทางขวาเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"ปลดล็อก"</string>
     <string name="description_target_camera" msgid="969071997552486814">"กล้องถ่ายรูป"</string>
     <string name="description_target_silent" msgid="893551287746522182">"ปิดเสียง"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index ff2e7ea..fd88fc1 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Mag-type ng PUK na may 8 numbero o mas mahaba."</string>
     <string name="needPuk" msgid="919668385956251611">"Na-PUK-lock ang iyong SIM card. I-type ang PUK code upang i-unlock ito."</string>
     <string name="needPuk2" msgid="4526033371987193070">"I-type ang PUK2 upang i-unblock ang SIM card."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Papasok na Caller ID"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Papalabas na Caller ID"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Pagpapasa ng tawag"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Magtakda ng oras"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Itakda ang petsa"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Itakda"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BAGO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Walang mga kinakailangang pahintulot"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Magdagdag ng account"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Aling account ang nais mong gamitin?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Magdagdag ng account"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Taasan"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Babaan"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> pindutin nang matagal."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"I-slide pataas upang magdagdag at pababa upang magbawas."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minuto ng pagdaragdag"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minuto ng pagbawas"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Oras ng pagdaragdag"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Oras ng pagbawas"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Itakda ang PM"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Itakda ang AM"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Buwan ng pagdagdag"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Buwan ng pagbawas"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Araw ng pagdaragdag"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Araw ng pagbawas"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Taon ng pagdaragdag"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Taon ng pagbawas"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"nilagyan ng check"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"hindi nilagyan ng check"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"pinili"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Ibahagi sa"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ibahagi sa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Hawakan sa pag-slide. Pindutin nang matagal."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Nakataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Nakababa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Pakanan para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"I-unlock"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Tahimik"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index c450761..251e47c 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"8 veya daha uzun basamaklı bir PUK kodu yazın."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM kartınızın PUK kilidi devrede. Kilidi açmak için PUK kodunu yazın."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Engellenen SIM kartı açmak için PUK2 kodunu yazın."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Gelen Çağrı Kimliği"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Giden Çağrı Kimliği"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Çağrı yönlendirme"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Saati ayarla"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Tarihi ayarla"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Ayarla"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Varsayılan"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"YENİ: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"İzin gerektirmez"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Hesap ekleyin"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Hangi hesabı kullanmak istiyorsunuz?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Hesap ekle"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Artır"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Azalt"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> rakamına dokunun ve basılı tutun."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Artırmak için yukarı, azaltmak için aşağı kaydırın."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Dakika değerini artır"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Dakika değerini azalt"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Saat değerini artır"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Saat değerini azalt"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"ÖS değerini ayarla"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"ÖÖ değerini ayarla"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Ay değerini artır"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Ay değerini azalt"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Gün değerini artır"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Gün değerini azalt"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Yıl değerini artır"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Yıl değerini azalt"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"işaretli"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"işaretlenmedi"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"seçili"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Şununla paylaş:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ile paylaş"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Kayan tutma yeri. Dokunun ve basılı tutun."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için aşağı."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sağa."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Sessiz"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 2afb95f..9054295 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Введіть PUK-код із 8 або більше цифр."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM-карта заблок. PUK-кодом. Введіть PUK-код, щоб її розблок."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Введ. PUK2, щоб розбл. SIM-карту."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Вхідн. ід. абонента"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Вихід. ід. абонента"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Переадрес. виклику"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Установити час"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Установити дату"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Застосувати"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"За умовч."</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВИЙ: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Дозвіл не потрібний"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Додати обліковий запис"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Який обліковий запис використовувати?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Додати облік. запис"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Додати"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Відняти"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> – торкніться й утримуйте."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Перемістіть угору, щоб додати, і вниз, щоб відняти."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Додати хвилину"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Відняти хвилину"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Додати годину"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Відняти годину"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Установити час \"пп\""</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Установити час \"дп\""</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Додати місяць"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Відняти місяць"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Додати день"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Відняти день"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Додати рік"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Відняти рік"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"перевірено"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"не перевірено"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"вибрано"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Надіслати через"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Надіслати через <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Вказівник-повзунок. Торкніться й утримуйте."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Униз, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Праворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Розблокувати"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Без звуку"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 329917e..609452d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Nhập PUK có từ 8 số trở lên."</string>
     <string name="needPuk" msgid="919668385956251611">"Thẻ SIM của bạn đã bị khóa PUK. Nhập mã PUK để mở khóa thẻ SIM đó."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Nhập mã PUK2 để bỏ chặn thẻ SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Số gọi đến"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Số gọi đi"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Chuyển tiếp cuộc gọi"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Đặt giờ"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Đặt ngày"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Đặt"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Mặc định"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"MỚI: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Không yêu cầu quyền"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Thêm tài khoản"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Bạn muốn sử dụng tài khoản nào?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Thêm tài khoản"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Tăng dần"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Giảm dần"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Chạm và giữ <xliff:g id="VALUE">%s</xliff:g>."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Trượt lên để tăng và trượt xuống để giảm."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Phút tăng dần"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Phút giảm dần"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Giờ tăng dần"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Giờ giảm dần."</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Đặt CH"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Đặt SA"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Tháng tăng dần"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Tháng giảm dần"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Ngày tăng dần"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Ngày giảm dần"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Năm tăng dần"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Năm giảm dần."</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"đã kiểm tra"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"chưa chọn"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"đã chọn"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Chia sẻ với"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Chia sẻ với <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Tay trượt. Chạm &amp; giữ."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Xuống để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Sang phải để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Mở khóa"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Máy ảnh"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Im lặng"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index d6ed9a9..5a9cadc 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"请键入至少 8 位数字的 PUK 码。"</string>
     <string name="needPuk" msgid="919668385956251611">"已对 SIM 卡进行 PUK 码锁定。键入 PUK 码将其解锁。"</string>
     <string name="needPuk2" msgid="4526033371987193070">"输入 PUK2 码以解锁 SIM 卡。"</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"来电显示"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"本机号码"</string>
     <string name="CfMmi" msgid="5123218989141573515">"来电转接"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"设置时间"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"设置日期"</string>
     <string name="date_time_set" msgid="5777075614321087758">"设置"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"默认"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"新增:"</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"不需要任何权限"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"添加帐户"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"您要使用哪个帐户?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"添加帐户"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"减少"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"触摸 <xliff:g id="VALUE">%s</xliff:g> 次并按住。"</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"向上滑动可增加值,向下滑动可减少值。"</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"增加分钟数"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"减少分钟数"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"增加小时数"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"减少小时数"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"设置下午时间"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"设置上午时间"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"增加月份值"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"减少月份值"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"增加天数"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"减少天数"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"增加年数"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"减少年份值"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"已选中"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"未选中"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"已选择"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"共享对象"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"与“<xliff:g id="APPLICATION_NAME">%s</xliff:g>”共享"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"滑动手柄。触摸并按住。"</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"向上滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"向下滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"向左滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"向右滑动<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"解锁"</string>
     <string name="description_target_camera" msgid="969071997552486814">"相机"</string>
     <string name="description_target_silent" msgid="893551287746522182">"静音"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index bc9337b..aa8eda1 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"輸入 8 位數以上的 PUK。"</string>
     <string name="needPuk" msgid="919668385956251611">"SIM 卡的 PUK 已鎖定。請輸入 PUK 碼解除鎖定。"</string>
     <string name="needPuk2" msgid="4526033371987193070">"請輸入 PUK2 以解鎖 SIM 卡。"</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"來電顯示"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"本機號碼"</string>
     <string name="CfMmi" msgid="5123218989141573515">"來電轉接"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"設定時間"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"日期設定"</string>
     <string name="date_time_set" msgid="5777075614321087758">"設定"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"預設值"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"新增:"</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"無須許可"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"新增帳戶"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"您要使用哪個帳戶?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"新增帳戶"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"減少"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> 輕觸並按住。"</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"向上滑動即可增加,向下滑動即可減少。"</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"增加分鐘數"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"減少分鐘數"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"增加時數"</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"減少時數"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"設定 PM 值"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"設定 AM 值"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"增加月份"</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"減少月份"</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"增加天數"</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"減少天數"</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"增加年份"</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"減少年份"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"已勾選"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"尚未勾選"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"已選取"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"分享對象:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"與「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」分享"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"滑動控制。持續輕觸。"</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"向下滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"向右滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"解除鎖定"</string>
     <string name="description_target_camera" msgid="969071997552486814">"相機"</string>
     <string name="description_target_silent" msgid="893551287746522182">"靜音"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 6471965..200bbea 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -50,10 +50,8 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Thayipha i-PUK enezinombolo ezingu-8 noma ngaphezu."</string>
     <string name="needPuk" msgid="919668385956251611">"Ikhadi lakho le-SIM livalwe nge-PUK. Thayipha ikhodi ye-PUK ukulivula."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Thayipha i-PUK2 ukuze uvule ikhadi le-SIM."</string>
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"I-ID Yocingo Olungenayo"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"I-ID Yomshayeli Ephumayo"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Ukudlulisa ikholi"</string>
@@ -1021,6 +1019,8 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Hlela isikhathi"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Setha idethi"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Hlela"</string>
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
     <string name="default_permission_group" msgid="2690160991405646128">"Okuzenzakalelayo"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"OKUSHA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Ayikho imvume edingekayo"</string>
@@ -1170,22 +1170,35 @@
     <string name="add_account_label" msgid="2935267344849993553">"Yengeza i-akhawunti"</string>
     <string name="choose_account_text" msgid="6303348737197849675">"Ingabe iyiphi i-akhawunti ofuna ukuyisebenzisa?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Engeza i-akhawunti"</string>
-    <string name="number_picker_increment_button" msgid="4830170763103463443">"Nciphisa"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</string>
+    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
+    <skip />
+    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
+    <skip />
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> thinta bese ucindezela."</string>
-    <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Shishilizisa kwenyuke kuye ekwenyusweni kwehle kuye ekwehlisweni."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Iminithi wokwenyusa"</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Iminithi yokwehlisa"</string>
-    <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Ihora lokwenyusa."</string>
-    <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Ihora lokwehlisa"</string>
+    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
+    <skip />
+    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
+    <skip />
+    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
+    <skip />
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Setha Ntambama"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Setha Ekuseni"</string>
-    <string name="date_picker_increment_month_button" msgid="6324978841467899081">"Inyanga yokwenyusa."</string>
-    <string name="date_picker_decrement_month_button" msgid="7304349355000398077">"Inyanga yokwehlisa."</string>
-    <string name="date_picker_increment_day_button" msgid="4397040141921413183">"Usuku lokwenyusa."</string>
-    <string name="date_picker_decrement_day_button" msgid="2427816793443629131">"Usuku lokwehlisa."</string>
-    <string name="date_picker_increment_year_button" msgid="3058553394722295105">"Unyaka wokwenyusa."</string>
-    <string name="date_picker_decrement_year_button" msgid="5193062846559743823">"Unyaka wokwehlisa"</string>
+    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
+    <skip />
+    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
+    <skip />
+    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
+    <skip />
     <string name="checkbox_checked" msgid="7222044992652711167">"kuhloliwe"</string>
     <string name="checkbox_not_checked" msgid="5174639551134444056">"akuhloliwe"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"Okukhethiwe"</string>
@@ -1205,10 +1218,14 @@
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Yabelana no"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Yabelana no <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Ihaambis isibambo. Thinta &amp; ubambe."</string>
-    <string name="description_direction_up" msgid="1983114130441878529">"Phezulu kwe <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_down" msgid="4294993639091088240">"Ngaphansi kwe <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="6814008463839915747">"Kwesokunxeleee kwe <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_right" msgid="4296057241963012862">"Ngakwesokudla kwe for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
     <string name="description_target_unlock" msgid="2228524900439801453">"Vula"</string>
     <string name="description_target_camera" msgid="969071997552486814">"Ikhamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Thulile"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 90ddc4b..d05a31c 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -353,49 +353,49 @@
     <!-- Resources for MultiWaveView in LockScreen -->
     <array name="lockscreen_targets_when_silent">
         <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
+        <item>@drawable/ic_lockscreen_search</item>
         <item>@drawable/ic_lockscreen_soundon</item>
         <item>@null</item>
     </array>
 
     <array name="lockscreen_target_descriptions_when_silent">
         <item>@string/description_target_unlock</item>
-        <item>@null</item>
+        <item>@string/description_target_search</item>
         <item>@string/description_target_soundon</item>
         <item>@null</item>
     </array>
 
     <array name="lockscreen_direction_descriptions">
         <item>@string/description_direction_right</item>
-        <item>@null</item>
+        <item>@string/description_direction_up</item>
         <item>@string/description_direction_left</item>
         <item>@null</item>
     </array>
 
     <array name="lockscreen_targets_when_soundon">
         <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
+        <item>@drawable/ic_lockscreen_search</item>
         <item>@drawable/ic_lockscreen_silent</item>
         <item>@null</item>
     </array>
 
     <array name="lockscreen_target_descriptions_when_soundon">
         <item>@string/description_target_unlock</item>
-        <item>@null</item>
+        <item>@string/description_target_search</item>
         <item>@string/description_target_silent</item>
         <item>@null</item>
     </array>
 
     <array name="lockscreen_targets_with_camera">
         <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
+        <item>@drawable/ic_lockscreen_search</item>
         <item>@drawable/ic_lockscreen_camera</item>
         <item>@null</item>
     </array>
 
     <array name="lockscreen_target_descriptions_with_camera">
         <item>@string/description_target_unlock</item>
-        <item>@null</item>
+        <item>@string/description_target_search</item>
         <item>@string/description_target_camera</item>
         <item>@null</item>
     </array>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2b27585..aabe407 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2349,6 +2349,8 @@
         <!-- Component name of an activity that allows the user to modify
              the settings for this service. -->
         <attr name="settingsActivity"/>
+        <!-- Set true when the spell checker supports sentence level spell checking. -->
+        <attr name="supportsSentenceSpellCheck" format="boolean" />
     </declare-styleable>
 
     <!-- This is the subtype of the spell checker. Subtype can describe locales (e.g. en_US, fr_FR...) -->
@@ -5552,4 +5554,21 @@
         <attr name="settingsActivity" />
     </declare-styleable>
 
+    <!-- Use <code>keyboard-layouts</code> as the root tag of the XML resource that
+         describes a collection of keyboard layouts provided by an application.
+         Each keyboard layout is declared by a <code>keyboard-layout</code> tag
+         with these attributes.
+
+         The XML resource that contains the keyboard layouts must be referenced from its
+         {@link android.hardware.input.InputManager#META_DATA_KEYBOARD_LAYOUTS}
+         meta-data entry used with broadcast receivers for
+         {@link android.hardware.input.InputManager#ACTION_QUERY_KEYBOARD_LAYOUTS}. -->
+    <declare-styleable name="KeyboardLayout">
+        <!-- The name of the keyboard layout, must be unique in the receiver. -->
+        <attr name="name" />
+        <!-- The display label of the keyboard layout. -->
+        <attr name="label" />
+        <!-- The key character map file resource. -->
+        <attr name="kcm" format="reference" />
+    </declare-styleable>
 </resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1649c48..d414c7f 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -740,6 +740,9 @@
         <flag name="splitActionBarWhenNarrow" value="1" />
     </attr>
 
+    <!-- The name of the logical parent of the activity as it appears in the manifest. -->
+    <attr name="parentActivityName" format="string" />
+
     <!-- The <code>manifest</code> tag is the root of an
          <code>AndroidManifest.xml</code> file,
          describing the contents of an Android package (.apk) file.  One
@@ -1348,6 +1351,7 @@
         <attr name="immersive" />
         <attr name="hardwareAccelerated" />
         <attr name="uiOptions" />
+        <attr name="parentActivityName" />
     </declare-styleable>
     
     <!-- The <code>activity-alias</code> tag declares a new
@@ -1384,6 +1388,7 @@
              component specific values). -->
         <attr name="enabled" />
         <attr name="exported" />
+        <attr name="parentActivityName" />
     </declare-styleable>
     
     <!-- The <code>meta-data</code> tag is used to attach additional
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 6d6b86b..0442be8 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -32,11 +32,9 @@
     <dimen name="toast_y_offset">64dip</dimen>
     <!-- Height of the status bar -->
     <dimen name="status_bar_height">25dip</dimen>
-    <!-- Height of the system bar (combined status + navigation, used on large screens) -->
-    <dimen name="system_bar_height">48dip</dimen>
-    <!-- Height of the horizontal navigation bar on devices that require it -->
+    <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_height">48dp</dimen>
-    <!-- Width of the vertical navigation bar on devices that require it -->
+    <!-- Width of the navigation bar when it is placed vertically on the screen -->
     <dimen name="navigation_bar_width">42dp</dimen>
     <!-- Height of notification icons in the status bar -->
     <dimen name="status_bar_icon_size">24dip</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7341c6c..ca0e913 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -202,6 +202,7 @@
   <java-symbol type="id" name="action2" />
   <java-symbol type="id" name="big_picture" />
   <java-symbol type="id" name="big_text" />
+  <java-symbol type="id" name="chronometer" />
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -991,6 +992,7 @@
   <java-symbol type="drawable" name="ic_lockscreen_camera" />
   <java-symbol type="drawable" name="ic_lockscreen_silent" />
   <java-symbol type="drawable" name="ic_lockscreen_unlock" />
+  <java-symbol type="drawable" name="ic_lockscreen_search" />
 
   <java-symbol type="layout" name="action_bar_home" />
   <java-symbol type="layout" name="action_bar_title_item" />
@@ -1079,6 +1081,8 @@
   <java-symbol type="layout" name="notification_intruder_content" />
   <java-symbol type="layout" name="notification_template_base" />
   <java-symbol type="layout" name="notification_template_big_picture" />
+  <java-symbol type="layout" name="notification_template_part_time" />
+  <java-symbol type="layout" name="notification_template_part_chronometer" />
 
   <java-symbol type="anim" name="slide_in_child_bottom" />
   <java-symbol type="anim" name="slide_in_right" />
@@ -1125,6 +1129,14 @@
   <!-- From android.policy -->
   <java-symbol type="anim" name="app_starting_exit" />
   <java-symbol type="anim" name="lock_screen_behind_enter" />
+  <java-symbol type="anim" name="dock_top_enter" />
+  <java-symbol type="anim" name="dock_top_exit" />
+  <java-symbol type="anim" name="dock_bottom_enter" />
+  <java-symbol type="anim" name="dock_bottom_exit" />
+  <java-symbol type="anim" name="dock_left_enter" />
+  <java-symbol type="anim" name="dock_left_exit" />
+  <java-symbol type="anim" name="dock_right_enter" />
+  <java-symbol type="anim" name="dock_right_exit" />
   <java-symbol type="array" name="config_keyboardTapVibePattern" />
   <java-symbol type="array" name="config_longPressVibePattern" />
   <java-symbol type="array" name="config_safeModeDisabledVibePattern" />
@@ -1150,7 +1162,6 @@
   <java-symbol type="dimen" name="navigation_bar_height" />
   <java-symbol type="dimen" name="navigation_bar_width" />
   <java-symbol type="dimen" name="status_bar_height" />
-  <java-symbol type="dimen" name="system_bar_height" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_off" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_on" />
   <java-symbol type="drawable" name="ic_jog_dial_unlock" />
@@ -3563,5 +3574,9 @@
 
   <public type="attr" name="layout_marginStart"/>
   <public type="attr" name="layout_marginEnd"/>
+  <public type="attr" name="kcm"/>
 
+  <public type="attr" name="parentActivityName" />
+
+  <public type="attr" name="supportsSentenceSpellCheck" />
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 718de0a..44f2ade 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3303,6 +3303,8 @@
     <string name="description_target_silent">Silent</string>
     <!-- Description of the sound on target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
     <string name="description_target_soundon">Sound on</string>
+    <!-- Description of the unlock target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_target_search">Search</string>
 
     <!-- Description of the unlock handle in the Slide unlock screen for tablets. [CHAR LIMIT=NONE] -->
     <string name="description_target_unlock_tablet">Swipe to unlock.</string>
diff --git a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
index ea94fa9..58269a8 100644
--- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.net;
 
+import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
 import static android.net.NetworkStats.TAG_NONE;
@@ -84,12 +85,12 @@
 
         final NetworkStats stats = mFactory.readNetworkStatsSummary();
         assertEquals(6, stats.size());
-        assertStatsEntry(stats, "lo", UID_ALL, SET_DEFAULT, TAG_NONE, 8308L, 8308L);
-        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 1507570L, 489339L);
-        assertStatsEntry(stats, "ifb0", UID_ALL, SET_DEFAULT, TAG_NONE, 52454L, 0L);
-        assertStatsEntry(stats, "ifb1", UID_ALL, SET_DEFAULT, TAG_NONE, 52454L, 0L);
-        assertStatsEntry(stats, "sit0", UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L);
-        assertStatsEntry(stats, "ip6tnl0", UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L);
+        assertStatsEntry(stats, "lo", UID_ALL, SET_ALL, TAG_NONE, 8308L, 8308L);
+        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L, 489339L);
+        assertStatsEntry(stats, "ifb0", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
+        assertStatsEntry(stats, "ifb1", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
+        assertStatsEntry(stats, "sit0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
+        assertStatsEntry(stats, "ip6tnl0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
     }
 
     public void testNetworkStatsSummaryDown() throws Exception {
@@ -102,8 +103,8 @@
 
         final NetworkStats stats = mFactory.readNetworkStatsSummary();
         assertEquals(7, stats.size());
-        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 1507570L, 489339L);
-        assertStatsEntry(stats, "wlan0", UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 2048L);
+        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L, 489339L);
+        assertStatsEntry(stats, "wlan0", UID_ALL, SET_ALL, TAG_NONE, 1024L, 2048L);
     }
 
     public void testNetworkStatsCombined() throws Exception {
@@ -115,7 +116,7 @@
         stageLong(40L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_packets"));
 
         final NetworkStats stats = mFactory.readNetworkStatsSummary();
-        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 1507570L + 10L,
+        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L + 10L,
                 2205L + 20L, 489339L + 30L, 2237L + 40L);
     }
 
@@ -128,7 +129,7 @@
         stageLong(40L, new File(mTestProc, "net/xt_qtaguid/iface_stat/rmnet0/tx_packets"));
 
         final NetworkStats stats = mFactory.readNetworkStatsSummary();
-        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 10L, 20L, 30L, 40L);
+        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 10L, 20L, 30L, 40L);
     }
 
     public void testKernelTags() throws Exception {
@@ -153,9 +154,9 @@
 
         final NetworkStats stats = mFactory.readNetworkStatsSummary();
         assertEquals(6, stats.size());
-        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 2112L, 24L, 700L, 10L);
-        assertStatsEntry(stats, "test1", UID_ALL, SET_DEFAULT, TAG_NONE, 6L, 8L, 10L, 12L);
-        assertStatsEntry(stats, "test2", UID_ALL, SET_DEFAULT, TAG_NONE, 1L, 2L, 3L, 4L);
+        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 2112L, 24L, 700L, 10L);
+        assertStatsEntry(stats, "test1", UID_ALL, SET_ALL, TAG_NONE, 6L, 8L, 10L, 12L);
+        assertStatsEntry(stats, "test2", UID_ALL, SET_ALL, TAG_NONE, 1L, 2L, 3L, 4L);
     }
 
     /**
diff --git a/docs/html/guide/developing/testing/testing_otheride.jd b/docs/html/guide/developing/testing/testing_otheride.jd
index 93af979..7745ae7 100644
--- a/docs/html/guide/developing/testing/testing_otheride.jd
+++ b/docs/html/guide/developing/testing/testing_otheride.jd
@@ -209,7 +209,7 @@
 <p>
   To update a test project with the <code>android</code> tool, enter:
 </p>
-<pre>android update-test-project -m &lt;main_path&gt; -p &lt;test_path&gt;</pre>
+<pre>android update test-project -m &lt;main_path&gt; -p &lt;test_path&gt;</pre>
 
 <table>
     <tr>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index ba8dc5e..62d18ae 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -834,12 +834,6 @@
           <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/widget_design.html">
                 <span class="en">App Widget Design</span>
               </a></li>
-          <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/activity_task_design.html">
-                <span class="en">Activity and Task Design</span>
-              </a></li>
-          <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/menu_design.html">
-                <span class="en">Menu Design</span>
-              </a></li>
         </ul>
       </li>
       </ul>
diff --git a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
index f8ca3f8..8e4528e 100644
--- a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
@@ -3,6 +3,43 @@
 parent.link=index.html
 @jd:body
 
+
+
+
+<div id="deprecatedSticker">
+  <a href="#" 
+     onclick="$('#naMessage').show();$('#deprecatedSticker').hide();return false">
+    <strong>This doc is deprecated</strong></a>
+</div>
+
+
+<div id="naMessage" style="display:block">
+<div><p><strong>This document has been deprecated.</strong></p>
+ <p>For information about designing an activity structure and navigation, read the design guidelines
+for <a href="{@docRoot}design/patterns/app-structure.html">App Structure</a> and
+<a href="{@docRoot}design/patterns/navigation.html">Navigation</a>, or the developer guide
+about <a
+href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>.</p>
+
+ <input style="margin-top:1em;padding:5px" type="button"
+        value="That's nice, but I still want to read this document"
+onclick="$('#naMessage').hide();$('#deprecatedSticker').show()" />
+</div>
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 <div id="qv-wrapper">
 <div id="qv">
 
diff --git a/docs/html/guide/practices/ui_guidelines/index.jd b/docs/html/guide/practices/ui_guidelines/index.jd
index 3255275..24fb855 100644
--- a/docs/html/guide/practices/ui_guidelines/index.jd
+++ b/docs/html/guide/practices/ui_guidelines/index.jd
@@ -39,26 +39,6 @@
 design widgets that fit with others on the Home screen. They include links to
 graphics files and templates that will make your designer's life easier.</dd>
 </dl>
- <dl>
-  <dt><a href="{@docRoot}guide/practices/ui_guidelines/activity_task_design.html">Activity and Task Design Guidelines</a> </dt>
-  <dd>Activities are the basic, independent building blocks of applications.
-      As you design your application's UI and feature set, you are free to
-      re-use activities from other applications as if they were yours,
-      to enrich and extend your application.   These guidelines
-      describe how activities work, illustrates them with examples, and
-      describes important underlying principles and mechanisms, such as
-      multitasking, activity reuse, intents, the activity stack, and 
-      tasks. It covers this all from a high-level design perspective.
-</dd>
-  <dt><a href="{@docRoot}guide/practices/ui_guidelines/menu_design.html">Menu Design Guidelines</a> </dt>
-  <dd>Android applications make use of Option menus and Context menus 
-      that enable users to perform operations and navigate to other parts
-      of your application or to other applications.  These guidelines describe
-      the difference between Options anontext menus, how to arrange
-      menu items, when to put commands on-screen, and other details about
-      menu design.
-</dd>
-</dl>
 
 
 
diff --git a/docs/html/guide/practices/ui_guidelines/menu_design.jd b/docs/html/guide/practices/ui_guidelines/menu_design.jd
index 7576b6c..b4e2ea7 100644
--- a/docs/html/guide/practices/ui_guidelines/menu_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/menu_design.jd
@@ -2,7 +2,38 @@
 parent.title=UI Guidelines
 parent.link=index.html
 @jd:body
+
+
+
+
+<div id="deprecatedSticker">
+  <a href="#" 
+     onclick="$('#naMessage').show();$('#deprecatedSticker').hide();return false">
+    <strong>This doc is deprecated</strong></a>
+</div>
+
+
+<div id="naMessage" style="display:block">
+<div><p><strong>This document has been deprecated.</strong></p>
+ <p>For design guidelines about adding user actions and other options, read the design guidelines 
+for <a href="{@docRoot}design/patterns/actionbar.html">Action Bar</a> or the developer guide about
+<a href="{@docRoot}guide/topics/ui/menus.html">Menus</a>.</p>
+
+ <input style="margin-top:1em;padding:5px" type="button"
+        value="That's nice, but I still want to read this document"
+onclick="$('#naMessage').hide();$('#deprecatedSticker').show()" />
+</div>
+</div>
 	
+
+
+
+
+
+
+
+
+
 <div id="qv-wrapper">
 <div id="qv">
 			
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index bbbe6fb1..5297c23 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -299,6 +299,31 @@
           </li>
         </ul>
       </li>
+      
+      <li class="toggle-list">
+        <div><a href="<?cs var:toroot ?>training/displaying-bitmaps/index.html">
+            <span class="en">Displaying Bitmaps Efficiently<span class="new">&nbsp;new!</span></span>
+          </a>
+        </div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/load-bitmap.html">
+            <span class="en">Loading Large Bitmaps Efficiently</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/process-bitmap.html">
+            <span class="en">Processing Bitmaps Off the UI Thread</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/cache-bitmap.html">
+            <span class="en">Caching Bitmaps</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/displaying-bitmaps/display-bitmap.html">
+            <span class="en">Displaying Bitmaps in Your UI</span>
+          </a>
+          </li>
+        </ul>
+      </li>
 
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>training/accessibility/index.html">
diff --git a/docs/html/shareables/training/BitmapFun.zip b/docs/html/shareables/training/BitmapFun.zip
new file mode 100644
index 0000000..e7e71f9
--- /dev/null
+++ b/docs/html/shareables/training/BitmapFun.zip
Binary files differ
diff --git a/docs/html/sitemap.txt b/docs/html/sitemap.txt
index 958fe56..3f26dd0 100644
--- a/docs/html/sitemap.txt
+++ b/docs/html/sitemap.txt
@@ -160,8 +160,6 @@
 http://developer.android.com/guide/practices/ui_guidelines/icon_design_dialog.html
 http://developer.android.com/guide/practices/ui_guidelines/icon_design_list.html
 http://developer.android.com/guide/practices/ui_guidelines/widget_design.html
-http://developer.android.com/guide/practices/ui_guidelines/activity_task_design.html
-http://developer.android.com/guide/practices/ui_guidelines/menu_design.html
 http://developer.android.com/guide/practices/design/performance.html
 http://developer.android.com/guide/practices/design/responsiveness.html
 http://developer.android.com/guide/practices/design/seamlessness.html
diff --git a/docs/html/training/accessibility/index.jd b/docs/html/training/accessibility/index.jd
index d5178a9..333f9f2 100644
--- a/docs/html/training/accessibility/index.jd
+++ b/docs/html/training/accessibility/index.jd
@@ -13,7 +13,6 @@
 <h2>Dependencies and prerequisites</h2>
 <ul>
   <li>Android 2.0 (API Level 5) or higher</li>
-Playback</a></li>
 </ul>
 
 <h2>You should also read</h2>
diff --git a/docs/html/training/displaying-bitmaps/cache-bitmap.jd b/docs/html/training/displaying-bitmaps/cache-bitmap.jd
new file mode 100644
index 0000000..94abe21
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/cache-bitmap.jd
@@ -0,0 +1,337 @@
+page.title=Caching Bitmaps
+parent.title=Displaying Bitmaps Efficiently
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Displaying Bitmaps in Your UI
+next.link=display-bitmap.html
+previous.title=Processing Bitmaps Off the UI Thread
+previous.link=process-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#memory-cache">Use a Memory Cache</a></li>
+  <li><a href="#disk-cache">Use a Disk Cache</a></li>
+  <li><a href="#config-changes">Handle Configuration Changes</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+  <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Loading a single bitmap into your user interface (UI) is straightforward, however things get more
+complicated if you need to load a larger set of images at once. In many cases (such as with
+components like {@link android.widget.ListView}, {@link android.widget.GridView} or {@link
+android.support.v4.view.ViewPager }), the total number of images on-screen combined with images that
+might soon scroll onto the screen are essentially unlimited.</p>
+
+<p>Memory usage is kept down with components like this by recycling the child views as they move
+off-screen. The garbage collector also frees up your loaded bitmaps, assuming you don't keep any
+long lived references. This is all good and well, but in order to keep a fluid and fast-loading UI
+you want to avoid continually processing these images each time they come back on-screen. A memory
+and disk cache can often help here, allowing components to quickly reload processed images.</p>
+
+<p>This lesson walks you through using a memory and disk bitmap cache to improve the responsiveness
+and fluidity of your UI when loading multiple bitmaps.</p>
+
+<h2 id="memory-cache">Use a Memory Cache</h2>
+
+<p>A memory cache offers fast access to bitmaps at the cost of taking up valuable application
+memory. The {@link android.util.LruCache} class (also available in the <a
+href="{@docRoot}reference/android/support/v4/util/LruCache.html">Support Library</a> for use back
+to API Level 4) is particularly well suited to the task of caching bitmaps, keeping recently
+referenced objects in a strong referenced {@link java.util.LinkedHashMap} and evicting the least
+recently used member before the cache exceeds its designated size.</p>
+
+<p class="note"><strong>Note:</strong> In the past, a popular memory cache implementation was a
+{@link java.lang.ref.SoftReference} or {@link java.lang.ref.WeakReference} bitmap cache, however
+this is not recommended. Starting from Android 2.3 (API Level 9) the garbage collector is more
+aggressive with collecting soft/weak references which makes them fairly ineffective. In addition,
+prior to Android 3.0 (API Level 11), the backing data of a bitmap was stored in native memory which
+is not released in a predictable manner, potentially causing an application to briefly exceed its
+memory limits and crash.</p>
+
+<p>In order to choose a suitable size for a {@link android.util.LruCache}, a number of factors
+should be taken into consideration, for example:</p>
+
+<ul>
+  <li>How memory intensive is the rest of your activity and/or application?</li>
+  <li>How many images will be on-screen at once? How many need to be available ready to come
+  on-screen?</li>
+  <li>What is the screen size and density of the device? An extra high density screen (xhdpi) device
+  like <a href="http://www.android.com/devices/detail/galaxy-nexus">Galaxy Nexus</a> will need a
+  larger cache to hold the same number of images in memory compared to a device like <a
+  href="http://www.android.com/devices/detail/nexus-s">Nexus S</a> (hdpi).</li>
+  <li>What dimensions and configuration are the bitmaps and therefore how much memory will each take
+  up?</li>
+  <li>How frequently will the images be accessed? Will some be accessed more frequently than others?
+  If so, perhaps you may want to keep certain items always in memory or even have multiple {@link
+  android.util.LruCache} objects for different groups of bitmaps.</li>
+  <li>Can you balance quality against quantity? Sometimes it can be more useful to store a larger
+  number of lower quality bitmaps, potentially loading a higher quality version in another
+  background task.</li>
+</ul>
+
+<p>There is no specific size or formula that suits all applications, it's up to you to analyze your
+usage and come up with a suitable solution. A cache that is too small causes additional overhead with
+no benefit, a cache that is too large can once again cause {@code java.lang.OutOfMemory} exceptions
+and leave the rest of your app little memory to work with.</p>
+
+<p>Here’s an example of setting up a {@link android.util.LruCache} for bitmaps:</p>
+
+<pre>
+private LruCache<String, Bitmap> mMemoryCache;
+
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+    ...
+    // Get memory class of this device, exceeding this amount will throw an
+    // OutOfMemory exception.
+    final int memClass = ((ActivityManager) context.getSystemService(
+            Context.ACTIVITY_SERVICE)).getMemoryClass();
+
+    // Use 1/8th of the available memory for this memory cache.
+    final int cacheSize = 1024 * 1024 * memClass / 8;
+
+    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
+        &#64;Override
+        protected int sizeOf(String key, Bitmap bitmap) {
+            // The cache size will be measured in bytes rather than number of items.
+            return bitmap.getByteCount();
+        }
+    };
+    ...
+}
+
+public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
+    if (getBitmapFromMemCache(key) == null) {
+        mMemoryCache.put(key, bitmap);
+    }
+}
+
+public Bitmap getBitmapFromMemCache(String key) {
+    return mMemoryCache.get(key);
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> In this example, one eighth of the application memory is
+allocated for our cache. On a normal/hdpi device this is a minimum of around 4MB (32/8). A full
+screen {@link android.widget.GridView} filled with images on a device with 800x480 resolution would
+use around 1.5MB (800*480*4 bytes), so this would cache a minimum of around 2.5 pages of images in
+memory.</p>
+
+<p>When loading a bitmap into an {@link android.widget.ImageView}, the {@link android.util.LruCache}
+is checked first. If an entry is found, it is used immediately to update the {@link
+android.widget.ImageView}, otherwise a background thread is spawned to process the image:</p>
+
+<pre>
+public void loadBitmap(int resId, ImageView imageView) {
+    final String imageKey = String.valueOf(resId);
+
+    final Bitmap bitmap = getBitmapFromMemCache(imageKey);
+    if (bitmap != null) {
+        mImageView.setImageBitmap(bitmap);
+    } else {
+        mImageView.setImageResource(R.drawable.image_placeholder);
+        BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
+        task.execute(resId);
+    }
+}
+</pre>
+
+<p>The <a href="process-bitmap.html#BitmapWorkerTask">{@code BitmapWorkerTask}</a> also needs to be
+updated to add entries to the memory cache:</p>
+
+<pre>
+class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
+    ...
+    // Decode image in background.
+    &#64;Override
+    protected Bitmap doInBackground(Integer... params) {
+        final Bitmap bitmap = decodeSampledBitmapFromResource(
+                getResources(), params[0], 100, 100));
+        addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
+        return bitmap;
+    }
+    ...
+}
+</pre>
+
+<h2 id="disk-cache">Use a Disk Cache</h2>
+
+<p>A memory cache is useful in speeding up access to recently viewed bitmaps, however you cannot
+rely on images being available in this cache. Components like {@link android.widget.GridView} with
+larger datasets can easily fill up a memory cache. Your application could be interrupted by another
+task like a phone call, and while in the background it might be killed and the memory cache
+destroyed. Once the user resumes, your application it has to process each image again.</p>
+
+<p>A disk cache can be used in these cases to persist processed bitmaps and help decrease loading
+times where images are no longer available in a memory cache. Of course, fetching images from disk
+is slower than loading from memory and should be done in a background thread, as disk read times can
+be unpredictable.</p>
+
+<p class="note"><strong>Note:</strong> A {@link android.content.ContentProvider} might be a more
+appropriate place to store cached images if they are accessed more frequently, for example in an
+image gallery application.</p>
+
+<p>Included in the sample code of this class is a basic {@code DiskLruCache} implementation.
+However, a more robust and recommended {@code DiskLruCache} solution is included in the Android 4.0
+source code ({@code libcore/luni/src/main/java/libcore/io/DiskLruCache.java}). Back-porting this
+class for use on previous Android releases should be fairly straightforward (a <a
+href="http://www.google.com/search?q=disklrucache">quick search</a> shows others who have already
+implemented this solution).</p>
+
+<p>Here’s updated example code that uses the simple {@code DiskLruCache} included in the sample
+application of this class:</p>
+
+<pre>
+private DiskLruCache mDiskCache;
+private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
+private static final String DISK_CACHE_SUBDIR = "thumbnails";
+
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+    ...
+    // Initialize memory cache
+    ...
+    File cacheDir = getCacheDir(this, DISK_CACHE_SUBDIR);
+    mDiskCache = DiskLruCache.openCache(this, cacheDir, DISK_CACHE_SIZE);
+    ...
+}
+
+class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
+    ...
+    // Decode image in background.
+    &#64;Override
+    protected Bitmap doInBackground(Integer... params) {
+        final String imageKey = String.valueOf(params[0]);
+
+        // Check disk cache in background thread
+        Bitmap bitmap = getBitmapFromDiskCache(imageKey);
+
+        if (bitmap == null) { // Not found in disk cache
+            // Process as normal
+            final Bitmap bitmap = decodeSampledBitmapFromResource(
+                    getResources(), params[0], 100, 100));
+        }
+
+        // Add final bitmap to caches
+        addBitmapToCache(String.valueOf(imageKey, bitmap);
+
+        return bitmap;
+    }
+    ...
+}
+
+public void addBitmapToCache(String key, Bitmap bitmap) {
+    // Add to memory cache as before
+    if (getBitmapFromMemCache(key) == null) {
+        mMemoryCache.put(key, bitmap);
+    }
+
+    // Also add to disk cache
+    if (!mDiskCache.containsKey(key)) {
+        mDiskCache.put(key, bitmap);
+    }
+}
+
+public Bitmap getBitmapFromDiskCache(String key) {
+    return mDiskCache.get(key);
+}
+
+// Creates a unique subdirectory of the designated app cache directory. Tries to use external
+// but if not mounted, falls back on internal storage.
+public static File getCacheDir(Context context, String uniqueName) {
+    // Check if media is mounted or storage is built-in, if so, try and use external cache dir
+    // otherwise use internal cache dir
+    final String cachePath = Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
+            || !Environment.isExternalStorageRemovable() ?
+                    context.getExternalCacheDir().getPath() : context.getCacheDir().getPath();
+
+    return new File(cachePath + File.separator + uniqueName);
+}
+</pre>
+
+<p>While the memory cache is checked in the UI thread, the disk cache is checked in the background
+thread. Disk operations should never take place on the UI thread. When image processing is
+complete, the final bitmap is added to both the memory and disk cache for future use.</p>
+
+<h2 id="config-changes">Handle Configuration Changes</h2>
+
+<p>Runtime configuration changes, such as a screen orientation change, cause Android to destroy and
+restart the running activity with the new configuration (For more information about this behavior,
+see <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a>).
+You want to avoid having to process all your images again so the user has a smooth and fast
+experience when a configuration change occurs.</p>
+
+<p>Luckily, you have a nice memory cache of bitmaps that you built in the <a
+href="#memory-cache">Use a Memory Cache</a> section. This cache can be passed through to the new
+activity instance using a {@link android.app.Fragment} which is preserved by calling {@link
+android.app.Fragment#setRetainInstance setRetainInstance(true)}). After the activity has been
+recreated, this retained {@link android.app.Fragment} is reattached and you gain access to the
+existing cache object, allowing images to be quickly fetched and re-populated into the {@link
+android.widget.ImageView} objects.</p>
+
+<p>Here’s an example of retaining a {@link android.util.LruCache} object across configuration
+changes using a {@link android.app.Fragment}:</p>
+
+<pre>
+private LruCache<String, Bitmap> mMemoryCache;
+
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+    ...
+    RetainFragment mRetainFragment =
+            RetainFragment.findOrCreateRetainFragment(getFragmentManager());
+    mMemoryCache = RetainFragment.mRetainedCache;
+    if (mMemoryCache == null) {
+        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
+            ... // Initialize cache here as usual
+        }
+        mRetainFragment.mRetainedCache = mMemoryCache;
+    }
+    ...
+}
+
+class RetainFragment extends Fragment {
+    private static final String TAG = "RetainFragment";
+    public LruCache<String, Bitmap> mRetainedCache;
+
+    public RetainFragment() {}
+
+    public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) {
+        RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG);
+        if (fragment == null) {
+            fragment = new RetainFragment();
+        }
+        return fragment;
+    }
+
+    &#64;Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        <strong>setRetainInstance(true);</strong>
+    }
+}
+</pre>
+
+<p>To test this out, try rotating a device both with and without retaining the {@link
+android.app.Fragment}. You should notice little to no lag as the images populate the activity almost
+instantly from memory when you retain the cache. Any images not found in the memory cache are
+hopefully available in the disk cache, if not, they are processed as usual.</p>
diff --git a/docs/html/training/displaying-bitmaps/display-bitmap.jd b/docs/html/training/displaying-bitmaps/display-bitmap.jd
new file mode 100644
index 0000000..7a93313
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/display-bitmap.jd
@@ -0,0 +1,400 @@
+page.title=Displaying Bitmaps in Your UI
+parent.title=Displaying Bitmaps Efficiently
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Caching Bitmaps
+previous.link=cache-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#viewpager">Load Bitmaps into a ViewPager Implementation</a></li>
+  <li><a href="#gridview">Load Bitmaps into a GridView Implementation</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}design/patterns/swipe-views.html">Android Design: Swipe Views</a></li>
+  <li><a href="{@docRoot}design/building-blocks/grid-lists.html">Android Design: Grid Lists</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+  <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p></p>
+
+<p>This lesson brings together everything from previous lessons, showing you how to load multiple
+bitmaps into {@link android.support.v4.view.ViewPager} and {@link android.widget.GridView}
+components using a background thread and bitmap cache, while dealing with concurrency and
+configuration changes.</p>
+
+<h2 id="viewpager">Load Bitmaps into a ViewPager Implementation</h2>
+
+<p>The <a href="{@docRoot}design/patterns/swipe-views.html">swipe view pattern</a> is an excellent
+way to navigate the detail view of an image gallery. You can implement this pattern using a {@link
+android.support.v4.view.ViewPager} component backed by a {@link
+android.support.v4.view.PagerAdapter}. However, a more suitable backing adapter is the subclass
+{@link android.support.v4.app.FragmentStatePagerAdapter} which automatically destroys and saves
+state of the {@link android.app.Fragment Fragments} in the {@link android.support.v4.view.ViewPager}
+as they disappear off-screen, keeping memory usage down.</p>
+
+<p class="note"><strong>Note:</strong> If you have a smaller number of images and are confident they
+all fit within the application memory limit, then using a regular {@link
+android.support.v4.view.PagerAdapter} or {@link android.support.v4.app.FragmentPagerAdapter} might
+be more appropriate.</p>
+
+<p>Here’s an implementation of a {@link android.support.v4.view.ViewPager} with {@link
+android.widget.ImageView} children. The main activity holds the {@link
+android.support.v4.view.ViewPager} and the adapter:</p>
+
+<pre>
+public class ImageDetailActivity extends FragmentActivity {
+    public static final String EXTRA_IMAGE = "extra_image";
+
+    private ImagePagerAdapter mAdapter;
+    private ViewPager mPager;
+
+    // A static dataset to back the ViewPager adapter
+    public final static Integer[] imageResIds = new Integer[] {
+            R.drawable.sample_image_1, R.drawable.sample_image_2, R.drawable.sample_image_3,
+            R.drawable.sample_image_4, R.drawable.sample_image_5, R.drawable.sample_image_6,
+            R.drawable.sample_image_7, R.drawable.sample_image_8, R.drawable.sample_image_9};
+
+    &#64;Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.image_detail_pager); // Contains just a ViewPager
+
+        mAdapter = new ImagePagerAdapter(getSupportFragmentManager(), imageResIds.length);
+        mPager = (ViewPager) findViewById(R.id.pager);
+        mPager.setAdapter(mAdapter);
+    }
+
+    public static class ImagePagerAdapter extends FragmentStatePagerAdapter {
+        private final int mSize;
+
+        public ImagePagerAdapter(FragmentManager fm, int size) {
+            super(fm);
+            mSize = size;
+        }
+
+        &#64;Override
+        public int getCount() {
+            return mSize;
+        }
+
+        &#64;Override
+        public Fragment getItem(int position) {
+            return ImageDetailFragment.newInstance(position);
+        }
+    }
+}
+</pre>
+
+<p>The details {@link android.app.Fragment} holds the {@link android.widget.ImageView} children:</p>
+
+<pre>
+public class ImageDetailFragment extends Fragment {
+    private static final String IMAGE_DATA_EXTRA = "resId";
+    private int mImageNum;
+    private ImageView mImageView;
+
+    static ImageDetailFragment newInstance(int imageNum) {
+        final ImageDetailFragment f = new ImageDetailFragment();
+        final Bundle args = new Bundle();
+        args.putInt(IMAGE_DATA_EXTRA, imageNum);
+        f.setArguments(args);
+        return f;
+    }
+
+    // Empty constructor, required as per Fragment docs
+    public ImageDetailFragment() {}
+
+    &#64;Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mImageNum = getArguments() != null ? getArguments().getInt(IMAGE_DATA_EXTRA) : -1;
+    }
+
+    &#64;Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        // image_detail_fragment.xml contains just an ImageView
+        final View v = inflater.inflate(R.layout.image_detail_fragment, container, false);
+        mImageView = (ImageView) v.findViewById(R.id.imageView);
+        return v;
+    }
+
+    &#64;Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        final int resId = ImageDetailActivity.imageResIds[mImageNum];
+        <strong>mImageView.setImageResource(resId);</strong> // Load image into ImageView
+    }
+}
+</pre>
+
+<p>Hopefully you noticed the issue with this implementation; The images are being read from
+resources on the UI thread which can lead to an application hanging and being force closed. Using an
+{@link android.os.AsyncTask} as described in the <a href="process-bitmap.html">Processing Bitmaps Off
+the UI Thread</a> lesson, it’s straightforward to move image loading and processing to a background
+thread:</p>
+
+<pre>
+public class ImageDetailActivity extends FragmentActivity {
+    ...
+
+    public void loadBitmap(int resId, ImageView imageView) {
+        mImageView.setImageResource(R.drawable.image_placeholder);
+        BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
+        task.execute(resId);
+    }
+
+    ... // include <a href="process-bitmap.html#BitmapWorkerTask">{@code BitmapWorkerTask}</a> class
+}
+
+public class ImageDetailFragment extends Fragment {
+    ...
+
+    &#64;Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        if (ImageDetailActivity.class.isInstance(getActivity())) {
+            final int resId = ImageDetailActivity.imageResIds[mImageNum];
+            // Call out to ImageDetailActivity to load the bitmap in a background thread
+            ((ImageDetailActivity) getActivity()).loadBitmap(resId, mImageView);
+        }
+    }
+}
+</pre>
+
+<p>Any additional processing (such as resizing or fetching images from the network) can take place
+in the <a href="process-bitmap.html#BitmapWorkerTask">{@code BitmapWorkerTask}</a> without affecting
+responsiveness of the main UI. If the background thread is doing more than just loading an image
+directly from disk, it can also be beneficial to add a memory and/or disk cache as described in the
+lesson <a href="cache-bitmap.html#memory-cache">Caching Bitmaps</a>. Here's the additional
+modifications for a memory cache:</p>
+
+<pre>
+public class ImageDetailActivity extends FragmentActivity {
+    ...
+    private LruCache<String, Bitmap> mMemoryCache;
+
+    &#64;Override
+    public void onCreate(Bundle savedInstanceState) {
+        ...
+        // initialize LruCache as per <a href="cache-bitmap.html#memory-cache">Use a Memory Cache</a> section
+    }
+
+    public void loadBitmap(int resId, ImageView imageView) {
+        final String imageKey = String.valueOf(resId);
+
+        final Bitmap bitmap = mMemoryCache.get(imageKey);
+        if (bitmap != null) {
+            mImageView.setImageBitmap(bitmap);
+        } else {
+            mImageView.setImageResource(R.drawable.image_placeholder);
+            BitmapWorkerTask task = new BitmapWorkerTask(mImageView);
+            task.execute(resId);
+        }
+    }
+
+    ... // include updated BitmapWorkerTask from <a href="cache-bitmap.html#memory-cache">Use a Memory Cache</a> section
+}
+</pre>
+
+<p>Putting all these pieces together gives you a responsive {@link
+android.support.v4.view.ViewPager} implementation with minimal image loading latency and the ability
+to do as much or as little background processing on your images as needed.</p>
+
+<h2 id="gridview">Load Bitmaps into a GridView Implementation</h2>
+
+<p>The <a href="{@docRoot}design/building-blocks/grid-lists.html">grid list building block</a> is
+useful for showing image data sets and can be implemented using a {@link android.widget.GridView}
+component in which many images can be on-screen at any one time and many more need to be ready to
+appear if the user scrolls up or down. When implementing this type of control, you must ensure the
+UI remains fluid, memory usage remains under control and concurrency is handled correctly (due to
+the way {@link android.widget.GridView} recycles its children views).</p>
+
+<p>To start with, here is a standard {@link android.widget.GridView} implementation with {@link
+android.widget.ImageView} children placed inside a {@link android.app.Fragment}:</p>
+
+<pre>
+public class ImageGridFragment extends Fragment implements AdapterView.OnItemClickListener {
+    private ImageAdapter mAdapter;
+
+    // A static dataset to back the GridView adapter
+    public final static Integer[] imageResIds = new Integer[] {
+            R.drawable.sample_image_1, R.drawable.sample_image_2, R.drawable.sample_image_3,
+            R.drawable.sample_image_4, R.drawable.sample_image_5, R.drawable.sample_image_6,
+            R.drawable.sample_image_7, R.drawable.sample_image_8, R.drawable.sample_image_9};
+
+    // Empty constructor as per Fragment docs
+    public ImageGridFragment() {}
+
+    &#64;Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mAdapter = new ImageAdapter(getActivity());
+    }
+
+    &#64;Override
+    public View onCreateView(
+            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        final View v = inflater.inflate(R.layout.image_grid_fragment, container, false);
+        final GridView mGridView = (GridView) v.findViewById(R.id.gridView);
+        mGridView.setAdapter(mAdapter);
+        mGridView.setOnItemClickListener(this);
+        return v;
+    }
+
+    &#64;Override
+    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
+        final Intent i = new Intent(getActivity(), ImageDetailActivity.class);
+        i.putExtra(ImageDetailActivity.EXTRA_IMAGE, position);
+        startActivity(i);
+    }
+
+    private class ImageAdapter extends BaseAdapter {
+        private final Context mContext;
+
+        public ImageAdapter(Context context) {
+            super();
+            mContext = context;
+        }
+
+        &#64;Override
+        public int getCount() {
+            return imageResIds.length;
+        }
+
+        &#64;Override
+        public Object getItem(int position) {
+            return imageResIds[position];
+        }
+
+        &#64;Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        &#64;Override
+        public View getView(int position, View convertView, ViewGroup container) {
+            ImageView imageView;
+            if (convertView == null) { // if it's not recycled, initialize some attributes
+                imageView = new ImageView(mContext);
+                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
+                imageView.setLayoutParams(new GridView.LayoutParams(
+                        LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+            } else {
+                imageView = (ImageView) convertView;
+            }
+            <strong>imageView.setImageResource(imageResIds[position]);</strong> // Load image into ImageView
+            return imageView;
+        }
+    }
+}
+</pre>
+
+<p>Once again, the problem with this implementation is that the image is being set in the UI thread.
+While this may work for small, simple images (due to system resource loading and caching), if any
+additional processing needs to be done, your UI grinds to a halt.</p>
+
+<p>The same asynchronous processing and caching methods from the previous section can be implemented
+here. However, you also need to wary of concurrency issues as the {@link android.widget.GridView}
+recycles its children views. To handle this, use the techniques discussed in the <a
+href="process-bitmap#concurrency">Processing Bitmaps Off the UI Thread</a> lesson. Here is the updated
+solution:</p>
+
+<pre>
+public class ImageGridFragment extends Fragment implements AdapterView.OnItemClickListener {
+    ...
+
+    private class ImageAdapter extends BaseAdapter {
+        ...
+
+        &#64;Override
+        public View getView(int position, View convertView, ViewGroup container) {
+            ...
+            <strong>loadBitmap(imageResIds[position], imageView)</strong>
+            return imageView;
+        }
+    }
+
+    public void loadBitmap(int resId, ImageView imageView) {
+        if (cancelPotentialWork(resId, imageView)) {
+            final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+            final AsyncDrawable asyncDrawable =
+                    new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
+            imageView.setImageDrawable(asyncDrawable);
+            task.execute(resId);
+        }
+    }
+
+    static class AsyncDrawable extends BitmapDrawable {
+        private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
+
+        public AsyncDrawable(Resources res, Bitmap bitmap,
+                BitmapWorkerTask bitmapWorkerTask) {
+            super(res, bitmap);
+            bitmapWorkerTaskReference =
+                new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
+        }
+
+        public BitmapWorkerTask getBitmapWorkerTask() {
+            return bitmapWorkerTaskReference.get();
+        }
+    }
+
+    public static boolean cancelPotentialWork(int data, ImageView imageView) {
+        final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
+
+        if (bitmapWorkerTask != null) {
+            final int bitmapData = bitmapWorkerTask.data;
+            if (bitmapData != data) {
+                // Cancel previous task
+                bitmapWorkerTask.cancel(true);
+            } else {
+                // The same work is already in progress
+                return false;
+            }
+        }
+        // No task associated with the ImageView, or an existing task was cancelled
+        return true;
+    }
+
+    private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
+       if (imageView != null) {
+           final Drawable drawable = imageView.getDrawable();
+           if (drawable instanceof AsyncDrawable) {
+               final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+               return asyncDrawable.getBitmapWorkerTask();
+           }
+        }
+        return null;
+    }
+
+    ... // include updated <a href="process-bitmap.html#BitmapWorkerTaskUpdated">{@code BitmapWorkerTask}</a> class
+</pre>
+
+<p class="note"><strong>Note:</strong> The same code can easily be adapted to work with {@link
+android.widget.ListView} as well.</p>
+
+<p>This implementation allows for flexibility in how the images are processed and loaded without
+impeding the smoothness of the UI. In the background task you can load images from the network or
+resize large digital camera photos and the images appear as the tasks finish processing.</p>
+
+<p>For a full example of this and other concepts discussed in this lesson, please see the included
+sample application.</p>
diff --git a/docs/html/training/displaying-bitmaps/index.jd b/docs/html/training/displaying-bitmaps/index.jd
new file mode 100644
index 0000000..6755c24
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/index.jd
@@ -0,0 +1,78 @@
+page.title=Displaying Bitmaps Efficiently
+
+trainingnavtop=true
+startpage=true
+next.title=Loading Large Bitmaps Efficiently
+next.link=load-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2>
+<ul>
+  <li>Android 2.1 (API Level 7) or higher</li>
+  <li><a href="{@docRoot}sdk/compatibility-library.html">Support Library</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+  <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>This class covers some common techniques for processing and loading {@link
+android.graphics.Bitmap} objects in a way that keeps your user interface (UI) components responsive
+and avoids exceeding your application memory limit. If you're not careful, bitmaps can quickly
+consume your available memory budget leading to an application crash due to the dreaded
+exception:<br />{@code java.lang.OutofMemoryError: bitmap size exceeds VM budget}.</p>
+
+<p>There are a number of reasons why loading bitmaps in your Android application is tricky:</p>
+
+<ul>
+  <li>Mobile devices typically have constrained system resources. Android devices can have as little
+  as 16MB of memory available to a single application. The <a
+  href="http://source.android.com/compatibility/downloads.html">Android Compatibility Definition
+  Document</a> (CDD), <i>Section 3.7. Virtual Machine Compatibility</i> gives the required minimum
+  application memory for various screen sizes and densities. Applications should be optimized to
+  perform under this minimum memory limit. However, keep in mind many devices are configured with
+  higher limits.</li>
+  <li>Bitmaps take up a lot of memory, especially for rich images like photographs. For example, the
+  camera on the <a href="http://www.google.com/nexus/">Galaxy Nexus</a> takes photos up to 2592x1936
+  pixels (5 megapixels). If the bitmap configuration used is {@link
+  android.graphics.Bitmap.Config ARGB_8888} (the default from the Android 2.3 onward) then loading
+  this image into memory takes about 19MB of memory (2592*1936*4 bytes), immediately exhausting the
+  per-app limit on some devices.</li>
+  <li>Android app UI’s frequently require several bitmaps to be loaded at once. Components such as
+  {@link android.widget.ListView}, {@link android.widget.GridView} and {@link
+  android.support.v4.view.ViewPager} commonly include multiple bitmaps on-screen at once with many
+  more potentially off-screen ready to show at the flick of a finger.</li>
+</ul>
+
+<h2>Lessons</h2>
+
+<dl>
+  <dt><b><a href="load-bitmap.html">Loading Large Bitmaps Efficiently</a></b></dt>
+    <dd>This lesson walks you through decoding large bitmaps without exceeding the per application
+    memory limit.</dd>
+
+  <dt><b><a href="process-bitmap.html">Processing Bitmaps Off the UI Thread</a></b></dt>
+    <dd>Bitmap processing (resizing, downloading from a remote source, etc.) should never take place
+    on the main UI thread. This lesson walks you through processing bitmaps in a background thread
+    using {@link android.os.AsyncTask} and explains how to handle concurrency issues.</dd>
+
+  <dt><b><a href="cache-bitmap.html">Caching Bitmaps</a></b></dt>
+    <dd>This lesson walks you through using a memory and disk bitmap cache to improve the
+    responsiveness and fluidity of your UI when loading multiple bitmaps.</dd>
+
+  <dt><b><a href="display-bitmap.html">Displaying Bitmaps in Your UI</a></b></dt>
+    <dd>This lesson brings everything together, showing you how to load multiple bitmaps into
+    components like {@link android.support.v4.view.ViewPager} and {@link android.widget.GridView}
+    using a background thread and bitmap cache.</dd>
+
+</dl>
\ No newline at end of file
diff --git a/docs/html/training/displaying-bitmaps/load-bitmap.jd b/docs/html/training/displaying-bitmaps/load-bitmap.jd
new file mode 100644
index 0000000..c0a5709
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/load-bitmap.jd
@@ -0,0 +1,165 @@
+page.title=Loading Large Bitmaps Efficiently
+parent.title=Displaying Bitmaps Efficiently
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Processing Bitmaps Off the UI Thread
+next.link=process-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#read-bitmap">Read Bitmap Dimensions and Type</a></li>
+  <li><a href="#load-bitmap">Load a Scaled Down Version into Memory</a></li>
+</ol>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+  <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Images come in all shapes and sizes. In many cases they are larger than required for a typical
+application user interface (UI). For example, the system Gallery application displays photos taken
+using your Android devices's camera which are typically much higher resolution than the screen
+density of your device.</p>
+
+<p>Given that you are working with limited memory, ideally you only want to load a lower resolution
+version in memory. The lower resolution version should match the size of the UI component that
+displays it. An image with a higher resolution does not provide any visible benefit, but still takes
+up precious memory and incurs additional performance overhead due to additional on the fly
+scaling.</p>
+
+<p>This lesson walks you through decoding large bitmaps without exceeding the per application
+memory limit by loading a smaller subsampled version in memory.</p>
+
+<h2 id="read-bitmap">Read Bitmap Dimensions and Type</h2>
+
+<p>The {@link android.graphics.BitmapFactory} class provides several decoding methods ({@link
+android.graphics.BitmapFactory#decodeByteArray(byte[],int,int,android.graphics.BitmapFactory.Options)
+decodeByteArray()}, {@link
+android.graphics.BitmapFactory#decodeFile(java.lang.String,android.graphics.BitmapFactory.Options)
+decodeFile()}, {@link
+android.graphics.BitmapFactory#decodeResource(android.content.res.Resources,int,android.graphics.BitmapFactory.Options)
+decodeResource()}, etc.) for creating a {@link android.graphics.Bitmap} from various sources. Choose
+the most appropriate decode method based on your image data source. These methods attempt to
+allocate memory for the constructed bitmap and therefore can easily result in an {@code OutOfMemory}
+exception. Each type of decode method has additional signatures that let you specify decoding
+options via the {@link android.graphics.BitmapFactory.Options} class. Setting the {@link
+android.graphics.BitmapFactory.Options#inJustDecodeBounds} property to {@code true} while decoding
+avoids memory allocation, returning {@code null} for the bitmap object but setting {@link
+android.graphics.BitmapFactory.Options#outWidth}, {@link
+android.graphics.BitmapFactory.Options#outHeight} and {@link
+android.graphics.BitmapFactory.Options#outMimeType}. This technique allows you to read the
+dimensions and type of the image data prior to construction (and memory allocation) of the
+bitmap.</p>
+
+<pre>
+BitmapFactory.Options options = new BitmapFactory.Options();
+options.inJustDecodeBounds = true;
+BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
+int imageHeight = options.outHeight;
+int imageWidth = options.outWidth;
+String imageType = options.outMimeType;
+</pre>
+
+<p>To avoid {@code java.lang.OutOfMemory} exceptions, check the dimensions of a bitmap before
+decoding it, unless you absolutely trust the source to provide you with predictably sized image data
+that comfortably fits within the available memory.</p>
+
+<h2 id="load-bitmap">Load a Scaled Down Version into Memory</h2>
+
+<p>Now that the image dimensions are known, they can be used to decide if the full image should be
+loaded into memory or if a subsampled version should be loaded instead. Here are some factors to
+consider:</p>
+
+<ul>
+  <li>Estimated memory usage of loading the full image in memory.</li>
+  <li>Amount of memory you are willing to commit to loading this image given any other memory
+  requirements of your application.</li>
+  <li>Dimensions of the target {@link android.widget.ImageView} or UI component that the image
+  is to be loaded into.</li>
+  <li>Screen size and density of the current device.</li>
+</ul>
+
+<p>For example, it’s not worth loading a 1024x768 pixel image into memory if it will eventually be
+displayed in a 128x96 pixel thumbnail in an {@link android.widget.ImageView}.</p>
+
+<p>To tell the decoder to subsample the image, loading a smaller version into memory, set {@link
+android.graphics.BitmapFactory.Options#inSampleSize} to {@code true} in your {@link
+android.graphics.BitmapFactory.Options} object. For example, an image with resolution 2048x1536 that
+is decoded with an {@link android.graphics.BitmapFactory.Options#inSampleSize} of 4 produces a
+bitmap of approximately 512x384. Loading this into memory uses 0.75MB rather than 12MB for the full
+image (assuming a bitmap configuration of {@link android.graphics.Bitmap.Config ARGB_8888}). Here’s
+a method to calculate a the sample size value based on a target width and height:</p>
+
+<pre>
+public static int calculateInSampleSize(
+            BitmapFactory.Options options, int reqWidth, int reqHeight) {
+    // Raw height and width of image
+    final int height = options.outHeight;
+    final int width = options.outWidth;
+    int inSampleSize = 1;
+
+    if (height > reqHeight || width > reqWidth) {
+        if (width > height) {
+            inSampleSize = Math.round((float)height / (float)reqHeight);
+        } else {
+            inSampleSize = Math.round((float)width / (float)reqWidth);
+        }
+    }
+    return inSampleSize;
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> Using powers of 2 for {@link
+android.graphics.BitmapFactory.Options#inSampleSize} values is faster and more efficient for the
+decoder. However, if you plan to cache the resized versions in memory or on disk, it’s usually still
+worth decoding to the most appropriate image dimensions to save space.</p>
+
+<p>To use this method, first decode with {@link
+android.graphics.BitmapFactory.Options#inJustDecodeBounds} set to {@code true}, pass the options
+through and then decode again using the new {@link
+android.graphics.BitmapFactory.Options#inSampleSize} value and {@link
+android.graphics.BitmapFactory.Options#inJustDecodeBounds} set to {@code false}:</p>
+
+<a name="decodeSampledBitmapFromResource"></a>
+<pre>
+public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
+        int reqWidth, int reqHeight) {
+
+    // First decode with inJustDecodeBounds=true to check dimensions
+    final BitmapFactory.Options options = new BitmapFactory.Options();
+    options.inJustDecodeBounds = true;
+    BitmapFactory.decodeResource(res, resId, options);
+
+    // Calculate inSampleSize
+    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+
+    // Decode bitmap with inSampleSize set
+    options.inJustDecodeBounds = false;
+    return BitmapFactory.decodeResource(res, resId, options);
+}
+</pre>
+
+<p>This method makes it easy to load a bitmap of arbitrarily large size into an {@link
+android.widget.ImageView} that displays a 100x100 pixel thumbnail, as shown in the following example
+code:</p>
+
+<pre>
+mImageView.setImageBitmap(
+    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
+</pre>
+
+<p>You can follow a similar process to decode bitmaps from other sources, by substituting the
+appropriate {@link
+android.graphics.BitmapFactory#decodeByteArray(byte[],int,int,android.graphics.BitmapFactory.Options)
+BitmapFactory.decode*} method as needed.</p>
\ No newline at end of file
diff --git a/docs/html/training/displaying-bitmaps/process-bitmap.jd b/docs/html/training/displaying-bitmaps/process-bitmap.jd
new file mode 100644
index 0000000..c1450b4
--- /dev/null
+++ b/docs/html/training/displaying-bitmaps/process-bitmap.jd
@@ -0,0 +1,239 @@
+page.title=Processing Bitmaps Off the UI Thread
+parent.title=Displaying Bitmaps Efficiently
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Caching Bitmaps
+next.link=cache-bitmap.html
+previous.title=Loading Large Bitmaps Efficiently
+previous.link=load-bitmap.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#async-task">Use an AsyncTask</a></li>
+  <li><a href="#concurrency">Handle Concurrency</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/practices/design/responsiveness.html">Designing for Responsiveness</a></li>
+  <li><a
+  href="http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html">Multithreading
+  for Performance</a></li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+  <a href="{@docRoot}shareables/training/BitmapFun.zip" class="button">Download the sample</a>
+  <p class="filename">BitmapFun.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>The {@link
+android.graphics.BitmapFactory#decodeByteArray(byte[],int,int,android.graphics.BitmapFactory.Options)
+BitmapFactory.decode*} methods, discussed in the <a href="load-bitmap.html">Load Large Bitmaps
+Efficiently</a> lesson, should not be executed on the main UI thread if the source data is read from
+disk or a network location (or really any source other than memory). The time this data takes to
+load is unpredictable and depends on a variety of factors (speed of reading from disk or network,
+size of image, power of CPU, etc.). If one of these tasks blocks the UI thread, the system flags
+your application as non-responsive and the user has the option of closing it (see <a
+href="{@docRoot}guide/practices/design/responsiveness.html">Designing for Responsiveness</a> for
+more information).</p>
+
+<p>This lesson walks you through processing bitmaps in a background thread using
+{@link android.os.AsyncTask} and shows you how to handle concurrency issues.</p>
+
+<h2 id="async-task">Use an AsyncTask</h2>
+
+<p>The {@link android.os.AsyncTask} class provides an easy way to execute some work in a background
+thread and publish the results back on the UI thread. To use it, create a subclass and override the
+provided methods. Here’s an example of loading a large image into an {@link
+android.widget.ImageView} using {@link android.os.AsyncTask} and <a
+href="load-bitmap.html#decodeSampledBitmapFromResource">{@code
+decodeSampledBitmapFromResource()}</a>: </p>
+
+<a name="BitmapWorkerTask"></a>
+<pre>
+class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
+    private final WeakReference<ImageView> imageViewReference;
+    private int data = 0;
+
+    public BitmapWorkerTask(ImageView imageView) {
+        // Use a WeakReference to ensure the ImageView can be garbage collected
+        imageViewReference = new WeakReference<ImageView>(imageView);
+    }
+
+    // Decode image in background.
+    &#64;Override
+    protected Bitmap doInBackground(Integer... params) {
+        data = params[0];
+        return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
+    }
+
+    // Once complete, see if ImageView is still around and set bitmap.
+    &#64;Override
+    protected void onPostExecute(Bitmap bitmap) {
+        if (imageViewReference != null && bitmap != null) {
+            final ImageView imageView = imageViewReference.get();
+            if (imageView != null) {
+                imageView.setImageBitmap(bitmap);
+            }
+        }
+    }
+}
+</pre>
+
+<p>The {@link java.lang.ref.WeakReference} to the {@link android.widget.ImageView} ensures that the
+{@link android.os.AsyncTask} does not prevent the {@link android.widget.ImageView} and anything it
+references from being garbage collected. There’s no guarantee the {@link android.widget.ImageView}
+is still around when the task finishes, so you must also check the reference in {@link
+android.os.AsyncTask#onPostExecute(Result) onPostExecute()}. The {@link android.widget.ImageView}
+may no longer exist, if for example, the user navigates away from the activity or if a
+configuration change happens before the task finishes.</p>
+
+<p>To start loading the bitmap asynchronously, simply create a new task and execute it:</p>
+
+<pre>
+public void loadBitmap(int resId, ImageView imageView) {
+    BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+    task.execute(resId);
+}
+</pre>
+
+<h2 id="concurrency">Handle Concurrency</h2>
+
+<p>Common view components such as {@link android.widget.ListView} and {@link
+android.widget.GridView} introduce another issue when used in conjunction with the {@link
+android.os.AsyncTask} as demonstrated in the previous section. In order to be efficient with memory,
+these components recycle child views as the user scrolls. If each child view triggers an {@link
+android.os.AsyncTask}, there is no guarantee that when it completes, the associated view has not
+already been recycled for use in another child view. Furthermore, there is no guarantee that the
+order in which asynchronous tasks are started is the order that they complete.</p>
+
+<p>The blog post <a
+href="http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html">Multithreading
+for Performance</a> further discusses dealing with concurrency, and offers a solution where the
+{@link android.widget.ImageView} stores a reference to the most recent {@link android.os.AsyncTask}
+which can later be checked when the task completes. Using a similar method, the {@link
+android.os.AsyncTask} from the previous section can be extended to follow a similar pattern.</p>
+
+<p>Create a dedicated {@link android.graphics.drawable.Drawable} subclass to store a reference
+back to the worker task. In this case, a {@link android.graphics.drawable.BitmapDrawable} is used so
+that a placeholder image can be displayed in the {@link android.widget.ImageView} while the task
+completes:</p>
+
+<a name="AsyncDrawable"></a>
+<pre>
+static class AsyncDrawable extends BitmapDrawable {
+    private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
+
+    public AsyncDrawable(Resources res, Bitmap bitmap,
+            BitmapWorkerTask bitmapWorkerTask) {
+        super(res, bitmap);
+        bitmapWorkerTaskReference =
+            new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
+    }
+
+    public BitmapWorkerTask getBitmapWorkerTask() {
+        return bitmapWorkerTaskReference.get();
+    }
+}
+</pre>
+
+<p>Before executing the <a href="#BitmapWorkerTask">{@code BitmapWorkerTask}</a>, you create an <a
+href="#AsyncDrawable">{@code AsyncDrawable}</a> and bind it to the target {@link
+android.widget.ImageView}:</p>
+
+<pre>
+public void loadBitmap(int resId, ImageView imageView) {
+    if (cancelPotentialWork(resId, imageView)) {
+        final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+        final AsyncDrawable asyncDrawable =
+                new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
+        imageView.setImageDrawable(asyncDrawable);
+        task.execute(resId);
+    }
+}
+</pre>
+
+<p>The {@code cancelPotentialWork} method referenced in the code sample above checks if another
+running task is already associated with the {@link android.widget.ImageView}. If so, it attempts to
+cancel the previous task by calling {@link android.os.AsyncTask#cancel cancel()}. In a small number
+of cases, the new task data matches the existing task and nothing further needs to happen. Here is
+the implementation of {@code cancelPotentialWork}:</p>
+
+<pre>
+public static boolean cancelPotentialWork(int data, ImageView imageView) {
+    final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
+
+    if (bitmapWorkerTask != null) {
+        final int bitmapData = bitmapWorkerTask.data;
+        if (bitmapData != data) {
+            // Cancel previous task
+            bitmapWorkerTask.cancel(true);
+        } else {
+            // The same work is already in progress
+            return false;
+        }
+    }
+    // No task associated with the ImageView, or an existing task was cancelled
+    return true;
+}
+</pre>
+
+<p>A helper method, {@code getBitmapWorkerTask()}, is used above to retrieve the task associated
+with a particular {@link android.widget.ImageView}:</p>
+
+<pre>
+private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
+   if (imageView != null) {
+       final Drawable drawable = imageView.getDrawable();
+       if (drawable instanceof AsyncDrawable) {
+           final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+           return asyncDrawable.getBitmapWorkerTask();
+       }
+    }
+    return null;
+}
+</pre>
+
+<p>The last step is updating {@code onPostExecute()} in <a href="#BitmapWorkerTask">{@code
+BitmapWorkerTask}</a> so that it checks if the task is cancelled and if the current task matches the
+one associated with the {@link android.widget.ImageView}:</p>
+
+<a name="BitmapWorkerTaskUpdated"></a>
+<pre>
+class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
+    ...
+
+    &#64;Override
+    protected void onPostExecute(Bitmap bitmap) {
+        <strong>if (isCancelled()) {
+            bitmap = null;
+        }</strong>
+
+        if (imageViewReference != null && bitmap != null) {
+            final ImageView imageView = imageViewReference.get();
+            <strong>final BitmapWorkerTask bitmapWorkerTask =
+                    getBitmapWorkerTask(imageView);</strong>
+            if (<strong>this == bitmapWorkerTask &&</strong> imageView != null) {
+                imageView.setImageBitmap(bitmap);
+            }
+        }
+    }
+}
+</pre>
+
+<p>This implementation is now suitable for use in {@link android.widget.ListView} and {@link
+android.widget.GridView} components as well as any other components that recycle their child
+views. Simply call {@code loadBitmap} where you normally set an image to your {@link
+android.widget.ImageView}. For example, in a {@link android.widget.GridView} implementation this
+would be in the {@link android.widget.Adapter#getView getView()} method of the backing adapter.</p>
\ No newline at end of file
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index ed5b2f6..c726d0e 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -16,11 +16,9 @@
 
 package android.graphics;
 
-import android.os.Debug;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.DisplayMetrics;
-import android.util.Log;
 
 import java.io.OutputStream;
 import java.nio.Buffer;
@@ -183,7 +181,7 @@
 
     /**
      * Sets the layout bounds as an array of left, top, right, bottom integers
-     * @param padding the array containing the padding values
+     * @param bounds the array containing the padding values
      *
      * @hide
      */
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 0521e69..e101581 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -161,7 +161,31 @@
     public void updateTexImage() {
         int err = nativeUpdateTexImage(); 
         if (err != 0) {
-            throw new RuntimeException("Error during updateTexImage (see logs)");
+            throw new RuntimeException("Error during updateTexImage (see logcat for details)");
+        }
+    }
+
+    /**
+     * Detach the SurfaceTexture from the OpenGL ES context with which it is currently associated.
+     * This can be used to change from one OpenGL ES context to another.
+     *
+     * @hide
+     */
+    public void detachFromGLContext() {
+        int err = nativeDetachFromGLContext();
+        if (err != 0) {
+            throw new RuntimeException("Error during detachFromGLContext (see logcat for details)");
+        }
+    }
+
+    /**
+     *
+     * @hide
+     */
+    public void attachToGLContext(int texName) {
+        int err = nativeAttachToGLContext(texName);
+        if (err != 0) {
+            throw new RuntimeException("Error during detachFromGLContext (see logcat for details)");
         }
     }
 
@@ -269,6 +293,8 @@
     private native long nativeGetTimestamp();
     private native void nativeSetDefaultBufferSize(int width, int height);
     private native int nativeUpdateTexImage();
+    private native int nativeDetachFromGLContext();
+    private native int nativeAttachToGLContext(int texName);
     private native int nativeGetQueuedCount();
     private native void nativeRelease();
 
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 82dd308..c7e71eb 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -903,9 +903,18 @@
      * @hide
      */
     public void setMasterMute(boolean state) {
+        setMasterMute(state, FLAG_SHOW_UI);
+    }
+
+    /**
+     * set master mute state with optional flags.
+     *
+     * @hide
+     */
+    public void setMasterMute(boolean state, int flags) {
         IAudioService service = getService();
         try {
-            service.setMasterMute(state, mICallBack);
+            service.setMasterMute(state, flags, mICallBack);
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in setMasterMute", e);
         }
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index f59848f..2e456f0 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -827,13 +827,13 @@
     }
 
     /** @see AudioManager#setMasterMute(boolean, IBinder) */
-    public void setMasterMute(boolean state, IBinder cb) {
+    public void setMasterMute(boolean state, int flags, IBinder cb) {
         if (state != AudioSystem.getMasterMute()) {
             AudioSystem.setMasterMute(state);
             // Post a persist master volume msg
             sendMsg(mAudioHandler, MSG_PERSIST_MASTER_VOLUME_MUTE, SENDMSG_REPLACE, state ? 1
                     : 0, 0, null, PERSIST_DELAY);
-            sendMasterMuteUpdate(state, AudioManager.FLAG_SHOW_UI);
+            sendMasterMuteUpdate(state, flags);
         }
     }
 
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 17d8e4d..b775095 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -45,7 +45,7 @@
 
     boolean isStreamMute(int streamType);
 
-    void setMasterMute(boolean state, IBinder cb);
+    void setMasterMute(boolean state, int flags, IBinder cb);
 
     boolean isMasterMute();
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java
index c501d3f..7be2707 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java
@@ -22,7 +22,7 @@
 import com.android.mediaframeworktest.functional.CodecTest;
 
 import android.content.Context;
-import android.test.ActivityInstrumentationTestCase;
+import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
@@ -33,25 +33,28 @@
 /**
  * Junit / Instrumentation test case for the media player api
  */
-public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
-   private boolean duratoinWithinTolerence = false;
-   private String TAG = "MediaPlayerApiTest";
-   private boolean isWMAEnable = false;
-   private boolean isWMVEnable = false;
+public class MediaPlayerApiTest extends  ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+    private boolean duratoinWithinTolerence = false;
+    private String TAG = "MediaPlayerApiTest";
+    private boolean isWMAEnable = false;
+    private boolean isWMVEnable = false;
 
-   Context mContext;
+    Context mContext;
 
-   public MediaPlayerApiTest() {
-     super("com.android.mediaframeworktest", MediaFrameworkTest.class);
-     isWMAEnable = MediaProfileReader.getWMAEnable();
-     isWMVEnable = MediaProfileReader.getWMVEnable();
-   }
+    public MediaPlayerApiTest() {
+       super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+       isWMAEnable = MediaProfileReader.getWMAEnable();
+       isWMVEnable = MediaProfileReader.getWMVEnable();
+    }
 
     protected void setUp() throws Exception {
-      super.setUp();
-   
-  }
-    
+       //Insert a 2 second before launching the test activity. This is
+       //the workaround for the race condition of requesting the updated surface.
+       Thread.sleep(2000);
+       getActivity();
+       super.setUp();
+    }
+
     public boolean verifyDuration(int duration, int expectedDuration){
       if ((duration > expectedDuration * 1.1) || (duration < expectedDuration * 0.9))
          return false;
diff --git a/packages/InputDevices/Android.mk b/packages/InputDevices/Android.mk
new file mode 100644
index 0000000..446b47e
--- /dev/null
+++ b/packages/InputDevices/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := 
+
+LOCAL_PACKAGE_NAME := InputDevices
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
+
+########################
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/InputDevices/AndroidManifest.xml b/packages/InputDevices/AndroidManifest.xml
new file mode 100644
index 0000000..6831a74
--- /dev/null
+++ b/packages/InputDevices/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.inputdevices"
+        coreApp="true"
+        android:sharedUserId="android.uid.system">
+
+    <application
+            android:allowClearUserData="false"
+            android:label="@string/app_label"
+            android:process="system">
+
+        <receiver android:name=".InputDeviceReceiver">
+            <intent-filter>
+                <action android:name="android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS" />
+            </intent-filter>
+            <meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS"
+                    android:resource="@xml/keyboard_layouts" />
+        </receiver>
+    </application>
+</manifest>
diff --git a/packages/InputDevices/MODULE_LICENSE_APACHE2 b/packages/InputDevices/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/InputDevices/MODULE_LICENSE_APACHE2
diff --git a/packages/InputDevices/NOTICE b/packages/InputDevices/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/packages/InputDevices/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm
new file mode 100644
index 0000000..a7823fd
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_us.kcm
@@ -0,0 +1,15 @@
+# Copyright (C) 2012 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.
+
+# PLACEHOLDER CONTENT #
diff --git a/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm b/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm
new file mode 100644
index 0000000..a7823fd
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm
@@ -0,0 +1,15 @@
+# Copyright (C) 2012 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.
+
+# PLACEHOLDER CONTENT #
diff --git a/packages/InputDevices/res/raw/keyboard_layout_german.kcm b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
new file mode 100644
index 0000000..a7823fd
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
@@ -0,0 +1,15 @@
+# Copyright (C) 2012 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.
+
+# PLACEHOLDER CONTENT #
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
new file mode 100644
index 0000000..6d5ee98
--- /dev/null
+++ b/packages/InputDevices/res/values/strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Name of the application. [CHAR LIMIT=35] -->
+    <string name="app_label">Input Devices</string>
+
+    <!-- US English keyboard layout label. [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_english_us_label">English (US)</string>
+
+    <!-- US English (Dvorak style) keyboard layout label. [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_english_us_dvorak_label">English (US), Dvorak</string>
+
+    <!-- German keyboard layout label. [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_german_label">German</string>
+</resources>
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
new file mode 100644
index 0000000..459a0e4
--- /dev/null
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android">
+    <keyboard-layout android:name="keyboard_layout_english_us"
+            android:label="@string/keyboard_layout_english_us_label"
+            android:kcm="@raw/keyboard_layout_english_us" />
+
+    <keyboard-layout android:name="keyboard_layout_english_us_dvorak"
+            android:label="@string/keyboard_layout_english_us_dvorak_label"
+            android:kcm="@raw/keyboard_layout_english_us_dvorak" />
+
+    <keyboard-layout android:name="keyboard_layout_german"
+            android:label="@string/keyboard_layout_german_label"
+            android:kcm="@raw/keyboard_layout_german" />
+</keyboard-layouts>
diff --git a/packages/InputDevices/src/com/android/inputdevices/InputDeviceReceiver.java b/packages/InputDevices/src/com/android/inputdevices/InputDeviceReceiver.java
new file mode 100644
index 0000000..50a7c2f
--- /dev/null
+++ b/packages/InputDevices/src/com/android/inputdevices/InputDeviceReceiver.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 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.inputdevices;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class InputDeviceReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        // Nothing to do at this time.
+    }
+}
diff --git a/packages/SystemUI/res/anim/status_bar_in.xml b/packages/SystemUI/res/anim/status_bar_in.xml
deleted file mode 100644
index 79fe5f1..0000000
--- a/packages/SystemUI/res/anim/status_bar_in.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromYDelta="100%p" android:toYDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/status_bar_out.xml b/packages/SystemUI/res/anim/status_bar_out.xml
deleted file mode 100644
index 80863cf..0000000
--- a/packages/SystemUI/res/anim/status_bar_out.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:toYDelta="100%p" android:fromYDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:toAlpha="0.5" android:fromAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index b1aaade..0ba8cce 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -26,6 +26,7 @@
     android:orientation="vertical"
     android:focusable="true"
     android:descendantFocusability="afterDescendants"
+    android:fitsSystemWindows="true"
     >
 
     <LinearLayout android:id="@+id/icons"
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index dc5c540..02411d4 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -67,8 +67,6 @@
 
     <!-- Standard animations for hiding and showing the status bar. -->
     <style name="Animation.StatusBar">
-        <item name="android:windowEnterAnimation">@anim/status_bar_enter</item>
-        <item name="android:windowExitAnimation">@anim/status_bar_exit</item>
     </style>
 
     <style name="Animation.StatusBar.IntruderAlert">
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index d7a5056..1ae15be 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -69,9 +69,9 @@
         IWindowManager wm = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
         try {
-            SERVICES[0] = wm.canStatusBarHide()
-                    ? R.string.config_statusBarComponent
-                    : R.string.config_systemBarComponent;
+            SERVICES[0] = wm.hasSystemNavBar()
+                    ? R.string.config_systemBarComponent
+                    : R.string.config_statusBarComponent;
         } catch (RemoteException e) {
             Slog.w(TAG, "Failing checking whether status bar can hide", e);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 12c05ed..5ba72c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1766,11 +1766,6 @@
                 // HWComposer is unable to handle SW-rendered RGBX_8888 layers.
                 PixelFormat.RGB_565);
 
-        // the status bar should be in an overlay if possible
-        final Display defaultDisplay
-            = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
-                .getDefaultDisplay();
-
         // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags.  The status bar occupies
         // very little screen real-estate and is updated fairly frequently.  By using CPU rendering
         // for the status bar, we prevent the GPU from having to wake up just to do these small
@@ -1779,9 +1774,7 @@
         lp.gravity = getStatusBarGravity();
         lp.setTitle("StatusBar");
         lp.packageName = mContext.getPackageName();
-        lp.windowAnimations = R.style.Animation_StatusBar;
         WindowManagerImpl.getDefault().addView(makeStatusBarView(), lp);
-
     }
     
     void addExpandedWindow() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index cc07240..0c8208f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -23,6 +23,7 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.Canvas;
 import android.graphics.RectF;
+import android.hardware.input.InputManager;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.ServiceManager;
@@ -47,7 +48,6 @@
     final float GLOW_MAX_SCALE_FACTOR = 1.8f;
     final float BUTTON_QUIESCENT_ALPHA = 0.6f;
 
-    IWindowManager mWindowManager;
     long mDownTime;
     int mCode;
     int mTouchSlop;
@@ -93,9 +93,6 @@
         
         a.recycle();
 
-        mWindowManager = IWindowManager.Stub.asInterface(
-                ServiceManager.getService(Context.WINDOW_SERVICE));
-
         setClickable(true);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
     }
@@ -276,12 +273,7 @@
                 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
                 flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
                 InputDevice.SOURCE_KEYBOARD);
-        try {
-            //Slog.d(TAG, "injecting event " + ev);
-            mWindowManager.injectInputEventNoWait(ev);
-        } catch (RemoteException ex) {
-            // System process is dead
-        }
+        InputManager.injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java
deleted file mode 100644
index 3e9a9d8..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.tablet;
-
-import java.util.ArrayList;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.util.DisplayMetrics;
-import android.util.Slog;
-import android.view.Display;
-import android.view.WindowManager;
-import android.view.WindowManagerImpl;
-import android.view.WindowManagerPolicy;
-
-public class HeightReceiver extends BroadcastReceiver {
-    private static final String TAG = "StatusBar.HeightReceiver";
-
-    public interface OnBarHeightChangedListener {
-        public void onBarHeightChanged(int height);
-    }
-
-    Context mContext;
-    ArrayList<OnBarHeightChangedListener> mListeners = new ArrayList<OnBarHeightChangedListener>();
-    WindowManager mWindowManager;
-    int mHeight;
-    boolean mPlugged;
-
-    public HeightReceiver(Context context) {
-        mContext = context;
-        mWindowManager = WindowManagerImpl.getDefault();
-    }
-
-    public void addOnBarHeightChangedListener(OnBarHeightChangedListener l) {
-        mListeners.add(l);
-        l.onBarHeightChanged(mHeight);
-    }
-
-    public void removeOnBarHeightChangedListener(OnBarHeightChangedListener l) {
-        mListeners.remove(l);
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        final boolean plugged
-                = intent.getBooleanExtra(WindowManagerPolicy.EXTRA_HDMI_PLUGGED_STATE, false);
-        setPlugged(plugged);
-    }
-
-    public void registerReceiver() {
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction(WindowManagerPolicy.ACTION_HDMI_PLUGGED);
-        final Intent val = mContext.registerReceiver(this, filter);
-        onReceive(mContext, val);
-    }
-
-    private void setPlugged(boolean plugged) {
-        mPlugged = plugged;
-        updateHeight();
-    }
-
-    public void updateHeight() {
-        final Resources res = mContext.getResources();
-
-        int height = -1;
-        if (mPlugged) {
-            final DisplayMetrics metrics = new DisplayMetrics();
-            Display display = mWindowManager.getDefaultDisplay();
-            display.getRealMetrics(metrics);
-
-            //Slog.i(TAG, "updateHeight: display metrics=" + metrics);
-            final int shortSide = Math.min(metrics.widthPixels, metrics.heightPixels);
-            final int externalShortSide = Math.min(display.getRawExternalWidth(),
-                    display.getRawExternalHeight());
-            height = shortSide - externalShortSide;
-        }
-
-        final int minHeight
-                = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
-        if (height < minHeight) {
-            height = minHeight;
-        }
-        Slog.i(TAG, "Resizing status bar plugged=" + mPlugged + " height="
-                + height + " old=" + mHeight);
-        mHeight = height;
-
-        final int N = mListeners.size();
-        for (int i=0; i<N; i++) {
-            mListeners.get(i).onBarHeightChanged(height);
-        }
-    }
-
-    public int getHeight() {
-        return mHeight;
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 7325a37..09283f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -87,7 +87,6 @@
 import com.android.systemui.statusbar.policy.Prefs;
 
 public class TabletStatusBar extends BaseStatusBar implements
-        HeightReceiver.OnBarHeightChangedListener,
         InputMethodsPanel.OnHardKeyboardEnabledChangeListener,
         RecentsPanelView.OnRecentsPanelVisibilityChangedListener {
     public static final boolean DEBUG = false;
@@ -162,7 +161,6 @@
 
     ViewGroup mPile;
 
-    HeightReceiver mHeightReceiver;
     BatteryController mBatteryController;
     BluetoothController mBluetoothController;
     LocationController mLocationController;
@@ -204,12 +202,11 @@
     
     private void addStatusBarWindow() {
         final View sb = makeStatusBarView();
-        final int height = getStatusBarHeight();
 
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
-                height,
-                WindowManager.LayoutParams.TYPE_STATUS_BAR,
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                     | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
@@ -218,20 +215,14 @@
                 // HWComposer is unable to handle SW-rendered RGBX_8888 layers.
                 PixelFormat.RGB_565);
 
-        // the status bar should be in an overlay if possible
-        final Display defaultDisplay
-            = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
-                .getDefaultDisplay();
-
         // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags.  The status bar occupies
         // very little screen real-estate and is updated fairly frequently.  By using CPU rendering
         // for the status bar, we prevent the GPU from having to wake up just to do these small
         // updates, which should help keep power consumption down.
 
         lp.gravity = getStatusBarGravity();
-        lp.setTitle("StatusBar");
+        lp.setTitle("SystemBar");
         lp.packageName = mContext.getPackageName();
-        lp.windowAnimations = R.style.Animation_StatusBar;
         WindowManagerImpl.getDefault().addView(sb, lp);
     }
 
@@ -414,7 +405,6 @@
 
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
-        mHeightReceiver.updateHeight(); // display size may have changed
         loadDimens();
         mNotificationPanelParams.height = getNotificationPanelHeight();
         WindowManagerImpl.getDefault().updateViewLayout(mNotificationPanel,
@@ -426,7 +416,7 @@
         final Resources res = mContext.getResources();
 
         mNaturalBarHeight = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.system_bar_height);
+                com.android.internal.R.dimen.navigation_bar_height);
 
         int newIconSize = res.getDimensionPixelSize(
             com.android.internal.R.dimen.system_bar_icon_size);
@@ -478,10 +468,6 @@
         mWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
 
-        // This guy will listen for HDMI plugged broadcasts so we can resize the
-        // status bar as appropriate.
-        mHeightReceiver = new HeightReceiver(mContext);
-        mHeightReceiver.registerReceiver();
         loadDimens();
 
         final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
@@ -637,8 +623,6 @@
         // set the initial view visibility
         setAreThereNotifications();
 
-        mHeightReceiver.addOnBarHeightChangedListener(this);
-
         // receive broadcasts
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
@@ -674,7 +658,9 @@
     }
 
     public int getStatusBarHeight() {
-        return mHeightReceiver.getHeight();
+        return mStatusBarView != null ? mStatusBarView.getHeight()
+                : mContext.getResources().getDimensionPixelSize(
+                        com.android.internal.R.dimen.navigation_bar_height);
     }
 
     protected int getStatusBarGravity() {
@@ -1336,14 +1322,6 @@
         }
     }
 
-    private void sendKey(KeyEvent key) {
-        try {
-            if (DEBUG) Slog.d(TAG, "injecting key event: " + key);
-            mWindowManager.injectInputEventNoWait(key);
-        } catch (RemoteException ex) {
-        }
-    }
-
     private View.OnClickListener mOnClickListener = new View.OnClickListener() {
         public void onClick(View v) {
             if (v == mRecentButton) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 804cd9e..a472375 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -105,6 +105,7 @@
     private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
     private static final int MSG_DEVICE_PROVISIONED = 308;
     protected static final int MSG_DPM_STATE_CHANGED = 309;
+    protected static final int MSG_USER_CHANGED = 310;
 
     /**
      * When we receive a
@@ -209,6 +210,9 @@
                     case MSG_DPM_STATE_CHANGED:
                         handleDevicePolicyManagerStateChanged();
                         break;
+                    case MSG_USER_CHANGED:
+                        handleUserChanged(msg.arg1);
+                        break;
                 }
             }
         };
@@ -268,6 +272,8 @@
         filter.addAction(SPN_STRINGS_UPDATED_ACTION);
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+        filter.addAction(Intent.ACTION_USER_SWITCHED);
+        filter.addAction(Intent.ACTION_USER_REMOVED);
         context.registerReceiver(new BroadcastReceiver() {
 
             public void onReceive(Context context, Intent intent) {
@@ -302,6 +308,9 @@
                 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
                         .equals(action)) {
                     mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED));
+                } else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+                    mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_CHANGED,
+                            intent.getIntExtra(Intent.EXTRA_USERID, 0), 0));
                 }
             }
         }, filter);
@@ -313,6 +322,12 @@
         }
     }
 
+    protected void handleUserChanged(int userId) {
+        for (int i = 0; i < mInfoCallbacks.size(); i++) {
+            mInfoCallbacks.get(i).onUserChanged(userId);
+        }
+    }
+
     protected void handleDeviceProvisioned() {
         for (int i = 0; i < mInfoCallbacks.size(); i++) {
             mInfoCallbacks.get(i).onDeviceProvisioned();
@@ -542,6 +557,11 @@
          * See {@link DevicePolicyManager#ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED}
          */
         void onDevicePolicyManagerStateChanged();
+
+        /**
+         * Called when the user changes.
+         */
+        void onUserChanged(int userId);
     }
 
     // Simple class that allows methods to easily be overwritten
@@ -570,6 +590,9 @@
 
         public void onDevicePolicyManagerStateChanged() {
         }
+
+        public void onUserChanged(int userId) {
+        }
     }
 
     /**
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 377ea66..52fb875 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -85,7 +85,7 @@
  * This class is created by the initialization routine of the {@link WindowManagerPolicy},
  * and runs on its thread.  The keyguard UI is created from that thread in the
  * constructor of this class.  The apis may be called from other threads, including the
- * {@link com.android.server.wm.InputManager}'s and {@link android.view.WindowManager}'s.
+ * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s.
  * Therefore, methods on this class are synchronized, and any action that is pointed
  * directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI
  * thread of the keyguard.
@@ -342,6 +342,10 @@
         if (soundPath == null || mUnlockSoundId == 0) {
             if (DEBUG) Log.d(TAG, "failed to load sound from " + soundPath);
         }
+        IntentFilter userFilter = new IntentFilter();
+        userFilter.addAction(Intent.ACTION_USER_SWITCHED);
+        userFilter.addAction(Intent.ACTION_USER_REMOVED);
+        mContext.registerReceiver(mUserChangeReceiver, userFilter);
     }
 
     /**
@@ -801,6 +805,29 @@
         return mKeyguardViewProperties.isSecure();
     }
 
+    private void onUserSwitched(int userId) {
+        mLockPatternUtils.setCurrentUser(userId);
+        synchronized (KeyguardViewMediator.this) {
+            resetStateLocked();
+        }
+    }
+
+    private void onUserRemoved(int userId) {
+        mLockPatternUtils.removeUser(userId);
+    }
+
+    private BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+                onUserSwitched(intent.getIntExtra(Intent.EXTRA_USERID, 0));
+            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+                onUserRemoved(intent.getIntExtra(Intent.EXTRA_USERID, 0));
+            }
+        }
+    };
+
     private BroadcastReceiver mBroadCastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 2e7769b..404dc6f 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -757,6 +757,12 @@
                 hideFaceLockArea();
             }
         }
+
+        @Override
+        public void onUserChanged(int userId) {
+            mLockPatternUtils.setCurrentUser(userId);
+            updateScreen(getInitialMode(), true);
+        }
     };
 
     @Override
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index c9a130b..e8ba21d 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -17,10 +17,8 @@
 package com.android.internal.policy.impl;
 
 import com.android.internal.R;
-import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallback;
 import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
 import com.android.internal.policy.impl.KeyguardUpdateMonitor.SimStateCallback;
-import com.android.internal.policy.impl.LockScreen.MultiWaveViewMethods;
 import com.android.internal.telephony.IccCard.State;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.SlidingTab;
@@ -29,6 +27,7 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
+import android.app.SearchManager;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
@@ -39,6 +38,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.*;
+import android.speech.RecognizerIntent;
 import android.util.Log;
 import android.media.AudioManager;
 import android.os.RemoteException;
@@ -79,7 +79,8 @@
     private KeyguardStatusViewManager mStatusViewManager;
     private UnlockWidgetCommonMethods mUnlockWidgetMethods;
     private View mUnlockWidget;
-    public boolean mCameraDisabled;
+    private boolean mCameraDisabled;
+    private boolean mSearchDisabled;
 
     InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
 
@@ -94,14 +95,14 @@
 
         @Override
         public void onDevicePolicyManagerStateChanged() {
-            updateCameraTarget();
+            updateTargets();
         }
 
     };
 
     SimStateCallback mSimStateCallback = new SimStateCallback() {
         public void onSimStateChanged(State simState) {
-            updateCameraTarget();
+            updateTargets();
         }
     };
 
@@ -243,11 +244,12 @@
 
         MultiWaveViewMethods(MultiWaveView multiWaveView) {
             mMultiWaveView = multiWaveView;
+
+            // TODO: get search icon.  See Launcher.updateGlobalSearchIcon()
         }
 
-        public boolean isCameraTargetPresent() {
-            return mMultiWaveView
-                .getTargetPosition(com.android.internal.R.drawable.ic_lockscreen_camera) != -1;
+        public boolean isTargetPresent(int resId) {
+            return mMultiWaveView.getTargetPosition(resId) != -1;
         }
 
         public void updateResources() {
@@ -263,6 +265,7 @@
                 mMultiWaveView.setTargetResources(resId);
             }
             setEnabled(com.android.internal.R.drawable.ic_lockscreen_camera, !mCameraDisabled);
+            setEnabled(com.android.internal.R.drawable.ic_lockscreen_search, !mSearchDisabled);
         }
 
         public void onGrabbed(View v, int handle) {
@@ -276,8 +279,13 @@
         public void onTrigger(View v, int target) {
             final int resId = mMultiWaveView.getResourceIdForTarget(target);
             switch (resId) {
+                case com.android.internal.R.drawable.ic_lockscreen_search:
+                    launchActivity(new Intent(RecognizerIntent.ACTION_WEB_SEARCH));
+                    mCallback.pokeWakelock();
+                    break;
+
                 case com.android.internal.R.drawable.ic_lockscreen_camera:
-                    launchCamera();
+                    launchActivity(new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA));
                     mCallback.pokeWakelock();
                     break;
 
@@ -292,8 +300,7 @@
             }
         }
 
-        private void launchCamera() {
-            Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+        private void launchActivity(Intent intent) {
             intent.setFlags(
                     Intent.FLAG_ACTIVITY_NEW_TASK
                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
@@ -457,18 +464,29 @@
         }
     }
 
-    private void updateCameraTarget() {
+    private void updateTargets() {
         boolean disabledByAdmin = mLockPatternUtils.getDevicePolicyManager()
                 .getCameraDisabled(null);
         boolean disabledBySimState = mUpdateMonitor.isSimLocked();
-        boolean targetPresent = (mUnlockWidgetMethods instanceof MultiWaveViewMethods)
-                ? ((MultiWaveViewMethods) mUnlockWidgetMethods).isCameraTargetPresent() : false;
+        boolean cameraTargetPresent = (mUnlockWidgetMethods instanceof MultiWaveViewMethods)
+                ? ((MultiWaveViewMethods) mUnlockWidgetMethods)
+                        .isTargetPresent(com.android.internal.R.drawable.ic_lockscreen_camera)
+                        : false;
+        boolean searchTargetPresent = (mUnlockWidgetMethods instanceof MultiWaveViewMethods)
+                ? ((MultiWaveViewMethods) mUnlockWidgetMethods)
+                        .isTargetPresent(com.android.internal.R.drawable.ic_lockscreen_search)
+                        : false;
+
+        // TODO: test to see if search is available
+        boolean searchActionAvailable = true;
+
         if (disabledByAdmin) {
             Log.v(TAG, "Camera disabled by Device Policy");
         } else if (disabledBySimState) {
             Log.v(TAG, "Camera disabled by Sim State");
         }
-        mCameraDisabled = disabledByAdmin || disabledBySimState || !targetPresent;
+        mCameraDisabled = disabledByAdmin || disabledBySimState || !cameraTargetPresent;
+        mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent;
         mUnlockWidgetMethods.updateResources();
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
index 9a6d2cc..17e671d 100644
--- a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
@@ -41,7 +41,7 @@
 class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient
         implements KeyguardScreen {
 
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true; /* TODO: revert before JB release */
     private static final String TAG = "UnlockScreen";
 
     // how long before we clear the wrong pattern
@@ -321,6 +321,7 @@
             implements LockPatternView.OnPatternListener {
 
         public void onPatternStart() {
+            if (DEBUG) Log.d(TAG, "Got pattern start");
             mLockPatternView.removeCallbacks(mCancelPatternRunnable);
         }
 
@@ -336,6 +337,7 @@
                 // Give just a little extra time if they hit one of the first few dots
                 mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS);
             }
+            if (DEBUG) Log.d(TAG, "Got pattern cell");
         }
 
         public void onPatternDetected(List<LockPatternView.Cell> pattern) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index fb1e106..5697284 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1,5 +1,4 @@
 /*
- * Copyright (C) 2006 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.
@@ -72,6 +71,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
 import android.view.IApplicationToken;
@@ -132,6 +132,9 @@
 import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
 import android.view.WindowManagerImpl;
 import android.view.WindowManagerPolicy;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
 import android.view.KeyCharacterMap.FallbackAction;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Animation;
@@ -237,8 +240,6 @@
     static final int SYSTEM_UI_CHANGING_LAYOUT =
             View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
 
-    // Useful scan codes.
-    private static final int SW_LID = 0x00;
     private static final int BTN_MOUSE = 0x110;
 
     /* Table of Application Launch keys.  Maps from key codes to intent categories.
@@ -299,11 +300,13 @@
     boolean mHeadless;
     boolean mSafeMode;
     WindowState mStatusBar = null;
-    boolean mStatusBarCanHide;
+    boolean mHasSystemNavBar;
     int mStatusBarHeight;
     final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>();
     WindowState mNavigationBar = null;
     boolean mHasNavigationBar = false;
+    boolean mCanHideNavigationBar = false;
+    boolean mNavigationBarOnBottom = true;
     int mNavigationBarWidth = 0, mNavigationBarHeight = 0;
 
     WindowState mKeyguard = null;
@@ -320,15 +323,13 @@
     RecentApplicationsDialog mRecentAppsDialog;
     int mRecentAppsDialogHeldModifiers;
 
-    private static final int LID_ABSENT = -1;
-    private static final int LID_CLOSED = 0;
-    private static final int LID_OPEN = 1;
-
     int mLidOpen = LID_ABSENT;
 
     boolean mSystemReady;
     boolean mSystemBooted;
     boolean mHdmiPlugged;
+    int mExternalDisplayWidth;
+    int mExternalDisplayHeight;
     int mUiMode;
     int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
     int mLidOpenRotation;
@@ -464,6 +465,8 @@
     // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.)
     int mIncallPowerBehavior;
 
+    Display mDisplay;
+
     int mLandscapeRotation = 0;  // default landscape rotation
     int mSeascapeRotation = 0;   // "other" landscape rotation, 180 degrees from mLandscapeRotation
     int mPortraitRotation = 0;   // default portrait rotation
@@ -927,10 +930,13 @@
         }
     }
 
-    public void setInitialDisplaySize(int width, int height) {
-        int shortSize;
+    public void setInitialDisplaySize(Display display, int width, int height) {
+        mDisplay = display;
+
+        int shortSize, longSize;
         if (width > height) {
             shortSize = height;
+            longSize = width;
             mLandscapeRotation = Surface.ROTATION_0;
             mSeascapeRotation = Surface.ROTATION_180;
             if (mContext.getResources().getBoolean(
@@ -943,6 +949,7 @@
             }
         } else {
             shortSize = width;
+            longSize = height;
             mPortraitRotation = Surface.ROTATION_0;
             mUpsideDownRotation = Surface.ROTATION_180;
             if (mContext.getResources().getBoolean(
@@ -955,36 +962,62 @@
             }
         }
 
+        mExternalDisplayWidth = mDisplay.getRawExternalWidth();
+        mExternalDisplayHeight = mDisplay.getRawExternalHeight();
+
+        mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_height);
+        mNavigationBarHeight = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.navigation_bar_height);
+        mNavigationBarWidth = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.navigation_bar_width);
+
         // Determine whether the status bar can hide based on the size
-        // of the screen.  We assume sizes > 600dp are tablets where we
+        // of the screen.  We assume sizes >= 600dp are tablets where we
         // will use the system bar.
+        // XXX: This will change to 720dp soon.
         int shortSizeDp = shortSize
                 * DisplayMetrics.DENSITY_DEFAULT
                 / DisplayMetrics.DENSITY_DEVICE;
-        mStatusBarCanHide = shortSizeDp < 600;
-        mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
-                mStatusBarCanHide
-                ? com.android.internal.R.dimen.status_bar_height
-                : com.android.internal.R.dimen.system_bar_height);
+        mHasSystemNavBar = shortSizeDp >= 600;
 
-        mHasNavigationBar = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_showNavigationBar);
-        // Allow a system property to override this. Used by the emulator.
-        // See also hasNavigationBar().
-        String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
-        if (! "".equals(navBarOverride)) {
-            if      (navBarOverride.equals("1")) mHasNavigationBar = false;
-            else if (navBarOverride.equals("0")) mHasNavigationBar = true;
+        if (!mHasSystemNavBar) {
+            mHasNavigationBar = mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_showNavigationBar);
+            // Allow a system property to override this. Used by the emulator.
+            // See also hasNavigationBar().
+            String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
+            if (! "".equals(navBarOverride)) {
+                if      (navBarOverride.equals("1")) mHasNavigationBar = false;
+                else if (navBarOverride.equals("0")) mHasNavigationBar = true;
+            }
+        } else {
+            mHasNavigationBar = false;
         }
 
-        mNavigationBarHeight = mHasNavigationBar
-                ? mContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.navigation_bar_height)
-                : 0;
-        mNavigationBarWidth = mHasNavigationBar
-                ? mContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.navigation_bar_width)
-                : 0;
+        if (mHasSystemNavBar) {
+            // The system bar is always at the bottom.  If you are watching
+            // a video in landscape, we don't need to hide it if we can still
+            // show a 16:9 aspect ratio with it.
+            int longSizeDp = longSize
+                    * DisplayMetrics.DENSITY_DEFAULT
+                    / DisplayMetrics.DENSITY_DEVICE;
+            int barHeightDp = mNavigationBarHeight
+                    * DisplayMetrics.DENSITY_DEFAULT
+                    / DisplayMetrics.DENSITY_DEVICE;
+            int aspect = ((shortSizeDp-barHeightDp) * 16) / longSizeDp;
+            // We have computed the aspect ratio with the bar height taken
+            // out to be 16:aspect.  If this is less than 9, then hiding
+            // the navigation bar will provide more useful space for wide
+            // screen movies.
+            mCanHideNavigationBar = aspect < 9;
+        } else if (mHasNavigationBar) {
+            // The navigation bar is at the right in landscape; it seems always
+            // useful to hide it for showing a video.
+            mCanHideNavigationBar = true;
+        } else {
+            mCanHideNavigationBar = false;
+        }
 
         if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
             mHdmiRotation = mPortraitRotation;
@@ -1085,16 +1118,11 @@
             lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
             wm.addView(mPointerLocationView, lp);
 
-            try {
-                mPointerLocationInputChannel =
-                        mWindowManager.monitorInput("PointerLocationView");
-                mPointerLocationInputEventReceiver =
-                        new PointerLocationInputEventReceiver(mPointerLocationInputChannel,
-                                Looper.myLooper(), mPointerLocationView);
-            } catch (RemoteException ex) {
-                Slog.e(TAG, "Could not set up input monitoring channel for PointerLocation.",
-                        ex);
-            }
+            mPointerLocationInputChannel =
+                    mWindowManagerFuncs.monitorInput("PointerLocationView");
+            mPointerLocationInputEventReceiver =
+                    new PointerLocationInputEventReceiver(mPointerLocationInputChannel,
+                            Looper.myLooper(), mPointerLocationView);
         }
     }
 
@@ -1188,18 +1216,7 @@
     }
     
     void readLidState() {
-        try {
-            int sw = mWindowManager.getSwitchState(SW_LID);
-            if (sw > 0) {
-                mLidOpen = LID_OPEN;
-            } else if (sw == 0) {
-                mLidOpen = LID_CLOSED;
-            } else {
-                mLidOpen = LID_ABSENT;
-            }
-        } catch (RemoteException e) {
-            // Ignore
-        }
+        mLidOpen = mWindowManagerFuncs.getLidState();
     }
     
     private int determineHiddenState(int mode, int hiddenValue, int visibleValue) {
@@ -1318,13 +1335,13 @@
         return STATUS_BAR_LAYER;
     }
 
-    public boolean canStatusBarHide() {
-        return mStatusBarCanHide;
+    public boolean hasSystemNavBar() {
+        return mHasSystemNavBar;
     }
 
     public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation) {
         // Assumes that the navigation bar appears on the side of the display in landscape.
-        if (fullWidth > fullHeight) {
+        if (mHasNavigationBar && fullWidth > fullHeight) {
             return fullWidth - mNavigationBarWidth;
         }
         return fullWidth;
@@ -1333,8 +1350,8 @@
     public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation) {
         // Assumes the navigation bar appears on the bottom of the display in portrait.
         return fullHeight
-            - (mStatusBarCanHide ? 0 : mStatusBarHeight)
-            - ((fullWidth > fullHeight) ? 0 : mNavigationBarHeight);
+            - (mHasSystemNavBar ? mNavigationBarHeight : 0)
+            - ((mHasNavigationBar && fullWidth > fullHeight) ? 0 : mNavigationBarHeight);
     }
 
     public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation) {
@@ -1348,7 +1365,7 @@
         // exclude it since applications can't generally use that part of the
         // screen.
         return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation)
-                - (mStatusBarCanHide ? mStatusBarHeight : 0);
+                - (mHasSystemNavBar ? 0 : mStatusBarHeight);
     }
 
     public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
@@ -1357,6 +1374,7 @@
     
     public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
         return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
+                && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
                 && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER;
     }
     
@@ -1495,10 +1513,10 @@
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.STATUS_BAR_SERVICE,
                         "PhoneWindowManager");
-                // TODO: Need to handle the race condition of the status bar proc
-                // dying and coming back before the removeWindowLw cleanup has happened.
                 if (mStatusBar != null) {
-                    return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+                    if (mStatusBar.isAlive()) {
+                        return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+                    }
                 }
                 mStatusBar = win;
                 break;
@@ -1506,6 +1524,11 @@
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.STATUS_BAR_SERVICE,
                         "PhoneWindowManager");
+                if (mNavigationBar != null) {
+                    if (mNavigationBar.isAlive()) {
+                        return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+                    }
+                }
                 mNavigationBar = win;
                 if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                 break;
@@ -1550,7 +1573,28 @@
     public int selectAnimationLw(WindowState win, int transit) {
         if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win
               + ": transit=" + transit);
-        if (transit == TRANSIT_PREVIEW_DONE) {
+        if (win == mStatusBar) {
+            if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
+                return R.anim.dock_top_exit;
+            } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+                return R.anim.dock_top_enter;
+            }
+        } else if (win == mNavigationBar) {
+            // This can be on either the bottom or the right.
+            if (mNavigationBarOnBottom) {
+                if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
+                    return R.anim.dock_bottom_exit;
+                } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+                    return R.anim.dock_bottom_enter;
+                }
+            } else {
+                if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
+                    return R.anim.dock_right_exit;
+                } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+                    return R.anim.dock_right_enter;
+                }
+            }
+        } if (transit == TRANSIT_PREVIEW_DONE) {
             if (win.hasAppShownWindows()) {
                 if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT");
                 return com.android.internal.R.anim.app_starting_exit;
@@ -2036,7 +2080,8 @@
         if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR))
                 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
             int availRight, availBottom;
-            if ((attrs.systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) {
+            if (mCanHideNavigationBar &&
+                    (attrs.systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) {
                 availRight = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
                 availBottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
             } else {
@@ -2082,8 +2127,9 @@
         pf.right = df.right = vf.right = mDockRight;
         pf.bottom = df.bottom = vf.bottom = mDockBottom;
 
-        final boolean navVisible = (mNavigationBar == null || mNavigationBar.isVisibleLw()) &&
-                (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+        // For purposes of putting out fake window up to steal focus, we will
+        // drive nav being hidden only by whether it is requested.
+        boolean navVisible = (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
 
         // When the navigation bar isn't visible, we put up a fake
         // input window to catch all touch events.  This way we can
@@ -2101,117 +2147,107 @@
                     0, false, false, true);
         }
 
-        // decide where the status bar goes ahead of time
-        if (mStatusBar != null) {
-            if (mNavigationBar != null) {
-                // Force the navigation bar to its appropriate place and
-                // size.  We need to do this directly, instead of relying on
-                // it to bubble up from the nav bar, because this needs to
-                // change atomically with screen rotations.
-                if (displayWidth < displayHeight) {
-                    // Portrait screen; nav bar goes on bottom.
-                    mTmpNavigationFrame.set(0, displayHeight-mNavigationBarHeight,
-                            displayWidth, displayHeight);
-                    mStableBottom = mTmpNavigationFrame.top;
-                    if (navVisible) {
-                        mDockBottom = mTmpNavigationFrame.top;
-                        mRestrictedScreenHeight = mDockBottom - mDockTop;
-                    } else {
-                        // We currently want to hide the navigation UI.  Do this by just
-                        // moving it off the screen, so it can still receive input events
-                        // to know when to be re-shown.
-                        mTmpNavigationFrame.offset(0, mNavigationBarHeight);
-                    }
-                } else {
-                    // Landscape screen; nav bar goes to the right.
-                    mTmpNavigationFrame.set(displayWidth-mNavigationBarWidth, 0,
-                            displayWidth, displayHeight);
-                    mStableRight = mTmpNavigationFrame.left;
-                    if (navVisible) {
-                        mDockRight = mTmpNavigationFrame.left;
-                        mRestrictedScreenWidth = mDockRight - mDockLeft;
-                    } else {
-                        // We currently want to hide the navigation UI.  Do this by just
-                        // moving it off the screen, so it can still receive input events
-                        // to know when to be re-shown.
-                        mTmpNavigationFrame.offset(mNavigationBarWidth, 0);
+        // For purposes of positioning and showing the nav bar, if we have
+        // decided that it can't be hidden (because of the screen aspect ratio),
+        // then take that into account.
+        navVisible |= !mCanHideNavigationBar;
+
+        if (mNavigationBar != null) {
+            // Force the navigation bar to its appropriate place and
+            // size.  We need to do this directly, instead of relying on
+            // it to bubble up from the nav bar, because this needs to
+            // change atomically with screen rotations.
+            mNavigationBarOnBottom = !mHasNavigationBar || displayWidth < displayHeight;
+            if (mNavigationBarOnBottom) {
+                // It's a system nav bar or a portrait screen; nav bar goes on bottom.
+                int top = displayHeight - mNavigationBarHeight;
+                if (mHdmiPlugged) {
+                    if (top > mExternalDisplayHeight) {
+                        top = mExternalDisplayHeight;
                     }
                 }
-                // Make sure the content and current rectangles are updated to
-                // account for the restrictions from the navigation bar.
-                mContentTop = mCurTop = mDockTop;
-                mContentBottom = mCurBottom = mDockBottom;
-                mContentLeft = mCurLeft = mDockLeft;
-                mContentRight = mCurRight = mDockRight;
-                // And compute the final frame.
-                mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
-                        mTmpNavigationFrame, mTmpNavigationFrame);
-                if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
+                mTmpNavigationFrame.set(0, top, displayWidth, displayHeight);
+                mStableBottom = mTmpNavigationFrame.top;
+                if (navVisible) {
+                    mNavigationBar.showLw(true);
+                    mDockBottom = mTmpNavigationFrame.top;
+                    mRestrictedScreenHeight = mDockBottom - mDockTop;
+                } else {
+                    // We currently want to hide the navigation UI.
+                    mNavigationBar.hideLw(true);
+                }
+            } else {
+                // Landscape screen; nav bar goes to the right.
+                int left = displayWidth - mNavigationBarWidth;
+                if (mHdmiPlugged) {
+                    if (left > mExternalDisplayWidth) {
+                        left = mExternalDisplayWidth;
+                    }
+                }
+                mTmpNavigationFrame.set(left, 0, displayWidth, displayHeight);
+                mStableRight = mTmpNavigationFrame.left;
+                if (navVisible) {
+                    mNavigationBar.showLw(true);
+                    mDockRight = mTmpNavigationFrame.left;
+                    mRestrictedScreenWidth = mDockRight - mDockLeft;
+                } else {
+                    // We currently want to hide the navigation UI.
+                    mNavigationBar.hideLw(true);
+                }
             }
-            if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
-                    mDockLeft, mDockTop, mDockRight, mDockBottom));
+            // Make sure the content and current rectangles are updated to
+            // account for the restrictions from the navigation bar.
+            mContentTop = mCurTop = mDockTop;
+            mContentBottom = mCurBottom = mDockBottom;
+            mContentLeft = mCurLeft = mDockLeft;
+            mContentRight = mCurRight = mDockRight;
+            // And compute the final frame.
+            mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
+                    mTmpNavigationFrame, mTmpNavigationFrame);
+            if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
+        }
+        if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
+                mDockLeft, mDockTop, mDockRight, mDockBottom));
 
-            // apply navigation bar insets
-            pf.left = df.left = vf.left = mDockLeft;
-            pf.top = df.top = vf.top = mDockTop;
-            pf.right = df.right = vf.right = mDockRight;
-            pf.bottom = df.bottom = vf.bottom = mDockBottom;
+        // decide where the status bar goes ahead of time
+        if (mStatusBar != null) {
+            // apply any navigation bar insets
+            pf.left = df.left = mUnrestrictedScreenLeft;
+            pf.top = df.top = mUnrestrictedScreenTop;
+            pf.right = df.right = mUnrestrictedScreenWidth - mUnrestrictedScreenLeft;
+            pf.bottom = df.bottom = mUnrestrictedScreenHeight - mUnrestrictedScreenTop;
+            vf.left = mStableLeft;
+            vf.top = mStableTop;
+            vf.right = mStableRight;
+            vf.bottom = mStableBottom;
 
             mStatusBar.computeFrameLw(pf, df, vf, vf);
             final Rect r = mStatusBar.getFrameLw();
 
             // Compute the stable dimensions whether or not the status bar is hidden.
-            if (mStatusBarCanHide) {
-                if (mDockTop == r.top) mStableTop = r.bottom;
-                else if (mDockBottom == r.bottom) mStableBottom = r.top;
-            } else {
-                if (mStableTop == r.top) {
-                    mStableTop = r.bottom;
-                } else if (mStableBottom == r.bottom) {
-                    mStableBottom = r.top;
-                }
-            }
+            if (mDockTop == r.top) mStableTop = r.bottom;
+            else if (mDockBottom == r.bottom) mStableBottom = r.top;
 
+            // If the status bar is hidden, we don't want to cause
+            // windows behind it to scroll.
             if (mStatusBar.isVisibleLw()) {
-                // If the status bar is hidden, we don't want to cause
-                // windows behind it to scroll.
-                if (mStatusBarCanHide) {
-                    // Status bar may go away, so the screen area it occupies
-                    // is available to apps but just covering them when the
-                    // status bar is visible.
-                    if (mDockTop == r.top) mDockTop = r.bottom;
-                    else if (mDockBottom == r.bottom) mDockBottom = r.top;
-                    
-                    mContentTop = mCurTop = mDockTop;
-                    mContentBottom = mCurBottom = mDockBottom;
-                    mContentLeft = mCurLeft = mDockLeft;
-                    mContentRight = mCurRight = mDockRight;
+                // Status bar may go away, so the screen area it occupies
+                // is available to apps but just covering them when the
+                // status bar is visible.
+                if (mDockTop == r.top) mDockTop = r.bottom;
+                else if (mDockBottom == r.bottom) mDockBottom = r.top;
+                
+                mContentTop = mCurTop = mDockTop;
+                mContentBottom = mCurBottom = mDockBottom;
+                mContentLeft = mCurLeft = mDockLeft;
+                mContentRight = mCurRight = mDockRight;
 
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
-                        String.format(
-                            "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
-                            mDockLeft, mDockTop, mDockRight, mDockBottom,
-                            mContentLeft, mContentTop, mContentRight, mContentBottom,
-                            mCurLeft, mCurTop, mCurRight, mCurBottom));
-                } else {
-                    // Status bar can't go away; the part of the screen it
-                    // covers does not exist for anything behind it.
-                    if (mRestrictedScreenTop == r.top) {
-                        mRestrictedScreenTop = r.bottom;
-                        mRestrictedScreenHeight -= (r.bottom-r.top);
-                    } else if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) {
-                        mRestrictedScreenHeight -= (r.bottom-r.top);
-                    }
-
-                    mContentTop = mCurTop = mDockTop = mRestrictedScreenTop;
-                    mContentBottom = mCurBottom = mDockBottom
-                            = mRestrictedScreenTop + mRestrictedScreenHeight;
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: restricted screen area: ("
-                            + mRestrictedScreenLeft + ","
-                            + mRestrictedScreenTop + ","
-                            + (mRestrictedScreenLeft + mRestrictedScreenWidth) + ","
-                            + (mRestrictedScreenTop + mRestrictedScreenHeight) + ")");
-                }
+                if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
+                    String.format(
+                        "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
+                        mDockLeft, mDockTop, mDockRight, mDockBottom,
+                        mContentLeft, mContentTop, mContentRight, mContentBottom,
+                        mCurLeft, mCurTop, mCurRight, mCurBottom));
             }
         }
     }
@@ -2333,7 +2369,8 @@
                                         "Laying out status bar window: (%d,%d - %d,%d)",
                                         pf.left, pf.top, pf.right, pf.bottom));
                         }
-                    } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
+                    } else if (mCanHideNavigationBar
+                            && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
                             && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
                             && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
                         // Asking for layout as if the nav bar is hidden, lets the
@@ -2426,7 +2463,8 @@
                     pf.right = df.right = cf.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
                     pf.bottom = df.bottom = cf.bottom
                             = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
-                } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
+                } else if (mCanHideNavigationBar
+                        && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
                         && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
                         && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
                     // Asking for layout as if the nav bar is hidden, lets the
@@ -2623,19 +2661,17 @@
                 // has the FLAG_FULLSCREEN set.  Not sure if there is another way that to be the
                 // case though.
                 if (topIsFullscreen) {
-                    if (mStatusBarCanHide) {
-                        if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
-                        if (mStatusBar.hideLw(true)) {
-                            changes |= FINISH_LAYOUT_REDO_LAYOUT;
+                    if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
+                    if (mStatusBar.hideLw(true)) {
+                        changes |= FINISH_LAYOUT_REDO_LAYOUT;
 
-                            mHandler.post(new Runnable() { public void run() {
-                                if (mStatusBarService != null) {
-                                    try {
-                                        mStatusBarService.collapse();
-                                    } catch (RemoteException ex) {}
-                                }
-                            }});
-                        }
+                        mHandler.post(new Runnable() { public void run() {
+                            if (mStatusBarService != null) {
+                                try {
+                                    mStatusBarService.collapse();
+                                } catch (RemoteException ex) {}
+                            }
+                        }});
                     } else if (DEBUG_LAYOUT) {
                         Log.v(TAG, "Preventing status bar from hiding by policy");
                     }
@@ -2699,29 +2735,23 @@
             // behind it.
             return false;
         }
-        if (false) {
-            // Don't do this on the tablet, since the system bar never completely
-            // covers the screen, and with all its transparency this will
-            // incorrectly think it does cover it when it doesn't.  We'll revisit
-            // this later when we re-do the phone status bar.
-            if (mStatusBar != null && mStatusBar.isVisibleLw()) {
-                RectF rect = new RectF(mStatusBar.getShownFrameLw());
-                for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
-                    WindowState w = mStatusBarPanels.get(i);
-                    if (w.isVisibleLw()) {
-                        rect.union(w.getShownFrameLw());
-                    }
+        if (mStatusBar != null && mStatusBar.isVisibleLw()) {
+            RectF rect = new RectF(mStatusBar.getShownFrameLw());
+            for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
+                WindowState w = mStatusBarPanels.get(i);
+                if (w.isVisibleLw()) {
+                    rect.union(w.getShownFrameLw());
                 }
-                final int insetw = mRestrictedScreenWidth/10;
-                final int inseth = mRestrictedScreenHeight/10;
-                if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw,
-                            mRestrictedScreenHeight-inseth)) {
-                    // All of the status bar windows put together cover the
-                    // screen, so the app can't be seen.  (Note this test doesn't
-                    // work if the rects of these windows are at off offsets or
-                    // sizes, causing gaps in the rect union we have computed.)
-                    return false;
-                }
+            }
+            final int insetw = mRestrictedScreenWidth/10;
+            final int inseth = mRestrictedScreenHeight/10;
+            if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw,
+                        mRestrictedScreenHeight-inseth)) {
+                // All of the status bar windows put together cover the
+                // screen, so the app can't be seen.  (Note this test doesn't
+                // work if the rects of these windows are at odd offsets or
+                // sizes, causing gaps in the rect union we have computed.)
+                return false;
             }
         }
         return true;
@@ -2776,7 +2806,11 @@
     void setHdmiPlugged(boolean plugged) {
         if (mHdmiPlugged != plugged) {
             mHdmiPlugged = plugged;
-            updateRotation(true);
+            if (plugged && mDisplay != null) {
+                mExternalDisplayWidth = mDisplay.getRawExternalWidth();
+                mExternalDisplayHeight = mDisplay.getRawExternalHeight();
+            }
+            updateRotation(true, true);
             Intent intent = new Intent(ACTION_HDMI_PLUGGED);
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
@@ -3596,29 +3630,11 @@
         }
     }
 
-    public boolean detectSafeMode() {
-        try {
-            int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
-            int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S);
-            int dpadState = mWindowManager.getDPadKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER);
-            int trackballState = mWindowManager.getTrackballScancodeState(BTN_MOUSE);
-            int volumeDownState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_VOLUME_DOWN);
-            mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
-                    || volumeDownState > 0;
-            performHapticFeedbackLw(null, mSafeMode
-                    ? HapticFeedbackConstants.SAFE_MODE_ENABLED
-                    : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
-            if (mSafeMode) {
-                Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
-                        + " dpad=" + dpadState + " trackball=" + trackballState + ")");
-            } else {
-                Log.i(TAG, "SAFE MODE not enabled");
-            }
-            return mSafeMode;
-        } catch (RemoteException e) {
-            // Doom! (it's also local)
-            throw new RuntimeException("window manager dead");
-        }
+    public void setSafeMode(boolean safeMode) {
+        mSafeMode = safeMode;
+        performHapticFeedbackLw(null, safeMode
+                ? HapticFeedbackConstants.SAFE_MODE_ENABLED
+                : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
     }
     
     static long[] getLongIntArray(Resources r, int resid) {
@@ -3871,7 +3887,16 @@
     void updateRotation(boolean alwaysSendConfiguration) {
         try {
             //set orientation on WindowManager
-            mWindowManager.updateRotation(alwaysSendConfiguration);
+            mWindowManager.updateRotation(alwaysSendConfiguration, false);
+        } catch (RemoteException e) {
+            // Ignore
+        }
+    }
+
+    void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
+        try {
+            //set orientation on WindowManager
+            mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout);
         } catch (RemoteException e) {
             // Ignore
         }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e091edf..7dd736d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -47,6 +47,7 @@
 import com.android.internal.app.ShutdownThread;
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
+import com.android.internal.widget.LockSettingsService;
 import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.net.NetworkPolicyManagerService;
@@ -220,6 +221,7 @@
                     factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                     !firstBoot);
             ServiceManager.addService(Context.WINDOW_SERVICE, wm);
+            ServiceManager.addService(Context.INPUT_SERVICE, wm.getInputManagerService());
 
             ActivityManagerService.self().setWindowManager(wm);
 
@@ -266,6 +268,7 @@
         LocationManagerService location = null;
         CountryDetectorService countryDetector = null;
         TextServicesManagerService tsms = null;
+        LockSettingsService lockSettings = null;
 
         // Bring up services needed for UI.
         if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
@@ -308,6 +311,14 @@
 
         if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
             try {
+                Slog.i(TAG,  "LockSettingsService");
+                lockSettings = new LockSettingsService(context);
+                ServiceManager.addService("lock_settings", lockSettings);
+            } catch (Throwable e) {
+                reportWtf("starting LockSettingsService service", e);
+            }
+
+            try {
                 Slog.i(TAG, "Device Policy");
                 devicePolicy = new DevicePolicyManagerService(context);
                 ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
@@ -661,6 +672,11 @@
         } catch (Throwable e) {
             reportWtf("making Package Manager Service ready", e);
         }
+        try {
+            lockSettings.systemReady();
+        } catch (Throwable e) {
+            reportWtf("making Lock Settings Service ready", e);
+        }
 
         // These are needed to propagate to the runnable below.
         final Context contextF = context;
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 8c8e725..1b1638a 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -29,6 +29,7 @@
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
+import android.telephony.CellInfo;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Slog;
@@ -107,6 +108,8 @@
 
     private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
 
+    private CellInfo mCellInfo = null;
+
     static final int PHONE_STATE_PERMISSION_MASK =
                 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
                 PhoneStateListener.LISTEN_CALL_STATE |
@@ -236,6 +239,13 @@
                             remove(r.binder);
                         }
                     }
+                    if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
+                        try {
+                            r.callback.onCellInfoChanged(new CellInfo(mCellInfo));
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
                 }
             }
         } else {
@@ -325,6 +335,26 @@
         broadcastSignalStrengthChanged(signalStrength);
     }
 
+    public void notifyCellInfo(CellInfo cellInfo) {
+        if (!checkNotifyPermission("notifyCellInfo()")) {
+            return;
+        }
+
+        synchronized (mRecords) {
+            mCellInfo = cellInfo;
+            for (Record r : mRecords) {
+                if ((r.events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
+                    try {
+                        r.callback.onCellInfoChanged(new CellInfo(cellInfo));
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+    }
+
     public void notifyMessageWaitingChanged(boolean mwi) {
         if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
             return;
@@ -530,6 +560,7 @@
             pw.println("  mDataConnectionLinkProperties=" + mDataConnectionLinkProperties);
             pw.println("  mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
             pw.println("  mCellLocation=" + mCellLocation);
+            pw.println("  mCellInfo=" + mCellInfo);
             pw.println("registrations: count=" + recordCount);
             for (Record r : mRecords) {
                 pw.println("  " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
@@ -655,6 +686,12 @@
 
         }
 
+        if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
+
+        }
+
         if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.READ_PHONE_STATE, null);
diff --git a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 769cb6a..31aa21e 100644
--- a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -16,7 +16,7 @@
 
 package com.android.server.accessibility;
 
-import com.android.server.wm.InputFilter;
+import com.android.server.input.InputFilter;
 
 import android.content.Context;
 import android.util.Slog;
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 41cf9a6..d07aa7a 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -29,7 +29,7 @@
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.server.accessibility.AccessibilityInputFilter.Explorer;
-import com.android.server.wm.InputFilter;
+import com.android.server.input.InputFilter;
 
 import java.util.Arrays;
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index a6fbdd7..2da827e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -62,10 +62,10 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.IIntentReceiver;
 import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.IntentSender;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
@@ -75,12 +75,12 @@
 import android.content.pm.InstrumentationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PathPermission;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.UserInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
@@ -113,10 +113,10 @@
 import android.provider.Settings;
 import android.text.format.Time;
 import android.util.EventLog;
-import android.util.Pair;
-import android.util.Slog;
 import android.util.Log;
+import android.util.Pair;
 import android.util.PrintWriterPrinter;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.TimeUtils;
@@ -140,7 +140,6 @@
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.lang.IllegalStateException;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -10263,6 +10262,29 @@
             }
             pw.println();
             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
+            final int[] SINGLE_LONG_FORMAT = new int[] {
+                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
+            };
+            long[] longOut = new long[1];
+            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
+                    SINGLE_LONG_FORMAT, null, longOut, null);
+            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+            longOut[0] = 0;
+            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
+                    SINGLE_LONG_FORMAT, null, longOut, null);
+            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+            longOut[0] = 0;
+            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
+                    SINGLE_LONG_FORMAT, null, longOut, null);
+            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+            longOut[0] = 0;
+            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
+                    SINGLE_LONG_FORMAT, null, longOut, null);
+            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
+                    pw.print(shared); pw.println(" kB");
+            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
+                    pw.print(voltile); pw.println(" kB volatile");
         }
     }
 
@@ -13281,6 +13303,102 @@
         }
     }
 
+    @Override
+    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
+        ActivityRecord srec = ActivityRecord.forToken(token);
+        return srec.task.affinity != null && srec.task.affinity.equals(destAffinity);
+    }
+
+    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
+            Intent resultData) {
+        ComponentName dest = destIntent.getComponent();
+
+        synchronized (this) {
+            ActivityRecord srec = ActivityRecord.forToken(token);
+            ArrayList<ActivityRecord> history = srec.stack.mHistory;
+            final int start = history.indexOf(srec);
+            if (start < 0) {
+                // Current activity is not in history stack; do nothing.
+                return false;
+            }
+            int finishTo = start - 1;
+            ActivityRecord parent = null;
+            boolean foundParentInTask = false;
+            if (dest != null) {
+                TaskRecord tr = srec.task;
+                for (int i = start - 1; i >= 0; i--) {
+                    ActivityRecord r = history.get(i);
+                    if (tr != r.task) {
+                        // Couldn't find parent in the same task; stop at the one above this.
+                        // (Root of current task; in-app "home" behavior)
+                        // Always at least finish the current activity.
+                        finishTo = Math.min(start - 1, i + 1);
+                        parent = history.get(finishTo);
+                        break;
+                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
+                            r.info.name.equals(dest.getClassName())) {
+                        finishTo = i;
+                        parent = r;
+                        foundParentInTask = true;
+                        break;
+                    }
+                }
+            }
+
+            if (mController != null) {
+                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
+                if (next != null) {
+                    // ask watcher if this is allowed
+                    boolean resumeOK = true;
+                    try {
+                        resumeOK = mController.activityResuming(next.packageName);
+                    } catch (RemoteException e) {
+                        mController = null;
+                    }
+
+                    if (!resumeOK) {
+                        return false;
+                    }
+                }
+            }
+            final long origId = Binder.clearCallingIdentity();
+            for (int i = start; i > finishTo; i--) {
+                ActivityRecord r = history.get(i);
+                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
+                        "navigate-up");
+                // Only return the supplied result for the first activity finished
+                resultCode = Activity.RESULT_CANCELED;
+                resultData = null;
+            }
+
+            if (parent != null && foundParentInTask) {
+                final int parentLaunchMode = parent.info.launchMode;
+                final int destIntentFlags = destIntent.getFlags();
+                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
+                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
+                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
+                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
+                    parent.deliverNewIntentLocked(srec.app.uid, destIntent);
+                } else {
+                    try {
+                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
+                                destIntent.getComponent(), 0, UserId.getCallingUserId());
+                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
+                                null, aInfo, parent.appToken, null,
+                                0, -1, parent.launchedFromUid, 0, null, true, null);
+                        foundParentInTask = res == ActivityManager.START_SUCCESS;
+                    } catch (RemoteException e) {
+                        foundParentInTask = false;
+                    }
+                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
+                            resultData, "navigate-up");
+                }
+            }
+            Binder.restoreCallingIdentity(origId);
+            return foundParentInTask;
+        }
+    }
+
     // =========================================================
     // LIFETIME MANAGEMENT
     // =========================================================
diff --git a/services/java/com/android/server/wm/InputApplicationHandle.java b/services/java/com/android/server/input/InputApplicationHandle.java
similarity index 90%
rename from services/java/com/android/server/wm/InputApplicationHandle.java
rename to services/java/com/android/server/input/InputApplicationHandle.java
index 1812f11..42c1052 100644
--- a/services/java/com/android/server/wm/InputApplicationHandle.java
+++ b/services/java/com/android/server/input/InputApplicationHandle.java
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.wm;
-
+package com.android.server.input;
 
 /**
  * Functions as a handle for an application that can receive input.
@@ -30,7 +29,7 @@
     private int ptr;
 
     // The window manager's application window token.
-    public final AppWindowToken appWindowToken;
+    public final Object appWindowToken;
 
     // Application name.
     public String name;
@@ -40,7 +39,7 @@
 
     private native void nativeDispose();
 
-    public InputApplicationHandle(AppWindowToken appWindowToken) {
+    public InputApplicationHandle(Object appWindowToken) {
         this.appWindowToken = appWindowToken;
     }
 
diff --git a/services/java/com/android/server/wm/InputFilter.java b/services/java/com/android/server/input/InputFilter.java
similarity index 96%
rename from services/java/com/android/server/wm/InputFilter.java
rename to services/java/com/android/server/input/InputFilter.java
index 8f0001a..2ce0a02 100644
--- a/services/java/com/android/server/wm/InputFilter.java
+++ b/services/java/com/android/server/input/InputFilter.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.server.wm;
+package com.android.server.input;
+
+import com.android.server.wm.WindowManagerService;
 
 import android.os.Handler;
 import android.os.Looper;
@@ -33,7 +35,7 @@
  * system's behavior changes as follows:
  * <ul>
  * <li>Input events are first delivered to the {@link WindowManagerPolicy}
- * interception methods before queueing as usual.  This critical step takes care of managing
+ * interception methods before queuing as usual.  This critical step takes care of managing
  * the power state of the device and handling wake keys.</li>
  * <li>Input events are then asynchronously delivered to the input filter's
  * {@link #onInputEvent(InputEvent)} method instead of being enqueued for dispatch to
@@ -79,7 +81,7 @@
  * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} policy flag.  The input filter may
  * sometimes receive events that do not have this flag set.  It should take note of
  * the fact that the policy intends to drop the event, clean up its state, and
- * then send appropriate cancelation events to the dispatcher if needed.
+ * then send appropriate cancellation events to the dispatcher if needed.
  * </p><p>
  * For example, suppose the input filter is processing a gesture and one of the touch events
  * it receives does not have the {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag set.
@@ -89,8 +91,8 @@
  * Corollary: Events that set sent to the dispatcher should usually include the
  * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag.  Otherwise, they will be dropped!
  * </p><p>
- * It may be prudent to disable automatic key repeating for synthetically generated
- * keys by setting the {@link WindowManagerPolicy#FLAG_DISABLE_KEY_REPEAT} policy flag.
+ * It may be prudent to disable automatic key repeating for synthetic key events
+ * by setting the {@link WindowManagerPolicy#FLAG_DISABLE_KEY_REPEAT} policy flag.
  * </p>
  */
 public abstract class InputFilter {
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
new file mode 100644
index 0000000..b8cc65e
--- /dev/null
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -0,0 +1,743 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.input;
+
+import com.android.internal.util.XmlUtils;
+import com.android.server.Watchdog;
+import com.android.server.input.InputFilter.Host;
+import com.android.server.wm.WindowManagerService;
+
+import org.xmlpull.v1.XmlPullParser;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.database.ContentObserver;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
+import android.os.Binder;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.os.Process;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.util.Slog;
+import android.util.Xml;
+import android.view.InputChannel;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.KeyEvent;
+import android.view.PointerIcon;
+import android.view.Surface;
+import android.view.ViewConfiguration;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/*
+ * Wraps the C++ InputManager and provides its callbacks.
+ */
+public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
+    static final String TAG = "InputManager";
+    static final boolean DEBUG = false;
+
+    private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
+
+    // Pointer to native input manager service object.
+    private final int mPtr;
+
+    private final Context mContext;
+    private final Callbacks mCallbacks;
+    private final Handler mHandler;
+
+    private static native int nativeInit(InputManagerService service,
+            Context context, MessageQueue messageQueue);
+    private static native void nativeStart(int ptr);
+    private static native void nativeSetDisplaySize(int ptr, int displayId,
+            int width, int height, int externalWidth, int externalHeight);
+    private static native void nativeSetDisplayOrientation(int ptr, int displayId, int rotation);
+    
+    private static native int nativeGetScanCodeState(int ptr,
+            int deviceId, int sourceMask, int scanCode);
+    private static native int nativeGetKeyCodeState(int ptr,
+            int deviceId, int sourceMask, int keyCode);
+    private static native int nativeGetSwitchState(int ptr,
+            int deviceId, int sourceMask, int sw);
+    private static native boolean nativeHasKeys(int ptr,
+            int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists);
+    private static native void nativeRegisterInputChannel(int ptr, InputChannel inputChannel,
+            InputWindowHandle inputWindowHandle, boolean monitor);
+    private static native void nativeUnregisterInputChannel(int ptr, InputChannel inputChannel);
+    private static native void nativeSetInputFilterEnabled(int ptr, boolean enable);
+    private static native int nativeInjectInputEvent(int ptr, InputEvent event,
+            int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
+            int policyFlags);
+    private static native void nativeSetInputWindows(int ptr, InputWindowHandle[] windowHandles);
+    private static native void nativeSetInputDispatchMode(int ptr, boolean enabled, boolean frozen);
+    private static native void nativeSetSystemUiVisibility(int ptr, int visibility);
+    private static native void nativeSetFocusedApplication(int ptr,
+            InputApplicationHandle application);
+    private static native InputDevice nativeGetInputDevice(int ptr, int deviceId);
+    private static native void nativeGetInputConfiguration(int ptr, Configuration configuration);
+    private static native int[] nativeGetInputDeviceIds(int ptr);
+    private static native boolean nativeTransferTouchFocus(int ptr,
+            InputChannel fromChannel, InputChannel toChannel);
+    private static native void nativeSetPointerSpeed(int ptr, int speed);
+    private static native void nativeSetShowTouches(int ptr, boolean enabled);
+    private static native String nativeDump(int ptr);
+    private static native void nativeMonitor(int ptr);
+
+    // Input event injection constants defined in InputDispatcher.h.
+    private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
+    private static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1;
+    private static final int INPUT_EVENT_INJECTION_FAILED = 2;
+    private static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3;
+
+    // Maximum number of milliseconds to wait for input event injection.
+    private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
+
+    // Key states (may be returned by queries about the current state of a
+    // particular key code, scan code or switch).
+    
+    /** The key state is unknown or the requested key itself is not supported. */
+    public static final int KEY_STATE_UNKNOWN = -1;
+
+    /** The key is up. /*/
+    public static final int KEY_STATE_UP = 0;
+
+    /** The key is down. */
+    public static final int KEY_STATE_DOWN = 1;
+
+    /** The key is down but is a virtual key press that is being emulated by the system. */
+    public static final int KEY_STATE_VIRTUAL = 2;
+
+    // State for the currently installed input filter.
+    final Object mInputFilterLock = new Object();
+    InputFilter mInputFilter;
+    InputFilterHost mInputFilterHost;
+
+    public InputManagerService(Context context, Callbacks callbacks) {
+        this.mContext = context;
+        this.mCallbacks = callbacks;
+        this.mHandler = new Handler();
+
+        Slog.i(TAG, "Initializing input manager");
+        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
+    }
+
+    public void start() {
+        Slog.i(TAG, "Starting input manager");
+        nativeStart(mPtr);
+
+        // Add ourself to the Watchdog monitors.
+        Watchdog.getInstance().addMonitor(this);
+
+        registerPointerSpeedSettingObserver();
+        registerShowTouchesSettingObserver();
+
+        updatePointerSpeedFromSettings();
+        updateShowTouchesFromSettings();
+    }
+    
+    public void setDisplaySize(int displayId, int width, int height,
+            int externalWidth, int externalHeight) {
+        if (width <= 0 || height <= 0 || externalWidth <= 0 || externalHeight <= 0) {
+            throw new IllegalArgumentException("Invalid display id or dimensions.");
+        }
+        
+        if (DEBUG) {
+            Slog.d(TAG, "Setting display #" + displayId + " size to " + width + "x" + height
+                    + " external size " + externalWidth + "x" + externalHeight);
+        }
+        nativeSetDisplaySize(mPtr, displayId, width, height, externalWidth, externalHeight);
+    }
+    
+    public void setDisplayOrientation(int displayId, int rotation) {
+        if (rotation < Surface.ROTATION_0 || rotation > Surface.ROTATION_270) {
+            throw new IllegalArgumentException("Invalid rotation.");
+        }
+        
+        if (DEBUG) {
+            Slog.d(TAG, "Setting display #" + displayId + " orientation to " + rotation);
+        }
+        nativeSetDisplayOrientation(mPtr, displayId, rotation);
+    }
+    
+    public void getInputConfiguration(Configuration config) {
+        if (config == null) {
+            throw new IllegalArgumentException("config must not be null.");
+        }
+        
+        nativeGetInputConfiguration(mPtr, config);
+    }
+
+    /**
+     * Gets the current state of a key or button by key code.
+     * @param deviceId The input device id, or -1 to consult all devices.
+     * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
+     * consider all input sources.  An input device is consulted if at least one of its
+     * non-class input source bits matches the specified source mask.
+     * @param keyCode The key code to check.
+     * @return The key state.
+     */
+    public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) {
+        return nativeGetKeyCodeState(mPtr, deviceId, sourceMask, keyCode);
+    }
+    
+    /**
+     * Gets the current state of a key or button by scan code.
+     * @param deviceId The input device id, or -1 to consult all devices.
+     * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
+     * consider all input sources.  An input device is consulted if at least one of its
+     * non-class input source bits matches the specified source mask.
+     * @param scanCode The scan code to check.
+     * @return The key state.
+     */
+    public int getScanCodeState(int deviceId, int sourceMask, int scanCode) {
+        return nativeGetScanCodeState(mPtr, deviceId, sourceMask, scanCode);
+    }
+    
+    /**
+     * Gets the current state of a switch by switch code.
+     * @param deviceId The input device id, or -1 to consult all devices.
+     * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
+     * consider all input sources.  An input device is consulted if at least one of its
+     * non-class input source bits matches the specified source mask.
+     * @param switchCode The switch code to check.
+     * @return The switch state.
+     */
+    public int getSwitchState(int deviceId, int sourceMask, int switchCode) {
+        return nativeGetSwitchState(mPtr, deviceId, sourceMask, switchCode);
+    }
+
+    /**
+     * Determines whether the specified key codes are supported by a particular device.
+     * @param deviceId The input device id, or -1 to consult all devices.
+     * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
+     * consider all input sources.  An input device is consulted if at least one of its
+     * non-class input source bits matches the specified source mask.
+     * @param keyCodes The array of key codes to check.
+     * @param keyExists An array at least as large as keyCodes whose entries will be set
+     * to true or false based on the presence or absence of support for the corresponding
+     * key codes.
+     * @return True if the lookup was successful, false otherwise.
+     */
+    @Override
+    public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) {
+        if (keyCodes == null) {
+            throw new IllegalArgumentException("keyCodes must not be null.");
+        }
+        if (keyExists == null || keyExists.length < keyCodes.length) {
+            throw new IllegalArgumentException("keyExists must not be null and must be at "
+                    + "least as large as keyCodes.");
+        }
+        
+        return nativeHasKeys(mPtr, deviceId, sourceMask, keyCodes, keyExists);
+    }
+    
+    /**
+     * Creates an input channel that will receive all input from the input dispatcher.
+     * @param inputChannelName The input channel name.
+     * @return The input channel.
+     */
+    public InputChannel monitorInput(String inputChannelName) {
+        if (inputChannelName == null) {
+            throw new IllegalArgumentException("inputChannelName must not be null.");
+        }
+        
+        InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
+        nativeRegisterInputChannel(mPtr, inputChannels[0], null, true);
+        inputChannels[0].dispose(); // don't need to retain the Java object reference
+        return inputChannels[1];
+    }
+
+    /**
+     * Registers an input channel so that it can be used as an input event target.
+     * @param inputChannel The input channel to register.
+     * @param inputWindowHandle The handle of the input window associated with the
+     * input channel, or null if none.
+     */
+    public void registerInputChannel(InputChannel inputChannel,
+            InputWindowHandle inputWindowHandle) {
+        if (inputChannel == null) {
+            throw new IllegalArgumentException("inputChannel must not be null.");
+        }
+        
+        nativeRegisterInputChannel(mPtr, inputChannel, inputWindowHandle, false);
+    }
+    
+    /**
+     * Unregisters an input channel.
+     * @param inputChannel The input channel to unregister.
+     */
+    public void unregisterInputChannel(InputChannel inputChannel) {
+        if (inputChannel == null) {
+            throw new IllegalArgumentException("inputChannel must not be null.");
+        }
+        
+        nativeUnregisterInputChannel(mPtr, inputChannel);
+    }
+
+    /**
+     * Sets an input filter that will receive all input events before they are dispatched.
+     * The input filter may then reinterpret input events or inject new ones.
+     *
+     * To ensure consistency, the input dispatcher automatically drops all events
+     * in progress whenever an input filter is installed or uninstalled.  After an input
+     * filter is uninstalled, it can no longer send input events unless it is reinstalled.
+     * Any events it attempts to send after it has been uninstalled will be dropped.
+     *
+     * @param filter The input filter, or null to remove the current filter.
+     */
+    public void setInputFilter(InputFilter filter) {
+        synchronized (mInputFilterLock) {
+            final InputFilter oldFilter = mInputFilter;
+            if (oldFilter == filter) {
+                return; // nothing to do
+            }
+
+            if (oldFilter != null) {
+                mInputFilter = null;
+                mInputFilterHost.disconnectLocked();
+                mInputFilterHost = null;
+                oldFilter.uninstall();
+            }
+
+            if (filter != null) {
+                mInputFilter = filter;
+                mInputFilterHost = new InputFilterHost();
+                filter.install(mInputFilterHost);
+            }
+
+            nativeSetInputFilterEnabled(mPtr, filter != null);
+        }
+    }
+
+    @Override
+    public boolean injectInputEvent(InputEvent event, int mode) {
+        if (event == null) {
+            throw new IllegalArgumentException("event must not be null");
+        }
+        if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC
+                && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
+                && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
+            throw new IllegalArgumentException("mode is invalid");
+        }
+
+        final int pid = Binder.getCallingPid();
+        final int uid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        final int result;
+        try {
+            result = nativeInjectInputEvent(mPtr, event, pid, uid, mode,
+                    INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+        switch (result) {
+            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
+                Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
+                throw new SecurityException(
+                        "Injecting to another application requires INJECT_EVENTS permission");
+            case INPUT_EVENT_INJECTION_SUCCEEDED:
+                return true;
+            case INPUT_EVENT_INJECTION_TIMED_OUT:
+                Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
+                return false;
+            case INPUT_EVENT_INJECTION_FAILED:
+            default:
+                Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
+                return false;
+        }
+    }
+
+    /**
+     * Gets information about the input device with the specified id.
+     * @param id The device id.
+     * @return The input device or null if not found.
+     */
+    @Override
+    public InputDevice getInputDevice(int deviceId) {
+        return nativeGetInputDevice(mPtr, deviceId);
+    }
+    
+    /**
+     * Gets the ids of all input devices in the system.
+     * @return The input device ids.
+     */
+    @Override
+    public int[] getInputDeviceIds() {
+        return nativeGetInputDeviceIds(mPtr);
+    }
+    
+    public void setInputWindows(InputWindowHandle[] windowHandles) {
+        nativeSetInputWindows(mPtr, windowHandles);
+    }
+    
+    public void setFocusedApplication(InputApplicationHandle application) {
+        nativeSetFocusedApplication(mPtr, application);
+    }
+    
+    public void setInputDispatchMode(boolean enabled, boolean frozen) {
+        nativeSetInputDispatchMode(mPtr, enabled, frozen);
+    }
+
+    public void setSystemUiVisibility(int visibility) {
+        nativeSetSystemUiVisibility(mPtr, visibility);
+    }
+
+    /**
+     * Atomically transfers touch focus from one window to another as identified by
+     * their input channels.  It is possible for multiple windows to have
+     * touch focus if they support split touch dispatch
+     * {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this
+     * method only transfers touch focus of the specified window without affecting
+     * other windows that may also have touch focus at the same time.
+     * @param fromChannel The channel of a window that currently has touch focus.
+     * @param toChannel The channel of the window that should receive touch focus in
+     * place of the first.
+     * @return True if the transfer was successful.  False if the window with the
+     * specified channel did not actually have touch focus at the time of the request.
+     */
+    public boolean transferTouchFocus(InputChannel fromChannel, InputChannel toChannel) {
+        if (fromChannel == null) {
+            throw new IllegalArgumentException("fromChannel must not be null.");
+        }
+        if (toChannel == null) {
+            throw new IllegalArgumentException("toChannel must not be null.");
+        }
+        return nativeTransferTouchFocus(mPtr, fromChannel, toChannel);
+    }
+
+    /**
+     * Set the pointer speed.
+     * @param speed The pointer speed as a value between -7 (slowest) and 7 (fastest)
+     * where 0 is the default speed.
+     */
+    @Override
+    public void tryPointerSpeed(int speed) {
+        if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,
+                "tryPointerSpeed()")) {
+            throw new SecurityException("Requires SET_POINTER_SPEED permission");
+        }
+
+        setPointerSpeedUnchecked(speed);
+    }
+
+    public void updatePointerSpeedFromSettings() {
+        int speed = getPointerSpeedSetting();
+        setPointerSpeedUnchecked(speed);
+    }
+
+    private void setPointerSpeedUnchecked(int speed) {
+        speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED),
+                InputManager.MAX_POINTER_SPEED);
+        nativeSetPointerSpeed(mPtr, speed);
+    }
+
+    private void registerPointerSpeedSettingObserver() {
+        mContext.getContentResolver().registerContentObserver(
+                Settings.System.getUriFor(Settings.System.POINTER_SPEED), true,
+                new ContentObserver(mHandler) {
+                    @Override
+                    public void onChange(boolean selfChange) {
+                        updatePointerSpeedFromSettings();
+                    }
+                });
+    }
+
+    private int getPointerSpeedSetting() {
+        int speed = InputManager.DEFAULT_POINTER_SPEED;
+        try {
+            speed = Settings.System.getInt(mContext.getContentResolver(),
+                    Settings.System.POINTER_SPEED);
+        } catch (SettingNotFoundException snfe) {
+        }
+        return speed;
+    }
+
+    public void updateShowTouchesFromSettings() {
+        int setting = getShowTouchesSetting(0);
+        nativeSetShowTouches(mPtr, setting != 0);
+    }
+
+    private void registerShowTouchesSettingObserver() {
+        mContext.getContentResolver().registerContentObserver(
+                Settings.System.getUriFor(Settings.System.SHOW_TOUCHES), true,
+                new ContentObserver(mHandler) {
+                    @Override
+                    public void onChange(boolean selfChange) {
+                        updateShowTouchesFromSettings();
+                    }
+                });
+    }
+
+    private int getShowTouchesSetting(int defaultValue) {
+        int result = defaultValue;
+        try {
+            result = Settings.System.getInt(mContext.getContentResolver(),
+                    Settings.System.SHOW_TOUCHES);
+        } catch (SettingNotFoundException snfe) {
+        }
+        return result;
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump InputManager from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid());
+            return;
+        }
+
+        pw.println("INPUT MANAGER (dumpsys input)\n");
+        String dumpStr = nativeDump(mPtr);
+        if (dumpStr != null) {
+            pw.println(dumpStr);
+        }
+    }
+
+    private boolean checkCallingPermission(String permission, String func) {
+        // Quick check: if the calling permission is me, it's all okay.
+        if (Binder.getCallingPid() == Process.myPid()) {
+            return true;
+        }
+
+        if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
+            return true;
+        }
+        String msg = "Permission Denial: " + func + " from pid="
+                + Binder.getCallingPid()
+                + ", uid=" + Binder.getCallingUid()
+                + " requires " + permission;
+        Slog.w(TAG, msg);
+        return false;
+    }
+
+    // Called by the heartbeat to ensure locks are not held indefinitely (for deadlock detection).
+    public void monitor() {
+        synchronized (mInputFilterLock) { }
+        nativeMonitor(mPtr);
+    }
+
+    // Native callback.
+    private void notifyConfigurationChanged(long whenNanos) {
+        mCallbacks.notifyConfigurationChanged();
+    }
+
+    // Native callback.
+    private void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
+        mCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
+    }
+
+    // Native callback.
+    private void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
+        mCallbacks.notifyInputChannelBroken(inputWindowHandle);
+    }
+
+    // Native callback.
+    private long notifyANR(InputApplicationHandle inputApplicationHandle,
+            InputWindowHandle inputWindowHandle) {
+        return mCallbacks.notifyANR(inputApplicationHandle, inputWindowHandle);
+    }
+
+    // Native callback.
+    final boolean filterInputEvent(InputEvent event, int policyFlags) {
+        synchronized (mInputFilterLock) {
+            if (mInputFilter != null) {
+                mInputFilter.filterInputEvent(event, policyFlags);
+                return false;
+            }
+        }
+        event.recycle();
+        return true;
+    }
+
+    // Native callback.
+    private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
+        return mCallbacks.interceptKeyBeforeQueueing(
+                event, policyFlags, isScreenOn);
+    }
+
+    // Native callback.
+    private int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
+        return mCallbacks.interceptMotionBeforeQueueingWhenScreenOff(policyFlags);
+    }
+
+    // Native callback.
+    private long interceptKeyBeforeDispatching(InputWindowHandle focus,
+            KeyEvent event, int policyFlags) {
+        return mCallbacks.interceptKeyBeforeDispatching(focus, event, policyFlags);
+    }
+
+    // Native callback.
+    private KeyEvent dispatchUnhandledKey(InputWindowHandle focus,
+            KeyEvent event, int policyFlags) {
+        return mCallbacks.dispatchUnhandledKey(focus, event, policyFlags);
+    }
+
+    // Native callback.
+    private boolean checkInjectEventsPermission(int injectorPid, int injectorUid) {
+        return mContext.checkPermission(android.Manifest.permission.INJECT_EVENTS,
+                injectorPid, injectorUid) == PackageManager.PERMISSION_GRANTED;
+    }
+
+    // Native callback.
+    private int getVirtualKeyQuietTimeMillis() {
+        return mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
+    }
+
+    // Native callback.
+    private String[] getExcludedDeviceNames() {
+        ArrayList<String> names = new ArrayList<String>();
+
+        // Read partner-provided list of excluded input devices
+        XmlPullParser parser = null;
+        // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
+        File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH);
+        FileReader confreader = null;
+        try {
+            confreader = new FileReader(confFile);
+            parser = Xml.newPullParser();
+            parser.setInput(confreader);
+            XmlUtils.beginDocument(parser, "devices");
+
+            while (true) {
+                XmlUtils.nextElement(parser);
+                if (!"device".equals(parser.getName())) {
+                    break;
+                }
+                String name = parser.getAttributeValue(null, "name");
+                if (name != null) {
+                    names.add(name);
+                }
+            }
+        } catch (FileNotFoundException e) {
+            // It's ok if the file does not exist.
+        } catch (Exception e) {
+            Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
+        } finally {
+            try { if (confreader != null) confreader.close(); } catch (IOException e) { }
+        }
+
+        return names.toArray(new String[names.size()]);
+    }
+
+    // Native callback.
+    private int getKeyRepeatTimeout() {
+        return ViewConfiguration.getKeyRepeatTimeout();
+    }
+
+    // Native callback.
+    private int getKeyRepeatDelay() {
+        return ViewConfiguration.getKeyRepeatDelay();
+    }
+
+    // Native callback.
+    private int getHoverTapTimeout() {
+        return ViewConfiguration.getHoverTapTimeout();
+    }
+
+    // Native callback.
+    private int getHoverTapSlop() {
+        return ViewConfiguration.getHoverTapSlop();
+    }
+
+    // Native callback.
+    private int getDoubleTapTimeout() {
+        return ViewConfiguration.getDoubleTapTimeout();
+    }
+
+    // Native callback.
+    private int getLongPressTimeout() {
+        return ViewConfiguration.getLongPressTimeout();
+    }
+
+    // Native callback.
+    private int getPointerLayer() {
+        return mCallbacks.getPointerLayer();
+    }
+
+    // Native callback.
+    private PointerIcon getPointerIcon() {
+        return PointerIcon.getDefaultIcon(mContext);
+    }
+
+    /**
+     * Callback interface implemented by the Window Manager.
+     */
+    public interface Callbacks {
+        public void notifyConfigurationChanged();
+
+        public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen);
+
+        public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle);
+
+        public long notifyANR(InputApplicationHandle inputApplicationHandle,
+                InputWindowHandle inputWindowHandle);
+
+        public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
+
+        public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags);
+
+        public long interceptKeyBeforeDispatching(InputWindowHandle focus,
+                KeyEvent event, int policyFlags);
+
+        public KeyEvent dispatchUnhandledKey(InputWindowHandle focus,
+                KeyEvent event, int policyFlags);
+
+        public int getPointerLayer();
+    }
+
+    /**
+     * Hosting interface for input filters to call back into the input manager.
+     */
+    private final class InputFilterHost implements InputFilter.Host {
+        private boolean mDisconnected;
+
+        public void disconnectLocked() {
+            mDisconnected = true;
+        }
+
+        public void sendInputEvent(InputEvent event, int policyFlags) {
+            if (event == null) {
+                throw new IllegalArgumentException("event must not be null");
+            }
+
+            synchronized (mInputFilterLock) {
+                if (!mDisconnected) {
+                    nativeInjectInputEvent(mPtr, event, 0, 0,
+                            InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0,
+                            policyFlags | WindowManagerPolicy.FLAG_FILTERED);
+                }
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/wm/InputWindowHandle.java b/services/java/com/android/server/input/InputWindowHandle.java
similarity index 93%
rename from services/java/com/android/server/wm/InputWindowHandle.java
rename to services/java/com/android/server/input/InputWindowHandle.java
index 264877c..03d66af 100644
--- a/services/java/com/android/server/wm/InputWindowHandle.java
+++ b/services/java/com/android/server/input/InputWindowHandle.java
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.server.wm;
+package com.android.server.input;
 
 import android.graphics.Region;
 import android.view.InputChannel;
-import android.view.WindowManagerPolicy;
 
 /**
  * Functions as a handle for a window that can receive input.
@@ -35,7 +34,7 @@
     public final InputApplicationHandle inputApplicationHandle;
 
     // The window manager's window state.
-    public final WindowManagerPolicy.WindowState windowState;
+    public final Object windowState;
 
     // The input channel associated with the window.
     public InputChannel inputChannel;
@@ -91,7 +90,7 @@
     private native void nativeDispose();
 
     public InputWindowHandle(InputApplicationHandle inputApplicationHandle,
-            WindowManagerPolicy.WindowState windowState) {
+            Object windowState) {
         this.inputApplicationHandle = inputApplicationHandle;
         this.windowState = windowState;
     }
diff --git a/services/java/com/android/server/net/NetworkIdentitySet.java b/services/java/com/android/server/net/NetworkIdentitySet.java
index af03fb3..397f9f4 100644
--- a/services/java/com/android/server/net/NetworkIdentitySet.java
+++ b/services/java/com/android/server/net/NetworkIdentitySet.java
@@ -21,7 +21,6 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.net.ProtocolException;
 import java.util.HashSet;
 
 /**
@@ -33,48 +32,46 @@
 public class NetworkIdentitySet extends HashSet<NetworkIdentity> {
     private static final int VERSION_INIT = 1;
     private static final int VERSION_ADD_ROAMING = 2;
+    private static final int VERSION_ADD_NETWORK_ID = 3;
 
     public NetworkIdentitySet() {
     }
 
     public NetworkIdentitySet(DataInputStream in) throws IOException {
         final int version = in.readInt();
-        switch (version) {
-            case VERSION_INIT: {
-                final int size = in.readInt();
-                for (int i = 0; i < size; i++) {
-                    final int ignoredVersion = in.readInt();
-                    final int type = in.readInt();
-                    final int subType = in.readInt();
-                    final String subscriberId = readOptionalString(in);
-                    add(new NetworkIdentity(type, subType, subscriberId, false));
-                }
-                break;
+        final int size = in.readInt();
+        for (int i = 0; i < size; i++) {
+            if (version <= VERSION_INIT) {
+                final int ignored = in.readInt();
             }
-            case VERSION_ADD_ROAMING: {
-                final int size = in.readInt();
-                for (int i = 0; i < size; i++) {
-                    final int type = in.readInt();
-                    final int subType = in.readInt();
-                    final String subscriberId = readOptionalString(in);
-                    final boolean roaming = in.readBoolean();
-                    add(new NetworkIdentity(type, subType, subscriberId, roaming));
-                }
-                break;
+            final int type = in.readInt();
+            final int subType = in.readInt();
+            final String subscriberId = readOptionalString(in);
+            final String networkId;
+            if (version >= VERSION_ADD_NETWORK_ID) {
+                networkId = readOptionalString(in);
+            } else {
+                networkId = null;
             }
-            default: {
-                throw new ProtocolException("unexpected version: " + version);
+            final boolean roaming;
+            if (version >= VERSION_ADD_ROAMING) {
+                roaming = in.readBoolean();
+            } else {
+                roaming = false;
             }
+
+            add(new NetworkIdentity(type, subType, subscriberId, networkId, false));
         }
     }
 
     public void writeToStream(DataOutputStream out) throws IOException {
-        out.writeInt(VERSION_ADD_ROAMING);
+        out.writeInt(VERSION_ADD_NETWORK_ID);
         out.writeInt(size());
         for (NetworkIdentity ident : this) {
             out.writeInt(ident.getType());
             out.writeInt(ident.getSubType());
             writeOptionalString(out, ident.getSubscriberId());
+            writeOptionalString(out, ident.getNetworkId());
             out.writeBoolean(ident.getRoaming());
         }
     }
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 1f1e720..b0657a6 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -48,6 +48,7 @@
 import static android.net.NetworkTemplate.MATCH_WIFI;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.telephony.TelephonyManager.SIM_STATE_READY;
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
@@ -113,6 +114,7 @@
 import com.android.internal.R;
 import com.android.internal.os.AtomicFile;
 import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Objects;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
@@ -160,6 +162,8 @@
     private static final int VERSION_ADDED_TIMEZONE = 6;
     private static final int VERSION_ADDED_INFERRED = 7;
     private static final int VERSION_SWITCH_APP_ID = 8;
+    private static final int VERSION_ADDED_NETWORK_ID = 9;
+    private static final int VERSION_LATEST = VERSION_ADDED_NETWORK_ID;
 
     // @VisibleForTesting
     public static final int TYPE_WARNING = 0x1;
@@ -175,6 +179,7 @@
     private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
     private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
     private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
+    private static final String ATTR_NETWORK_ID = "networkId";
     private static final String ATTR_CYCLE_DAY = "cycleDay";
     private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
     private static final String ATTR_WARNING_BYTES = "warningBytes";
@@ -491,6 +496,7 @@
         for (NetworkPolicy policy : mNetworkPolicy.values()) {
             // ignore policies that aren't relevant to user
             if (!isTemplateRelevant(policy.template)) continue;
+            if (!policy.hasCycle()) continue;
 
             final long start = computeLastCycleBoundary(currentTime, policy);
             final long end = currentTime;
@@ -528,21 +534,24 @@
 
     /**
      * Test if given {@link NetworkTemplate} is relevant to user based on
-     * current device state, such as when {@link #getActiveSubscriberId()}
-     * matches. This is regardless of data connection status.
+     * current device state, such as when
+     * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
+     * data connection status.
      */
     private boolean isTemplateRelevant(NetworkTemplate template) {
+        final TelephonyManager tele = TelephonyManager.from(mContext);
+
         switch (template.getMatchRule()) {
             case MATCH_MOBILE_3G_LOWER:
             case MATCH_MOBILE_4G:
             case MATCH_MOBILE_ALL:
-                // mobile templates aren't relevant in airplane mode
-                if (isAirplaneModeOn(mContext)) {
+                // mobile templates are relevant when SIM is ready and
+                // subscriberId matches.
+                if (tele.getSimState() == SIM_STATE_READY) {
+                    return Objects.equal(tele.getSubscriberId(), template.getSubscriberId());
+                } else {
                     return false;
                 }
-
-                // mobile templates are relevant when subscriberid is active
-                return Objects.equal(getActiveSubscriberId(), template.getSubscriberId());
         }
         return true;
     }
@@ -761,7 +770,7 @@
         final long currentTime = currentTimeMillis();
         for (NetworkPolicy policy : mNetworkPolicy.values()) {
             // shortcut when policy has no limit
-            if (policy.limitBytes == LIMIT_DISABLED) {
+            if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
                 setNetworkTemplateEnabled(policy.template, true);
                 continue;
             }
@@ -784,13 +793,16 @@
      * for the given {@link NetworkTemplate}.
      */
     private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
+        final TelephonyManager tele = TelephonyManager.from(mContext);
+
         switch (template.getMatchRule()) {
             case MATCH_MOBILE_3G_LOWER:
             case MATCH_MOBILE_4G:
             case MATCH_MOBILE_ALL:
                 // TODO: offer more granular control over radio states once
                 // 4965893 is available.
-                if (Objects.equal(getActiveSubscriberId(), template.getSubscriberId())) {
+                if (tele.getSimState() == SIM_STATE_READY
+                        && Objects.equal(tele.getSubscriberId(), template.getSubscriberId())) {
                     setPolicyDataEnable(TYPE_MOBILE, enabled);
                     setPolicyDataEnable(TYPE_WIMAX, enabled);
                 }
@@ -863,9 +875,15 @@
         for (NetworkPolicy policy : mNetworkRules.keySet()) {
             final String[] ifaces = mNetworkRules.get(policy);
 
-            final long start = computeLastCycleBoundary(currentTime, policy);
-            final long end = currentTime;
-            final long totalBytes = getTotalBytes(policy.template, start, end);
+            final long start;
+            final long totalBytes;
+            if (policy.hasCycle()) {
+                start = computeLastCycleBoundary(currentTime, policy);
+                totalBytes = getTotalBytes(policy.template, start, currentTime);
+            } else {
+                start = Long.MAX_VALUE;
+                totalBytes = 0;
+            }
 
             if (LOGD) {
                 Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces "
@@ -923,9 +941,14 @@
         if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()");
         if (mSuppressDefaultPolicy) return;
 
-        final String subscriberId = getActiveSubscriberId();
+        final TelephonyManager tele = TelephonyManager.from(mContext);
+
+        // avoid creating policy when SIM isn't ready
+        if (tele.getSimState() != SIM_STATE_READY) return;
+
+        final String subscriberId = tele.getSubscriberId();
         final NetworkIdentity probeIdent = new NetworkIdentity(
-                TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, false);
+                TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false);
 
         // examine to see if any policy is defined for active mobile
         boolean mobileDefined = false;
@@ -986,6 +1009,12 @@
                     } else if (TAG_NETWORK_POLICY.equals(tag)) {
                         final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
                         final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
+                        final String networkId;
+                        if (version >= VERSION_ADDED_NETWORK_ID) {
+                            networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
+                        } else {
+                            networkId = null;
+                        }
                         final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
                         final String cycleTimezone;
                         if (version >= VERSION_ADDED_TIMEZONE) {
@@ -1031,12 +1060,12 @@
                         }
 
                         final NetworkTemplate template = new NetworkTemplate(
-                                networkTemplate, subscriberId);
+                                networkTemplate, subscriberId, networkId);
                         mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
                                 cycleTimezone, warningBytes, limitBytes, lastWarningSnooze,
                                 lastLimitSnooze, metered, inferred));
 
-                    } else if (TAG_UID_POLICY.equals(tag)) {
+                    } else if (TAG_UID_POLICY.equals(tag) && version < VERSION_SWITCH_APP_ID) {
                         final int uid = readIntAttribute(in, ATTR_UID);
                         final int policy = readIntAttribute(in, ATTR_POLICY);
 
@@ -1046,7 +1075,7 @@
                         } else {
                             Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
                         }
-                    } else if (TAG_APP_POLICY.equals(tag)) {
+                    } else if (TAG_APP_POLICY.equals(tag) && version >= VERSION_SWITCH_APP_ID) {
                         final int appId = readIntAttribute(in, ATTR_APP_ID);
                         final int policy = readIntAttribute(in, ATTR_POLICY);
 
@@ -1099,7 +1128,7 @@
             out.startDocument(null, true);
 
             out.startTag(null, TAG_POLICY_LIST);
-            writeIntAttribute(out, ATTR_VERSION, VERSION_SWITCH_APP_ID);
+            writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
             writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
 
             // write all known network policies
@@ -1112,6 +1141,10 @@
                 if (subscriberId != null) {
                     out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
                 }
+                final String networkId = template.getNetworkId();
+                if (networkId != null) {
+                    out.attribute(null, ATTR_NETWORK_ID, networkId);
+                }
                 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
                 out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone);
                 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
@@ -1318,7 +1351,7 @@
             policy = findPolicyForNetworkLocked(ident);
         }
 
-        if (policy == null) {
+        if (policy == null || !policy.hasCycle()) {
             // missing policy means we can't derive useful quota info
             return null;
         }
@@ -1340,9 +1373,11 @@
     }
 
     @Override
-    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         mContext.enforceCallingOrSelfPermission(DUMP, TAG);
 
+        final IndentingPrintWriter fout = new IndentingPrintWriter(writer, "  ");
+
         final HashSet<String> argSet = new HashSet<String>();
         for (String arg : args) {
             argSet.add(arg);
@@ -1365,31 +1400,36 @@
 
             fout.print("Restrict background: "); fout.println(mRestrictBackground);
             fout.println("Network policies:");
+            fout.increaseIndent();
             for (NetworkPolicy policy : mNetworkPolicy.values()) {
-                fout.print("  "); fout.println(policy.toString());
+                fout.println(policy.toString());
             }
+            fout.decreaseIndent();
 
             fout.println("Policy for apps:");
+            fout.increaseIndent();
             int size = mAppPolicy.size();
             for (int i = 0; i < size; i++) {
                 final int appId = mAppPolicy.keyAt(i);
                 final int policy = mAppPolicy.valueAt(i);
-                fout.print("  appId=");
+                fout.print("appId=");
                 fout.print(appId);
                 fout.print(" policy=");
                 dumpPolicy(fout, policy);
                 fout.println();
             }
+            fout.decreaseIndent();
 
             final SparseBooleanArray knownUids = new SparseBooleanArray();
             collectKeys(mUidForeground, knownUids);
             collectKeys(mUidRules, knownUids);
 
             fout.println("Status for known UIDs:");
+            fout.increaseIndent();
             size = knownUids.size();
             for (int i = 0; i < size; i++) {
                 final int uid = knownUids.keyAt(i);
-                fout.print("  UID=");
+                fout.print("UID=");
                 fout.print(uid);
 
                 fout.print(" foreground=");
@@ -1410,6 +1450,7 @@
 
                 fout.println();
             }
+            fout.decreaseIndent();
         }
     }
 
@@ -1697,12 +1738,6 @@
         }
     }
 
-    private String getActiveSubscriberId() {
-        final TelephonyManager telephony = (TelephonyManager) mContext.getSystemService(
-                Context.TELEPHONY_SERVICE);
-        return telephony.getSubscriberId();
-    }
-
     private long getTotalBytes(NetworkTemplate template, long start, long end) {
         try {
             return mNetworkStats.getSummaryForNetwork(template, start, end).getTotalBytes();
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 8796afc..b847673 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -34,7 +34,7 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.NetworkTemplate.buildTemplateWifi;
+import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.provider.Settings.Secure.NETSTATS_DEV_BUCKET_DURATION;
 import static android.provider.Settings.Secure.NETSTATS_DEV_DELETE_AGE;
@@ -836,7 +836,7 @@
                 trustedTime);
 
         // collect wifi sample
-        template = buildTemplateWifi();
+        template = buildTemplateWifiWildcard();
         devTotal = mDevRecorder.getTotalSinceBootLocked(template);
         xtTotal = new NetworkStats.Entry();
         uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 4bea5e4..1bd15f6 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -60,6 +60,7 @@
 import java.util.List;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Scanner;
 
 /**
  * UsbDeviceManager manages USB state in device mode.
@@ -81,6 +82,8 @@
             "/sys/class/android_usb/android0/f_mass_storage/lun/file";
     private static final String RNDIS_ETH_ADDR_PATH =
             "/sys/class/android_usb/android0/f_rndis/ethaddr";
+    private static final String AUDIO_SOURCE_PCM_PATH =
+            "/sys/class/android_usb/android0/f_audio_source/pcm";
 
     private static final int MSG_UPDATE_STATE = 0;
     private static final int MSG_ENABLE_ADB = 1;
@@ -105,6 +108,7 @@
     private final boolean mHasUsbAccessory;
     private boolean mUseUsbNotification;
     private boolean mAdbEnabled;
+    private boolean mAudioSourceEnabled;
     private Map<String, List<Pair<String, String>>> mOemModeMap;
 
     private class AdbSettingsObserver extends ContentObserver {
@@ -291,6 +295,8 @@
                 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
                 updateState(state);
                 mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB);
+                mAudioSourceEnabled = containsFunction(mCurrentFunctions,
+                        UsbManager.USB_FUNCTION_AUDIO_SOURCE);
 
                 // Upgrade step for previous versions that used persist.service.adb.enable
                 String value = SystemProperties.get("persist.service.adb.enable", "");
@@ -504,6 +510,28 @@
             mContext.sendStickyBroadcast(intent);
         }
 
+        private void updateAudioSourceFunction(boolean enabled) {
+            // send a sticky broadcast containing current USB state
+            Intent intent = new Intent(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
+            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+            intent.putExtra("state", (enabled ? 1 : 0));
+            if (enabled) {
+                try {
+                    Scanner scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH));
+                    int card = scanner.nextInt();
+                    int device = scanner.nextInt();
+                    intent.putExtra("card", card);
+                    intent.putExtra("device", device);
+                } catch (FileNotFoundException e) {
+                    Slog.e(TAG, "could not open audio source PCM file", e);
+                }
+            }
+
+            mContext.sendStickyBroadcast(intent);
+            mAudioSourceEnabled = enabled;
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -523,6 +551,11 @@
                     }
                     if (mBootCompleted) {
                         updateUsbState();
+                        boolean audioSourceEnabled = containsFunction(mCurrentFunctions,
+                                UsbManager.USB_FUNCTION_AUDIO_SOURCE);
+                        if (audioSourceEnabled != mAudioSourceEnabled) {
+                            updateAudioSourceFunction(audioSourceEnabled);
+                        }
                     }
                     break;
                 case MSG_ENABLE_ADB:
@@ -543,6 +576,7 @@
                     if (mCurrentAccessory != null) {
                         mSettingsManager.accessoryAttached(mCurrentAccessory);
                     }
+                    updateAudioSourceFunction(mAudioSourceEnabled);
                     break;
             }
         }
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index e3d46d8..1f8348d 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 
+import com.android.server.input.InputApplicationHandle;
 import com.android.server.wm.WindowManagerService.H;
 
 import android.content.pm.ActivityInfo;
@@ -285,4 +286,4 @@
         }
         return stringName;
     }
-}
\ No newline at end of file
+}
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index a19035a..b2cf3e0c 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import com.android.server.input.InputApplicationHandle;
+import com.android.server.input.InputWindowHandle;
 import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
 import com.android.server.wm.WindowManagerService.H;
 
diff --git a/services/java/com/android/server/wm/FakeWindowImpl.java b/services/java/com/android/server/wm/FakeWindowImpl.java
index 121ce18..2527f46 100644
--- a/services/java/com/android/server/wm/FakeWindowImpl.java
+++ b/services/java/com/android/server/wm/FakeWindowImpl.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wm;
 
+import com.android.server.input.InputApplicationHandle;
+import com.android.server.input.InputWindowHandle;
+
 import android.os.Looper;
 import android.os.Process;
 import android.util.Slog;
diff --git a/services/java/com/android/server/wm/InputManager.java b/services/java/com/android/server/wm/InputManager.java
deleted file mode 100644
index 56c3519..0000000
--- a/services/java/com/android/server/wm/InputManager.java
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import com.android.internal.util.XmlUtils;
-import com.android.server.Watchdog;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.database.ContentObserver;
-import android.os.Environment;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.util.Slog;
-import android.util.Xml;
-import android.view.InputChannel;
-import android.view.InputDevice;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.PointerIcon;
-import android.view.Surface;
-import android.view.ViewConfiguration;
-import android.view.WindowManager;
-import android.view.WindowManagerPolicy;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/*
- * Wraps the C++ InputManager and provides its callbacks.
- */
-public class InputManager implements Watchdog.Monitor {
-    static final String TAG = "InputManager";
-    
-    private static final boolean DEBUG = false;
-
-    private final Callbacks mCallbacks;
-    private final Context mContext;
-    private final WindowManagerService mWindowManagerService;
-
-    private static native void nativeInit(Context context,
-            Callbacks callbacks, MessageQueue messageQueue);
-    private static native void nativeStart();
-    private static native void nativeSetDisplaySize(int displayId, int width, int height,
-            int externalWidth, int externalHeight);
-    private static native void nativeSetDisplayOrientation(int displayId, int rotation);
-    
-    private static native int nativeGetScanCodeState(int deviceId, int sourceMask,
-            int scanCode);
-    private static native int nativeGetKeyCodeState(int deviceId, int sourceMask,
-            int keyCode);
-    private static native int nativeGetSwitchState(int deviceId, int sourceMask,
-            int sw);
-    private static native boolean nativeHasKeys(int deviceId, int sourceMask,
-            int[] keyCodes, boolean[] keyExists);
-    private static native void nativeRegisterInputChannel(InputChannel inputChannel,
-            InputWindowHandle inputWindowHandle, boolean monitor);
-    private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
-    private static native void nativeSetInputFilterEnabled(boolean enable);
-    private static native int nativeInjectInputEvent(InputEvent event,
-            int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
-            int policyFlags);
-    private static native void nativeSetInputWindows(InputWindowHandle[] windowHandles);
-    private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
-    private static native void nativeSetSystemUiVisibility(int visibility);
-    private static native void nativeSetFocusedApplication(InputApplicationHandle application);
-    private static native InputDevice nativeGetInputDevice(int deviceId);
-    private static native void nativeGetInputConfiguration(Configuration configuration);
-    private static native int[] nativeGetInputDeviceIds();
-    private static native boolean nativeTransferTouchFocus(InputChannel fromChannel,
-            InputChannel toChannel);
-    private static native void nativeSetPointerSpeed(int speed);
-    private static native void nativeSetShowTouches(boolean enabled);
-    private static native String nativeDump();
-    private static native void nativeMonitor();
-    
-    // Input event injection constants defined in InputDispatcher.h.
-    static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
-    static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1;
-    static final int INPUT_EVENT_INJECTION_FAILED = 2;
-    static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3;
-    
-    // Input event injection synchronization modes defined in InputDispatcher.h
-    static final int INPUT_EVENT_INJECTION_SYNC_NONE = 0;
-    static final int INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1;
-    static final int INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH = 2;
-    
-    // Key states (may be returned by queries about the current state of a
-    // particular key code, scan code or switch).
-    
-    /** The key state is unknown or the requested key itself is not supported. */
-    public static final int KEY_STATE_UNKNOWN = -1;
-
-    /** The key is up. /*/
-    public static final int KEY_STATE_UP = 0;
-
-    /** The key is down. */
-    public static final int KEY_STATE_DOWN = 1;
-
-    /** The key is down but is a virtual key press that is being emulated by the system. */
-    public static final int KEY_STATE_VIRTUAL = 2;
-
-    // State for the currently installed input filter.
-    final Object mInputFilterLock = new Object();
-    InputFilter mInputFilter;
-    InputFilterHost mInputFilterHost;
-
-    public InputManager(Context context, WindowManagerService windowManagerService) {
-        this.mContext = context;
-        this.mWindowManagerService = windowManagerService;
-        this.mCallbacks = new Callbacks();
-
-        Looper looper = windowManagerService.mH.getLooper();
-
-        Slog.i(TAG, "Initializing input manager");
-        nativeInit(mContext, mCallbacks, looper.getQueue());
-
-        // Add ourself to the Watchdog monitors.
-        Watchdog.getInstance().addMonitor(this);
-    }
-
-    public void start() {
-        Slog.i(TAG, "Starting input manager");
-        nativeStart();
-
-        registerPointerSpeedSettingObserver();
-        registerShowTouchesSettingObserver();
-
-        updatePointerSpeedFromSettings();
-        updateShowTouchesFromSettings();
-    }
-    
-    public void setDisplaySize(int displayId, int width, int height,
-            int externalWidth, int externalHeight) {
-        if (width <= 0 || height <= 0 || externalWidth <= 0 || externalHeight <= 0) {
-            throw new IllegalArgumentException("Invalid display id or dimensions.");
-        }
-        
-        if (DEBUG) {
-            Slog.d(TAG, "Setting display #" + displayId + " size to " + width + "x" + height
-                    + " external size " + externalWidth + "x" + externalHeight);
-        }
-        nativeSetDisplaySize(displayId, width, height, externalWidth, externalHeight);
-    }
-    
-    public void setDisplayOrientation(int displayId, int rotation) {
-        if (rotation < Surface.ROTATION_0 || rotation > Surface.ROTATION_270) {
-            throw new IllegalArgumentException("Invalid rotation.");
-        }
-        
-        if (DEBUG) {
-            Slog.d(TAG, "Setting display #" + displayId + " orientation to " + rotation);
-        }
-        nativeSetDisplayOrientation(displayId, rotation);
-    }
-    
-    public void getInputConfiguration(Configuration config) {
-        if (config == null) {
-            throw new IllegalArgumentException("config must not be null.");
-        }
-        
-        nativeGetInputConfiguration(config);
-    }
-    
-    /**
-     * Gets the current state of a key or button by key code.
-     * @param deviceId The input device id, or -1 to consult all devices.
-     * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
-     * consider all input sources.  An input device is consulted if at least one of its
-     * non-class input source bits matches the specified source mask.
-     * @param keyCode The key code to check.
-     * @return The key state.
-     */
-    public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) {
-        return nativeGetKeyCodeState(deviceId, sourceMask, keyCode);
-    }
-    
-    /**
-     * Gets the current state of a key or button by scan code.
-     * @param deviceId The input device id, or -1 to consult all devices.
-     * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
-     * consider all input sources.  An input device is consulted if at least one of its
-     * non-class input source bits matches the specified source mask.
-     * @param scanCode The scan code to check.
-     * @return The key state.
-     */
-    public int getScanCodeState(int deviceId, int sourceMask, int scanCode) {
-        return nativeGetScanCodeState(deviceId, sourceMask, scanCode);
-    }
-    
-    /**
-     * Gets the current state of a switch by switch code.
-     * @param deviceId The input device id, or -1 to consult all devices.
-     * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
-     * consider all input sources.  An input device is consulted if at least one of its
-     * non-class input source bits matches the specified source mask.
-     * @param switchCode The switch code to check.
-     * @return The switch state.
-     */
-    public int getSwitchState(int deviceId, int sourceMask, int switchCode) {
-        return nativeGetSwitchState(deviceId, sourceMask, switchCode);
-    }
-
-    /**
-     * Determines whether the specified key codes are supported by a particular device.
-     * @param deviceId The input device id, or -1 to consult all devices.
-     * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
-     * consider all input sources.  An input device is consulted if at least one of its
-     * non-class input source bits matches the specified source mask.
-     * @param keyCodes The array of key codes to check.
-     * @param keyExists An array at least as large as keyCodes whose entries will be set
-     * to true or false based on the presence or absence of support for the corresponding
-     * key codes.
-     * @return True if the lookup was successful, false otherwise.
-     */
-    public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) {
-        if (keyCodes == null) {
-            throw new IllegalArgumentException("keyCodes must not be null.");
-        }
-        if (keyExists == null || keyExists.length < keyCodes.length) {
-            throw new IllegalArgumentException("keyExists must not be null and must be at "
-                    + "least as large as keyCodes.");
-        }
-        
-        return nativeHasKeys(deviceId, sourceMask, keyCodes, keyExists);
-    }
-    
-    /**
-     * Creates an input channel that will receive all input from the input dispatcher.
-     * @param inputChannelName The input channel name.
-     * @return The input channel.
-     */
-    public InputChannel monitorInput(String inputChannelName) {
-        if (inputChannelName == null) {
-            throw new IllegalArgumentException("inputChannelName must not be null.");
-        }
-        
-        InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
-        nativeRegisterInputChannel(inputChannels[0], null, true);
-        inputChannels[0].dispose(); // don't need to retain the Java object reference
-        return inputChannels[1];
-    }
-
-    /**
-     * Registers an input channel so that it can be used as an input event target.
-     * @param inputChannel The input channel to register.
-     * @param inputWindowHandle The handle of the input window associated with the
-     * input channel, or null if none.
-     */
-    public void registerInputChannel(InputChannel inputChannel,
-            InputWindowHandle inputWindowHandle) {
-        if (inputChannel == null) {
-            throw new IllegalArgumentException("inputChannel must not be null.");
-        }
-        
-        nativeRegisterInputChannel(inputChannel, inputWindowHandle, false);
-    }
-    
-    /**
-     * Unregisters an input channel.
-     * @param inputChannel The input channel to unregister.
-     */
-    public void unregisterInputChannel(InputChannel inputChannel) {
-        if (inputChannel == null) {
-            throw new IllegalArgumentException("inputChannel must not be null.");
-        }
-        
-        nativeUnregisterInputChannel(inputChannel);
-    }
-
-    /**
-     * Sets an input filter that will receive all input events before they are dispatched.
-     * The input filter may then reinterpret input events or inject new ones.
-     *
-     * To ensure consistency, the input dispatcher automatically drops all events
-     * in progress whenever an input filter is installed or uninstalled.  After an input
-     * filter is uninstalled, it can no longer send input events unless it is reinstalled.
-     * Any events it attempts to send after it has been uninstalled will be dropped.
-     *
-     * @param filter The input filter, or null to remove the current filter.
-     */
-    public void setInputFilter(InputFilter filter) {
-        synchronized (mInputFilterLock) {
-            final InputFilter oldFilter = mInputFilter;
-            if (oldFilter == filter) {
-                return; // nothing to do
-            }
-
-            if (oldFilter != null) {
-                mInputFilter = null;
-                mInputFilterHost.disconnectLocked();
-                mInputFilterHost = null;
-                oldFilter.uninstall();
-            }
-
-            if (filter != null) {
-                mInputFilter = filter;
-                mInputFilterHost = new InputFilterHost();
-                filter.install(mInputFilterHost);
-            }
-
-            nativeSetInputFilterEnabled(filter != null);
-        }
-    }
-
-    /**
-     * Injects an input event into the event system on behalf of an application.
-     * The synchronization mode determines whether the method blocks while waiting for
-     * input injection to proceed.
-     * 
-     * {@link #INPUT_EVENT_INJECTION_SYNC_NONE} never blocks.  Injection is asynchronous and
-     * is assumed always to be successful.
-     * 
-     * {@link #INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT} waits for previous events to be
-     * dispatched so that the input dispatcher can determine whether input event injection will
-     * be permitted based on the current input focus.  Does not wait for the input event to
-     * finish processing.
-     * 
-     * {@link #INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH} waits for the input event to
-     * be completely processed.
-     * 
-     * @param event The event to inject.
-     * @param injectorPid The pid of the injecting application.
-     * @param injectorUid The uid of the injecting application.
-     * @param syncMode The synchronization mode.
-     * @param timeoutMillis The injection timeout in milliseconds.
-     * @return One of the INPUT_EVENT_INJECTION_XXX constants.
-     */
-    public int injectInputEvent(InputEvent event, int injectorPid, int injectorUid,
-            int syncMode, int timeoutMillis) {
-        if (event == null) {
-            throw new IllegalArgumentException("event must not be null");
-        }
-        if (injectorPid < 0 || injectorUid < 0) {
-            throw new IllegalArgumentException("injectorPid and injectorUid must not be negative.");
-        }
-        if (timeoutMillis <= 0) {
-            throw new IllegalArgumentException("timeoutMillis must be positive");
-        }
-
-        return nativeInjectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis,
-                WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
-    }
-
-    /**
-     * Gets information about the input device with the specified id.
-     * @param id The device id.
-     * @return The input device or null if not found.
-     */
-    public InputDevice getInputDevice(int deviceId) {
-        return nativeGetInputDevice(deviceId);
-    }
-    
-    /**
-     * Gets the ids of all input devices in the system.
-     * @return The input device ids.
-     */
-    public int[] getInputDeviceIds() {
-        return nativeGetInputDeviceIds();
-    }
-    
-    public void setInputWindows(InputWindowHandle[] windowHandles) {
-        nativeSetInputWindows(windowHandles);
-    }
-    
-    public void setFocusedApplication(InputApplicationHandle application) {
-        nativeSetFocusedApplication(application);
-    }
-    
-    public void setInputDispatchMode(boolean enabled, boolean frozen) {
-        nativeSetInputDispatchMode(enabled, frozen);
-    }
-
-    public void setSystemUiVisibility(int visibility) {
-        nativeSetSystemUiVisibility(visibility);
-    }
-
-    /**
-     * Atomically transfers touch focus from one window to another as identified by
-     * their input channels.  It is possible for multiple windows to have
-     * touch focus if they support split touch dispatch
-     * {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this
-     * method only transfers touch focus of the specified window without affecting
-     * other windows that may also have touch focus at the same time.
-     * @param fromChannel The channel of a window that currently has touch focus.
-     * @param toChannel The channel of the window that should receive touch focus in
-     * place of the first.
-     * @return True if the transfer was successful.  False if the window with the
-     * specified channel did not actually have touch focus at the time of the request.
-     */
-    public boolean transferTouchFocus(InputChannel fromChannel, InputChannel toChannel) {
-        if (fromChannel == null) {
-            throw new IllegalArgumentException("fromChannel must not be null.");
-        }
-        if (toChannel == null) {
-            throw new IllegalArgumentException("toChannel must not be null.");
-        }
-        return nativeTransferTouchFocus(fromChannel, toChannel);
-    }
-
-    /**
-     * Set the pointer speed.
-     * @param speed The pointer speed as a value between -7 (slowest) and 7 (fastest)
-     * where 0 is the default speed.
-     */
-    public void setPointerSpeed(int speed) {
-        speed = Math.min(Math.max(speed, -7), 7);
-        nativeSetPointerSpeed(speed);
-    }
-
-    public void updatePointerSpeedFromSettings() {
-        int speed = getPointerSpeedSetting(0);
-        setPointerSpeed(speed);
-    }
-
-    private void registerPointerSpeedSettingObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.POINTER_SPEED), true,
-                new ContentObserver(mWindowManagerService.mH) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updatePointerSpeedFromSettings();
-                    }
-                });
-    }
-
-    private int getPointerSpeedSetting(int defaultValue) {
-        int speed = defaultValue;
-        try {
-            speed = Settings.System.getInt(mContext.getContentResolver(),
-                    Settings.System.POINTER_SPEED);
-        } catch (SettingNotFoundException snfe) {
-        }
-        return speed;
-    }
-
-    public void updateShowTouchesFromSettings() {
-        int setting = getShowTouchesSetting(0);
-        nativeSetShowTouches(setting != 0);
-    }
-
-    private void registerShowTouchesSettingObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.SHOW_TOUCHES), true,
-                new ContentObserver(mWindowManagerService.mH) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateShowTouchesFromSettings();
-                    }
-                });
-    }
-
-    private int getShowTouchesSetting(int defaultValue) {
-        int result = defaultValue;
-        try {
-            result = Settings.System.getInt(mContext.getContentResolver(),
-                    Settings.System.SHOW_TOUCHES);
-        } catch (SettingNotFoundException snfe) {
-        }
-        return result;
-    }
-
-    public void dump(PrintWriter pw) {
-        String dumpStr = nativeDump();
-        if (dumpStr != null) {
-            pw.println(dumpStr);
-        }
-    }
-
-    // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
-    public void monitor() {
-        synchronized (mInputFilterLock) { }
-        nativeMonitor();
-    }
-
-    private final class InputFilterHost implements InputFilter.Host {
-        private boolean mDisconnected;
-
-        public void disconnectLocked() {
-            mDisconnected = true;
-        }
-
-        public void sendInputEvent(InputEvent event, int policyFlags) {
-            if (event == null) {
-                throw new IllegalArgumentException("event must not be null");
-            }
-
-            synchronized (mInputFilterLock) {
-                if (!mDisconnected) {
-                    nativeInjectInputEvent(event, 0, 0, INPUT_EVENT_INJECTION_SYNC_NONE, 0,
-                            policyFlags | WindowManagerPolicy.FLAG_FILTERED);
-                }
-            }
-        }
-    }
-
-    /*
-     * Callbacks from native.
-     */
-    private final class Callbacks {
-        static final String TAG = "InputManager-Callbacks";
-        
-        private static final boolean DEBUG_VIRTUAL_KEYS = false;
-        private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
-        private static final String CALIBRATION_DIR_PATH = "usr/idc/";
-        
-        @SuppressWarnings("unused")
-        public void notifyConfigurationChanged(long whenNanos) {
-            mWindowManagerService.mInputMonitor.notifyConfigurationChanged();
-        }
-        
-        @SuppressWarnings("unused")
-        public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
-            mWindowManagerService.mInputMonitor.notifyLidSwitchChanged(whenNanos, lidOpen);
-        }
-        
-        @SuppressWarnings("unused")
-        public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
-            mWindowManagerService.mInputMonitor.notifyInputChannelBroken(inputWindowHandle);
-        }
-        
-        @SuppressWarnings("unused")
-        public long notifyANR(InputApplicationHandle inputApplicationHandle,
-                InputWindowHandle inputWindowHandle) {
-            return mWindowManagerService.mInputMonitor.notifyANR(
-                    inputApplicationHandle, inputWindowHandle);
-        }
-
-        @SuppressWarnings("unused")
-        final boolean filterInputEvent(InputEvent event, int policyFlags) {
-            synchronized (mInputFilterLock) {
-                if (mInputFilter != null) {
-                    mInputFilter.filterInputEvent(event, policyFlags);
-                    return false;
-                }
-            }
-            event.recycle();
-            return true;
-        }
-
-        @SuppressWarnings("unused")
-        public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
-            return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
-                    event, policyFlags, isScreenOn);
-        }
-
-        @SuppressWarnings("unused")
-        public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
-            return mWindowManagerService.mInputMonitor.interceptMotionBeforeQueueingWhenScreenOff(
-                    policyFlags);
-        }
-
-        @SuppressWarnings("unused")
-        public long interceptKeyBeforeDispatching(InputWindowHandle focus,
-                KeyEvent event, int policyFlags) {
-            return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(
-                    focus, event, policyFlags);
-        }
-        
-        @SuppressWarnings("unused")
-        public KeyEvent dispatchUnhandledKey(InputWindowHandle focus,
-                KeyEvent event, int policyFlags) {
-            return mWindowManagerService.mInputMonitor.dispatchUnhandledKey(
-                    focus, event, policyFlags);
-        }
-        
-        @SuppressWarnings("unused")
-        public boolean checkInjectEventsPermission(int injectorPid, int injectorUid) {
-            return mContext.checkPermission(
-                    android.Manifest.permission.INJECT_EVENTS, injectorPid, injectorUid)
-                    == PackageManager.PERMISSION_GRANTED;
-        }
-
-        @SuppressWarnings("unused")
-        public int getVirtualKeyQuietTimeMillis() {
-            return mContext.getResources().getInteger(
-                    com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
-        }
-
-        @SuppressWarnings("unused")
-        public String[] getExcludedDeviceNames() {
-            ArrayList<String> names = new ArrayList<String>();
-            
-            // Read partner-provided list of excluded input devices
-            XmlPullParser parser = null;
-            // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
-            File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH);
-            FileReader confreader = null;
-            try {
-                confreader = new FileReader(confFile);
-                parser = Xml.newPullParser();
-                parser.setInput(confreader);
-                XmlUtils.beginDocument(parser, "devices");
-
-                while (true) {
-                    XmlUtils.nextElement(parser);
-                    if (!"device".equals(parser.getName())) {
-                        break;
-                    }
-                    String name = parser.getAttributeValue(null, "name");
-                    if (name != null) {
-                        names.add(name);
-                    }
-                }
-            } catch (FileNotFoundException e) {
-                // It's ok if the file does not exist.
-            } catch (Exception e) {
-                Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
-            } finally {
-                try { if (confreader != null) confreader.close(); } catch (IOException e) { }
-            }
-            
-            return names.toArray(new String[names.size()]);
-        }
-
-        @SuppressWarnings("unused")
-        public int getKeyRepeatTimeout() {
-            return ViewConfiguration.getKeyRepeatTimeout();
-        }
-
-        @SuppressWarnings("unused")
-        public int getKeyRepeatDelay() {
-            return ViewConfiguration.getKeyRepeatDelay();
-        }
-
-        @SuppressWarnings("unused")
-        public int getHoverTapTimeout() {
-            return ViewConfiguration.getHoverTapTimeout();
-        }
-
-        @SuppressWarnings("unused")
-        public int getHoverTapSlop() {
-            return ViewConfiguration.getHoverTapSlop();
-        }
-
-        @SuppressWarnings("unused")
-        public int getDoubleTapTimeout() {
-            return ViewConfiguration.getDoubleTapTimeout();
-        }
-
-        @SuppressWarnings("unused")
-        public int getLongPressTimeout() {
-            return ViewConfiguration.getLongPressTimeout();
-        }
-
-        @SuppressWarnings("unused")
-        public int getPointerLayer() {
-            return mWindowManagerService.mPolicy.windowTypeToLayerLw(
-                    WindowManager.LayoutParams.TYPE_POINTER)
-                    * WindowManagerService.TYPE_LAYER_MULTIPLIER
-                    + WindowManagerService.TYPE_LAYER_OFFSET;
-        }
-
-        @SuppressWarnings("unused")
-        public PointerIcon getPointerIcon() {
-            return PointerIcon.getDefaultIcon(mContext);
-        }
-    }
-}
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index fb74d27..c28cfa2 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -16,6 +16,10 @@
 
 package com.android.server.wm;
 
+import com.android.server.input.InputManagerService;
+import com.android.server.input.InputApplicationHandle;
+import com.android.server.input.InputWindowHandle;
+
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.util.Log;
@@ -27,7 +31,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 
-final class InputMonitor {
+final class InputMonitor implements InputManagerService.Callbacks {
     private final WindowManagerService mService;
     
     // Current window with input focus for keys and other non-touch events.  May be null.
@@ -93,7 +97,7 @@
         }
         
         if (appWindowToken == null && inputApplicationHandle != null) {
-            appWindowToken = inputApplicationHandle.appWindowToken;
+            appWindowToken = (AppWindowToken)inputApplicationHandle.appWindowToken;
             if (appWindowToken != null) {
                 Slog.i(WindowManagerService.TAG,
                         "Input event dispatching timed out sending to application "
@@ -301,7 +305,14 @@
         WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
         return mService.mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
     }
-    
+
+    /* Callback to get pointer layer. */
+    public int getPointerLayer() {
+        return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_POINTER)
+                * WindowManagerService.TYPE_LAYER_MULTIPLIER
+                + WindowManagerService.TYPE_LAYER_OFFSET;
+    }
+
     /* Called when the current input focus changes.
      * Layer assignment is assumed to be complete by the time this is called.
      */
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 77f94d9..67e057e 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -139,7 +139,7 @@
 
         final int NEAT = mService.mExitingAppTokens.size();
         for (i=0; i<NEAT; i++) {
-            final AppWindowAnimator appAnimator = mService.mAppTokens.get(i).mAppAnimator;
+            final AppWindowAnimator appAnimator = mService.mExitingAppTokens.get(i).mAppAnimator;
             final boolean wasAnimating = appAnimator.animation != null
                     && appAnimator.animation != WindowManagerService.sDummyAnimation;
             if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
@@ -440,9 +440,12 @@
                 w.mWinAnimator.prepareSurfaceLocked(true);
             }
 
+            if (mDimParams != null) {
+                mDimAnimator.updateParameters(mContext.getResources(), mDimParams, mCurrentTime);
+            }
             if (mDimAnimator != null && mDimAnimator.mDimShown) {
-                mAnimating |= mDimAnimator.updateSurface(mService.mInnerFields.mDimming,
-                            mCurrentTime, !mService.okToDisplay());
+                mAnimating |= mDimAnimator.updateSurface(mDimParams != null, mCurrentTime,
+                        !mService.okToDisplay());
             }
 
             if (mService.mBlackFrame != null) {
@@ -453,10 +456,6 @@
                     mService.mBlackFrame.clearMatrix();
                 }
             }
-
-            if (mDimParams != null) {
-                mDimAnimator.updateParameters(mContext.getResources(), mDimParams, mCurrentTime);
-            }
         } catch (RuntimeException e) {
             Log.wtf(TAG, "Unhandled exception in Window Manager", e);
         } finally {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 7eca401..716b7b1 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -44,6 +44,8 @@
 import com.android.server.PowerManagerService;
 import com.android.server.Watchdog;
 import com.android.server.am.BatteryStatsService;
+import com.android.server.input.InputFilter;
+import com.android.server.input.InputManagerService;
 
 import android.Manifest;
 import android.app.ActivityManagerNative;
@@ -243,10 +245,6 @@
      */
     static final boolean CUSTOM_SCREEN_ROTATION = true;
 
-    // Maximum number of milliseconds to wait for input event injection.
-    // FIXME is this value reasonable?
-    private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
-
     // Maximum number of milliseconds to wait for input devices to be enumerated before
     // proceding with safe mode detection.
     private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
@@ -626,7 +624,7 @@
     float mTransitionAnimationScale = 1.0f;
     float mAnimatorDurationScale = 1.0f;
 
-    final InputManager mInputManager;
+    final InputManagerService mInputManager;
 
     // Who is holding the screen on.
     Session mHoldingScreenOn;
@@ -894,7 +892,7 @@
                 "KEEP_SCREEN_ON_FLAG");
         mHoldingScreenWakeLock.setReferenceCounted(false);
 
-        mInputManager = new InputManager(context, this);
+        mInputManager = new InputManagerService(context, mInputMonitor);
         mAnimator = new WindowAnimator(this, context, mPolicy);
 
         PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
@@ -915,6 +913,10 @@
         Watchdog.getInstance().addMonitor(this);
     }
 
+    public InputManagerService getInputManagerService() {
+        return mInputManager;
+    }
+
     @Override
     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
             throws RemoteException {
@@ -4849,90 +4851,22 @@
                 mAnimatorDurationScale };
     }
 
-    public int getSwitchState(int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getSwitchState()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
+    // Called by window manager policy. Not exposed externally.
+    @Override
+    public int getLidState() {
+        final int SW_LID = 0x00;
+        int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_LID);
+        if (sw > 0) {
+            return LID_OPEN;
+        } else if (sw == 0) {
+            return LID_CLOSED;
+        } else {
+            return LID_ABSENT;
         }
-        return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
     }
 
-    public int getSwitchStateForDevice(int devid, int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getSwitchStateForDevice()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
-        }
-        return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
-    }
-
-    public int getScancodeState(int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getScancodeState()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
-        }
-        return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
-    }
-
-    public int getScancodeStateForDevice(int devid, int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getScancodeStateForDevice()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
-        }
-        return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
-    }
-
-    public int getTrackballScancodeState(int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getTrackballScancodeState()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
-        }
-        return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
-    }
-
-    public int getDPadScancodeState(int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getDPadScancodeState()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
-        }
-        return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
-    }
-
-    public int getKeycodeState(int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getKeycodeState()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
-        }
-        return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
-    }
-
-    public int getKeycodeStateForDevice(int devid, int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getKeycodeStateForDevice()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
-        }
-        return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
-    }
-
-    public int getTrackballKeycodeState(int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getTrackballKeycodeState()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
-        }
-        return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
-    }
-
-    public int getDPadKeycodeState(int sw) {
-        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
-                "getDPadKeycodeState()")) {
-            throw new SecurityException("Requires READ_INPUT_STATE permission");
-        }
-        return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
-    }
-    
-    public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
-        return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
-    }
-
+    // Called by window manager policy.  Not exposed externally.
+    @Override
     public InputChannel monitorInput(String inputChannelName) {
         if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                 "monitorInput()")) {
@@ -4945,14 +4879,6 @@
         mInputManager.setInputFilter(filter);
     }
 
-    public InputDevice getInputDevice(int deviceId) {
-        return mInputManager.getInputDevice(deviceId);
-    }
-
-    public int[] getInputDeviceIds() {
-        return mInputManager.getInputDeviceIds();
-    }
-
     public void enableScreenAfterBoot() {
         synchronized(mWindowMap) {
             if (DEBUG_BOOT) {
@@ -5109,7 +5035,7 @@
         mPolicy.enableScreenAfterBoot();
 
         // Make sure the last requested orientation has been applied.
-        updateRotationUnchecked(false);
+        updateRotationUnchecked(false, false);
     }
 
     public void showBootMessage(final CharSequence msg, final boolean always) {
@@ -5383,7 +5309,7 @@
 
         mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
                 rotation == -1 ? mRotation : rotation);
-        updateRotationUnchecked(false);
+        updateRotationUnchecked(false, false);
     }
 
     /**
@@ -5399,7 +5325,7 @@
         if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
 
         mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
-        updateRotationUnchecked(false);
+        updateRotationUnchecked(false, false);
     }
 
     /**
@@ -5409,8 +5335,8 @@
      * such that the current rotation might need to be updated, such as when the
      * device is docked or rotated into a new posture.
      */
-    public void updateRotation(boolean alwaysSendConfiguration) {
-        updateRotationUnchecked(alwaysSendConfiguration);
+    public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
+        updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
     }
 
     /**
@@ -5440,8 +5366,7 @@
         }
     }
 
-    public void updateRotationUnchecked(
-            boolean alwaysSendConfiguration) {
+    public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
         if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
                    + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
 
@@ -5449,6 +5374,10 @@
         boolean changed;
         synchronized(mWindowMap) {
             changed = updateRotationUncheckedLocked(false);
+            if (!changed || forceRelayout) {
+                mLayoutNeeded = true;
+                performLayoutAndPlaceSurfacesLocked();
+            }
         }
 
         if (changed || alwaysSendConfiguration) {
@@ -6435,164 +6364,6 @@
         sendScreenStatusToClients();
     }
 
-    /**
-     * Injects a keystroke event into the UI.
-     * Even when sync is false, this method may block while waiting for current
-     * input events to be dispatched.
-     *
-     * @param ev A motion event describing the keystroke action.  (Be sure to use
-     * {@link SystemClock#uptimeMillis()} as the timebase.)
-     * @param sync If true, wait for the event to be completed before returning to the caller.
-     * @return Returns true if event was dispatched, false if it was dropped for any reason
-     */
-    public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
-        long downTime = ev.getDownTime();
-        long eventTime = ev.getEventTime();
-
-        int action = ev.getAction();
-        int code = ev.getKeyCode();
-        int repeatCount = ev.getRepeatCount();
-        int metaState = ev.getMetaState();
-        int deviceId = ev.getDeviceId();
-        int scancode = ev.getScanCode();
-        int source = ev.getSource();
-        int flags = ev.getFlags();
-        
-        if (source == InputDevice.SOURCE_UNKNOWN) {
-            source = InputDevice.SOURCE_KEYBOARD;
-        }
-
-        if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
-        if (downTime == 0) downTime = eventTime;
-
-        KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
-                deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
-
-        final int pid = Binder.getCallingPid();
-        final int uid = Binder.getCallingUid();
-        final long ident = Binder.clearCallingIdentity();
-        
-        final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
-                sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
-                        : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
-                INJECTION_TIMEOUT_MILLIS);
-        
-        Binder.restoreCallingIdentity(ident);
-        return reportInjectionResult(result, pid);
-    }
-
-    /**
-     * Inject a pointer (touch) event into the UI.
-     * Even when sync is false, this method may block while waiting for current
-     * input events to be dispatched.
-     *
-     * @param ev A motion event describing the pointer (touch) action.  (As noted in
-     * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
-     * {@link SystemClock#uptimeMillis()} as the timebase.)
-     * @param sync If true, wait for the event to be completed before returning to the caller.
-     * @return Returns true if event was dispatched, false if it was dropped for any reason
-     */
-    public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
-        final int pid = Binder.getCallingPid();
-        final int uid = Binder.getCallingUid();
-        final long ident = Binder.clearCallingIdentity();
-        
-        MotionEvent newEvent = MotionEvent.obtain(ev);
-        if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
-            newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
-        }
-        
-        final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
-                sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
-                        : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
-                INJECTION_TIMEOUT_MILLIS);
-        
-        Binder.restoreCallingIdentity(ident);
-        return reportInjectionResult(result, pid);
-    }
-
-    /**
-     * Inject a trackball (navigation device) event into the UI.
-     * Even when sync is false, this method may block while waiting for current
-     * input events to be dispatched.
-     *
-     * @param ev A motion event describing the trackball action.  (As noted in
-     * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
-     * {@link SystemClock#uptimeMillis()} as the timebase.)
-     * @param sync If true, wait for the event to be completed before returning to the caller.
-     * @return Returns true if event was dispatched, false if it was dropped for any reason
-     */
-    public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
-        final int pid = Binder.getCallingPid();
-        final int uid = Binder.getCallingUid();
-        final long ident = Binder.clearCallingIdentity();
-        
-        MotionEvent newEvent = MotionEvent.obtain(ev);
-        if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
-            newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
-        }
-        
-        final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
-                sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
-                        : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
-                INJECTION_TIMEOUT_MILLIS);
-        
-        Binder.restoreCallingIdentity(ident);
-        return reportInjectionResult(result, pid);
-    }
-    
-    /**
-     * Inject an input event into the UI without waiting for dispatch to commence.
-     * This variant is useful for fire-and-forget input event injection.  It does not
-     * block any longer than it takes to enqueue the input event.
-     *
-     * @param ev An input event.  (Be sure to set the input source correctly.)
-     * @return Returns true if event was dispatched, false if it was dropped for any reason
-     */
-    public boolean injectInputEventNoWait(InputEvent ev) {
-        final int pid = Binder.getCallingPid();
-        final int uid = Binder.getCallingUid();
-        final long ident = Binder.clearCallingIdentity();
-        
-        final int result = mInputManager.injectInputEvent(ev, pid, uid,
-                InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
-                INJECTION_TIMEOUT_MILLIS);
-        
-        Binder.restoreCallingIdentity(ident);
-        return reportInjectionResult(result, pid);
-    }
-    
-    private boolean reportInjectionResult(int result, int pid) {
-        switch (result) {
-            case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
-                Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
-                throw new SecurityException(
-                        "Injecting to another application requires INJECT_EVENTS permission");
-            case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
-                return true;
-            case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
-                Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
-                return false;
-            case InputManager.INPUT_EVENT_INJECTION_FAILED:
-            default:
-                Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
-                return false;
-        }
-    }
-
-    /**
-     * Temporarily set the pointer speed.  Does not save the new setting.
-     * Used by the settings application.
-     */
-    public void setPointerSpeed(int speed) {
-        if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,
-                "setPointerSpeed()")) {
-            throw new SecurityException("Requires SET_POINTER_SPEED permission");
-        }
-
-        mInputManager.setPointerSpeed(speed);
-    }
-
     private WindowState getFocusedWindow() {
         synchronized (mWindowMap) {
             return getFocusedWindowLocked();
@@ -6607,11 +6378,29 @@
         if (!mInputMonitor.waitForInputDevicesReady(
                 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
             Slog.w(TAG, "Devices still not ready after waiting "
-                    + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
-                    + " milliseconds before attempting to detect safe mode.");
+                   + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
+                   + " milliseconds before attempting to detect safe mode.");
         }
 
-        mSafeMode = mPolicy.detectSafeMode();
+        final int BTN_MOUSE = 0x110;
+        int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
+                KeyEvent.KEYCODE_MENU);
+        int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
+        int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
+                KeyEvent.KEYCODE_DPAD_CENTER);
+        int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
+                BTN_MOUSE);
+        int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
+                KeyEvent.KEYCODE_VOLUME_DOWN);
+        mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
+                || volumeDownState > 0;
+        if (mSafeMode) {
+            Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
+                    + " dpad=" + dpadState + " trackball=" + trackballState + ")");
+        } else {
+            Log.i(TAG, "SAFE MODE not enabled");
+        }
+        mPolicy.setSafeMode(mSafeMode);
         return mSafeMode;
     }
 
@@ -6641,7 +6430,7 @@
             mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY,
                     mDisplay.getRawWidth(), mDisplay.getRawHeight(),
                     mDisplay.getRawExternalWidth(), mDisplay.getRawExternalHeight());
-            mPolicy.setInitialDisplaySize(mInitialDisplayWidth, mInitialDisplayHeight);
+            mPolicy.setInitialDisplaySize(mDisplay, mInitialDisplayWidth, mInitialDisplayHeight);
         }
 
         try {
@@ -7361,7 +7150,7 @@
             mBaseDisplayWidth = width;
             mBaseDisplayHeight = height;
         }
-        mPolicy.setInitialDisplaySize(mBaseDisplayWidth, mBaseDisplayHeight);
+        mPolicy.setInitialDisplaySize(mDisplay, mBaseDisplayWidth, mBaseDisplayHeight);
 
         mLayoutNeeded = true;
 
@@ -7393,8 +7182,8 @@
         }
     }
 
-    public boolean canStatusBarHide() {
-        return mPolicy.canStatusBarHide();
+    public boolean hasSystemNavBar() {
+        return mPolicy.hasSystemNavBar();
     }
 
     // -------------------------------------------------------------
@@ -8397,8 +8186,6 @@
             final int N = mWindows.size();
             for (i=N-1; i>=0; i--) {
                 WindowState w = mWindows.get(i);
-                //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
-                w.mContentChanged = false;
 
                 if (someoneLosingFocus && w == mCurrentFocus && w.isDisplayedLw()) {
                     focusDisplayed = true;
@@ -8419,7 +8206,7 @@
                     updateWallpaperVisibilityLocked();
                 }
             }
-            if (!mInnerFields.mDimming) {
+            if (!mInnerFields.mDimming && mAnimator.mDimParams != null) {
                 mAnimator.stopDimming();
             }
         } catch (RuntimeException e) {
@@ -8500,6 +8287,27 @@
         for (i=N-1; i>=0; i--) {
             final WindowState w = mWindows.get(i);
             final WindowStateAnimator winAnimator = w.mWinAnimator; 
+            
+            // If the window has moved due to its containing
+            // content frame changing, then we'd like to animate
+            // it.
+            if (w.mHasSurface && w.shouldAnimateMove()) {
+                // Frame has moved, containing content frame
+                // has also moved, and we're not currently animating...
+                // let's do something.
+                Animation a = AnimationUtils.loadAnimation(mContext,
+                        com.android.internal.R.anim.window_move_from_decor);
+                winAnimator.setAnimation(a);
+                winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
+                winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+            } else {
+                winAnimator.mAnimDw = innerDw;
+                winAnimator.mAnimDh = innerDh;
+            }
+
+            //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
+            w.mContentChanged = false;
+            
             // TODO(cmautner): Can this move up to the loop at the end of try/catch above?
             updateResizingWindows(w);
 
@@ -8519,24 +8327,6 @@
                         }
                     }
                 }
-    
-                // If the window has moved due to its containing
-                // content frame changing, then we'd like to animate
-                // it.  The checks here are ordered by what is least
-                // likely to be true first.
-                if (w.shouldAnimateMove()) {
-                    // Frame has moved, containing content frame
-                    // has also moved, and we're not currently animating...
-                    // let's do something.
-                    Animation a = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.window_move_from_decor);
-                    winAnimator.setAnimation(a);
-                    winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
-                    winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
-                } else {
-                    winAnimator.mAnimDw = innerDw;
-                    winAnimator.mAnimDh = innerDh;
-                }
             }
         }
 
@@ -9277,11 +9067,6 @@
         mPolicy.lockNow();
     }
 
-    void dumpInput(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
-        pw.println("WINDOW MANAGER INPUT (dumpsys window input)");
-        mInputManager.dump(pw);
-    }
-
     void dumpPolicyLocked(FileDescriptor fd, PrintWriter pw, String[] args, boolean dumpAll) {
         pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
         mPolicy.dump("    ", fd, pw, args);
@@ -9671,7 +9456,6 @@
                 pw.println("Window manager dump options:");
                 pw.println("  [-a] [-h] [cmd] ...");
                 pw.println("  cmd may be one of:");
-                pw.println("    i[input]: input subsystem state");
                 pw.println("    p[policy]: policy state");
                 pw.println("    s[essions]: active sessions");
                 pw.println("    t[okens]: token list");
@@ -9692,10 +9476,7 @@
         if (opti < args.length) {
             String cmd = args[opti];
             opti++;
-            if ("input".equals(cmd) || "i".equals(cmd)) {
-                dumpInput(fd, pw, true);
-                return;
-            } else if ("policy".equals(cmd) || "p".equals(cmd)) {
+            if ("policy".equals(cmd) || "p".equals(cmd)) {
                 synchronized(mWindowMap) {
                     dumpPolicyLocked(fd, pw, args, true);
                 }
@@ -9730,8 +9511,6 @@
             }
         }
 
-        dumpInput(fd, pw, dumpAll);
-
         synchronized(mWindowMap) {
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 05797a4..4de6425 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -23,6 +23,8 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
+import com.android.server.input.InputWindowHandle;
+
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Matrix;
@@ -870,6 +872,7 @@
         return true;
     }
 
+    @Override
     public boolean hideLw(boolean doAnimation) {
         return hideLw(doAnimation, true);
     }
@@ -912,6 +915,11 @@
         return true;
     }
 
+    @Override
+    public boolean isAlive() {
+        return mClient.asBinder().isBinderAlive();
+    }
+
     private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
         outRegion.set(
                 frame.left + inset.left, frame.top + inset.top,
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index c02dd36..ac4fd15 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -4,9 +4,9 @@
 LOCAL_SRC_FILES:= \
     com_android_server_AlarmManagerService.cpp \
     com_android_server_BatteryService.cpp \
-    com_android_server_InputApplicationHandle.cpp \
-    com_android_server_InputManager.cpp \
-    com_android_server_InputWindowHandle.cpp \
+    com_android_server_input_InputApplicationHandle.cpp \
+    com_android_server_input_InputManagerService.cpp \
+    com_android_server_input_InputWindowHandle.cpp \
     com_android_server_LightsService.cpp \
     com_android_server_PowerManagerService.cpp \
     com_android_server_SerialService.cpp \
diff --git a/services/jni/com_android_server_InputApplicationHandle.cpp b/services/jni/com_android_server_input_InputApplicationHandle.cpp
similarity index 96%
rename from services/jni/com_android_server_InputApplicationHandle.cpp
rename to services/jni/com_android_server_input_InputApplicationHandle.cpp
index c76ab53..0109430 100644
--- a/services/jni/com_android_server_InputApplicationHandle.cpp
+++ b/services/jni/com_android_server_input_InputApplicationHandle.cpp
@@ -21,7 +21,7 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/threads.h>
 
-#include "com_android_server_InputApplicationHandle.h"
+#include "com_android_server_input_InputApplicationHandle.h"
 
 namespace android {
 
@@ -135,12 +135,12 @@
         LOG_FATAL_IF(! var, "Unable to find field " fieldName);
 
 int register_android_server_InputApplicationHandle(JNIEnv* env) {
-    int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputApplicationHandle",
+    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputApplicationHandle",
             gInputApplicationHandleMethods, NELEM(gInputApplicationHandleMethods));
     LOG_FATAL_IF(res < 0, "Unable to register native methods.");
 
     jclass clazz;
-    FIND_CLASS(clazz, "com/android/server/wm/InputApplicationHandle");
+    FIND_CLASS(clazz, "com/android/server/input/InputApplicationHandle");
 
     GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, clazz,
             "ptr", "I");
diff --git a/services/jni/com_android_server_InputApplicationHandle.h b/services/jni/com_android_server_input_InputApplicationHandle.h
similarity index 100%
rename from services/jni/com_android_server_InputApplicationHandle.h
rename to services/jni/com_android_server_input_InputApplicationHandle.h
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
similarity index 73%
rename from services/jni/com_android_server_InputManager.cpp
rename to services/jni/com_android_server_input_InputManagerService.cpp
index 5c3e002..22795bf 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -46,8 +46,8 @@
 #include <android/graphics/GraphicsJNI.h>
 
 #include "com_android_server_PowerManagerService.h"
-#include "com_android_server_InputApplicationHandle.h"
-#include "com_android_server_InputWindowHandle.h"
+#include "com_android_server_input_InputApplicationHandle.h"
+#include "com_android_server_input_InputWindowHandle.h"
 
 namespace android {
 
@@ -77,7 +77,7 @@
     jmethodID getLongPressTimeout;
     jmethodID getPointerLayer;
     jmethodID getPointerIcon;
-} gCallbacksClassInfo;
+} gServiceClassInfo;
 
 static struct {
     jclass clazz;
@@ -166,7 +166,7 @@
     virtual ~NativeInputManager();
 
 public:
-    NativeInputManager(jobject contextObj, jobject callbacksObj, const sp<Looper>& looper);
+    NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper);
 
     inline sp<InputManager> getInputManager() const { return mInputManager; }
 
@@ -222,7 +222,7 @@
     sp<InputManager> mInputManager;
 
     jobject mContextObj;
-    jobject mCallbacksObj;
+    jobject mServiceObj;
     sp<Looper> mLooper;
 
     Mutex mLock;
@@ -269,12 +269,12 @@
 
 
 NativeInputManager::NativeInputManager(jobject contextObj,
-        jobject callbacksObj, const sp<Looper>& looper) :
+        jobject serviceObj, const sp<Looper>& looper) :
         mLooper(looper) {
     JNIEnv* env = jniEnv();
 
     mContextObj = env->NewGlobalRef(contextObj);
-    mCallbacksObj = env->NewGlobalRef(callbacksObj);
+    mServiceObj = env->NewGlobalRef(serviceObj);
 
     {
         AutoMutex _l(mLock);
@@ -298,7 +298,7 @@
     JNIEnv* env = jniEnv();
 
     env->DeleteGlobalRef(mContextObj);
-    env->DeleteGlobalRef(mCallbacksObj);
+    env->DeleteGlobalRef(mServiceObj);
 }
 
 void NativeInputManager::dump(String8& dump) {
@@ -387,15 +387,15 @@
 void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
     JNIEnv* env = jniEnv();
 
-    jint virtualKeyQuietTime = env->CallIntMethod(mCallbacksObj,
-            gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
+    jint virtualKeyQuietTime = env->CallIntMethod(mServiceObj,
+            gServiceClassInfo.getVirtualKeyQuietTimeMillis);
     if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
         outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
     }
 
     outConfig->excludedDeviceNames.clear();
-    jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mCallbacksObj,
-            gCallbacksClassInfo.getExcludedDeviceNames));
+    jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mServiceObj,
+            gServiceClassInfo.getExcludedDeviceNames));
     if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
         jsize length = env->GetArrayLength(excludedDeviceNames);
         for (jsize i = 0; i < length; i++) {
@@ -408,14 +408,14 @@
         env->DeleteLocalRef(excludedDeviceNames);
     }
 
-    jint hoverTapTimeout = env->CallIntMethod(mCallbacksObj,
-            gCallbacksClassInfo.getHoverTapTimeout);
+    jint hoverTapTimeout = env->CallIntMethod(mServiceObj,
+            gServiceClassInfo.getHoverTapTimeout);
     if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
-        jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
-                gCallbacksClassInfo.getDoubleTapTimeout);
+        jint doubleTapTimeout = env->CallIntMethod(mServiceObj,
+                gServiceClassInfo.getDoubleTapTimeout);
         if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
-            jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
-                    gCallbacksClassInfo.getLongPressTimeout);
+            jint longPressTimeout = env->CallIntMethod(mServiceObj,
+                    gServiceClassInfo.getLongPressTimeout);
             if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
                 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
 
@@ -430,8 +430,8 @@
         }
     }
 
-    jint hoverTapSlop = env->CallIntMethod(mCallbacksObj,
-            gCallbacksClassInfo.getHoverTapSlop);
+    jint hoverTapSlop = env->CallIntMethod(mServiceObj,
+            gServiceClassInfo.getHoverTapSlop);
     if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
         outConfig->pointerGestureTapSlop = hoverTapSlop;
     }
@@ -467,8 +467,8 @@
         controller->setDisplayOrientation(mLocked.displayOrientation);
 
         JNIEnv* env = jniEnv();
-        jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
-                gCallbacksClassInfo.getPointerIcon);
+        jobject pointerIconObj = env->CallObjectMethod(mServiceObj,
+                gServiceClassInfo.getPointerIcon);
         if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
             PointerIcon pointerIcon;
             status_t status = android_view_PointerIcon_load(env, pointerIconObj,
@@ -490,7 +490,7 @@
 void NativeInputManager::ensureSpriteControllerLocked() {
     if (mLocked.spriteController == NULL) {
         JNIEnv* env = jniEnv();
-        jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
+        jint layer = env->CallIntMethod(mServiceObj, gServiceClassInfo.getPointerLayer);
         if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
             layer = -1;
         }
@@ -509,7 +509,7 @@
 
     switch (switchCode) {
     case SW_LID:
-        env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
+        env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyLidSwitchChanged,
                 when, switchValue == 0);
         checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
         break;
@@ -523,7 +523,7 @@
 
     JNIEnv* env = jniEnv();
 
-    env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
+    env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyConfigurationChanged, when);
     checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
 }
 
@@ -540,8 +540,8 @@
     jobject inputWindowHandleObj =
             getInputWindowHandleObjLocalRef(env, inputWindowHandle);
 
-    jlong newTimeout = env->CallLongMethod(mCallbacksObj,
-                gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
+    jlong newTimeout = env->CallLongMethod(mServiceObj,
+                gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
     if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
         newTimeout = 0; // abort dispatch
     } else {
@@ -563,7 +563,7 @@
     jobject inputWindowHandleObj =
             getInputWindowHandleObjLocalRef(env, inputWindowHandle);
     if (inputWindowHandleObj) {
-        env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
+        env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputChannelBroken,
                 inputWindowHandleObj);
         checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
 
@@ -574,14 +574,14 @@
 void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
     JNIEnv* env = jniEnv();
 
-    jint keyRepeatTimeout = env->CallIntMethod(mCallbacksObj,
-            gCallbacksClassInfo.getKeyRepeatTimeout);
+    jint keyRepeatTimeout = env->CallIntMethod(mServiceObj,
+            gServiceClassInfo.getKeyRepeatTimeout);
     if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
         outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
     }
 
-    jint keyRepeatDelay = env->CallIntMethod(mCallbacksObj,
-            gCallbacksClassInfo.getKeyRepeatDelay);
+    jint keyRepeatDelay = env->CallIntMethod(mServiceObj,
+            gServiceClassInfo.getKeyRepeatDelay);
     if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
         outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
     }
@@ -734,7 +734,7 @@
     }
 
     // The callee is responsible for recycling the event.
-    jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
+    jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
             inputEventObj, policyFlags);
     if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
         pass = true;
@@ -758,8 +758,8 @@
         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
         jint wmActions;
         if (keyEventObj) {
-            wmActions = env->CallIntMethod(mCallbacksObj,
-                    gCallbacksClassInfo.interceptKeyBeforeQueueing,
+            wmActions = env->CallIntMethod(mServiceObj,
+                    gServiceClassInfo.interceptKeyBeforeQueueing,
                     keyEventObj, policyFlags, isScreenOn);
             if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
                 wmActions = 0;
@@ -802,8 +802,8 @@
             }
         } else {
             JNIEnv* env = jniEnv();
-            jint wmActions = env->CallIntMethod(mCallbacksObj,
-                        gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
+            jint wmActions = env->CallIntMethod(mServiceObj,
+                        gServiceClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
                         policyFlags);
             if (checkAndClearExceptionFromCallback(env,
                     "interceptMotionBeforeQueueingWhenScreenOff")) {
@@ -858,8 +858,8 @@
         jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
         if (keyEventObj) {
-            jlong delayMillis = env->CallLongMethod(mCallbacksObj,
-                    gCallbacksClassInfo.interceptKeyBeforeDispatching,
+            jlong delayMillis = env->CallLongMethod(mServiceObj,
+                    gServiceClassInfo.interceptKeyBeforeDispatching,
                     inputWindowHandleObj, keyEventObj, policyFlags);
             bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
             android_view_KeyEvent_recycle(env, keyEventObj);
@@ -891,8 +891,8 @@
         jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
         if (keyEventObj) {
-            jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
-                    gCallbacksClassInfo.dispatchUnhandledKey,
+            jobject fallbackKeyEventObj = env->CallObjectMethod(mServiceObj,
+                    gServiceClassInfo.dispatchUnhandledKey,
                     inputWindowHandleObj, keyEventObj, policyFlags);
             if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
                 fallbackKeyEventObj = NULL;
@@ -925,8 +925,8 @@
 bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
         int32_t injectorPid, int32_t injectorUid) {
     JNIEnv* env = jniEnv();
-    jboolean result = env->CallBooleanMethod(mCallbacksObj,
-            gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
+    jboolean result = env->CallBooleanMethod(mServiceObj,
+            gServiceClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
     if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
         result = false;
     }
@@ -947,103 +947,75 @@
 
 // ----------------------------------------------------------------------------
 
-static sp<NativeInputManager> gNativeInputManager;
-
-static bool checkInputManagerUnitialized(JNIEnv* env) {
-    if (gNativeInputManager == NULL) {
-        ALOGE("Input manager not initialized.");
-        jniThrowRuntimeException(env, "Input manager not initialized.");
-        return true;
-    }
-    return false;
+static jint nativeInit(JNIEnv* env, jclass clazz,
+        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
+    sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
+    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, looper);
+    im->incStrong(serviceObj);
+    return reinterpret_cast<jint>(im);
 }
 
-static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
-        jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
-    if (gNativeInputManager == NULL) {
-        sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
-        gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
-    } else {
-        ALOGE("Input manager already initialized.");
-        jniThrowRuntimeException(env, "Input manager already initialized.");
-    }
-}
+static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
-
-    status_t result = gNativeInputManager->getInputManager()->start();
+    status_t result = im->getInputManager()->start();
     if (result) {
         jniThrowRuntimeException(env, "Input manager could not be started.");
     }
 }
 
-static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
+static void nativeSetDisplaySize(JNIEnv* env, jclass clazz, jint ptr,
         jint displayId, jint width, jint height, jint externalWidth, jint externalHeight) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     // XXX we could get this from the SurfaceFlinger directly instead of requiring it
     // to be passed in like this, not sure which is better but leaving it like this
     // keeps the window manager in direct control of when display transitions propagate down
     // to the input dispatcher
-    gNativeInputManager->setDisplaySize(displayId, width, height, externalWidth, externalHeight);
+    im->setDisplaySize(displayId, width, height, externalWidth, externalHeight);
 }
 
-static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
-        jint displayId, jint orientation) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
+        jint ptr, jint displayId, jint orientation) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    gNativeInputManager->setDisplayOrientation(displayId, orientation);
+    im->setDisplayOrientation(displayId, orientation);
 }
 
-static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
-        jint deviceId, jint sourceMask, jint scanCode) {
-    if (checkInputManagerUnitialized(env)) {
-        return AKEY_STATE_UNKNOWN;
-    }
+static jint nativeGetScanCodeState(JNIEnv* env, jclass clazz,
+        jint ptr, jint deviceId, jint sourceMask, jint scanCode) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
+    return im->getInputManager()->getReader()->getScanCodeState(
             deviceId, uint32_t(sourceMask), scanCode);
 }
 
-static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
-        jint deviceId, jint sourceMask, jint keyCode) {
-    if (checkInputManagerUnitialized(env)) {
-        return AKEY_STATE_UNKNOWN;
-    }
+static jint nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
+        jint ptr, jint deviceId, jint sourceMask, jint keyCode) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
+    return im->getInputManager()->getReader()->getKeyCodeState(
             deviceId, uint32_t(sourceMask), keyCode);
 }
 
-static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
-        jint deviceId, jint sourceMask, jint sw) {
-    if (checkInputManagerUnitialized(env)) {
-        return AKEY_STATE_UNKNOWN;
-    }
+static jint nativeGetSwitchState(JNIEnv* env, jclass clazz,
+        jint ptr, jint deviceId, jint sourceMask, jint sw) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
+    return im->getInputManager()->getReader()->getSwitchState(
             deviceId, uint32_t(sourceMask), sw);
 }
 
-static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
-        jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
-    if (checkInputManagerUnitialized(env)) {
-        return JNI_FALSE;
-    }
+static jboolean nativeHasKeys(JNIEnv* env, jclass clazz,
+        jint ptr, jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
     uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
     jsize numCodes = env->GetArrayLength(keyCodes);
     jboolean result;
     if (numCodes == env->GetArrayLength(keyCodes)) {
-        result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
+        result = im->getInputManager()->getReader()->hasKeys(
                 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
     } else {
         result = JNI_FALSE;
@@ -1059,21 +1031,18 @@
              "inputChannel is not initialized");
 }
 
-static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
+static void handleInputChannelDisposed(JNIEnv* env,
         jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
+    NativeInputManager* im = static_cast<NativeInputManager*>(data);
+
     ALOGW("Input channel object '%s' was disposed without first being unregistered with "
             "the input manager!", inputChannel->getName().string());
-
-    if (gNativeInputManager != NULL) {
-        gNativeInputManager->unregisterInputChannel(env, inputChannel);
-    }
+    im->unregisterInputChannel(env, inputChannel);
 }
 
-static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
-        jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
+        jint ptr, jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
             inputChannelObj);
@@ -1085,7 +1054,7 @@
     sp<InputWindowHandle> inputWindowHandle =
             android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
 
-    status_t status = gNativeInputManager->registerInputChannel(
+    status_t status = im->registerInputChannel(
             env, inputChannel, inputWindowHandle, monitor);
     if (status) {
         String8 message;
@@ -1096,15 +1065,13 @@
 
     if (! monitor) {
         android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
-                android_server_InputManager_handleInputChannelDisposed, NULL);
+                handleInputChannelDisposed, im);
     }
 }
 
-static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
-        jobject inputChannelObj) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
+        jint ptr, jobject inputChannelObj) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
             inputChannelObj);
@@ -1115,7 +1082,7 @@
 
     android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
 
-    status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
+    status_t status = im->unregisterInputChannel(env, inputChannel);
     if (status && status != BAD_VALUE) { // ignore already unregistered channel
         String8 message;
         message.appendFormat("Failed to unregister input channel.  status=%d", status);
@@ -1123,21 +1090,17 @@
     }
 }
 
-static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
-        jboolean enabled) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
+        jint ptr, jboolean enabled) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
+    im->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
 }
 
-static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
-        jobject inputEventObj, jint injectorPid, jint injectorUid,
+static jint nativeInjectInputEvent(JNIEnv* env, jclass clazz,
+        jint ptr, jobject inputEventObj, jint injectorPid, jint injectorUid,
         jint syncMode, jint timeoutMillis, jint policyFlags) {
-    if (checkInputManagerUnitialized(env)) {
-        return INPUT_EVENT_INJECTION_FAILED;
-    }
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
         KeyEvent keyEvent;
@@ -1147,7 +1110,7 @@
             return INPUT_EVENT_INJECTION_FAILED;
         }
 
-        return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
+        return im->getInputManager()->getDispatcher()->injectInputEvent(
                 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
                 uint32_t(policyFlags));
     } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
@@ -1157,7 +1120,7 @@
             return INPUT_EVENT_INJECTION_FAILED;
         }
 
-        return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
+        return im->getInputManager()->getDispatcher()->injectInputEvent(
                 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
                 uint32_t(policyFlags));
     } else {
@@ -1166,50 +1129,40 @@
     }
 }
 
-static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
-        jobjectArray windowHandleObjArray) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeSetInputWindows(JNIEnv* env, jclass clazz,
+        jint ptr, jobjectArray windowHandleObjArray) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    gNativeInputManager->setInputWindows(env, windowHandleObjArray);
+    im->setInputWindows(env, windowHandleObjArray);
 }
 
-static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
-        jobject applicationHandleObj) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
+        jint ptr, jobject applicationHandleObj) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    gNativeInputManager->setFocusedApplication(env, applicationHandleObj);
+    im->setFocusedApplication(env, applicationHandleObj);
 }
 
-static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
-        jclass clazz, jboolean enabled, jboolean frozen) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeSetInputDispatchMode(JNIEnv* env,
+        jclass clazz, jint ptr, jboolean enabled, jboolean frozen) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    gNativeInputManager->setInputDispatchMode(enabled, frozen);
+    im->setInputDispatchMode(enabled, frozen);
 }
 
-static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
-        jclass clazz, jint visibility) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeSetSystemUiVisibility(JNIEnv* env,
+        jclass clazz, jint ptr, jint visibility) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    gNativeInputManager->setSystemUiVisibility(visibility);
+    im->setSystemUiVisibility(visibility);
 }
 
-static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
-        jclass clazz, jint deviceId) {
-    if (checkInputManagerUnitialized(env)) {
-        return NULL;
-    }
+static jobject nativeGetInputDevice(JNIEnv* env,
+        jclass clazz, jint ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     InputDeviceInfo deviceInfo;
-    status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
+    status_t status = im->getInputManager()->getReader()->getInputDeviceInfo(
             deviceId, & deviceInfo);
     if (status) {
         return NULL;
@@ -1249,14 +1202,12 @@
     return deviceObj;
 }
 
-static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
-        jclass clazz) {
-    if (checkInputManagerUnitialized(env)) {
-        return NULL;
-    }
+static jintArray nativeGetInputDeviceIds(JNIEnv* env,
+        jclass clazz, jint ptr) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     Vector<int> deviceIds;
-    gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
+    im->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
 
     jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
     if (! deviceIdsObj) {
@@ -1267,25 +1218,21 @@
     return deviceIdsObj;
 }
 
-static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
-        jclass clazz, jobject configObj) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeGetInputConfiguration(JNIEnv* env,
+        jclass clazz, jint ptr, jobject configObj) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     InputConfiguration config;
-    gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
+    im->getInputManager()->getReader()->getInputConfiguration(& config);
 
     env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
     env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
     env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
 }
 
-static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
-        jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
-    if (checkInputManagerUnitialized(env)) {
-        return false;
-    }
+static jboolean nativeTransferTouchFocus(JNIEnv* env,
+        jclass clazz, jint ptr, jobject fromChannelObj, jobject toChannelObj) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     sp<InputChannel> fromChannel =
             android_view_InputChannel_getInputChannel(env, fromChannelObj);
@@ -1296,101 +1243,93 @@
         return false;
     }
 
-    return gNativeInputManager->getInputManager()->getDispatcher()->
+    return im->getInputManager()->getDispatcher()->
             transferTouchFocus(fromChannel, toChannel);
 }
 
-static void android_server_InputManager_nativeSetPointerSpeed(JNIEnv* env,
-        jclass clazz, jint speed) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeSetPointerSpeed(JNIEnv* env,
+        jclass clazz, jint ptr, jint speed) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    gNativeInputManager->setPointerSpeed(speed);
+    im->setPointerSpeed(speed);
 }
 
-static void android_server_InputManager_nativeSetShowTouches(JNIEnv* env,
-        jclass clazz, jboolean enabled) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeSetShowTouches(JNIEnv* env,
+        jclass clazz, jint ptr, jboolean enabled) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    gNativeInputManager->setShowTouches(enabled);
+    im->setShowTouches(enabled);
 }
 
-static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
-    if (checkInputManagerUnitialized(env)) {
-        return NULL;
-    }
+static jstring nativeDump(JNIEnv* env, jclass clazz, jint ptr) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     String8 dump;
-    gNativeInputManager->dump(dump);
+    im->dump(dump);
     return env->NewStringUTF(dump.string());
 }
 
-static void android_server_InputManager_nativeMonitor(JNIEnv* env, jclass clazz) {
-    if (checkInputManagerUnitialized(env)) {
-        return;
-    }
+static void nativeMonitor(JNIEnv* env, jclass clazz, jint ptr) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    gNativeInputManager->getInputManager()->getReader()->monitor();
-    gNativeInputManager->getInputManager()->getDispatcher()->monitor();
+    im->getInputManager()->getReader()->monitor();
+    im->getInputManager()->getDispatcher()->monitor();
 }
 
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gInputManagerMethods[] = {
     /* name, signature, funcPtr */
-    { "nativeInit", "(Landroid/content/Context;"
-            "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
-            (void*) android_server_InputManager_nativeInit },
-    { "nativeStart", "()V",
-            (void*) android_server_InputManager_nativeStart },
-    { "nativeSetDisplaySize", "(IIIII)V",
-            (void*) android_server_InputManager_nativeSetDisplaySize },
-    { "nativeSetDisplayOrientation", "(II)V",
-            (void*) android_server_InputManager_nativeSetDisplayOrientation },
-    { "nativeGetScanCodeState", "(III)I",
-            (void*) android_server_InputManager_nativeGetScanCodeState },
-    { "nativeGetKeyCodeState", "(III)I",
-            (void*) android_server_InputManager_nativeGetKeyCodeState },
-    { "nativeGetSwitchState", "(III)I",
-            (void*) android_server_InputManager_nativeGetSwitchState },
-    { "nativeHasKeys", "(II[I[Z)Z",
-            (void*) android_server_InputManager_nativeHasKeys },
+    { "nativeInit",
+            "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/MessageQueue;)I",
+            (void*) nativeInit },
+    { "nativeStart", "(I)V",
+            (void*) nativeStart },
+    { "nativeSetDisplaySize", "(IIIIII)V",
+            (void*) nativeSetDisplaySize },
+    { "nativeSetDisplayOrientation", "(III)V",
+            (void*) nativeSetDisplayOrientation },
+    { "nativeGetScanCodeState", "(IIII)I",
+            (void*) nativeGetScanCodeState },
+    { "nativeGetKeyCodeState", "(IIII)I",
+            (void*) nativeGetKeyCodeState },
+    { "nativeGetSwitchState", "(IIII)I",
+            (void*) nativeGetSwitchState },
+    { "nativeHasKeys", "(III[I[Z)Z",
+            (void*) nativeHasKeys },
     { "nativeRegisterInputChannel",
-            "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
-            (void*) android_server_InputManager_nativeRegisterInputChannel },
-    { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
-            (void*) android_server_InputManager_nativeUnregisterInputChannel },
-    { "nativeSetInputFilterEnabled", "(Z)V",
-            (void*) android_server_InputManager_nativeSetInputFilterEnabled },
-    { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
-            (void*) android_server_InputManager_nativeInjectInputEvent },
-    { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindowHandle;)V",
-            (void*) android_server_InputManager_nativeSetInputWindows },
-    { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplicationHandle;)V",
-            (void*) android_server_InputManager_nativeSetFocusedApplication },
-    { "nativeSetInputDispatchMode", "(ZZ)V",
-            (void*) android_server_InputManager_nativeSetInputDispatchMode },
-    { "nativeSetSystemUiVisibility", "(I)V",
-            (void*) android_server_InputManager_nativeSetSystemUiVisibility },
-    { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
-            (void*) android_server_InputManager_nativeGetInputDevice },
-    { "nativeGetInputDeviceIds", "()[I",
-            (void*) android_server_InputManager_nativeGetInputDeviceIds },
-    { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
-            (void*) android_server_InputManager_nativeGetInputConfiguration },
-    { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
-            (void*) android_server_InputManager_nativeTransferTouchFocus },
-    { "nativeSetPointerSpeed", "(I)V",
-            (void*) android_server_InputManager_nativeSetPointerSpeed },
-    { "nativeSetShowTouches", "(Z)V",
-            (void*) android_server_InputManager_nativeSetShowTouches },
-    { "nativeDump", "()Ljava/lang/String;",
-            (void*) android_server_InputManager_nativeDump },
-    { "nativeMonitor", "()V",
-            (void*) android_server_InputManager_nativeMonitor },
+            "(ILandroid/view/InputChannel;Lcom/android/server/input/InputWindowHandle;Z)V",
+            (void*) nativeRegisterInputChannel },
+    { "nativeUnregisterInputChannel", "(ILandroid/view/InputChannel;)V",
+            (void*) nativeUnregisterInputChannel },
+    { "nativeSetInputFilterEnabled", "(IZ)V",
+            (void*) nativeSetInputFilterEnabled },
+    { "nativeInjectInputEvent", "(ILandroid/view/InputEvent;IIIII)I",
+            (void*) nativeInjectInputEvent },
+    { "nativeSetInputWindows", "(I[Lcom/android/server/input/InputWindowHandle;)V",
+            (void*) nativeSetInputWindows },
+    { "nativeSetFocusedApplication", "(ILcom/android/server/input/InputApplicationHandle;)V",
+            (void*) nativeSetFocusedApplication },
+    { "nativeSetInputDispatchMode", "(IZZ)V",
+            (void*) nativeSetInputDispatchMode },
+    { "nativeSetSystemUiVisibility", "(II)V",
+            (void*) nativeSetSystemUiVisibility },
+    { "nativeGetInputDevice", "(II)Landroid/view/InputDevice;",
+            (void*) nativeGetInputDevice },
+    { "nativeGetInputDeviceIds", "(I)[I",
+            (void*) nativeGetInputDeviceIds },
+    { "nativeGetInputConfiguration", "(ILandroid/content/res/Configuration;)V",
+            (void*) nativeGetInputConfiguration },
+    { "nativeTransferTouchFocus", "(ILandroid/view/InputChannel;Landroid/view/InputChannel;)Z",
+            (void*) nativeTransferTouchFocus },
+    { "nativeSetPointerSpeed", "(II)V",
+            (void*) nativeSetPointerSpeed },
+    { "nativeSetShowTouches", "(IZ)V",
+            (void*) nativeSetShowTouches },
+    { "nativeDump", "(I)Ljava/lang/String;",
+            (void*) nativeDump },
+    { "nativeMonitor", "(I)V",
+            (void*) nativeMonitor },
 };
 
 #define FIND_CLASS(var, className) \
@@ -1406,77 +1345,77 @@
         LOG_FATAL_IF(! var, "Unable to find field " fieldName);
 
 int register_android_server_InputManager(JNIEnv* env) {
-    int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
+    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputManagerService",
             gInputManagerMethods, NELEM(gInputManagerMethods));
     LOG_FATAL_IF(res < 0, "Unable to register native methods.");
 
     // Callbacks
 
     jclass clazz;
-    FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
+    FIND_CLASS(clazz, "com/android/server/input/InputManagerService");
 
-    GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
+    GET_METHOD_ID(gServiceClassInfo.notifyConfigurationChanged, clazz,
             "notifyConfigurationChanged", "(J)V");
 
-    GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
+    GET_METHOD_ID(gServiceClassInfo.notifyLidSwitchChanged, clazz,
             "notifyLidSwitchChanged", "(JZ)V");
 
-    GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
-            "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
+    GET_METHOD_ID(gServiceClassInfo.notifyInputChannelBroken, clazz,
+            "notifyInputChannelBroken", "(Lcom/android/server/input/InputWindowHandle;)V");
 
-    GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
+    GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz,
             "notifyANR",
-            "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
+            "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;)J");
 
-    GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
+    GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
             "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
 
-    GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
+    GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
             "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
+    GET_METHOD_ID(gServiceClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
             clazz,
             "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
+    GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeDispatching, clazz,
             "interceptKeyBeforeDispatching",
-            "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)J");
+            "(Lcom/android/server/input/InputWindowHandle;Landroid/view/KeyEvent;I)J");
 
-    GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
+    GET_METHOD_ID(gServiceClassInfo.dispatchUnhandledKey, clazz,
             "dispatchUnhandledKey",
-            "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
+            "(Lcom/android/server/input/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
 
-    GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
+    GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz,
             "checkInjectEventsPermission", "(II)Z");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getVirtualKeyQuietTimeMillis, clazz,
             "getVirtualKeyQuietTimeMillis", "()I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getExcludedDeviceNames, clazz,
             "getExcludedDeviceNames", "()[Ljava/lang/String;");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getKeyRepeatTimeout, clazz,
             "getKeyRepeatTimeout", "()I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getKeyRepeatDelay, clazz,
             "getKeyRepeatDelay", "()I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getHoverTapTimeout, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getHoverTapTimeout, clazz,
             "getHoverTapTimeout", "()I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getHoverTapSlop, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getHoverTapSlop, clazz,
             "getHoverTapSlop", "()I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getDoubleTapTimeout, clazz,
             "getDoubleTapTimeout", "()I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getLongPressTimeout, clazz,
             "getLongPressTimeout", "()I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getPointerLayer, clazz,
             "getPointerLayer", "()I");
 
-    GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
+    GET_METHOD_ID(gServiceClassInfo.getPointerIcon, clazz,
             "getPointerIcon", "()Landroid/view/PointerIcon;");
 
     // KeyEvent
@@ -1484,7 +1423,6 @@
     FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
     gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
 
-
     // MotionEvent
 
     FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
diff --git a/services/jni/com_android_server_InputWindowHandle.cpp b/services/jni/com_android_server_input_InputWindowHandle.cpp
similarity index 96%
rename from services/jni/com_android_server_InputWindowHandle.cpp
rename to services/jni/com_android_server_input_InputWindowHandle.cpp
index 0607eee..01fb781 100644
--- a/services/jni/com_android_server_InputWindowHandle.cpp
+++ b/services/jni/com_android_server_input_InputWindowHandle.cpp
@@ -24,8 +24,8 @@
 #include <android_view_InputChannel.h>
 #include <android/graphics/Region.h>
 
-#include "com_android_server_InputWindowHandle.h"
-#include "com_android_server_InputApplicationHandle.h"
+#include "com_android_server_input_InputWindowHandle.h"
+#include "com_android_server_input_InputApplicationHandle.h"
 
 namespace android {
 
@@ -218,19 +218,19 @@
         LOG_FATAL_IF(! var, "Unable to find field " fieldName);
 
 int register_android_server_InputWindowHandle(JNIEnv* env) {
-    int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputWindowHandle",
+    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputWindowHandle",
             gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods));
     LOG_FATAL_IF(res < 0, "Unable to register native methods.");
 
     jclass clazz;
-    FIND_CLASS(clazz, "com/android/server/wm/InputWindowHandle");
+    FIND_CLASS(clazz, "com/android/server/input/InputWindowHandle");
 
     GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, clazz,
             "ptr", "I");
 
     GET_FIELD_ID(gInputWindowHandleClassInfo.inputApplicationHandle,
             clazz,
-            "inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
+            "inputApplicationHandle", "Lcom/android/server/input/InputApplicationHandle;");
 
     GET_FIELD_ID(gInputWindowHandleClassInfo.inputChannel, clazz,
             "inputChannel", "Landroid/view/InputChannel;");
diff --git a/services/jni/com_android_server_InputWindowHandle.h b/services/jni/com_android_server_input_InputWindowHandle.h
similarity index 100%
rename from services/jni/com_android_server_InputWindowHandle.h
rename to services/jni/com_android_server_input_InputWindowHandle.h
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 60be35a..cc3c328 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -32,6 +32,7 @@
     <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
     <uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 88ee867..1773e33 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -70,6 +70,7 @@
 import android.os.INetworkManagementService;
 import android.os.IPowerManager;
 import android.os.MessageQueue.IdleHandler;
+import android.os.SystemClock;
 import android.os.UserId;
 import android.test.AndroidTestCase;
 import android.test.mock.MockPackageManager;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index daf20183..103d8e1 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -84,7 +84,7 @@
  */
 @LargeTest
 public class NetworkStatsServiceTest extends AndroidTestCase {
-    private static final String TAG = "NetworkStatsServiceTest";
+    private static final String TAG  = "NetworkStatsServiceTest";
 
     private static final String TEST_IFACE = "test0";
     private static final String TEST_IFACE2 = "test1";
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
index 7f05f56..e40f166 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
@@ -20,8 +20,6 @@
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 
 import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.NetworkIdentity;
 import android.net.NetworkStats;
 import android.net.NetworkTemplate;
 import android.test.AndroidTestCase;
@@ -145,12 +143,6 @@
         }
     }
 
-    public static NetworkIdentitySet buildWifiIdent() {
-        final NetworkIdentitySet set = new NetworkIdentitySet();
-        set.add(new NetworkIdentity(ConnectivityManager.TYPE_WIFI, 0, null, false));
-        return set;
-    }
-
     private static void assertSummaryTotal(NetworkStatsCollection collection,
             NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
         final NetworkStats.Entry entry = collection.getSummary(
diff --git a/telephony/java/android/telephony/CdmaCellIdentity.java b/telephony/java/android/telephony/CdmaCellIdentity.java
new file mode 100644
index 0000000..5b8454f
--- /dev/null
+++ b/telephony/java/android/telephony/CdmaCellIdentity.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * CellIdentity is to represent a unique CDMA cell
+ *
+ * @hide pending API review
+ */
+public final class CdmaCellIdentity extends CellIdentity implements Parcelable {
+    // Network Id 0..65535
+    private final int mNetworkId;
+    // CDMA System Id 0..32767
+    private final int mSystemId;
+    // Base Station Id 0..65535
+    private final int mBasestationId;
+    /**
+     * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+     * It is represented in units of 0.25 seconds and ranges from -2592000
+     * to 2592000, both values inclusive (corresponding to a range of -180
+     * to +180 degrees).
+     */
+    private final int mLongitude;
+    /**
+     * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+     * It is represented in units of 0.25 seconds and ranges from -1296000
+     * to 1296000, both values inclusive (corresponding to a range of -90
+     * to +90 degrees).
+     */
+    private final int mLatitude;
+
+    /**
+     * public constructor
+     * @param nid Network Id 0..65535
+     * @param sid CDMA System Id 0..32767
+     * @param bid Base Station Id 0..65535
+     * @param lon Longitude is a decimal number ranges from -2592000
+     *        to 2592000
+     * @param lat Latitude is a decimal number ranges from -1296000
+     *        to 1296000
+     * @param attr is comma separated “key=value” attribute pairs.
+     */
+    public CdmaCellIdentity (int nid, int sid,
+            int bid, int lon, int lat, String attr) {
+        super(CELLID_TYPE_CDMA, attr);
+        mNetworkId = nid;
+        mSystemId = sid;
+        mBasestationId = bid;
+        mLongitude = lon;
+        mLatitude = lat;
+    }
+
+    private CdmaCellIdentity(Parcel in) {
+        super(in);
+        mNetworkId = in.readInt();
+        mSystemId = in.readInt();
+        mBasestationId = in.readInt();
+        mLongitude = in.readInt();
+        mLatitude = in.readInt();
+    }
+
+    CdmaCellIdentity(CdmaCellIdentity cid) {
+        super(cid);
+        mNetworkId = cid.mNetworkId;
+        mSystemId = cid.mSystemId;
+        mBasestationId = cid.mBasestationId;
+        mLongitude = cid.mLongitude;
+        mLatitude = cid.mLatitude;
+    }
+
+    /**
+     * @return Network Id 0..65535
+     */
+    public int getNetworkId() {
+        return mNetworkId;
+    }
+
+    /**
+     * @return System Id 0..32767
+     */
+    public int getSystemId() {
+        return mSystemId;
+    }
+
+    /**
+     * @return Base Station Id 0..65535
+     */
+    public int getBasestationId() {
+        return mBasestationId;
+    }
+
+    /**
+     * @return Base station longitude, which is a decimal number as
+     * specified in 3GPP2 C.S0005-A v6.0. It is represented in units
+     * of 0.25 seconds and ranges from -2592000 to 2592000, both
+     * values inclusive (corresponding to a range of -180
+     * to +180 degrees).
+     */
+    public int getLongitude() {
+        return mLongitude;
+    }
+
+    /**
+     * @return Base station
+     */
+    /**
+     * @return Base station latitude, which is a decimal number as
+     * specified in 3GPP2 C.S0005-A v6.0. It is represented in units
+     * of 0.25 seconds and ranges from -1296000 to 1296000, both
+     * values inclusive (corresponding to a range of -90
+     * to +90 degrees).
+     */
+    public int getLatitude() {
+        return mLatitude;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(mNetworkId);
+        dest.writeInt(mSystemId);
+        dest.writeInt(mBasestationId);
+        dest.writeInt(mLongitude);
+        dest.writeInt(mLatitude);
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public static final Creator<CdmaCellIdentity> CREATOR =
+            new Creator<CdmaCellIdentity>() {
+        @Override
+        public CdmaCellIdentity createFromParcel(Parcel in) {
+            return new CdmaCellIdentity(in);
+        }
+
+        @Override
+        public CdmaCellIdentity[] newArray(int size) {
+            return new CdmaCellIdentity[size];
+        }
+    };
+}
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
new file mode 100644
index 0000000..65c220f
--- /dev/null
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * CellIdentity is to represent ONE unique cell in the world
+ * it contains all levels of info to identity country, carrier, etc.
+ *
+ * @hide pending API review
+ */
+public abstract class CellIdentity implements Parcelable {
+
+    // Cell is a GSM Cell {@link GsmCellIdentity}
+    public static final int CELLID_TYPE_GSM = 1;
+    // Cell is a CMDA Cell {@link CdmaCellIdentity}
+    public static final int CELLID_TYPE_CDMA = 2;
+    // Cell is a LTE Cell {@link LteCellIdentity}
+    public static final int CELLID_TYPE_LTE = 3;
+
+    private int mCellIdType;
+    private String mCellIdAttributes;
+
+    protected CellIdentity(int type, String attr) {
+        this.mCellIdType = type;
+        this.mCellIdAttributes = new String(attr);
+    }
+
+    protected CellIdentity(Parcel in) {
+        this.mCellIdType = in.readInt();
+        this.mCellIdAttributes = new String(in.readString());
+    }
+
+    protected CellIdentity(CellIdentity cid) {
+        this.mCellIdType = cid.mCellIdType;
+        this.mCellIdAttributes = new String(cid.mCellIdAttributes);
+    }
+
+    /**
+     * @return Cell Identity type as one of CELLID_TYPE_XXXX
+     */
+    public int getCellIdType() {
+        return mCellIdType;
+    }
+
+
+    /**
+     * @return Cell identity attribute pairs
+     * Comma separated “key=value” pairs.
+     *   key := must must an single alpha-numeric word
+     *   value := “quoted value string”
+     *
+     * Current list of keys and values:
+     *   type = fixed | mobile
+     */
+    public String getCellIdAttributes() {
+        return mCellIdAttributes;
+    }
+
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mCellIdType);
+        dest.writeString(mCellIdAttributes);
+    }
+}
diff --git a/telephony/java/android/telephony/CellInfo.aidl b/telephony/java/android/telephony/CellInfo.aidl
new file mode 100644
index 0000000..8bbb0b4
--- /dev/null
+++ b/telephony/java/android/telephony/CellInfo.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2007, 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.telephony;
+
+parcelable CellInfo;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
new file mode 100644
index 0000000..9bea30c
--- /dev/null
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represent one snapshot observation of one cell info
+ * which contains the time of observation.
+ *
+ * @hide Pending API review
+ */
+public final class CellInfo implements Parcelable {
+    // Type to distinguish where time stamp gets recorded.
+    public static final int CELL_INFO_TIMESTAMP_TYPE_UNKNOWN = 0;
+    public static final int CELL_INFO_TIMESTAMP_TYPE_ANTENNA = 1;
+    public static final int CELL_INFO_TIMESTAMP_TYPE_MODEM = 2;
+    public static final int CELL_INFO_TIMESTAMP_TYPE_OEM_RIL = 3;
+    public static final int CELL_INFO_TIMESTAMP_TYPE_JAVA_RIL = 4;
+
+    // Observation time stamped as type in nanoseconds since boot
+    private final long mTimeStamp;
+    // Where time stamp gets recorded.
+    // Value of CELL_INFO_TIMESTAMP_TYPE_XXXX
+    private final int mTimeStampType;
+
+    private final boolean mRegistered;
+
+    private final SignalStrength mStrength;
+    private final long mTimingAdvance;
+
+    private final int mCellIdentityType;
+    private final CellIdentity mCellIdentity;
+
+    /**
+     * Public constructor
+     * @param timeStampType is one of CELL_INFO_TIMESTAMP_TYPE_XXXX
+     * @param timeStamp is observation time in nanoseconds since boot
+     * @param timingAdv is observed timing advance
+     * @param registered is true when register to this cellIdentity
+     * @param strength is observed signal strength
+     * @param cellIdentity is observed mobile cell
+     */
+    public CellInfo(int timeStampType, long timeStamp, long timingAdv,
+            boolean registered, SignalStrength strength,
+            CellIdentity cellIdentity) {
+
+        if (timeStampType < CELL_INFO_TIMESTAMP_TYPE_UNKNOWN ||
+                timeStampType > CELL_INFO_TIMESTAMP_TYPE_JAVA_RIL) {
+            mTimeStampType = CELL_INFO_TIMESTAMP_TYPE_UNKNOWN;
+        } else {
+            mTimeStampType = timeStampType;
+        }
+
+        mRegistered = registered;
+        mTimeStamp = timeStamp;
+        mTimingAdvance = timingAdv;
+        mStrength = new SignalStrength(strength);
+
+        mCellIdentityType = cellIdentity.getCellIdType();
+        // TODO: make defense copy
+        mCellIdentity = cellIdentity;
+    }
+
+    public CellInfo(CellInfo ci) {
+        this.mTimeStampType = ci.mTimeStampType;
+        this.mRegistered = ci.mRegistered;
+        this.mTimeStamp = ci.mTimeStamp;
+        this.mTimingAdvance = ci.mTimingAdvance;
+        this.mCellIdentityType = ci.mCellIdentityType;
+        this.mStrength = new SignalStrength(ci.mStrength);
+        switch(mCellIdentityType) {
+            case CellIdentity.CELLID_TYPE_GSM:
+                mCellIdentity = new GsmCellIdentity((GsmCellIdentity)ci.mCellIdentity);
+                break;
+            default:
+                mCellIdentity = null;
+        }
+    }
+
+    private CellInfo(Parcel in) {
+        mTimeStampType = in.readInt();
+        mRegistered = (in.readInt() == 1) ? true : false;
+        mTimeStamp = in.readLong();
+        mTimingAdvance = in.readLong();
+        mCellIdentityType = in.readInt();
+        mStrength = SignalStrength.CREATOR.createFromParcel(in);
+        switch(mCellIdentityType) {
+            case CellIdentity.CELLID_TYPE_GSM:
+                mCellIdentity = GsmCellIdentity.CREATOR.createFromParcel(in);
+                break;
+            default:
+                mCellIdentity = null;
+        }
+    }
+
+    /**
+     * @return the observation time in nanoseconds since boot
+     */
+    public long getTimeStamp() {
+        return mTimeStamp;
+    }
+
+    /**
+     * @return Where time stamp gets recorded.
+     * one of CELL_INFO_TIMESTAMP_TYPE_XXXX
+     */
+    public int getTimeStampType() {
+        return mTimeStampType;
+    }
+
+    /**
+     * @return true when register to this cellIdentity
+     */
+    public boolean isRegistered() {
+        return mRegistered;
+    }
+
+    /**
+     * @return observed timing advance
+     */
+    public long getTimingAdvance() {
+        return mTimingAdvance;
+    }
+
+    /**
+     * @return observed signal strength
+     */
+    public SignalStrength getSignalStrength() {
+        // make a defense copy
+        return new SignalStrength(mStrength);
+    }
+
+    /**
+     * @return observed cell identity
+     */
+    public CellIdentity getCellIdentity() {
+        // TODO: make a defense copy
+        return mCellIdentity;
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("TimeStampType: ");
+        switch(mTimeStampType) {
+            case 1:
+                sb.append("antenna");
+                break;
+            case 2:
+                sb.append("modem");
+                break;
+            case 3:
+                sb.append("oem_ril");
+                break;
+            case 4:
+                sb.append("java_ril");
+                break;
+            default:
+                sb.append("unknown");
+        }
+        sb.append(", TimeStamp: ").append(mTimeStamp).append(" ns");
+        sb.append(", Registered: ").append(mRegistered ? "YES" : "NO");
+        sb.append(", TimingAdvance: ").append(mTimingAdvance);
+        sb.append(", Strength : " + mStrength);
+        sb.append(", Cell Iden: " + mCellIdentity);
+
+        return sb.toString();
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mTimeStampType);
+        dest.writeInt(mRegistered ? 1 : 0);
+        dest.writeLong(mTimeStamp);
+        dest.writeLong(mTimingAdvance);
+        dest.writeInt(mCellIdentityType);
+        mStrength.writeToParcel(dest, flags);
+        mCellIdentity.writeToParcel(dest, flags);
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public static final Creator<CellInfo> CREATOR =
+            new Creator<CellInfo>() {
+        @Override
+        public CellInfo createFromParcel(Parcel in) {
+            return new CellInfo(in);
+        }
+
+        @Override
+        public CellInfo[] newArray(int size) {
+            return new CellInfo[size];
+        }
+    };
+}
diff --git a/telephony/java/android/telephony/GsmCellIdentity.java b/telephony/java/android/telephony/GsmCellIdentity.java
new file mode 100644
index 0000000..159cb52
--- /dev/null
+++ b/telephony/java/android/telephony/GsmCellIdentity.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * CellIdentity to represent a unique GSM or UMTS cell
+ *
+ * @hide pending API review
+ */
+public final class GsmCellIdentity extends CellIdentity implements Parcelable {
+
+    // 3-digit Mobile Country Code, 0..999
+    private final int mMcc;
+    // 2 or 3-digit Mobile Network Code, 0..999
+    private final int mMnc;
+    // 16-bit Location Area Code, 0..65535
+    private final int mLac;
+    // 16-bit GSM Cell Identity described in TS 27.007, 0..65535
+    // 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455
+    private final int mCid;
+    // 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511
+    private final int mPsc;
+
+    /**
+     * public constructor
+     * @param mcc 3-digit Mobile Country Code, 0..999
+     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
+     * @param lac 16-bit Location Area Code, 0..65535
+     * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity
+     * @param psc 9-bit UMTS Primary Scrambling Code
+     * @param attr is comma separated “key=value” attribute pairs.
+     */
+    public GsmCellIdentity (int mcc, int mnc,
+            int lac, int cid, int psc, String attr) {
+        super(CELLID_TYPE_GSM, attr);
+        mMcc = mcc;
+        mMnc = mnc;
+        mLac = lac;
+        mCid = cid;
+        mPsc = psc;
+    }
+
+    private GsmCellIdentity(Parcel in) {
+        super(in);
+        mMcc = in.readInt();
+        mMnc = in.readInt();
+        mLac = in.readInt();
+        mCid = in.readInt();
+        mPsc = in.readInt();
+    }
+
+    GsmCellIdentity(GsmCellIdentity cid) {
+        super(cid);
+        mMcc = cid.mMcc;
+        mMnc = cid.mMnc;
+        mLac = cid.mLac;
+        mCid = cid.mCid;
+        mPsc = cid.mPsc;
+    }
+
+    /**
+     * @return 3-digit Mobile Country Code, 0..999
+     */
+    public int getMcc() {
+        return mMcc;
+    }
+
+    /**
+     * @return 2 or 3-digit Mobile Network Code, 0..999
+     */
+    public int getMnc() {
+        return mMnc;
+    }
+
+    /**
+     * @return 16-bit Location Area Code, 0..65535
+     */
+    public int getLac() {
+        return mLac;
+    }
+
+    /**
+     * @return CID
+     * Either 16-bit GSM Cell Identity described
+     * in TS 27.007, 0..65535
+     * or 28-bit UMTS Cell Identity described
+     * in TS 25.331, 0..268435455
+     */
+    public int getCid() {
+        return mCid;
+    }
+
+    /**
+     * @return 9-bit UMTS Primary Scrambling Code described in
+     * TS 25.331, 0..511
+     */
+    public int getPsc() {
+        return mPsc;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(mMcc);
+        dest.writeInt(mMnc);
+        dest.writeInt(mLac);
+        dest.writeInt(mCid);
+        dest.writeInt(mPsc);
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public static final Creator<GsmCellIdentity> CREATOR =
+            new Creator<GsmCellIdentity>() {
+        @Override
+        public GsmCellIdentity createFromParcel(Parcel in) {
+            return new GsmCellIdentity(in);
+        }
+
+        @Override
+        public GsmCellIdentity[] newArray(int size) {
+            return new GsmCellIdentity[size];
+        }
+    };
+}
diff --git a/telephony/java/android/telephony/LteCellIdentity.java b/telephony/java/android/telephony/LteCellIdentity.java
new file mode 100644
index 0000000..396922e
--- /dev/null
+++ b/telephony/java/android/telephony/LteCellIdentity.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * CellIdentity is to represent a unique LTE cell
+ *
+ * @hide pending API review
+ */
+public final class LteCellIdentity extends CellIdentity implements Parcelable {
+
+    // 3-digit Mobile Country Code, 0..999
+    private final int mMcc;
+    // 2 or 3-digit Mobile Network Code, 0..999
+    private final int mMnc;
+    // 28-bit cell identity
+    private final int mCi;
+    // physical cell id 0..503
+    private final int mPci;
+    // 16-bit tracking area code
+    private final int mTac;
+
+    /**
+     *
+     * @param mcc 3-digit Mobile Country Code, 0..999
+     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
+     * @param ci 28-bit Cell Identity
+     * @param pci Physical Cell Id 0..503
+     * @param tac 16-bit Tracking Area Code
+     * @param attr is comma separated “key=value” attribute pairs.
+     */
+    public LteCellIdentity (int mcc, int mnc,
+            int ci, int pci, int tac, String attr) {
+        super(CELLID_TYPE_CDMA, attr);
+        mMcc = mcc;
+        mMnc = mnc;
+        mCi = ci;
+        mPci = pci;
+        mTac = tac;
+    }
+
+    private LteCellIdentity(Parcel in) {
+        super(in);
+        mMcc = in.readInt();
+        mMnc = in.readInt();
+        mCi = in.readInt();
+        mPci = in.readInt();
+        mTac = in.readInt();
+    }
+
+    LteCellIdentity(LteCellIdentity cid) {
+        super(cid);
+        mMcc = cid.mMcc;
+        mMnc = cid.mMnc;
+        mCi = cid.mCi;
+        mPci = cid.mPci;
+        mTac = cid.mTac;
+    }
+
+    /**
+     * @return 3-digit Mobile Country Code, 0..999
+     */
+    public int getMcc() {
+        return mMcc;
+    }
+
+    /**
+     * @return 2 or 3-digit Mobile Network Code, 0..999
+     */
+    public int getMnc() {
+        return mMnc;
+    }
+
+    /**
+     * @return 28-bit Cell Identity
+     */
+    public int getCi() {
+        return mCi;
+    }
+
+    /**
+     * @return Physical Cell Id 0..503
+     */
+    public int getPci() {
+        return mPci;
+    }
+
+    /**
+     * @return 16-bit Tracking Area Code
+     */
+    public int getTac() {
+        return mTac;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(mMcc);
+        dest.writeInt(mMnc);
+        dest.writeInt(mCi);
+        dest.writeInt(mPci);
+        dest.writeInt(mTac);
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public static final Creator<LteCellIdentity> CREATOR =
+            new Creator<LteCellIdentity>() {
+        @Override
+        public LteCellIdentity createFromParcel(Parcel in) {
+            return new LteCellIdentity(in);
+        }
+
+        @Override
+        public LteCellIdentity[] newArray(int size) {
+            return new LteCellIdentity[size];
+        }
+    };
+}
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.aidl b/telephony/java/android/telephony/NeighboringCellInfo.aidl
index c464332..8588970 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.aidl
+++ b/telephony/java/android/telephony/NeighboringCellInfo.aidl
@@ -1,4 +1,4 @@
-/* //device/java/android/android/content/Intent.aidl
+/*
 **
 ** Copyright 2007, The Android Open Source Project
 **
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index eda9b71..698206c 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -22,6 +22,7 @@
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.CellLocation;
+import android.telephony.CellInfo;
 import android.util.Log;
 
 import com.android.internal.telephony.IPhoneStateListener;
@@ -156,6 +157,14 @@
      */
     public static final int LISTEN_OTASP_CHANGED                            = 0x00000200;
 
+    /**
+     * Listen for changes to observed cell info.
+     *
+     * @see #onCellInfoChanged
+     * @hide pending API review
+     */
+    public static final int LISTEN_CELL_INFO = 0x00000400;
+
     public PhoneStateListener() {
     }
 
@@ -276,6 +285,20 @@
     }
 
     /**
+     * Callback invoked when a observed cell info gets changed.
+     *
+     * A notification should be sent when:
+     *     1. a cell is newly-observed.
+     *     2. a observed cell is not visible.
+     *     3. any of the cell info of a observed cell has changed.
+     *
+     * @hide pending API review
+     */
+    public void onCellInfoChanged(CellInfo cellInfo) {
+        // default implementation empty
+    }
+
+    /**
      * The callback methods need to be called on the handler thread where
      * this object was created.  If the binder did that for us it'd be nice.
      */
@@ -323,6 +346,10 @@
         public void onOtaspChanged(int otaspMode) {
             Message.obtain(mHandler, LISTEN_OTASP_CHANGED, otaspMode, 0).sendToTarget();
         }
+
+        public void onCellInfoChanged(CellInfo cellInfo) {
+            Message.obtain(mHandler, LISTEN_CELL_INFO, 0, 0).sendToTarget();
+        }
     };
 
     Handler mHandler = new Handler() {
@@ -360,6 +387,8 @@
                 case LISTEN_OTASP_CHANGED:
                     PhoneStateListener.this.onOtaspChanged(msg.arg1);
                     break;
+                case LISTEN_CELL_INFO:
+                    PhoneStateListener.this.onCellInfoChanged((CellInfo)msg.obj);
             }
         }
     };
diff --git a/telephony/java/android/telephony/ServiceState.aidl b/telephony/java/android/telephony/ServiceState.aidl
index 8522889..830e2cbf 100644
--- a/telephony/java/android/telephony/ServiceState.aidl
+++ b/telephony/java/android/telephony/ServiceState.aidl
@@ -1,4 +1,4 @@
-/* //device/java/android/android/content/Intent.aidl
+/*
 **
 ** Copyright 2007, The Android Open Source Project
 **
diff --git a/telephony/java/android/telephony/SignalStrength.aidl b/telephony/java/android/telephony/SignalStrength.aidl
index c25411e..e988c5f 100644
--- a/telephony/java/android/telephony/SignalStrength.aidl
+++ b/telephony/java/android/telephony/SignalStrength.aidl
@@ -1,4 +1,4 @@
-/* //device/java/android/android/content/Intent.aidl
+/*
 **
 ** Copyright (C) 2009 Qualcomm Innovation Center, Inc.  All Rights Reserved.
 ** Copyright (C) 2009 The Android Open Source Project
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index db78e2e..bc50906 100755
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -23,7 +23,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
-import android.util.Log;
 
 import com.android.internal.telephony.IPhoneSubInfo;
 import com.android.internal.telephony.ITelephony;
@@ -85,6 +84,10 @@
         return sInstance;
     }
 
+    /** {@hide} */
+    public static TelephonyManager from(Context context) {
+        return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+    }
 
     //
     // Broadcast Intent actions
@@ -1138,4 +1141,24 @@
         return sContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_sms_capable);
     }
+
+    /**
+     * Returns all observed cell information of the device.
+     *
+     * @return List of CellInfo or null if info unavailable.
+     *
+     * <p>Requires Permission:
+     * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
+     *
+     * @hide pending API review
+     */
+    public List<CellInfo> getAllCellInfo() {
+        try {
+            return getITelephony().getAllCellInfo();
+        } catch (RemoteException ex) {
+            return null;
+        } catch (NullPointerException ex) {
+            return null;
+        }
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index f769157..eb78a53e 100644
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -21,6 +21,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.telephony.CellInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.util.Log;
@@ -156,6 +157,14 @@
         }
     }
 
+    public void notifyCellInfo(Phone sender, CellInfo cellInfo) {
+        try {
+            mRegistry.notifyCellInfo(cellInfo);
+        } catch (RemoteException ex) {
+
+        }
+    }
+
     public void notifyOtaspChanged(Phone sender, int otaspMode) {
         try {
             mRegistry.notifyOtaspChanged(otaspMode);
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 082c097..d6a1edd 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -19,6 +19,7 @@
 import android.os.Bundle;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
+import android.telephony.CellInfo;
 
 oneway interface IPhoneStateListener {
     void onServiceStateChanged(in ServiceState serviceState);
@@ -33,5 +34,6 @@
     void onDataActivity(int direction);
     void onSignalStrengthsChanged(in SignalStrength signalStrength);
     void onOtaspChanged(in int otaspMode);
+    void onCellInfoChanged(in CellInfo cellInfo);
 }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 19441cd..12a7286 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -19,6 +19,7 @@
 import android.os.Bundle;
 import java.util.List;
 import android.telephony.NeighboringCellInfo;
+import android.telephony.CellInfo;
 
 /**
  * Interface used to interact with the phone.  Mostly this is used by the
@@ -278,5 +279,10 @@
      * or {@link PHone#LTE_ON_CDMA_TRUE}
      */
     int getLteOnCdmaMode();
+
+    /**
+     * Returns the all observed cell information of the device.
+     */
+    List<CellInfo> getAllCellInfo();
 }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 1f19282..3c9a99b 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -22,6 +22,7 @@
 import android.os.Bundle;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
+import android.telephony.CellInfo;
 import com.android.internal.telephony.IPhoneStateListener;
 
 interface ITelephonyRegistry {
@@ -39,4 +40,5 @@
     void notifyDataConnectionFailed(String reason, String apnType);
     void notifyCellLocation(in Bundle cellLocation);
     void notifyOtaspChanged(in int otaspMode);
+    void notifyCellInfo(in CellInfo cellInfo);
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneNotifier.java b/telephony/java/com/android/internal/telephony/PhoneNotifier.java
index 28a8d22..1076870 100644
--- a/telephony/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/telephony/java/com/android/internal/telephony/PhoneNotifier.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import android.telephony.CellInfo;
+
 /**
  * {@hide}
  */
@@ -42,4 +44,7 @@
     public void notifyDataActivity(Phone sender);
 
     public void notifyOtaspChanged(Phone sender, int otaspMode);
+
+    // TODO - trigger notifyCellInfo from ServiceStateTracker
+    public void notifyCellInfo(Phone sender, CellInfo cellInfo);
 }
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
index 7bbe696..cb67a93 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import com.android.internal.telephony.Phone;
+import android.telephony.CellInfo;
 
 /**
  * Stub class used for unit tests
@@ -59,4 +60,7 @@
 
     public void notifyOtaspChanged(Phone sender, int otaspMode) {
     }
+
+    public void notifyCellInfo(Phone sender, CellInfo cellInfo) {
+    }
 }
diff --git a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
index a13c0c9..b7e80d4 100644
--- a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
+++ b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
@@ -52,7 +52,7 @@
      * Test that dumps all the data usage metrics for wifi to instrumentation out.
      */
     public void testWifiIdle() {
-        NetworkTemplate template = NetworkTemplate.buildTemplateWifi();
+        NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard();
         fetchStats(template);
     }
 
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index c3ac22c..1f6279c 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -255,41 +255,6 @@
 	}    
 
     @SmallTest
-    public void testINJECT_EVENTS() {
-        try {
-            mWm.injectKeyEvent(new KeyEvent(0, 0), false);
-            fail("IWindowManager.injectKeyEvent did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-        
-        try {
-            mWm.injectPointerEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0), false);
-            fail("IWindowManager.injectPointerEvent did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-        
-        try {
-            mWm.injectTrackballEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0), false);
-            fail("IWindowManager.injectTrackballEvent did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-    }
-    
-    @SmallTest
     public void testDISABLE_KEYGUARD() {
         Binder token = new Binder();
         try {
@@ -347,73 +312,9 @@
     }
     
     @SmallTest
-    public void testREAD_INPUT_STATE() {
-        try {
-            mWm.getSwitchState(0);
-            fail("IWindowManager.getSwitchState did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-        
-        try {
-            mWm.getSwitchStateForDevice(0, 0);
-            fail("IWindowManager.getSwitchStateForDevice did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-        
-        try {
-            mWm.getScancodeState(0);
-            fail("IWindowManager.getScancodeState did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-        
-        try {
-            mWm.getScancodeStateForDevice(0, 0);
-            fail("IWindowManager.getScancodeStateForDevice did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-        
-        try {
-            mWm.getKeycodeState(0);
-            fail("IWindowManager.getKeycodeState did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-        
-        try {
-            mWm.getKeycodeStateForDevice(0, 0);
-            fail("IWindowManager.getKeycodeStateForDevice did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-    }
-    
-    @SmallTest
     public void testSET_ORIENTATION() {
         try {
-            mWm.updateRotation(true);
-            mWm.getSwitchState(0);
+            mWm.updateRotation(true, false);
             fail("IWindowManager.updateRotation did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
@@ -424,7 +325,6 @@
 
         try {
             mWm.freezeRotation(-1);
-            mWm.getSwitchState(0);
             fail("IWindowManager.freezeRotation did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
@@ -435,7 +335,6 @@
 
         try {
             mWm.thawRotation();
-            mWm.getSwitchState(0);
             fail("IWindowManager.thawRotation did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 198fce4..689aa8e 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -639,6 +639,12 @@
             // If an app requests write storage, they will also get read storage.
             bool hasReadExternalStoragePermission = false;
 
+            // Implement transition to read and write call log.
+            bool hasReadContactsPermission = false;
+            bool hasWriteContactsPermission = false;
+            bool hasReadCallLogPermission = false;
+            bool hasWriteCallLogPermission = false;
+
             // This next group of variables is used to implement a group of
             // backward-compatibility heuristics necessitated by the addition of
             // some new uses-feature constants in 2.1 and 2.2. In most cases, the
@@ -1006,6 +1012,14 @@
                                 hasReadExternalStoragePermission = true;
                             } else if (name == "android.permission.READ_PHONE_STATE") {
                                 hasReadPhoneStatePermission = true;
+                            } else if (name == "android.permission.READ_CONTACTS") {
+                                hasReadContactsPermission = true;
+                            } else if (name == "android.permission.WRITE_CONTACTS") {
+                                hasWriteContactsPermission = true;
+                            } else if (name == "android.permission.READ_CALL_LOG") {
+                                hasReadCallLogPermission = true;
+                            } else if (name == "android.permission.WRITE_CALL_LOG") {
+                                hasWriteCallLogPermission = true;
                             }
                             printf("uses-permission:'%s'\n", name.string());
                         } else {
@@ -1181,6 +1195,16 @@
                 printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n");
             }
 
+            // Pre-JellyBean call log permission compatibility.
+            if (targetSdk < 16) {
+                if (!hasReadCallLogPermission && hasReadContactsPermission) {
+                    printf("uses-permission:'android.permission.READ_CALL_LOG'\n");
+                }
+                if (!hasWriteCallLogPermission && hasWriteContactsPermission) {
+                    printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n");
+                }
+            }
+
             /* The following blocks handle printing "inferred" uses-features, based
              * on whether related features or permissions are used by the app.
              * Note that the various spec*Feature variables denote whether the
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index 8b1d41a..e6c9351 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -88,7 +88,7 @@
     // ---- unused implementation of IWindowManager ----
 
     @Override
-    public boolean canStatusBarHide() throws RemoteException {
+    public boolean hasSystemNavBar() throws RemoteException {
         // TODO Auto-generated method stub
         return false;
     }
@@ -161,92 +161,11 @@
     }
 
     @Override
-    public int getDPadKeycodeState(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int getDPadScancodeState(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-
-    @Override
-    public InputDevice getInputDevice(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int[] getInputDeviceIds() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getKeycodeState(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int getKeycodeStateForDevice(int arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-
-    @Override
     public int getPendingAppTransition() throws RemoteException {
         // TODO Auto-generated method stub
         return 0;
     }
 
-
-    @Override
-    public int getScancodeState(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int getScancodeStateForDevice(int arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int getSwitchState(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int getSwitchStateForDevice(int arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int getTrackballKeycodeState(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int getTrackballScancodeState(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public boolean hasKeys(int[] arg0, boolean[] arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
     @Override
     public boolean inKeyguardRestrictedInputMode() throws RemoteException {
         // TODO Auto-generated method stub
@@ -254,30 +173,6 @@
     }
 
     @Override
-    public boolean injectInputEventNoWait(InputEvent arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean injectKeyEvent(KeyEvent arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean injectPointerEvent(MotionEvent arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean injectTrackballEvent(MotionEvent arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
     public boolean inputMethodClientHasFocus(IInputMethodClient arg0) throws RemoteException {
         // TODO Auto-generated method stub
         return false;
@@ -302,12 +197,6 @@
     }
 
     @Override
-    public InputChannel monitorInput(String arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
     public void moveAppToken(int arg0, IBinder arg1) throws RemoteException {
         // TODO Auto-generated method stub
 
@@ -462,15 +351,8 @@
     }
 
     @Override
-    public void setPointerSpeed(int arg0) throws RemoteException {
+    public void updateRotation(boolean arg0, boolean arg1) throws RemoteException {
         // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void updateRotation(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
     }
 
     @Override